| readme.md | ||
ZeroTier Gateway Configuration Guide
Accessing Remote Subnets Through a Raspberry Pi Gateway
This guide explains how to configure a Raspberry Pi (or any Linux device) as a ZeroTier gateway to access remote subnets that are not directly on the ZeroTier network.
Network Topology
ZeroTier Clients (10.121.16.0/24)
↓ (ZeroTier tunnel)
Raspberry Pi5 Gateway (10.121.16.37)
↓ (eth0: 192.168.170.172)
Teltonika Router (192.168.170.1)
↓
Target Subnet (192.168.178.0/24)
Prerequisites Check
Before starting configuration, gather this information:
1. Identify Your Network Interfaces
# List all network interfaces
ip addr show
# List ZeroTier networks
sudo zerotier-cli listnetworks
Record:
- Gateway's local IP:
_________________(e.g., 192.168.170.172) - Gateway's ZeroTier IP:
_________________(e.g., 10.121.16.37) - ZeroTier interface name:
_________________(e.g., ztnhhth2eu) - ZeroTier network subnet:
_________________(e.g., 10.121.16.0/24) - Local interface name:
_________________(e.g., eth0) - Next-hop router IP:
_________________(e.g., 192.168.170.1) - Target subnet:
_________________(e.g., 192.168.178.0/24)
2. Check Current Routing
# View routing table
ip route show
# Check for existing routes to target subnet
ip route show | grep <TARGET_SUBNET>
Step-by-Step Configuration
STEP 1: Enable IP Forwarding
Check if already enabled:
cat /proc/sys/net/ipv4/ip_forward
# Should return: 1 (if enabled) or 0 (if disabled)
Enable IP forwarding:
# Enable temporarily (lost on reboot)
sudo sysctl -w net.ipv4.ip_forward=1
# Make permanent
echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf
# Verify
cat /proc/sys/net/ipv4/ip_forward
✅ Checkpoint: Should show 1
STEP 2: Configure Static Route to Target Subnet
Add the route:
# Template:
sudo ip route add <TARGET_SUBNET> via <NEXT_HOP_ROUTER> dev <LOCAL_INTERFACE>
# Example:
sudo ip route add 192.168.178.0/24 via 192.168.170.1 dev eth0
Verify the route:
ip route show | grep <TARGET_SUBNET>
# Example output: 192.168.178.0/24 via 192.168.170.1 dev eth0
Make persistent (create systemd service):
sudo nano /etc/systemd/system/static-routes.service
Paste this content (adjust values):
[Unit]
Description=Static routes for remote subnet access
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
ExecStart=/sbin/ip route add 192.168.178.0/24 via 192.168.170.1 dev eth0
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
Enable the service:
sudo systemctl enable static-routes.service
sudo systemctl start static-routes.service
sudo systemctl status static-routes.service
✅ Checkpoint: Test ping from gateway to target subnet
ping -c 4 <TARGET_IP>
# Example: ping -c 4 192.168.178.10
STEP 3: Configure NAT/Masquerading
Why needed: Makes ZeroTier traffic appear to come from the gateway's local IP, enabling return traffic.
Add masquerading rule:
# Template:
sudo iptables -t nat -A POSTROUTING -s <ZT_SUBNET> -d <TARGET_SUBNET> -o <LOCAL_INTERFACE> -j MASQUERADE
# Example:
sudo iptables -t nat -A POSTROUTING -s 10.121.16.0/24 -d 192.168.178.0/24 -o eth0 -j MASQUERADE
Verify the rule:
sudo iptables -t nat -L POSTROUTING -v -n | grep <ZT_SUBNET>
# Should show: MASQUERADE rule with your subnets
✅ Checkpoint: Rule should be visible in iptables
STEP 4: Configure Firewall FORWARD Rules
⚠️ CRITICAL STEP - Most common issue!
Check current FORWARD policy:
sudo iptables -L FORWARD -v -n
# Look at the first line: Chain FORWARD (policy ???)
If policy is DROP or you don't see rules for your ZeroTier interface, you MUST add them:
Add FORWARD rules:
# Allow traffic from ZeroTier to local network
sudo iptables -I FORWARD -i <ZT_INTERFACE> -o <LOCAL_INTERFACE> -j ACCEPT
# Allow return traffic (established connections)
sudo iptables -I FORWARD -i <LOCAL_INTERFACE> -o <ZT_INTERFACE> -m state --state RELATED,ESTABLISHED -j ACCEPT
# Example:
sudo iptables -I FORWARD -i ztnhhth2eu -o eth0 -j ACCEPT
sudo iptables -I FORWARD -i eth0 -o ztnhhth2eu -m state --state RELATED,ESTABLISHED -j ACCEPT
Verify FORWARD rules:
sudo iptables -L FORWARD -v -n | head -20
# Should show ACCEPT rules for your ZeroTier interface
✅ Checkpoint: Rules should appear at the top of FORWARD chain
STEP 5: Make Firewall Rules Persistent
Install iptables-persistent:
sudo apt-get update
sudo apt-get install -y iptables-persistent
Save current rules:
sudo iptables-save | sudo tee /etc/iptables/rules.v4
Verify saved rules:
sudo cat /etc/iptables/rules.v4 | grep -A 5 "POSTROUTING"
sudo cat /etc/iptables/rules.v4 | grep -A 5 "FORWARD"
STEP 6: Configure ZeroTier Central (Web Interface)
Go to: https://my.zerotier.com
- Select your ZeroTier network
- Scroll to Managed Routes section
- Click Add Route or Submit Route
- Add:
- Destination:
<TARGET_SUBNET>(e.g., 192.168.178.0/24) - Via:
<GATEWAY_ZT_IP>(e.g., 10.121.16.37)
- Destination:
- Click Submit
Wait 30-60 seconds for route to propagate to clients
✅ Checkpoint: Route should appear in ZeroTier Central UI
STEP 7: Configure Return Route on Next-Hop Router (Optional but Recommended)
On your router (e.g., Teltonika at 192.168.170.1):
Add static route:
- Destination/Network:
<ZT_SUBNET>(e.g., 10.121.16.0/24) - Subnet Mask: 255.255.255.0 (or /24)
- Gateway/Next Hop:
<GATEWAY_LOCAL_IP>(e.g., 192.168.170.172)
Why needed: Without this, devices on the target subnet won't know how to send replies back to ZeroTier clients.
⚠️ Note: If using masquerading (Step 3), this may not be strictly required, but it's good practice.
Verification & Testing
Test 1: From Gateway to Target Subnet
# On the gateway (Pi5)
ping -c 4 <TARGET_IP>
# Example: ping -c 4 192.168.178.10
Expected: Should work ✅
Test 2: From ZeroTier Client to Target Subnet
On client machine (e.g., X230):
# Check ZeroTier route exists
ip route show | grep <TARGET_SUBNET>
# Should show: 192.168.178.0/24 via 10.121.16.37 dev ztXXXXXX
# Test connectivity
ping -c 4 <TARGET_IP>
# Example: ping -c 4 192.168.178.10
# Trace the route
traceroute <TARGET_IP>
# Should show: hop 1 = gateway ZT IP, then target
Expected: Should work ✅
Troubleshooting Checklist
If ping from ZeroTier client doesn't work, check these in order:
1. ✓ Verify ZeroTier Route on Client
ip route show | grep <TARGET_SUBNET>
Fix: Wait for ZeroTier Central routes to propagate (up to 60 seconds), or restart ZeroTier:
sudo systemctl restart zerotier-one
2. ✓ Verify IP Forwarding on Gateway
cat /proc/sys/net/ipv4/ip_forward
Should be: 1
Fix: Run Step 1 again
3. ✓ Verify Static Route on Gateway
ip route show | grep <TARGET_SUBNET>
Should show: Route via next-hop router Fix: Run Step 2 again
4. ✓ Verify NAT/Masquerading Rule
sudo iptables -t nat -L POSTROUTING -v -n | grep <ZT_SUBNET>
Should show: MASQUERADE rule Fix: Run Step 3 again
5. ✓ Verify FORWARD Rules (MOST COMMON ISSUE!)
sudo iptables -L FORWARD -v -n | head -20
Should show:
- ACCEPT rule for
<ZT_INTERFACE> → <LOCAL_INTERFACE> - ACCEPT rule for
<LOCAL_INTERFACE> → <ZT_INTERFACE>(RELATED,ESTABLISHED)
Fix: Run Step 4 again
6. ✓ Check Packet Counters
# Check if packets are being processed
sudo iptables -t nat -L POSTROUTING -v -n | grep <ZT_SUBNET>
sudo iptables -L FORWARD -v -n | grep <ZT_INTERFACE>
Look for: pkts column should increase when you ping
If 0 packets: Traffic is being blocked before reaching that rule
7. ✓ Traceroute from Client
traceroute <TARGET_IP>
Diagnose:
- Stops at gateway: FORWARD rules or routing issue on gateway
- Reaches target but no response: Return routing issue (check Step 7)
- Doesn't reach gateway: ZeroTier route not configured
8. ✓ Test from Gateway First
# On gateway
ping <TARGET_IP>
If this fails: Problem is between gateway and target (routing, firewall on router, etc.) If this works but client fails: Problem is in gateway's forwarding/firewall
Quick Reference Commands
Check Configuration Status
# IP forwarding
cat /proc/sys/net/ipv4/ip_forward
# Routing table
ip route show
# NAT rules
sudo iptables -t nat -L POSTROUTING -v -n
# FORWARD rules
sudo iptables -L FORWARD -v -n
# ZeroTier status
sudo zerotier-cli listnetworks
View Real-Time Traffic
# Watch iptables counters update
watch -n 1 'sudo iptables -t nat -L POSTROUTING -v -n'
watch -n 1 'sudo iptables -L FORWARD -v -n'
Reset/Remove Configuration
# Remove static route
sudo ip route del <TARGET_SUBNET>
# Remove NAT rule (use exact match from -L output)
sudo iptables -t nat -D POSTROUTING -s <ZT_SUBNET> -d <TARGET_SUBNET> -o <LOCAL_INTERFACE> -j MASQUERADE
# Remove FORWARD rules (by number, check with -L --line-numbers)
sudo iptables -L FORWARD --line-numbers
sudo iptables -D FORWARD <LINE_NUMBER>
Common Issues & Solutions
Issue 1: "RTNETLINK answers: File exists"
Cause: Route already exists Solution: Remove existing route first, then add new one
sudo ip route del <TARGET_SUBNET>
sudo ip route add <TARGET_SUBNET> via <NEXT_HOP> dev <INTERFACE>
Issue 2: Ping works from gateway but not from ZeroTier clients
Cause: Missing FORWARD rules (policy DROP) Solution: Add FORWARD rules (Step 4)
Issue 3: Masquerading shows 0 packets
Cause: Traffic is blocked before reaching POSTROUTING chain Solution: Check FORWARD chain rules
Issue 4: Route not appearing on ZeroTier clients
Cause: ZeroTier Central route not configured or not propagated Solution:
- Check ZeroTier Central web interface
- Wait 60 seconds
- Restart ZeroTier:
sudo systemctl restart zerotier-one
Issue 5: Connection works briefly then stops
Cause: Rules not persistent, lost on reboot Solution: Save iptables rules (Step 5) and create systemd service for routes (Step 2)
Example: Complete Configuration
Network:
- ZeroTier subnet: 10.121.16.0/24
- Gateway ZT IP: 10.121.16.37
- Gateway local IP: 192.168.170.172
- ZT interface: ztnhhth2eu
- Local interface: eth0
- Next-hop router: 192.168.170.1
- Target subnet: 192.168.178.0/24
Commands:
# 1. Enable IP forwarding
sudo sysctl -w net.ipv4.ip_forward=1
echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf
# 2. Add static route
sudo ip route add 192.168.178.0/24 via 192.168.170.1 dev eth0
# 3. Add masquerading
sudo iptables -t nat -A POSTROUTING -s 10.121.16.0/24 -d 192.168.178.0/24 -o eth0 -j MASQUERADE
# 4. Add FORWARD rules
sudo iptables -I FORWARD -i ztnhhth2eu -o eth0 -j ACCEPT
sudo iptables -I FORWARD -i eth0 -o ztnhhth2eu -m state --state RELATED,ESTABLISHED -j ACCEPT
# 5. Save rules
sudo apt-get install -y iptables-persistent
sudo iptables-save | sudo tee /etc/iptables/rules.v4
# 6. Configure ZeroTier Central
# Go to https://my.zerotier.com → Add route: 192.168.178.0/24 via 10.121.16.37
# 7. Test
ping 192.168.178.10
Post-Configuration Checklist
- IP forwarding enabled and persistent
- Static route configured and persistent (systemd service)
- NAT/Masquerading rule added and saved
- FORWARD rules added and saved
- ZeroTier Central managed route configured
- Return route on next-hop router configured (optional)
- Tested from gateway: ping works ✅
- Tested from ZeroTier client: ping works ✅
- Rebooted gateway and verified everything still works ✅
Notes
- This configuration acts as a route-based gateway, not a site-to-site VPN
- All traffic is routed, not bridged
- Clients must use ZeroTier to access the remote subnet
- The gateway Pi must remain online for access to work
- Consider security: you're exposing a remote network to ZeroTier users
- Monitor the gateway:
htop,iftop, orvnstatfor traffic monitoring
Document Version: 1.0
Last Updated: February 16, 2026
Tested On: Raspberry Pi 5, Ubuntu 24.04, Debian 12