ZeroTier Behind NAT - Quick Reference¶
TL;DR¶
✅ ZeroTier works behind NAT with no port forwarding required ✅ Only needs outbound UDP 9993 + replies ✅ Automatic relay fallback = always works ✅ For OPNsense behind libvirt NAT: Just install and go
Minimal Configuration (OPNsense)¶
1. Install Plugin¶
2. Configure Network¶
{
"physical": {
"10.0.0.0/8": {"blacklist": true},
"172.16.0.0/12": {"blacklist": true},
"192.168.0.0/16": {"blacklist": true}
}
}
3. Verify Firewall¶
4. Authorize in Central¶
5. Test¶
zerotier-cli info # Should show ONLINE
zerotier-cli listnetworks # Should show IP assigned
ping 192.168.194.131 # Test connectivity
Essential Commands¶
# Status
zerotier-cli info
# Peers (check DIRECT vs RELAY)
zerotier-cli peers
# Networks
zerotier-cli listnetworks
# Logs
tail -f /var/log/zerotier-one.log
# Service
service zerotier status
service zerotier restart
Troubleshooting¶
Service won't start¶
- Check
local.confis valid JSON - Review
/var/log/zerotier-one.log
Shows RELAY instead of DIRECT¶
- This is normal and functional
- RELAY = working connection, just higher latency
- Only optimize if performance is poor
Can't reach peers¶
- Verify authorized in Central
- Check firewall allows ZeroTier interface traffic
- Test:
ping <zerotier-peer-ip>
High CPU / packet loss¶
- Add RFC1918 blacklist to
local.conf(see above) - Prevents ZeroTier-over-ZeroTier loop
Port Requirements¶
| Port | Protocol | Required? |
|---|---|---|
| 9993 | UDP outbound + replies | YES |
| 443 | TCP outbound (fallback) | If UDP blocked |
No inbound ports need to be forwarded
NAT Type Impact¶
| NAT Type | Result |
|---|---|
| Full/Restricted Cone | ✅ Direct connection |
| Symmetric | ⚠️ Relay (still works) |
92-96% of NATs support direct connections
libvirt NAT Notes¶
- Standard Linux iptables NAT = ZeroTier-friendly
- No special configuration needed
- Install ZeroTier in the guest (not host)
- Outbound UDP works through NAT automatically
Expected Behavior (Our Use Case)¶
opnsense-dev (KVM guest behind libvirt NAT):
- Connection type: RELAY or DIRECT (both fine)
- Latency: Native or +20-50ms (if relayed)
- Reliability: High
- Throughput: Sufficient for management/monitoring
Verification:
# From opnsense-dev
ping 192.168.194.131 # dumbo
ssh joe@192.168.194.10 # owl
# From remote host
ssh joe@192.168.194.199 # opnsense-dev
Common Mistakes¶
❌ Thinking RELAY = broken → RELAY is functional ❌ Trying to configure port forwarding → Not needed ❌ Worrying about double NAT → Usually works fine ❌ Forgetting to authorize in Central → Device can't communicate ❌ Invalid JSON in local.conf → Service fails silently
Key Takeaway¶
ZeroTier is designed for NAT. Install it, authorize it, and it will work. Optimize only if you have actual performance problems.
Full details: /Users/joe/src/scandora.net/docs/zerotier-nat-research.md