How can I route all internet traffic through Zerotier?

Hi everyone,

I installed Zerotier on my devices and set it all up so I can access my home network remotely.
It’s working perfectly, i.e. I can access all my NAS, router etc. at home from abroad.

However, my internet connection is not being routed through my home router. This is needed because I would like to watch local news videos etc.

Could someone help me on how to do this?

Here is the output of route etc.

piclient@piclient-desktop:~$ route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
default _gateway 0.0.0.0 UG 601 0 0 wlan1
10.42.0.0 0.0.0.0 255.255.255.0 U 600 0 0 wlan0
link-local 0.0.0.0 255.255.0.0 U 1000 0 0 wlan0
192.168.0.0 0.0.0.0 255.255.254.0 U 0 0 0 zerotier12
192.168.1.0 0.0.0.0 255.255.255.0 U 601 0 0 wlan1

piclient@piclient-desktop:~$ ip route list
default via 192.168.1.1 dev wlan1 proto dhcp metric 601
10.42.0.0/24 dev wlan0 proto kernel scope link src 10.42.0.1 metric 600
169.254.0.0/16 dev wlan0 scope link metric 1000
192.168.0.0/23 dev zerotier12 proto kernel scope link src 192.168.0.3
192.168.1.0/24 dev wlan1 proto kernel scope link src 192.168.1.103 metric 601
root@piclient-desktop:/home/piclient#

Do I need to change something on the server? Since everything else is working just fine, I am guessing that my client just somehow needs to be told to route all internet traffic through Zerotier rather than directly through wlan1, correct?

Thank you for your help!

Alex

Welcome! We have an article in the KB
https://zerotier.atlassian.net/wiki/spaces/SD/pages/7110693/Overriding+Default+Route+Full+Tunnel+Mode

Let us know how it goes.

Hello Travis,
thank you for your reply. I actually saw that article during me search. So it is not a question of just changing the default gateway in Ubuntu Mate but actually changing the server and the Zerotier config?

If so, the article mentions my public IP.
I do not have a public IPv4. That’s why I am using Zerotier because all other VPNs are not able to connect from an IPv4 only hotel hotspot to my IPv6 only home network.

So will this solution not work for me then?

Edit:
Additional question from me: Is my traffic right now already being routed through my Zerotier interface but then not directed to my home network because it is not a LAN request?

Setup:

  • Raspberry Pi running Ubuntu Mate 20.04 set up as my “Server” in my home. Currently 192.168.0.2
  • Raspberry Pi running Ubuntu Mate 20.04 set up as my “Client” in my hotel room (route output posted above). Currently 192.168.0.3.

I want all internet traffic from any app on the “Client” to go through the router connected to my “Server” with the IP 192.168.0.1

Right now I can access 192.168.0.x from my “Client” but not the internet through 192.168.0.1
So is this a problem in my Zerotier network configuration (online), my “Server” configuration, my “Client” configuration or all of them?
It seems like this should be so simple. Just tell the “Client” to send all internet traffic through 192.168.0.1 but I am guessing it is not?

You can use MASQUERADE instead of SNAT and the rest should be the same.

It’d be similar to this but using 0.0.0.0/0 like in the full-tunnel article instead of a specific subnet.

Hello Travis,

I added an edit before or while you replied.

Right now these are my iptables:
“Server”:

root@piclient-desktop:/etc# iptables-save

Generated by iptables-save v1.8.4 on Tue Sep 22 20:41:26 2020

*filter
:INPUT ACCEPT [10342:2161582]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [17618:8035097]
:sshguard - [0:0]
COMMIT

Completed on Tue Sep 22 20:41:26 2020

root@piclient-desktop:/etc#

“Client”

Generated by iptables-save v1.8.4 on Tue Sep 22 21:33:10 2020

*nat
:PREROUTING ACCEPT [21884:7848217]
:INPUT ACCEPT [447:134995]
:OUTPUT ACCEPT [3415:223164]
:POSTROUTING ACCEPT [3384:219164]
-A POSTROUTING -s 10.42.0.0/24 ! -d 10.42.0.0/24 -j MASQUERADE
COMMIT

Completed on Tue Sep 22 21:33:10 2020

Generated by iptables-save v1.8.4 on Tue Sep 22 21:33:10 2020

*filter
:INPUT ACCEPT [104848:33118495]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [197549:31491237]
:sshguard - [0:0]
-A INPUT -i wlan0 -p udp -m udp --dport 67 -j ACCEPT
-A INPUT -i wlan0 -p tcp -m tcp --dport 67 -j ACCEPT
-A INPUT -i wlan0 -p udp -m udp --dport 53 -j ACCEPT
-A INPUT -i wlan0 -p tcp -m tcp --dport 53 -j ACCEPT
-A FORWARD -d 10.42.0.0/24 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -s 10.42.0.0/24 -i wlan0 -j ACCEPT
-A FORWARD -i wlan0 -o wlan0 -j ACCEPT
-A FORWARD -o wlan0 -j REJECT --reject-with icmp-port-unreachable
-A FORWARD -i wlan0 -j REJECT --reject-with icmp-port-unreachable
COMMIT

Completed on Tue Sep 22 21:33:10 2020

root@piclient-desktop:/etc#

By the way, I need to be careful what I change on the server as it is 3000 miles away right now and any change needs to work :wink:

Best regards
Alex

Sounds like all machines are running linux. In this case, don’t forget step 3a in this guide:

https://zerotier.atlassian.net/wiki/spaces/SD/pages/7110693/Overriding+Default+Route+Full+Tunnel+Mode

the rp_filter setting needs to be set on linux clients in most cases.

1 Like

So, taking into account all my edits and comments above, you are saying that I need to set this iptables on my “Server”:

*nat

:PREROUTING ACCEPT [0:0]

:INPUT ACCEPT [0:0]

:OUTPUT ACCEPT [0:0]

:POSTROUTING ACCEPT [0:0]

-A POSTROUTING -o wlan0 -s 10.42.0.0 /22 `-j MASQUERADE

COMMIT

*filter

:INPUT ACCEPT [0:0]

:FORWARD DROP [0:0]

-A FORWARD -i zerotier12 -s 10.42.0.0 /22 -d 0.0.0.0 /0 -j ACCEPT

-A FORWARD -i wlan0 -s 0.0.0.0 /0 -d 10.42.0.0 /0 -j ACCEPT

:OUTPUT ACCEPT [0:0]

COMMIT

And then add the route
0.0.0.0/0 via 192.168.0.2
in the webconfig.

Then run
sudo zerotier-cli set <networkId> allowDefault= 1
on my “Client” or “Server”? I am guessing Server, is this correct?

And finally
sudo sysctl -w net.ipv4.conf.all.rp_filter= 2
on my Server? Or is this a Client command? Again I am guessing Server.

Server and Client, as mentioned above, are running Ubuntu Mate 20.04.

I see the edit now. A couple things:

Can you make your zerotier subnet be something other than 192.168.0.0/23. It looks like one of your physical networks is 192.168.1.0/24 which overlaps (and 192.168.1.0/24 is super common). Just use one of the “easy” ranges.

The " Route between ZeroTier and Physical Networks" article should work for this as far as firewall config goes. The masquerade stuff goes on the “server”; You don’t need to change the firewall on the “client”

zerotier will add the [0.0.0.0/0] via [server-zerotier-ip] managed route, as long as sudo zerotier-cli set <networkId> allowDefault=1 is enabled. This is how the “client” os knows to route through “server”

I always end up locking myself out eventually. :sweat_smile:

You can do something like questionable iptables commands; sleep 60; iptables-restore failsafe-rules

On the Linux clients, actually

On any client that wants to use the “router” as it’s default route.
non-linux clients have checkboxes for it.

It’s the other way around.
My physical network is 192.168.0.0 and my Zerotier is 192.168.1.0.
Is there a mistake in one of my settings? I am just asking because you swapped the two which maybe was because you read something that points to this conclusion?

To change it to an “easy” range, would I just need to change it on the WebUI config? Or would I need to adjust the server or client manually as well? If I change it to something like 10.50.x.x, will I still be able to access my LAN at home (range 192.168.0.x) without changing anything other than the assigned IPs on the WebUI?

Sorry, I made a mistake!
The 192.168.1.0 IP range is NOT part of the Zerotier network. It is my second wifi adapter (wlan1) which is used as a hotspot.

I should also add that when I set up my system I followed the following instructions:
https://zerotier.atlassian.net/wiki/spaces/SD/pages/193134593/One+Port+Linux+Bridge
which means I have

piserver@piserver-desktop:~$ tail -n+0 /etc/systemd/network/*
==> /etc/systemd/network/25-bridge-br0-en.network <==
[Match]
Name=eth0

    [Network]
    Bridge=br0

    ==> /etc/systemd/network/25-bridge-br0.network <==
    [Match]
    Name=br0

    [Network]
    Address=192.168.0.2/24
    Gateway=192.168.0.1
    DNS=1.1.1.1

    ==> /etc/systemd/network/25-bridge-br0-zt.network <==
    [Match]
    Name=zerotier12

    [Network]
    Bridge=br0

    ==> /etc/systemd/network/99-default.link <==

    ==> /etc/systemd/network/br0.netdev <==
    [NetDev]
    Name=br0
    Kind=bridge

    ==> /etc/systemd/network/location <==
    location:
    /etc/systemd/network/

So, starting from that configuration, what would be the correct approach to route all internet traffic through my Raspberry Pi “Server” at home (IP 192.168.0.2) or alternatively through the actual router at home which has the IP 192.168.0.1 but is of course not running Zerotier.

Please help me. I am really confused right now which approach to take/how to adjust my current system without destroying what is already working.

Sorry you’ve spent so much time on this.
That article is for a different use case and won’t help you route all traffic through ZeroTier. It might be easier to start over.

The Full Tunnel article, but with masquerade instead of snat.
I think we will edit the article to explain this.

No, I meant I originally set it up that way. And that is how I am connecting to the server right now.
So th question is whether I can leave all the settings as they are (stated in my previous post) and just adjust the iptables or whether I will have to start over (which is a problem because I have no physical access to my server and must not lose the Zerotier connection at any point.

Can you post the output of ip addr on the server?

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default ql
en 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq master br0 state UP gro
up default qlen 1000
    link/ether dc:xx:xx:b6:1a:e1 brd ff:ff:ff:ff:ff:ff
3: wlan0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc fq_codel state DOWN gro
up default qlen 1000
    link/ether dc:xx:xx:b6:1a:e2 brd ff:ff:ff:ff:ff:ff
4: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group defa
ult qlen 1000
    link/ether 76:xx:xx:71:58:b6 brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.2/24 brd 192.168.0.255 scope global br0
       valid_lft forever preferred_lft forever
    inet6 2a02:xxxx:9040:3eb4:74fb:70ff:fe71:58b6/64 scope global dynamic mngtmpaddr
 noprefixroute
       valid_lft 5400sec preferred_lft 2700sec
    inet6 2a02:xxxx:9040:3eb4::d698/128 scope global dynamic noprefixroute
       valid_lft 1601sec preferred_lft 1601sec
    inet6 2a02:xxxx:9040:3eb4:dea6:32ff:feb6:1ae1/64 scope global deprecated dynamic
 mngtmpaddr noprefixroute
       valid_lft 1716sec preferred_lft 0sec
    inet6 fe80::xxxx:eeff:fe7c:5ce5/64 scope link
       valid_lft forever preferred_lft forever
5: zerotier12: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 2800 qdisc fq_codel master br0
state UNKNOWN group default qlen 1000
    link/ether 76:xx:xx:71:58:b6 brd ff:ff:ff:ff:ff:ff

Thanks.

You might be able to masquerade through br0, but I haven’t tried that setup and don’t know if it’ll work or break anything.

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

OK. So just so I’m clear here. You’ve already configured your ZT network as a bridge to a physical network and that all works correctly? And you want your ZT clients to route all traffic through the default route of your physical network?

If all of the above is true, then all you have to do is add a default route to your zerotier network on the network config page:

0.0.0.0/0 via $ROUTER_IP_ADDRESS

Then on each client on the zerotier network, you have to set allowDefault=1. from the command line:

zerotier-cli set $NETWORK_ID allowDefault=1

I can only test my Android phone right now (at work). The Android client does not have such an option. How do I make it work on Android?

The android and iOS apps do have this option