Skip to content
Moritz Warning edited this page Apr 24, 2019 · 20 revisions

Layer 3 Routing of ZeroTier clients into an OpenWRT LAN

ZeroTier setup on OpenWRT

Installation

If not already installed, install ZeroTier on your router. On my router a TP-Link TL-WDR4300 with lede-17.01 branch (git-17.290.79498-d3f0685) / LEDE Reboot 17.01.4 r3560-79f57e422d I had to manually install the ZeroTier (1.1.14) package with the following commands:

root@openwrt:~# opkg update
root@openwrt:~# opkg install zerotier
Installing zerotier (1.1.14-4) to root...
...
Installing kmod-tun (4.4.92-1) to root...
...
Installing ip-tiny (4.4.0-9) to root...
...
Configuring kmod-tun.
Configuring ip-tiny.
Configuring zerotier.
Generate secret - please wait...
root@openwrt:~# 

ZeroTier service will autostart and join you to the public virtual network called Earth with network ID 8056c2e21c000001. Because this is maybe not what you want, you should stop the ZeroTier service for now:

root@openwrt:~# /etc/init.d/zerotier stop

Create your ZeroTier network

If not already done, create a network on any kind of ZeroTier controller. At least you could use the free service at https://my.zerotier.com to create a network.

My network setup looks like this (! not my real one !):

ZeroTier Controller
-------------------
Network ID: 8ad5123ed69d6f69
 IPv4 Auto-Assign (advanced)
  [x] Auto-Assign from Range: 172.28.28.1-172.28.28.255
 Managed Routes:
  172.28.28.0/24   (LAN)
  192.168.1.0/24   (172.28.28.1)
 IPv6 Auto-Assign
  [ ] ZeroTier RFC4193 (/128 for each device)
  [ ] ZeroTier 6PLANE (/80 routable for each device)
  [ ] Auto-Assign from Range

Configure ZeroTier on your OpenWRT router using UCI

The initial start of ZeroTier has created some unique files like your public/private key pair

/var/lib/zerotier-one/identity.public    # Your ZeroTier public key
/var/lib/zerotier-one/identity.secret    # Your ZeroTier private key
/var/lib/zerotier-one/authtoken.secret   # Your authentication token for the API (if ever needed)

A look at the uci config should show something like this:

root@openwrt:~# uci show zerotier
zerotier.sample_config=zerotier
zerotier.sample_config.enabled='1'
zerotier.sample_config.interface='wan'
zerotier.sample_config.join='8ad5123ed69d6f69'
zerotier.sample_config.secret='aabbccddee:0:5415e8....many...more...characters'

The zerotier.sample_config.secret is the content of /var/lib/zerotier-one/authtoken.secret

Join your ZeroTier network with OpenWRT

SSH into your OpenWRT router.

First we will disable the default sample_config of ZeroTier using the uci command line interface:

root@openwrt:~# uci set zerotier.sample_config.enabled='0'

Then we will configure a new ZeroTier connection with name openwrt_network using uci

root@openwrt:~# uci set zerotier.openwrt_network=zerotier
root@openwrt:~# uci set zerotier.openwrt_network.interface='wan'
root@openwrt:~# uci set zerotier.openwrt_network.secret="$(cat /var/lib/zerotier-one/identity.secret)"
root@openwrt:~# uci add_list zerotier.openwrt_network.join='8ad5123ed69d6f69'
root@openwrt:~# uci set zerotier.openwrt_network.enabled='1'
root@openwrt:~# uci commit zerotier

Hint: The zerotier.openwrt_network.join config variable is a so called list.

If you want to remove a network ID from the list use the following command:

root@openwrt:~# uci del_list zerotier.openwrt_network.join='<network id to remove from to join list>'

Now verify that /etc/config/zerotier represents your config, mine looks like this:

root@openwrt:~# cat /etc/config/zerotier

config zerotier 'sample_config'
        option interface 'wan'
        list join '8056c2e21c000001'
        option secret '<very long secret number>'
        option enabled '0'

config zerotier 'openwrt_network'
        option interface 'wan'
        option secret '<very long secret number>'
        option enabled '1'
        list join '8ad5123ed69d6f69'

As you can see, the sample_config is not enabled while openwrt_network is enabled.

If it looks similar on your end, reboot your router. (Yes, you must actually reboot your router here)

root@openwrt:~# reboot

After the reboot, re-login using SSH and verify that the ztXXXXXXXX interface is up and running. The XXXXXXXX is generated based on the network ID. zt0 is used as an short placeholder in the examples here.

root@openwrt:~# ifconfig zt0
zt0       Link encap:Ethernet  HWaddr 6A:2D:25:D7:33:02
          inet6 addr: fe80::682d:25ff:fed7:3302/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:2800  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:7 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B)  TX bytes:738 (738.0 B)

and your ZeroTier client should be in state online:

root@openwrt:~# zerotier-cli info
200 info 41c7017c10 ONLINE 1.1.14

After some time, your OpenWrt router should appear within your controller (my.zerotier.com or on your self-hosted one).

Make sure you Authorize the client, so it can pickup an IP from your network. Because we want to later route all traffic of all members of our ZeroTier Network ID into our LAN we make sure, that the ZeroTier IP address of our OpenWRT router is fixed to 172.28.28.1 by setting it up manually within the ZeroTier controller (eg. my.zerotier.com).

Hint If you change any network settings for the ZeroTier client running on your OpenWRT router you should reboot the router, because it will sometimes not pick up the changed configuration!

After authorization of the OpenWRT router as a ZeroTier client and after a reboot of your router, the router should pickup the config of your network (eg IP address) for its zt0 interface:

root@openwrt:~# ifconfig zt0
zt0       Link encap:Ethernet  HWaddr 6A:2D:25:D7:33:02
          inet addr:172.28.28.1  Bcast:172.28.28.255  Mask:255.255.255.0
          inet6 addr: fe80::d432:6dff:febe:dfc4/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:2800  Metric:1
          RX packets:699 errors:0 dropped:0 overruns:0 frame:0
          TX packets:707 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:71677 (69.9 KiB)  TX bytes:236370 (230.8 KiB)

It is now a good time to backup the configuration of your OpenWRT router before you continue.

Configure the routing within OpenWRT

Currently we have the following setup:

WAN-Interface of the OpenWRT router                   : a public IP on the internet
IP-Range of the LAN switch on the OpenWRT router      : 192.168.1.0/24
IP-Address of the zt0 interface on the OpenWRT router : 172.28.28.1
ZeroTier network route on the OpenWRT router          : 172.28.28.0/24 via zt0

Now we have to do some final setup within the web interface of the OpenWRT router:

Go to Network->Interfaces, click on Add new interface and enter the following settings:

Name of the new interface                : ZT0
Protocol of the new interface            : Unmanaged
Create a bridge over multiple interfaces : [ ]
Cover the following interface            : [x] zt0

Click on Submit and then on Save and Apply.

Then go to Network->Firewall, click on Add to create a new zone with the following settings:

Name: zero
Input: accept
Output: accept
Forward: accept
Masquerading: [ ]
MSS clamping: [ ]
Covered networks: [x] ZT0:
                  [ ] lan:
                  [ ] wan:
                  [ ] wan6:
Inter-Zone Forwarding
 Allow forward to destionation zones: [x] lan:
                                      [ ] wan: wan6:
 Allow forward from source zones    : [x] lan:
                                      [ ] wan: wan6:

Click on Save & Apply

I would now reboot the router again to make sure all the config is applied correctly.

Tests

Any ZeroTier client that now joins your ZeroTier Network (in my example: 8ad5123ed69d6f69) should automatically receive an IP address out of the 172.28.28.0/24 range while the ZeroTier client already running on your OpenWRT router has a fixed address of 172.28.28.1. Because of the route we set for the ZeroTier network within the ZeroTier controller at my.zerotier.com (192.168.1.0/24 via 172.28.18.1) any of your ZeroTier network members can now reach LAN-IPs (192.168.1.0/24) behind your OpenWRT router. Also allo ZeroTier clients (172.28.28.0/24) can reach each other.

How to compile ZeroTier using uClibc++

Note: Zerotier >1.1.14 cannot be compiled with uClibc++ anymore.

Install uClibc++

wget http://cxx.uclibc.org/src/uClibc++-0.2.4.tar.bz2
tar -xvjf uClibc++-0.2.4.tar.bz2
cd uClibc++-0.2.4
make

Now put this in the top section of Makefile in ZT source folder:

UC_INC=~/uClibc++-0.2.4/include
UC_LIB=~/uClibc++-0.2.4/src

LDFLAGS+= -L$(UC_LIB) -pthread
LDLIBS+= -L$(UC_LIB) -pthread -fno-builtin -nodefaultlibs -Wl,-Bstatic -luClibc++ -Wl,-Bdynamic  -lpthread -lm -lc -lsupc++ -lc -lgcc -lgcc_eh -lgcc_s  -lpthread -lm
CXXFLAGS+= -fno-builtin -nostdinc++ -I$(UC_INC) -DGCC_HASCLASSVISIBILITY -Wall -fPIE -fvisibility=hidden

Now call make.

Clone this wiki locally