ZeroTier Virtual Network Configuration
ZeroTier is a software-defined networking platform that creates virtual Layer 2 networks over the internet using peer-to-peer connectivity, making it a powerful VPN alternative for connecting VPS instances, bare-metal servers, and remote devices. Unlike traditional VPNs, ZeroTier handles NAT traversal automatically and allows you to build complex network topologies without dedicated gateway hardware.
Prerequisites
- Ubuntu 20.04+, Debian 11+, CentOS 8+, or Rocky Linux 8+
- Root or sudo access
- A ZeroTier account at
my.zerotier.com(free for up to 25 devices) - Outbound UDP access (port 9993)
Installing ZeroTier
Ubuntu/Debian:
# Install using the official script
curl -s https://install.zerotier.com | sudo bash
# Or manually via APT
curl -s 'https://raw.githubusercontent.com/zerotier/ZeroTierOne/main/doc/contact%40zerotier.com.gpg' | \
gpg --dearmor | sudo tee /usr/share/keyrings/zerotierone-archive-keyring.gpg > /dev/null
echo "deb [signed-by=/usr/share/keyrings/zerotierone-archive-keyring.gpg] \
http://download.zerotier.com/debian/bookworm bookworm main" | \
sudo tee /etc/apt/sources.list.d/zerotier.list
sudo apt update && sudo apt install -y zerotier-one
CentOS/Rocky Linux:
# Install and enable
sudo dnf install -y zerotier-one
sudo systemctl enable --now zerotier-one
# Verify the service is running
sudo systemctl status zerotier-one
# Get this node's ZeroTier address
sudo zerotier-cli info
# Output: 200 info <node-id> <version> ONLINE
Creating and Joining a Network
Create a network in the web interface:
- Log into
https://my.zerotier.com - Click Create A Network — a unique 16-character network ID is generated
- Note the Network ID (e.g.,
8056c2e21c000001)
Join the network from each node:
# Join using the network ID
sudo zerotier-cli join 8056c2e21c000001
# Check join status
sudo zerotier-cli listnetworks
# Leave a network
sudo zerotier-cli leave 8056c2e21c000001
List all joined networks and their status:
sudo zerotier-cli listnetworks
# Output shows network ID, name, MAC, IP, status, type
Member Authorization and IP Assignment
By default, new members require manual authorization unless you enable open access.
Authorize members via CLI (using API token):
# Get your API token from my.zerotier.com/account
ZT_TOKEN="your_api_token"
NETWORK_ID="8056c2e21c000001"
NODE_ID="abc123def456"
# Authorize a member
curl -X POST "https://api.zerotier.com/api/v1/network/${NETWORK_ID}/member/${NODE_ID}" \
-H "Authorization: token ${ZT_TOKEN}" \
-H "Content-Type: application/json" \
-d '{"config": {"authorized": true}}'
Configure IP assignment pools:
In the ZeroTier Central UI under Advanced > Managed Routes and IP Assignment, add an assignment pool:
IP Range: 10.147.17.1 - 10.147.17.254
Route: 10.147.17.0/24 → (leave empty for local)
# Verify assigned IP on the node
sudo zerotier-cli listnetworks | grep -i ip
ip addr show zt+ # Show ZeroTier interface
Routing and Bridging
Add a managed route to reach LAN subnets:
In ZeroTier Central, under the network's Routes section, add:
Destination: 192.168.1.0/24
Via: 10.147.17.5 # IP of the node connected to that LAN
Enable IP forwarding on the routing node:
# Enable forwarding permanently
sudo tee /etc/sysctl.d/99-zerotier.conf <<EOF
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1
EOF
sudo sysctl -p /etc/sysctl.d/99-zerotier.conf
# Allow forwarding between ZeroTier and LAN interfaces
sudo iptables -A FORWARD -i zt+ -j ACCEPT
sudo iptables -A FORWARD -o zt+ -j ACCEPT
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
# Make iptables rules persistent
sudo apt install -y iptables-persistent
sudo netfilter-persistent save
Layer 2 bridging (connect ZeroTier to physical LAN):
# Install bridge utilities
sudo apt install -y bridge-utils
# Create a bridge between ZeroTier and LAN interface
sudo ip link add br0 type bridge
sudo ip link set zt3jnwgqos master br0
sudo ip link set eth0 master br0
sudo ip link set br0 up
Firewall Rules
ZeroTier networks support built-in traffic rules in the Flow Rules section of the network:
# Drop traffic between members (default deny)
drop not ethertype ipv4 and not ethertype ipv6 and not ethertype arp;
# Allow specific port (e.g., port 22 between tagged members)
accept ztdest "server" and ipprotocol tcp and dport 22;
# Allow all traffic (open network)
accept;
Host-level firewall with UFW:
# Allow ZeroTier traffic on the virtual interface
sudo ufw allow in on zt+ to any port 22
sudo ufw allow in on zt+ to any port 80
sudo ufw allow in on zt+ to any port 443
# Block direct internet access to services
sudo ufw deny 80
sudo ufw deny 443
sudo ufw enable
Self-Hosted Controller
Run your own ZeroTier controller with ztncui for air-gapped or private deployments:
# Pull and run the self-hosted controller
docker run -d \
--name ztncui \
-p 3000:3000 \
-p 9993:9993/udp \
-v /opt/zerotier:/var/lib/zerotier-one \
-e ZTNCUI_PASSWD=admin_password \
keynetworks/ztncui
# Get the controller node ID
docker exec ztncui zerotier-cli info
Join the self-hosted network by specifying the controller:
# Join a network hosted on your controller (network ID starts with controller node ID)
sudo zerotier-cli join <controller-node-id>______
Troubleshooting
Node shows REQUESTING_CONFIGURATION:
# Check authorization status in ZeroTier Central
# The node must be authorized before it shows as OK
sudo zerotier-cli listnetworks
# Restart ZeroTier
sudo systemctl restart zerotier-one
Cannot reach other nodes:
# Check connectivity to ZeroTier roots
sudo zerotier-cli peers
# Test ping over ZeroTier interface
ping 10.147.17.2
# Check firewall on the target node allows ZeroTier
sudo ufw status
UDP port 9993 blocked by provider:
# ZeroTier can fall back to TCP relays, but performance is degraded
# Allow outbound UDP 9993
sudo ufw allow out 9993/udp
# For providers blocking UDP, check if relay mode is active
sudo zerotier-cli peers | grep RELAY
Conclusion
ZeroTier provides a flexible software-defined networking layer that simplifies connecting distributed infrastructure without complex VPN configurations. By combining managed routes, flow rules, and IP assignment pools, you can build secure multi-site networks that span cloud providers and on-premises environments, with optional self-hosted controllers for complete infrastructure independence.


