Bridging WiFi clients to a cloud VM through ZeroTier tunnels

What the setup needs to achieve?

When a phone is connected to the WiFi SSID of the OpenWrt router, it should be able to browse the internet through the L2 ZeroTier tunnel running on the OpenWrt router.

What is not working?

When I connect my phone to the WiFi SSID, it shows Limited Connection. The speed test sometimes works and fails the other times after doing ping (I am using Ookla’s speedtest app). Browsing the internet is a hit or a miss. I can send text messages, but can’t upload pictures.

The current setup

I have installed ZeroTier 1.10.6 on a cloud VM running Debian 11. I am using this VM both as a ZeroTier controller and exit node for the network traffic.

I created a network on controller with following configuration:

Output of /var/lib/zerotier-one/controller.d/network/[redacted].json:

{
    "authTokens": [null],
    "authorizationEndpoint": "",
    "capabilities": [],
    "clientId": "",
    "creationTime": 1692789775339,
    "dns": {
        "domain": "",
        "servers": []
    },
    "enableBroadcast": true,
    "id": "[redacted]",
    "ipAssignmentPools": [{
        "ipRangeEnd": "172.18.0.255",
        "ipRangeStart": "172.18.0.1"
    }],
    "mtu": 2800,
    "multicastLimit": 32,
    "name": "ZeroTier",
    "nwid": "[redacted]",
    "objtype": "network",
    "private": true,
    "remoteTraceLevel": 0,
    "remoteTraceTarget": null,
    "revision": 7,
    "routes": [{
        "target": "172.18.0.0/24",
        "via": null
    }],
    "rules": [{
        "etherType": 2048,
        "not": true,
        "or": false,
        "type": "MATCH_ETHERTYPE"
    }, {
        "etherType": 2054,
        "not": true,
        "or": false,
        "type": "MATCH_ETHERTYPE"
    }, {
        "etherType": 34525,
        "not": true,
        "or": false,
        "type": "MATCH_ETHERTYPE"
    }, {
        "type": "ACTION_DROP"
    }, {
        "type": "ACTION_ACCEPT"
    }],
    "rulesSource": "",
    "ssoEnabled": false,
    "tags": [],
    "v4AssignMode": {
        "zt": false
    },
    "v6AssignMode": {
        "6plane": false,
        "rfc4193": false,
        "zt": false
    }
}

I then added this VM to the network using zerotier-cli join [redacted-network_id].

This is the output of zerotier-cli listnetworks:

200 listnetworks <nwid> <name> <mac> <status> <type> <dev> <ZT assigned ips>
200 listnetworks [redacted-network-id] ZeroTier [redacted-mac] OK PRIVATE [redacted-ifname] 172.18.0.1/24

I then created a bridge on the VM, br-wifi and added the zerotier interface on the VM:

# brctl show
bridge name	bridge id		STP enabled	interfaces
br-wifi		8000.a26b65ed1275	no		[redacted-zerotier-ifname]

I added an IP address to the bridge interface, and configured dnsmasq to listen on this bridge

# ip addr show br-wifi
15: br-wifi: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1370 qdisc noqueue state UP group default qlen 1000
    link/ether a2:6b:65:ed:12:75 brd ff:ff:ff:ff:ff:ff
    inet 172.24.0.1/24 scope global br-wifi
       valid_lft forever preferred_lft forever
    inet6 fe80::a06b:65ff:feed:1275/64 scope link 
       valid_lft forever preferred_lft forever

Note: The WiFi clients connected to the OpenWrt router are supposed to get IP address assigned from this bridge.

I updated the firewall rules to allow traffic the ZeroTier and br-wifi interface and added
this rule in the NAT table:

iptables -t nat -A POSTROUTING -o ens4 -j MASQUERADE

I also enabled the IPv4 packet forwarding using this command:

sysctl net.ipv4.ip_forward

On the OpenWrt router, I installed the Zerotier package (1.6.5) and joined the same network. I created a WiFi interface (wlan1) on OpenWrt device and bridged it to the ZeroTier interface:

# brctl show 
bridge name	bridge id		STP enabled	interfaces
br-br_zt		7fff.cedda7e37fde	no	        wlan1
						                        [redacted-zerotier-ifname]
13: br-br_zt: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 66:10:85:b3:5f:b1 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::6410:85ff:feb3:5fb1/64 scope link 
       valid_lft forever preferred_lft forever
14: wlan1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-br_zt state UP group default qlen 1000
    link/ether e8:48:b8:80:24:bc brd ff:ff:ff:ff:ff:ff
    inet6 fe80::ea48:b8ff:fe80:24bc/64 scope link 
       valid_lft forever preferred_lft forever
15: [redacted-zerotier-ifname]: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 2800 qdisc fq_codel master br-br_zt state UNKNOWN group default qlen 1000
    link/ether ce:b8:44:93:8f:bc brd ff:ff:ff:ff:ff:ff
    inet 172.18.0.3/24 brd 172.18.0.255 scope global [redacted-zerotier-ifname]
       valid_lft forever preferred_lft forever

I enabled the ethernet bridging on the ZeroTier controller for both the devices (OpenWrt and VM).

When I connect my phone to the WiFi SSID of the OpenWrt router, my phone gets an IP address from the VM, but it shows limited connectivity.

Do you have a specific need for bridging? If you just want phones to browse out of somewhere then I would think default routing would suffice.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.