Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
docs:techref:unetd [2022/08/27 21:30] – created nbddocs:techref:unetd [2023/12/22 01:17] (current) – [Example setup] systemcrash
Line 1: Line 1:
 ====== unetd ====== ====== unetd ======
 unetd is a WireGuard based VPN daemon that simplifies creating and managing fully-meshed VPN connections between OpenWrt routers. unetd is a WireGuard based VPN daemon that simplifies creating and managing fully-meshed VPN connections between OpenWrt routers.
 +
 +Source: [[commit>project/unetd.git]]
  
 ===== Features ===== ===== Features =====
Line 20: Line 22:
       * configurable domain suffix       * configurable domain suffix
     * allows creating freeform service definitions, which allows services to query member IP addresses using ubus     * allows creating freeform service definitions, which allows services to query member IP addresses using ubus
 +    * Supports peer discovery via BitTorrent 'Mainline' DHT, which works even through double-NAT
 +
 +===== Building =====
 +==== OpenWrt ====
 +TBC
 +==== Linux ====
 +The following build dependencies are required:
 +    * cmake, pkg-config
 +    * libelf-dev, zlib1g-dev, libjson-c-dev
 +To build:
 +<code>
 +git clone https://git.openwrt.org/project/unetd.git
 +cd unetd
 +./build.sh
 +</code>
  
 ===== Example setup ===== ===== Example setup =====
  
-This set of example commands assumes two OpenWrt routers with the IP addresses ''192.168.1.13'' and ''192.168.1.15'' which have **not** been configured for unetd yet.+=== Preparation ===
  
-This creates a new JSON file test.json and also generates a signing key as test.json.key (if it doesn't exist already):+This set of example commands assumes two OpenWRT routers with the IP addresses ''192.168.1.13'' and ''192.168.1.15'' which have **not** been configured for unetd yet, each has ''unetd'', ''unet-cli'' and ''unet-tool'' installed. ''vxlan'' (and its implied ''kmod-vxlan'') are also installed. The assumption here is that the local host, here say ''192.168.1.2'' has these installed, and also forms a unet node. 
 + 
 +Note: ''unetd'' is not yet capable of installing these prerequisites above via ''opkg''.  
 + 
 +=== Example === 
 + 
 + 
 +This creates a new JSON file ''test.json'' locally and also generates a signing key in ''test.json.key'' locally (if it doesn't exist already):
   # unet-cli test.json create   # unet-cli test.json create
-This creates a VXLAN tunnel definition and adds all hosts that are members of the ''ap'' group:+ 
 +Result: 
 +<code>test.json: 
 +
 + "config":
 + "port": 51830, 
 + "keepalive": 10, 
 + "peer-exchange-port": 51831 
 + }, 
 + "hosts":
 + }, 
 + "services":
 +
 +
 +</code> 
 + 
 + 
 +This creates a VXLAN tunnel definition in ''test.json'' and predicates hosts that are to be members of it via the ''ap'' group:
   # unet-cli test.json add-service l2-tunnel type=vxlan members=@ap   # unet-cli test.json add-service l2-tunnel type=vxlan members=@ap
-This connects to 192.168.1.13 over SSH, generates an unetd interface named ''unet'', along with new host keys, puts in the signing key and also tells it to create the ''vx0'' vxlan device connected to the ''l2-tunnel'' service description we created in the last command, storing the public keys in test.json, along with the endpoint address ''192.168.1.13'':+ 
 +Result: 
 +<code>test.json: 
 +
 + ... 
 + "services":
 + "l2-tunnel":
 + "config":
 + }, 
 + "members":
 + "@ap" 
 + ], 
 + "type": "vxlan" 
 +
 +
 +
 +</code> 
 + 
 +This connects to 192.168.1.13 over SSH, and on 192.168.1.13, generates an unetd interface named ''unet'', along with new host keys, puts in the signing key and also tells it to create the ''vx0'' VXLAN device connected to the ''l2-tunnel'' service description we created in the last command, storing its public key in the local ''test.json'', along with its endpoint address ''192.168.1.13'':
   # unet-cli test.json add-ssh-host ap1 root@192.168.1.13 endpoint=192.168.1.13 tunnels=vx0:l2-tunnel groups=ap   # unet-cli test.json add-ssh-host ap1 root@192.168.1.13 endpoint=192.168.1.13 tunnels=vx0:l2-tunnel groups=ap
 +
 +Note: you will authenticate via SSH, either user:pass or key based, if that was set up in advance.
 +
 +Result:
 +<code>test.json:
 +{
 + ...
 + "hosts": {
 + "ap1": {
 + "key": "....=",
 + "endpoint": "192.168.1.13",
 + "groups": [
 + "ap"
 + ]
 + }
 + },
 + ...
 +}</code>
 +
 This does the same for the other host: This does the same for the other host:
   # unet-cli test.json add-ssh-host ap2 root@192.168.1.15 endpoint=192.168.1.15 tunnels=vx0:l2-tunnel groups=ap   # unet-cli test.json add-ssh-host ap2 root@192.168.1.15 endpoint=192.168.1.15 tunnels=vx0:l2-tunnel groups=ap
 +
 +Result:
 +<code>test.json:
 +{
 + ...
 + "hosts": {
 + ...
 + "ap2": {
 + "key": "...=",
 + "endpoint": "192.168.178.1",
 + "groups": [
 + "ap"
 + ]
 + }
 + },
 + ...
 +}</code>
 +
 This signs the network data and uploads it to unetd running on 192.168.1.13: This signs the network data and uploads it to unetd running on 192.168.1.13:
   # unet-cli test.json sign upload=192.168.1.13   # unet-cli test.json sign upload=192.168.1.13
      
-Please note that in this case, uploading the data to one of the two hosts is enough, because once it has processed the update, it will find the endpoint address of the other host and sync the network data with it automatically. After that last command, the unetd network should be up on both sides and the VXLAN tunnel created as well.+By now, uploading the data to one of the two hosts is enough, because once it (192.168.1.13) has processed the update, it (192.168.1.13) will find the endpoint address of the other host (192.168.1.15) and sync the network data with it automatically. After that last command, the unetd network should be up on both sidesand the VXLAN tunnel created as well.
  
 ===== Configuration ===== ===== Configuration =====
Line 51: Line 147:
 | ''connect'' | list | | List of external unetd host IP addresses to download network config updates from | | ''connect'' | list | | List of external unetd host IP addresses to download network config updates from |
 | ''domain'' | string | | Domain suffix for hosts in the generated hosts file | | ''domain'' | string | | Domain suffix for hosts in the generated hosts file |
 +| ''dht'' | boolean | | Enable DHT peer discovery for this network |
  
 The ''connect'' option only needs to be used for bootstrapping the setup in case you're not uploading the network data to the node directly. The ''connect'' option only needs to be used for bootstrapping the setup in case you're not uploading the network data to the node directly.
Line 65: Line 162:
                 "port": 51830,                 "port": 51830,
                 "keepalive": 10,                 "keepalive": 10,
-                "peer-exchange-port": 51831+                "peer-exchange-port": 51831
 +                "stun-servers":
 +                        "stun.l.google.com:19302", 
 +                        "stun1.l.google.com:19302" 
 +                ]
         },         },
         "hosts": {         "hosts": {
Line 99: Line 200:
 == Config properties: == == Config properties: ==
  
-^ Name ^ Type ^ Description ^ +^ Name                    ^ Type              ^ Description                                                                 
-| port | int | Wireguard tunnel port (can be overriden for individual hosts) | +''port''                | int               | Wireguard tunnel port (can be overriden for individual hosts)               
-| keepalive | int | Interval (in seconds) for keepalive and forcing peer reconnection attempts | +''keepalive''           | int               | Interval (in seconds) for keepalive and forcing peer reconnection attempts  
-| peer-exchange-port | int | Port for exchanging peer messages on the WireGuard tunnel |+''peer-exchange-port''  | int               | Port for exchanging peer messages on the WireGuard tunnel (0: disabled)     | 
 +| ''stun-servers''        | array of strings  | List of STUN servers written as hostname:port strings                       |
  
 == Host properties: == == Host properties: ==
  
-^ Name ^ Type ^ Description ^ +^ Name                    ^ Type              ^ Description                                                                                                               
-| key | string | Wireguard public key | +''key''                 | string            | Wireguard public key                                                                                                      
-| groups | array of strings | Names of groups that the host is a member of | +''groups''              | array of strings  | Names of groups that the host is a member of                                                                              
-| ipaddr | array of strings | Local IP addresses of the host (IPv4 or IPv6) | +''ipaddr''              | array of strings  | Local IP addresses of the host (IPv4 or IPv6)                                                                             
-| subnet | array of strings | Subnets routed by the host (IPv4 or IPv6) (format: ''<addr>/<mask>'') | +''subnet''              | array of strings  | Subnets routed by the host (IPv4 or IPv6) (format: ''<addr>/<mask>''                                                    
-| port | int | Wireguard tunnel port (overrides ''config'' property) | +''port''                | int               | Wireguard tunnel port (overrides ''config'' property)                                                                     
-| endpoint | string | Public endpoint address (format: ''<addr>'' for IPv4, ''[<addr>]'' for IPv6 with optional '':<port>'' suffix) | +''peer-exchange-port''  | int               | Host specific port for exchanging peer messages on the WireGuard tunnel (0: disabled)                                     | 
-| gateway | string | Name of another host to use as gateway (can be used for avoiding direct connections with all other peers from this host) |+| ''endpoint''            | string            | Public endpoint address (format: ''<addr>'' for IPv4, ''[<addr>]'' for IPv6 with optional '':<port>'' suffix)             
 +''gateway''             | string            | Name of another host to use as gateway (can be used for avoiding direct connections with all other peers from this host)  |
  
 == Service properties == == Service properties ==
  
-^ Name ^ Type ^ Description ^ +^ Name         ^ Type              ^ Description                                                    
-| type | string | Service type | +''type''     | string            | Service type                                                   
-| config | object | Service type specific config options | +''config''   | object            | Service type specific config options                           
-| members | array of strings | Members assigned to this service (use ''@<name>'' for groups) |+''members''  | array of strings  | Members assigned to this service (use ''@<name>'' for groups)  |
  
 ==== CLI usage ==== ==== CLI usage ====
Line 145: Line 248:
       - config options (create, set-config):       - config options (create, set-config):
         port=<val>                              set tunnel port (default: 51830)         port=<val>                              set tunnel port (default: 51830)
-        pex_port=<val>                          set peer-exchange port (default: 51831)+        pex_port=<val>                          set peer-exchange port (default: 51831, 0: disabled)
         keepalive=<val>                         set keepalive interval (seconds, 0: off, default: 10)         keepalive=<val>                         set keepalive interval (seconds, 0: off, default: 10)
 +        stun=[+|-]<host:port>[,<host:port>...]  set/add/remove STUN servers
       - host options (add-host, add-ssh-host, set-host):       - host options (add-host, add-ssh-host, set-host):
         key=<val>                               set host public key (required for add-host)         key=<val>                               set host public key (required for add-host)
         port=<val>                              set host tunnel port number         port=<val>                              set host tunnel port number
 +        pex_port=<val>                          set host peer-exchange port (default: network pex_port, 0: disabled)
         groups=[+|-]<val>[,<val>...]            set/add/remove groups that the host is a member of         groups=[+|-]<val>[,<val>...]            set/add/remove groups that the host is a member of
         ipaddr=[+|-]<val>[,<val>...]            set/add/remove host ip addresses         ipaddr=[+|-]<val>[,<val>...]            set/add/remove host ip addresses
Line 174: Line 279:
  
 </code> </code>
 +
 +==== DHT support ====
 +
 +For DHT peer discovery, the unet-dht package needs to be installed, and dht enabled in the interface on the nodes. For NAT support, you also need to configure at least one working STUN server in the network data. While peers can find each other through DHT directly, STUN is needed for figuring out the external wireguard port and establishing a network connection over it.
 +Please note that DHT based discovery needs some time for peers to actually discover each other, sometimes 1-3 minutes.
 +
  • Last modified: 2022/08/27 21:30
  • by nbd