Linux iptables and ZeroTier

Hi.
I’m new to VPN and was glad that ZeroTier was very easy to install and use. I connected several Windows PCs without any problem. But when I tried to connect to my Raspberry, every connection is rejected.

I found out, that the firewall (iptables) blocks the connection to the VPN. “zerotier-cli info” shows me OFFLINE, as soon as I start the iptables rules. I attached rules at the beginning of the chain to accept every incoming and outgoing connection from the IP range of the VPN(10.147.x.0). And I accept every connection from the virtual ZT interface.

But in the end every attempt to connect runs though the chain and is rejected. I read several HowTos, but they are all regarding the forwarding of communication and using the Raspberry as a kind of gateway.

But I just want to establish a connection to the Raspberry like to a normal computer. Any ideas?

Best regards,
Stefan

Welcome. Post your rules if you like: iptables-save

You basically need all outgoing udp ports allowed, and 9993 udp in.

For the outgoing, you might be able to get the “owner” module of iptables to work. The installer creates a zerotier-one user on the system in most cases.

iptables -A OUTPUT -m owner --uid-owner 998 -j ACCEPT

Make sure your zerotier interfaces are allowed to talk too:

iptables -A INPUT -i zt+ -j ACCEPT

iptables -A OUTPUT -o zt+ -j ACCEPT

hope that helps

1 Like

5 posts were split to a new topic: Device stuck OFFLINE / TUNNELED

Alternative suggestion… https://www.raspberrypi.org/documentation/configuration/security.md gives some guidance on using ufw as a firewall. Maybe use that & allow port 9993 ?

I reconstructed my iptables completely new and from the beginning.

My last config was enabling all IP addresses individually (e.g 192.168.0.55/32), also the VPN IPs. Now I opened the complete range (192.168.0.0/24 and 10.147.x.0/24).

There were some rules at the beginning I didn’t understand (:INPUT - [0:0]). I used a configuration app some years ago, and I think, there were some errors. I don’t know the meaning of the minus after INPUT.

Now I have default policies DROP and added chains for acceptance of x.x.x.0/24, the port 9993 and the virtual interface.

This works.Thanks to all.

Hi everyone!

I’m having the exact same issues with Zerotier on my RPi 3 over eth0 (192.168.1.7::192.168.1.1:255.255.255.0)
I’m completely lost with iptables, but can tell you that it’s bone-stock from the latest RPi-OS image (2021-01-11-raspios-buster-armhf)
I’ve been using the official Bridge your ZeroTier and local network with a RaspberryPi guide.
My zt user info is as follows: zerotier-one:x:999:995::/var/lib/zerotier-one:/bin/bash

Would anyone mind helping me with the commands to type, in order to achieve @Lalle75 's fix?

Thanks in advance! :heart_eyes:
Patrick

This is what I use, 2 commands, all traffic allowed in on zerotier NIC
iptables -I INPUT -i zt3jnzbdh7 -j ACCEPT

Use conntrack. this means that any allowed outbound connection attempt will be allowed to come back in. Other wise you have to open a bunch of ports and that sucks.
iptables -I INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

Hi,

I came here because

iptables -A INPUT -i zt+ -j ACCEPT

didn’t work for me.

Here is the full list of my rules:

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -p udp --sport 53 -j ACCEPT
-A INPUT -i zt+ -j ACCEPT
-A INPUT -p udp -j DROP
-A INPUT -i lo -j ACCEPT
-A INPUT -d 127.0.0.0/8 -i !lo -j REJECT --reject-with icmp-port-unreachable
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m state --state NEW  --dport 22 -j ACCEPT -m comment --comment "Allow SSH access"
-A INPUT -p tcp -m state --state NEW  --dport 9735 -j ACCEPT -m comment --comment "Allow incoming LND traffic"
-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT -m comment --comment "Allow Ping"
-A INPUT -j REJECT --reject-with icmp-port-unreachable
-A FORWARD -j REJECT --reject-with icmp-port-unreachable
-A OUTPUT -m owner --uid-owner 997 -j ACCEPT
-A OUTPUT -j ACCEPT
COMMIT

@zt-travis As you can see -A INPUT -i zt+ -j ACCEPT by itself didn’t help. Should I add something more for the FORWARD chain?

UPDATE: deleting -A INPUT -p udp -j DROP seems to help :thinking:

FYI, your rules are default accept in the above.

:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]

it looks like -A INPUT -p udp -j DROP is dropping all UDP
so
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT isn’t checked.

As a packet traverses a chain, each rule in turn is examined. If a rule does not match the packet, the packet is passed to the next rule. If a rule does match the packet, the rule takes the action indicated by the target/verdict, which may result in the packet being allowed to continue along the chain or may not
The packet continues to traverse the chain until either
1. a rule matches the packet and decides the ultimate fate of the packet, for example by calling one of the `ACCEPT` or `DROP`, or a module returning such an ultimate fate; or
2. a rule calls the `RETURN` verdict, in which case processing returns to the calling chain; or
3. the end of the chain is reached; traversal either continues in the parent chain (as if `RETURN` was used), or the base chain policy, which is an ultimate fate, is used.

:man_facepalming:

Should I also open 30520 and 30521 on external interfaces?

# ss -lptn 'sport = :30520'
State          Recv-Q         Send-Q                        Local Address:Port                    Peer Address:Port                                                         
LISTEN         0              128                      165.xx.xx.xx%eth0:30520                        0.0.0.0:*             users:(("zerotier-one",pid=493,fd=24))         
LISTEN         0              128                          10.19.0.5%eth0:30520                        0.0.0.0:*             users:(("zerotier-one",pid=493,fd=22))         
LISTEN         0              128                         10.114.0.2%eth1:30520                        0.0.0.0:*             users:(("zerotier-one",pid=493,fd=20))        
 
# ss -lptn 'sport = :30521'
State          Recv-Q         Send-Q                        Local Address:Port                    Peer Address:Port                                                         
LISTEN         0              128                      165.xx.xx.xx%eth0:30521                        0.0.0.0:*             users:(("zerotier-one",pid=493,fd=30))         
LISTEN         0              128                          10.19.0.5%eth0:30521                        0.0.0.0:*             users:(("zerotier-one",pid=493,fd=28))         
LISTEN         0              128                         10.114.0.2%eth1:30521                        0.0.0.0:*             users:(("zerotier-one",pid=493,fd=26))      

There’s two layers to think about.

  1. the underlying transport.
  2. the zerotier interfaces from joining networks.

Allowing outgoing udp and established incoming udp is for 1.
The zt+ -j ACCEPT is a easy way for 2.