# 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 ```bash # 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 ```bash # View routing table ip route show # Check for existing routes to target subnet ip route show | grep ``` --- ## Step-by-Step Configuration ### STEP 1: Enable IP Forwarding **Check if already enabled:** ```bash cat /proc/sys/net/ipv4/ip_forward # Should return: 1 (if enabled) or 0 (if disabled) ``` **Enable IP forwarding:** ```bash # 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:** ```bash # Template: sudo ip route add via dev # Example: sudo ip route add 192.168.178.0/24 via 192.168.170.1 dev eth0 ``` **Verify the route:** ```bash ip route show | grep # Example output: 192.168.178.0/24 via 192.168.170.1 dev eth0 ``` **Make persistent (create systemd service):** ```bash sudo nano /etc/systemd/system/static-routes.service ``` **Paste this content (adjust values):** ```ini [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:** ```bash 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 ```bash ping -c 4 # 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:** ```bash # Template: sudo iptables -t nat -A POSTROUTING -s -d -o -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:** ```bash sudo iptables -t nat -L POSTROUTING -v -n | grep # 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:** ```bash 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:** ```bash # Allow traffic from ZeroTier to local network sudo iptables -I FORWARD -i -o -j ACCEPT # Allow return traffic (established connections) sudo iptables -I FORWARD -i -o -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:** ```bash 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:** ```bash sudo apt-get update sudo apt-get install -y iptables-persistent ``` **Save current rules:** ```bash sudo iptables-save | sudo tee /etc/iptables/rules.v4 ``` **Verify saved rules:** ```bash 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 1. Select your ZeroTier network 2. Scroll to **Managed Routes** section 3. Click **Add Route** or **Submit Route** 4. Add: - **Destination:** `` (e.g., 192.168.178.0/24) - **Via:** `` (e.g., 10.121.16.37) 5. 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:** `` (e.g., 10.121.16.0/24) - **Subnet Mask:** 255.255.255.0 (or /24) - **Gateway/Next Hop:** `` (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 ```bash # On the gateway (Pi5) ping -c 4 # 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):** ```bash # Check ZeroTier route exists ip route show | grep # Should show: 192.168.178.0/24 via 10.121.16.37 dev ztXXXXXX # Test connectivity ping -c 4 # Example: ping -c 4 192.168.178.10 # Trace the route traceroute # 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 ```bash ip route show | grep ``` **Fix:** Wait for ZeroTier Central routes to propagate (up to 60 seconds), or restart ZeroTier: ```bash sudo systemctl restart zerotier-one ``` --- ### 2. ✓ Verify IP Forwarding on Gateway ```bash cat /proc/sys/net/ipv4/ip_forward ``` **Should be:** `1` **Fix:** Run Step 1 again --- ### 3. ✓ Verify Static Route on Gateway ```bash ip route show | grep ``` **Should show:** Route via next-hop router **Fix:** Run Step 2 again --- ### 4. ✓ Verify NAT/Masquerading Rule ```bash sudo iptables -t nat -L POSTROUTING -v -n | grep ``` **Should show:** MASQUERADE rule **Fix:** Run Step 3 again --- ### 5. ✓ Verify FORWARD Rules (MOST COMMON ISSUE!) ```bash sudo iptables -L FORWARD -v -n | head -20 ``` **Should show:** - ACCEPT rule for `` - ACCEPT rule for `` (RELATED,ESTABLISHED) **Fix:** Run Step 4 again --- ### 6. ✓ Check Packet Counters ```bash # Check if packets are being processed sudo iptables -t nat -L POSTROUTING -v -n | grep sudo iptables -L FORWARD -v -n | grep ``` **Look for:** `pkts` column should increase when you ping **If 0 packets:** Traffic is being blocked before reaching that rule --- ### 7. ✓ Traceroute from Client ```bash traceroute ``` **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 ```bash # On gateway ping ``` **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 ```bash # 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 ```bash # 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 ```bash # Remove static route sudo ip route del # Remove NAT rule (use exact match from -L output) sudo iptables -t nat -D POSTROUTING -s -d -o -j MASQUERADE # Remove FORWARD rules (by number, check with -L --line-numbers) sudo iptables -L FORWARD --line-numbers sudo iptables -D FORWARD ``` --- ## Common Issues & Solutions ### Issue 1: "RTNETLINK answers: File exists" **Cause:** Route already exists **Solution:** Remove existing route first, then add new one ```bash sudo ip route del sudo ip route add via dev ``` ### 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:** ```bash # 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`, or `vnstat` for traffic monitoring --- **Document Version:** 1.0 **Last Updated:** February 16, 2026 **Tested On:** Raspberry Pi 5, Ubuntu 24.04, Debian 12