Skip to content

Installing uNET in Ubuntu

Andy Milburn edited this page Aug 4, 2020 · 53 revisions
This has been tested on 14.04LTS, 16.04LTS, and 17.04 Ubuntu. 17.04 is wobbly (even without the uNET extension) so 16.04LTS is the recommended host os.

Acquire a uNET Address

First, you should request a new uNET address from Andy (andy@unet.technology). It will likely be of the form: uNET-LAB.XYZ-somename. If you're eager to play around, you can use one of our generic lab names:

The document Entity Names has a list of pre-configured entities. Please review it and follow those directions to get started. For larger entities or for situations where you will be interacting with other groups please contact Andy (andy@unet.technology) for a formally assigned name.

Virtual Box Settings

This has been tested on VirtualBox version 6.1.0 and version 5.2.8. The "Guest Additions" and Oracle Extensions Pack have intermittently interfered with the uNET kernel build. Be sure to note your version number when reporting issues to Andy

If you're installing onto a Virtual Box VM, create and launch a new VM in the usual way. 16.04LTS is the recommended OS, but others may work. Here's a link to download the 16.04LTS.iso. We're using the 64-bit option.

(Nat network with a name net TBD)

uNET itself has a very small footprint, but Ubuntu is a giant resource hog so we suggest configuring your VM to use 8gig of RAM and 20gig of disk space.

Once Linux is installed you're ready to configure and launch the VM. First, configure the network to enable multiple VMs within a single computer to communicate using uNET. Under the Machine->Settings->Network menu, choose "Network-Bridged Adapter".

We recommend you create a snapshot at this stage, so that you can always return to this machine state if something goes wrong with the uNET installation.

If you're making clones of snapshots, make sure the master image has its Network set to the default setting Nat. Also choose the option to reinitialize the MAC Address of all network cards and perform a full clone.

We recommend installing the latest "Guest Additions" provided by VirtualBox, and then within the VirtualBox "Devices" menu, choosing the "Bidirectional" option under "Shared Clipboards". This will allow you to copy commands from this installation wiki and then paste them (Shift+Ctrl+V) into the VirtualBox Terminal window for execution.

If the Virtual Box Additions install fails with a "modprobe" failure then reboot find the mount location of the VBox additions (use the command mount) and execute:

sudo ./VBoxLinuxAdditions.run
VirtualBox 5.2 NOTE: With the update to 5.2, we've noticed that the mouse cursor can vanish intermittently when inside the VM. If you "hide" the VM for several minutes(!) and then bring it forward again we find that this problems is resolved. This problem is recurring but inconsistent -- we're hoping to find a permanent fix soon. (Andy 02.22.18)

The Linux installation into the VM will take several minutes. While that is occurring read through the rest of this document.

uNET Pre-Configuration

Prior to installing uNET, we recommend the following optional steps to make the environment consistent with the ones here in the lab:

Find the "Terminal" application using the widget in the top-left corner, launch it, and then choose "Lock To Launcher" so that's it's always handy.


Change the hostname (usually defaults to "template") to match your uNET name in two files:

sudo vi /etc/hosts
sudo vi /etc/hostname

Note: if you're installing onto VirtualBox and you gave the VM a name during setup then you can skip this step.


Customize the tty prompt:

sudo vi /etc/bash.bashrc

and add the line:

unet-status -v

to the bottom of the file.


Install the uNET kernel extension for Linux

Change the working directory to be where the uNET installation files will be saved. For example

mkdir uNET
cd uNET

Pull down the uNET installation files.

wget unet.technology/unet-install.sh
chmod a+x unet-install.sh
sudo ./unet-install.sh |& tee output

This will install a number of files. You'll eventually be prompted to reboot in order to continue the installation.

sudo reboot

During the reboot, you'll be presented with the Unix GRUB menu. Use this to select the newly-installed uNET kernel. It's likely there will be more than one version of the kernel available on your system. To choose the new uNET kernel, look for the one with "yocto-standard" in it's title, probably under the 'Ubuntu Advanced Options' submenu. See below for an example:

After the reboot, check the status of uNET using.

dmesg | grep unet

You should see a log message indicating that uNET has been activated, and several happy-looking crypto messages. The main thing you're looking for is one that says "uNET activated." If you see this, you can finally, run:

sudo unet-provision

You'll be prompted for the uNET address you requested / chose earlier. If there are no error msgs, then reboot one more time:

sudo reboot

And after the reboot, check the uNET status with:

unet-status -v

Congratulations!

At this point it's important to save a "snapshot" of the VM. You can always return to this snapshot while testing in order to begin with a set of consistent initial conditions. When making multiple VMs, it's helpful to produce each one in isolation (no other VM instances running) so that this saved snapshot captures a state that contains no information about other network nodes.

Of course, there's not much you can do with only a single uNET node, so we suggest you repeat this process, choosing a new name and being careful to use the same "Bridged Adapater" settings above, so you'll have two uNET nodes that can see each other. You can then proceed to the "Testing" section below.

Testing

To begin testing, you'll need two or more VM instances (or actual Linux boxes) each with a uNET kernel installed. The first, simple test is to confirm that the two (or more) instances can "see" each other. In uNET, this is called "visibility".

uNET Visibility

Launch a single instance (or boot a single machine), in isolation (no other uNET devices connected). Check its status:

unet-status -v

You should see something like this:

-------------------------------------------------------------------------
Kern bld: #95 SMP PREEMPT Sun Aug 13 09:55:33 PDT 2017 - LAB: (1.89)
-------------------------------------------------------------------------
Local: uNET-LAB.DTLA-marsha
-------------------------------------------------------------------------
No connected entities.
-------------------------------------------------------------------------
No remote entities.
-------------------------------------------------------------------------

Now launch another VM (or machine). Remember that if you're using VMs it's important to launch them from the snapshot that you saved when the instance was in isolation. For actual hardware devices this is of course irrelevant. After booting up, check its status with:

unet-status -v

Initially this will report the same thing as the first instance, but after 10 or 20 seconds, running that unet-status command will produce something like:

-------------------------------------------------------------------------
Kern bld: #95 SMP PREEMPT Sun Aug 13 09:55:33 PDT 2017 - LAB: (1.89)
-------------------------------------------------------------------------
Local: uNET-LAB.DTLA-marsha
-------------------------------------------------------------------------
       uNET-LAB.DTLA-foster
            role: child
-------------------------------------------------------------------------

Similarly, on the first instance, unet-status will now report on the presence of the second instance.

Troubleshooting:
If the two instances don't "see" each other (as reported by uNET-status), make sure both have their Network Settings attached to the "Bridged Adapter". If they still aren't connecting, contact Andy!
If either instance reports "no uNET" in response to "unet-status", it has probably booted using the wrong kernel instance. Reboot and use the GRUB menu to choose the uNET-enabled kernel.

Testing with unetdrive

Instead of using "unet-status -v" you can simply run

unetdrive

Note that this command will "hang" in the terminal -- it presents a live interface, updated in realtime. Typing 'q' will exit the unetdrive command-line interface.

When invoked with no arguments, unetdrive simply monitors the visible uNET network. As you boot up additional instances, you will see them appear on the this interface.

To test connectivity, typing 'p' (for 'ping') followed by the uNET address of another node on the network, will send a small data packet to the other node, which it will then return. Each interface will flash briefly to indicate receipt of this packet. Note that you needn't type the entire uNET address here, just enough characters (> 1) to differentiate it from any other nodes.

If you're interested, now would be a good time to boot up Wireshark or any other network monitoring tools you like, to watch the uNET traffic running over the network. You'll be able to observe the small, efficient packets, but of course you won't be able to read anything beyond the initial headers due to the layered encryption.

Virtual Box Snapshots and Time Travel Paradoxes

When using Virtual Box VMs, it's possible (actually easy!) to produce anomalous network conditions which are counterintuitive. This is because the VM snapshots are, by definition, highly stateful. They preserve lots of detailed information about the conditions of the network at the moment the snapshot is taken. uNET networks are also stateful, so it's very easy to get the two systems into a disagreement about the nature of reality. Note that this is only an issue when testing on VMs -- hardware devices don't have this ability to travel back in time and so are much easier to use.

uNET is designed to handle devices suddenly disappearing / reappearing / spoofing / etc so it can be useful to take advantage of VMs in this way, but initially you should try to keep things simple. As a general rule, only ever launch a VM from a restored snapshot taken when that VM was alone on the network (alone with respect to the Bridged Adapter).

To make this easy, we're in the habit of always restoring to such a snapshot whenever we power down an instance, so it's ready to go the next time we need it. Just check the box "Restore current snapshot" whenever you close in instance, and things will be much less confusing.

Encryption and Load Testing

unetdrive has many more parameters and commands available designed to drive data across uNET connections and to gather statistical information about the performance of those connections.

Refer to the current Release Notes for features available for testing in the current build.

sudo unetdrive -h
Usage: unetdrive [options] <server-address>
Options: -[s:w:p:m:i:e:t:hvb]
  -s, --size <arg>     
	Size of packets (default is 1024)
  -w, --wait <arg>     
	Wait between packets (milliseconds, default is 4 - float)
  -p, --protocol <arg> 
	Protol (udp|tcp|ip-raw|unet|unet-raw) unet is default
  -m, --mt <arg>       
	Message type (default is 1200)
  -i, --id <arg>       
	Application id (default is app.chat)
  -e, --endpoint <arg> 
	Endpoint (ip address of server - udp only)
  -t, --target <arg>   
	Target total data to test (in mB)
  -h, --help           
	Print this help and exit
  -v, --version        
	Print version and exit
  -b, --bi-drectional  
	Bidirectional data gathering

The purpose of this app is to monitor the uNET network (displaying live entity status information), and to drive data among the uNET entities in several ways. The protocol can also be switched to UDP with the -p option for comparative testing. Note that for udp, the client will need to provide the IP address of the server using the -e option.

Simply running

unetdrive

will display status information about all visible uNET nodes, and their topology. This information updates automatically as changes in the uNET network take place.

uNET v 0.24 - ram: 6949.8

parent: uNET-LAB.DTLA-lee

#####   ####### #         ###                             ##                    #
 #   #     #    #        #   #                             #       #            #
 #    #    #    #       #     #                            #                    #
 #    #    #    #       #     #         # # ##   ####      #      ##     ####   #   #
 #    #    #    #       ####### ####### ## #  #      #     #       #    #    #  #  #
 #    #    #    #       #     #         #  #  #  #####     #       #    #       # #
 #    #    #    #       #     #         #  #  # #     #    #       #    #       ## #
 #   #     #    #       #     #         #  #  # #    ##    #       #    #    #  #   #
#####      #    ####### #     #         #  #  #  #### #   ###     ###    ####   #    #



+--------------------------------------+--------------------------------------+
|uNET-LAB.DTLA-lee                     |uNET-LAB.DTLA-kubrik                  |
|parent_connected             ref(186) |child_to_be                  ref(1)   |
+--------------------------------------+--------------------------------------+
uNET-LAB.DTLA-malick:app.unetdrive messageType: 52000 role: server peer: uNET-LAB.DTLA-lee:#.0
pong:sdfsdf
Listening for clients in 'uNET-LAB.DTLA-malick:app.unetdrive'
p: ping an entity, e: toggle emissions, c/C: crypto, d/D: debugging, q: quit

Using unetdrive in Two-Way Mode

You can also use unetdrive to test pushing data over the uNET network using standard linux sockets. (See the helloworld project for some example code if you're interested in writing your own user space applications that use uNET).

If you launch:

unetdrive

on a machine with the uNET address uNET-LAB.broderick, and on some other machine you launch:

unetdrive uNET-LAB.broderick

unetdrive will open two-way socket communication between the machines. The first machine (uNET-LAB.broderick) is running in "server" mode, and the second is in "client" mode. You can "text chat" between them by simply typing at the live unetdrive prompts on either machine.

When two machines are connected in this way, you can initiate a load-test of the data connection, by typing "e" at the prompt on either machine's running unetdrive instance. There are a variety of options you can adjust with respect to the size / speed / type / amount of data that will be driven.

Note that "uNET-LAB.broderick" in the example above will autocomplete (hit TAB after typing the first few characters) using network knowledge about the names of any visible uNET nodes.

There a some other useful scripts located in /usr/local/bin:

unet-status

Displays version information about the kernel and about the lab tools. The "-v" options adds information about all known entities.


unet-ping <name> <payload [optional]>

Will "ping" the named uNET node, and display roundtrip information. Note that "name" will autocomplete (hit TAB) using network knowledge about the names of any visible uNET nodes.


unet-disable / unet-enable

These turn off / on the uNET kernel service.


uNET-debug <0/1>

Turns on or off writing debug info to /var/log/kern.log.


unet-window-mon <optional-grep-string>

Opens up a new terminal window that displays the live output of the debugging console. Also turns on debugging.


uNet IP bridging

It is possible to configure a point to point IP link over unet. This requires a unet enabled iproute2

On instance #1 issue:

root@qemux86-64-john:~# ip link add name unet0 type unet local-entity 0.123456 remote-entity 1.abcdef0
root@qemux86-64-john:~# ip link set dev unet0 up
root@qemux86-64-john:~# ip route add 10.10.0.0/16 dev unet0
root@qemux86-64-john:~# ip address add 10.11.0.1/16 dev eth0

This creates a tunneling unet0 interface, installs a route at it (10.10.0.0/16) which also adding an alias address (10.11.0.1/16) on eth0.

On instance #2 issue:

root@qemux86-64-alice:~# ip link add name unet0 type unet local-entity 1.abcdef0 remote-entity 0.123456
root@qemux86-64-alice:~# ip link set dev unet0 up
root@qemux86-64-alice:~# ip route add 10.11.0.0/16 dev unet0
root@qemux86-64-alice:~# ip address add 10.10.0.1/16 dev eth0

This creates a tunneling unet0 interface, installs a route at it (10.11.0.0/16) which also adding an alias address (10.10.0.1/16) on eth0.

We can now ping the IP address of the other end; on instance #1.

root@qemux86-64-john:~# ping -c 1 10.10.0.1
PING 10.10.0.1 (10.10.0.1): 56 data bytes
64 bytes from 10.10.0.1: seq=0 ttl=64 time=78.127 ms

--- 10.10.0.1 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 78.127/78.127/78.127 ms

While on instance #2

root@qemux86-64-alice:~# ping -c 1 10.11.0.1
PING 10.11.0.1 (10.11.0.1): 56 data bytes
64 bytes from 10.11.0.1: seq=0 ttl=64 time=68.493 ms

--- 10.11.0.1 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 68.493/68.493/68.493 ms

Configfs options

Configuration for unet is performed via the configfs filesystem.

The root unet configuration directory is /config/unet and the available configuration options are:

Timeouts

  • apca_timeout Number of milliseconds to wait collecting APCA replies before moving to register. Default value is 500ms.
  • apcr_max_timeout Maximum timeout for exponential backoff of APCR messages. Default value is 250ms.
  • apcr_min_timeout Minimum timeout for exponential backoff of APCR messages. Default value is 30000ms (30 sec).
  • child_idle_timeout Period of inactivity until a child is moved to non-connected state. Default value is 30000ms (30 sec).
  • housekeeping_timeout Period of housekeeping activity. Smaller values increase CPU time but increase fidelity. Default value is 1000ms (1 sec).
  • keepalive_period Period after which we request a keepalive. Default value is 1000ms (1 sec).
  • register_timeout Period after which we resend a register request. Default value is 500ms.
  • reject_backoff Period of time we honor a previous register reject. Default value is 30000ms (30 sec).

Counters

  • keepalive_max Number of keepalives sent before declaring peer is unreachable. Default value is 3.
  • register_retries Number of retries when sending a register message. Default value is 3.

Boolean switches

  • children_count_policy If true, top bits of score is 32-log2(children-count). Default value is true.
  • random_score_policy If true, the lower 32 bits of score is randomly generated. If false it's a hash of the address of the sender. Default value is false.
  • strict_hierarchical_routing If true only communicate which attached peers (parent and children). If false any visible entity may be directly accessed. Default is true. Note that encryption requires this to be true.
  • force_relay_da_upstream If true forward DAs even from known originators. Default is false.
  • force_relay_rfdr_upstream If true forward RFDRs even from known originators. Default is false.
  • only_forward_from_valid_senders If true, only forward from valid senders. Default is true.
  • relay_disconnect_announce_upstream If true, forward all DAs upstream. Default is false.
  • try_reconnect_to_children If true, send reconnect to all children when entity is registered. Default is true.

Trust certicates

  • trust_chain The trust chain of the host. Default is empty.

Entities are created by issuing mkdir in the entities/ directory.

Valid configuration options of the entity are:

  • id binary override for id. Default is generated by parsing the name of the directory.
  • prefix binary override for prefix. Default is generated by parsing the name of the directory.
  • can_be_router If true entity advertises self as router. Default is true.
  • dev_class Class of the entity, by default is 2 (LINUX Box).
  • force_parent Forced parent of the entity. Default is empty.
  • cert The X.509 certificate of the entity. Default is empty.
  • privkey The PKCS8 private key of the entity. Default is empty.
  • enable If true, the entity is enabled. Default is false. This must be set as true as last step of configuration.

App entries are created by issuing mkdir in the apps/ directory.

Valid configuration options of the app entry are:

  • id binary override for id. Default is generated by parsing the name of the directory.
  • prefix binary override for prefix. Default is generated by parsing the name of the directory.
  • enable If true, the app entry is enabled. Default is false. This must be set as true as last step of configuration.

All other not listed attributes are for debugging purposes only and may be removed at any time.

Updates

Periodically the uNET team will issue updates to the lab software or the kernel itself. At each system boot, uNET checks for these updates. The lab software will update itself, but if there's a change to the kernel extension, you'll be asked to manually update the kernel with:

sudo unet-install-kernel
sudo reboot

Note that when running from VMs (such as VirtualBox), you need to explicitly reboot to have the update checking performed. Loading from a snapshot won't do this.

Clone this wiki locally