Find a file
2026-02-16 19:20:51 +00:00
readme.md Add readme.md 2026-02-16 19:20:51 +00:00

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

  1. Select your ZeroTier network
  2. Scroll to Managed Routes section
  3. Click Add Route or Submit Route
  4. Add:
    • Destination: <TARGET_SUBNET> (e.g., 192.168.178.0/24)
    • Via: <GATEWAY_ZT_IP> (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


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

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, or vnstat for traffic monitoring

Document Version: 1.0
Last Updated: February 16, 2026
Tested On: Raspberry Pi 5, Ubuntu 24.04, Debian 12