Nabto Edge TCP Tunnel Step-by-Step Guide

This thorough guide will show you how to setup the ready-made Nabto client and device tunnel endpoints to enable TCP remote access to your existing TCP services.

All the scenarios demonstrated through the commandline tunnel client app can be implemented in e.g. a mobile app; the commandline app is a good way to play with the different pairing modes supported by the Nabto IAM module - you can then select the mode (or modes) suitable for your specific scenario.

Nabto Cloud Configuration

To use Nabto Edge, you must first create a free account through the Nabto Cloud Console if not done already.

Once you have created an account, navigate to the Products page create a new Nabto Edge product. Note down the product ID.

Under this product under “settings”, add the “Public TCP Tunnel Client” App from the “Apps” tab.

In the “Configured Devices” tab, create a new device. From the device page, note the device ID.

You are now ready to start building the Embedded tunnel device application.

Embedded tunnel application

The embedded tunnel application is available as part of the Nabto Edge Embedded SDK. To build the embedded tunnel application, follow the build instructions for the general SDK build. Or you can download pre-compiled binaries.

After building or downloading binaries, run the device with the --init argument to configure your device and, when queried, provide the Product ID and Device ID from the previous section.

When asked if custom IAM state is needed, type y to be able to pick which pairing modes should be enabled. For this tutorial, we will enable Local Initial Pairing and Password Invite Pairing modes. To learn more about pairing modes and which to enable for your use case see our pairing guide.

$ ./tcp_tunnel_device --init
The device configuration home//config/device.json does not exists. Creating a new config.
Product Id: pr-aaaaaaaa
Device Id: de-bbbbbbbb
The IAM configuration home//config/device.json does not exists. Creating a new IAM configuration.
No IAM state file exists home//state/tcp_tunnel_device_iam_state.json. Creating a new IAM state
Do you want to create a custom IAM State? [y/n]: y
Creating custom iam configuration
Enable Local Initial Pairing: [y/n]: y
Enable Local Open Pairing: [y/n]: n
Enable Password Invite Pairing: [y/n]: y
Enable Password Open Pairing: [y/n]: n
The configuration and state has been initialized
The device Fingerprint is: 08c955a5f7505f16f03bc3e3e0db89ff56ce571e0dd6be153c5bae9174d62ac6

With the configuration in place, you are almost ready to start the device: The Nabto Edge Cloud services do not yet know the public key fingerprint of the device, and will reject the device.

To register the fingerprint, go to the device configuration page in the Nabto Cloud console (first click product, then click the device in question). Then enter the fingerprint from the command line output - in the example above the value is 08c955a5f7505f16f03bc3e3e0db89ff56ce571e0dd6be153c5bae9174d62ac6 - copy this value from your own tunnel output to the device fingerprint config on the Nabto Cloud console and save.

Now start the device with any arguments and it should be able to attach (note: on Windows, you may see a firewall popup - if so, you need to allow the tunnel application to listen for incoming connections):

$ ./tcp_tunnel_device
######## Nabto TCP Tunnel Device ########
# Product ID:        pr-aaaaaaaa
# Device ID:         de-bbbbbbbb
# Fingerprint:       08c955a5f7505f16f03bc3e3e0db89ff56ce571e0dd6be153c5bae9174d62ac6
# Version:           5.2.0
# Local UDP Port:    5592
#
# The device is not yet paired with the initial user. You can use Local Initial Pairing to get access.
#
# The initial user has not been paired yet. You can pair with the device using Password Invite Pairing.
# Initial Pairing Usermame:  admin
# Initial Pairing Password:  sCUhpbiRpjEc
# Initial Pairing SCT:       FUmot9E9XCKW
# Initial Pairing String:    p=pr-aaaaaaaa,d=de-bbbbbbbb,u=admin,pwd=sCUhpbiRpjEc,sct=FUmot9E9XCKW
#
######## Configured TCP Services ########
# Id               Type             Host             Port
# ssh              ssh              127.0.0.1        22
########
Attached to the basestation

Client tunnel application

The Nabto Edge TCP tunnel client is available through its own github repo. The client can be downloaded as a release asset binary, or you can build it yourself from source using the guide on the repo.

To use the client with the device, it must first be paired. To understand different pairing modes and role-based user permissions see the IAM guide. When pairing, a user is created for the client on the device. In the tunnel app, this user can be assigned three roles with decreasing amount of privileges: Administrator, Standard, and Guest.

The first user pairing with the device should be an administrator. The administrator has two ways to pair with the device:

If the client is located on the same subnet as the device, Local Initial Pairing can be used (since we enabled this during device initialization).

If the client and device are not on the same subnet, the administrator must pair using Password Invite Pairing that works both locally and remotely (also enabled during device initialization).

After pairing is complete, the tunnel client app adds a bookmark to allow quickly connecting later. The bookmark contains device identification info, the device’s public key fingerprint for authenticating it and a token that allows remote connections through the Nabto servers.

Local Initial Pairing

Running the client with the --pair-local option starts local discovery of the device using mDNS. When discovery is completed, the client will show a list of discovered devices. Pick your device from the list and press enter.

$ ./edge_tunnel_client --pair-local
Scanning for local devices for 2 seconds.
Found 1 local devices.
Choose a device for pairing:
[q]: Quit without pairing
[0]: ProductId: pr-aaaaaaaa DeviceId: de-bbbbbbbb
Choose a device: 0
Connected to the device. ProductId: pr-aaaaaaa DeviceId: de-bbbbbbbb
Several pairing modes exists choose one of the following.
[0]: Password Invite
[1]: Local Initial
Choose a pairing mode:

The client now lists the two pairing modes we enabled for the device. Pick Local Initial.

Choose a pairing mode: 1
The device [0] pr-aaaaaaaa.de-bbbbbbbb has been set into the bookmarks as index 0

If your device is not available locally, you can use password invite pairing below. Otherwise, you are now ready to start using your tunnel.

Password Invite Pairing for the administrator

As evident from the options output during Local Initial Pairing attempt above, the Password Invite pairing can also be done using the --pair-local option if the device can be discovered locally by mDNS. If the device cannot be discovered locally, the client needs five pieces of information: the Product, the Device ID, the username, the password, and a server connect token (SCT). With this information, the client is able to connect to and pair with the device either locally or remotely through the Nabto servers.

The TCP tunnel device comes with a pre-created administrator we must use for this initial pairing with the username admin. The password and SCT is generated by the device. Fortunately, the device prints all this information in an Initial Pairing String which we can copy, and pass to the client using the --pair-string option. Again, the available pairing modes will be listed, pick the Password Invite mode.

$ ./edge_tunnel_client --pair-string \
    p=pr-aaaaaaaa,d=de-bbbbbbbb,u=admin,pwd=bRrAAaoCTceN,sct=HRAMTPdhsqhs
Connected to device ProductId: pr-aaaaaaaa DeviceId: de-bbbbbbbb
Several pairing modes exists choose one of the following.
[0]: Password Invite
[1]: Local Initial
Choose a pairing mode: 0
The device [0] pr-aaaaaaaa.de-bbbbbbbb has been set into the bookmarks as index 0

Once the admin user is paired, additional uses of the pairing string will be rejected by the device (also if the admin was paired with Local Initial pairing). To pair additional users see Pairing more clients.

Using the tunnel

You are now ready to start using the tunnel. Now you can list the available services as provided by the device:

$ ./edge_tunnel_client --services
Connected to the device [0] pr-aaaaaaa.de-bbbbbbbb
Available services ...
Service: ssh        Type: ssh        Host: 127.0.0.1  Port: 22

Per default, the tunnel supports just the ssh service, see below on how to add another service. You can then start the service as follows:

$ ./tcp_tunnel_client --service ssh
Connected to the device [0] pr-aaaaaaaa.de-bbbbbbbb
TCP Tunnel opened for the service ssh listening on the local port 52530

Now you can connect an ssh client to localhost port 52530 to access the ssh service running on the same host as the embedded device application.

Access your remote service

The available services to be tunnelled by the device are defined in the configuration file ~/.nabto/edge/config/tcp_tunnel_device_services.json. To add e.g. a tunnel for an http server running on port 8081, add an entry to this file (note the JSON array syntax), then restart the device.

[
  {"Id":"ssh","Type":"ssh","Host":"127.0.0.1","Port":22},
  {"Id":"nginx","Type":"http","Host":"127.0.0.1","Port":8081}
]
$ ./tcp_tunnel_client  --services
Connected to the device [0] pr-aaaaaaaa.de-bbbbbbbb
Available services ...
Service: ssh        Type: ssh        Host: 127.0.0.1  Port: 22
Service: nginx      Type: http       Host: 127.0.0.1  Port: 8081

So now you can start an http tunnel:

$ ./tcp_tunnel_client  --service nginx
TCP Tunnel opened for the service nginx listening on the local port 52716

And then in another terminal, you can access the TCP service:

$ curl localhost:52716
<html>
  <body>
     <h1>Hello, world!</h1>
  </boddy>
</html>

Pairing more clients

The client now paired is the Administrator. This means the Local Initial Pairing pairing mode is disabled for further pairing, and only the Password Invite Pairing pairing mode is available. Therefore, no new clients can be paired unless the administrator creates an invitation or enables the open pairing modes as described below.

To invite a new client, start by creating a new user on the device - this can be done from the tunnel client using the --create-user option. The client will then prompt for a username and which role to assign to the new user. Assign the Standard role.

$ ./edge_tunnel_client --create-user
Connected to the device [0] pr-aaaaaaaa.de-bbbbbbbb
Choose a username for the new user.
Username: myname
Pick a role for the user
[q] Quit
[0] Administrator
[1] Guest
[2] Standard
[3] Unpaired
Choose a role: 2
Created a new user in the system
Username:        myname
Role:            Standard
SCT:             Z7mrJiMavc0T
Password:        ocueXffGnxnS
Pairing String:  p=pr-aaaaaaaa,d=de-bbbbbbbb,u=myname,pwd=ocueXffGnxnS,sct=Z7mrJiMavc0T

When the user is created, the client prints a Pairing String which can be passed on to the new client. To start a new client, either run the client on a seperate PC or provide a fresh home directory for the same client:

$ mkdir home-invite
$ ./edge_tunnel_client -H home-invite/ --pair-string \
   p=pr-aaaaaaaa,d=de-bbbbbbbb,u=myname,pwd=ocueXffGnxnS,sct=Z7mrJiMavc0T
Connected to device ProductId: pr-aaaaaaaa DeviceId: de-bbbbbbbb
The device [0] pr-aaaaaaaa.de-bbbbbbbb has been set into the bookmarks as index 0

The client now recognizes that only one pairing mode is available, and pairs without further prompts.

The new user can now use the device:

$ ./edge_tunnel_client -H home-invite/ --get-me
Connected to the device [0] pr-aaaaaaaa.de-bbbbbbbb
Username: myname, Role: Standard, SCT: Z7mrJiMavc0T, Fingerprint:  \
  06c0e14df2854a17504c653caaaae544d45327bc3a484f05947e8820df40f348

When initializing the device, we disabled Local Open Pairing and Password Open Pairing. The administrator can enable these to allow new clients to pair without the administrator needing to take action:

$ ./edge_tunnel_client --configure-open-pairing
Connected to the device [0] pr-aaaaaaaa.de-bbbbbbbb
Configuring open pairing.
Open pairing allows users to register themselves in the device.
Allow Local Open Pairing [y/n]: y
Allow Password Open Pairing [y/n]: y
To pair with the device using the password open pairing method use the following information
# Product Id:                          pr-f4nqpowq
# Device Id:                           de-m99qzink
# Password Open Password:              XgqCmc3aKuTT
# Password Open Server Connect Token:  VJdgfhrKpNM3
# Password Open Pairing String:        p=pr-f4nqpowq,d=de-m99qzink,pwd=XgqCmc3aKuTT,sct=VJdgfhrKpNM3

Password open pairing

After enabling the Password Open pairing mode, the client app outputs a pairing string to use for such pairing: Any client anywhere (local or remote) who specifies this pairing string are now allowed to pair without approval from the administrator. If you compare to the pairing string described above for Password Invite pairing, this string does not contain a username.

Users paired with an open pairing mode are assigned a role as per the device configuration - for the tunnel device application, this role is Guest.

Local open pairing

Local open pairing requires the client to be on the same subnet as the device, and is performed like Local Initial Pairing, using the --pair-local option, except the Local Initial pairing mode is not available. Instead pick the Local Open pairing mode. Again we are using a new home directory to get a client which is not already paired.

$ mkdir home-local
$ ./edge_tunnel_client -H home-local --pair-local
Scanning for local devices for 2 seconds.
Found 1 local devices.
Choose a device for pairing:
[q]: Quit without pairing
[0]: ProductId: pr-aaaaaaaa DeviceId: de-bbbbbbbb
Choose a device: 0
Connected to the device. ProductId: pr-aaaaaaa DeviceId: de-bbbbbbbb
Several pairing modes exists choose one of the following.
[0]: Password Open
[1]: Local Open
[2]: Password Invite
Choose a pairing mode: 1
The pairing needs a username, the username needs to be unique among the users registered in the device.
Username: localuser
The device [0] pr-aaaaaaaa.de-bbbbbbbb has been set into the bookmarks as index 0

The newly paired client is given the Guest role:

$ ./edge_tunnel_client --get-me
Connected to the device [0] pr-aaaaaaaa.de-bbbbbbbb
Username: localuser, Role: Guest, SCT: iYC2YqFFaqar, Fingerprint: 2ac884c766ea4833465808b5b65db04d959baf19768c574a88b674efcfa38573

Password Open pairing

If the device is available locally, Password Open pairing can be done similar to the local open pairing using the --pair-local option in the client and picking Password Open. You will then be prompted for your desired username and the open pairing password.

If the device is not available locally and a remote connection is needed, you can use the --pair-string option just like the password invite pairing mode (but using the pairing string from when Password Open pairing was enabled):

$ mkdir home-password
$ ./edge_tunnel_client -H home-password/ --pair-string p=pr-f4nqpowq,d=de-m99qzink,pwd=XgqCmc3aKuTT,sct=VJdgfhrKpNM3
Connected to device ProductId: pr-f4nqpowq DeviceId: de-m99qzink
Several pairing modes exists choose one of the following.
[0]: Password Open
[1]: Local Open
[2]: Password Invite
Choose a pairing mode: 0
Open Password Pairing requires a username. The username is a name you choose for the new user, the username has to be unique among the registered users on the device.
New Username: passworduser
The device [0] pr-f4nqpowq.de-m99qzink has been set into the bookmarks as index 0

This pairing works equally well locally and remote. Again the user is given the Guest role:

$ ./edge_tunnel_client -H home-password/ --get-me
Connected to the device [0] pr-f4nqpowq.de-m99qzink
Username: passworduser, Role: Guest, SCT: 5tfLZE5RCrV9, Fingerprint: d10ff29b14f2559ed8e0ae54e83c789b067a19055a61c5386bcf02595840c9a6