ZeroTier mesh network diagram

Install ZeroTier VPN on VPS — Build Your Private SDN

Updated October 9, 2026 · 8 min read

ZeroTier is a Software-Defined Networking (SDN) solution that connects every device as if they share the same local network — regardless of physical location. It uses end-to-end encrypted UDP with automatic NAT traversal, so there's no need to open ports or configure complex firewall rules.

Unlike WireGuard or OpenVPN, ZeroTier creates a true mesh network where every node communicates directly with each other, bypassing a central relay whenever possible. The free plan supports up to 25 nodes.

How ZeroTier Works

ZeroTier's architecture has three layers:

FeatureZeroTierWireGuardTailscale
ModelMesh SDNPoint-to-pointMesh (WireGuard-based)
NAT traversalAutomaticManual setupAutomatic
Free nodes25Unlimited (self-host)3 users
Self-host controllerYes (ZeroTierOne)FullyVia Headscale
Setup complexityVery easyModerateEasy

Install ZeroTier on Ubuntu/Debian VPS

Prerequisites: a ZeroTier account at my.zerotier.com and a Network ID created (or a self-hosted controller).

Step 1: Install ZeroTier

# Ubuntu / Debian (official installer)
curl -s https://install.zerotier.com | sudo bash

# Check service status
sudo systemctl status zerotier-one
sudo zerotier-cli status

# Expected output
# 200 info <NodeID> 1.14.0 ONLINE

Step 2: Join a Network

# Replace <NETWORK_ID> with your 16-digit network ID from my.zerotier.com
sudo zerotier-cli join <NETWORK_ID>

# Example
sudo zerotier-cli join 8056c2e21c000001

# Check network status
sudo zerotier-cli listnetworks
Note: After joining, you must go to my.zerotier.com → Members → click the Authorize checkbox for the node before it receives an IP address.

Step 3: Verify the Assigned IP

# Show assigned IP from the ZeroTier network
sudo zerotier-cli listnetworks
# 200 listnetworks 8056c2e21c000001 MyNetwork 72:cc:... OK PRIVATE ztXXXXXXXX 10.147.17.1/24

# Show interface details
ip addr show ztXXXXXXXX

Step 4: Test Connectivity

# Ping from another node (use the ZeroTier IP of the VPS)
ping 10.147.17.1

# SSH over the ZeroTier IP
ssh [email protected]

Configure IP Routing — Use VPS as Gateway

To route all traffic from other nodes through the VPS (acting as a VPN gateway):

Enable IP Forwarding on VPS

# Enable IPv4 forwarding
echo 'net.ipv4.ip_forward=1' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

# Set up NAT (replace eth0 with your actual interface)
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
sudo iptables -A FORWARD -i ztXXXXXXXX -j ACCEPT
sudo iptables -A FORWARD -o ztXXXXXXXX -m state --state RELATED,ESTABLISHED -j ACCEPT

# Persist iptables rules
sudo apt install iptables-persistent -y
sudo netfilter-persistent save

Add a Managed Route in ZeroTier Dashboard

# In my.zerotier.com → Network → Settings → Managed Routes
# Add:
# Destination: 0.0.0.0/0
# Via: 10.147.17.1  ← ZeroTier IP of the VPS gateway
Tip: Each client node also needs "Allow Global" and "Allow Default" enabled in the ZeroTier client settings — otherwise traffic won't route through the gateway.

Self-Host the ZeroTier Network Controller

For full control over the control plane without relying on my.zerotier.com, you can run the controller on your own VPS:

Install ztncui (Web UI for ZeroTier Controller)

# Install Node.js first
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs

# Install ztncui globally
sudo npm install -g ztncui
ztncui

# Or use Docker
docker run -d --name ztncui \
  -p 3000:3000 \
  -v /var/lib/zerotier-one:/var/lib/zerotier-one \
  -e NODE_ENV=production \
  key-networks/ztncui

Create a Network on the Self-Hosted Controller

# Get your VPS NodeID
sudo zerotier-cli info
# 200 info abcdef1234 1.14.0 ONLINE

# Create a network via the ZeroTier API
curl -s -H "X-ZT1-AUTH: $(sudo cat /var/lib/zerotier-one/authtoken.secret)" \
  -X POST http://localhost:9993/controller/network/abcdef1234______

# Format: controller_nodeid + 6 underscores/zeros, then fill in config

ZeroTier with Docker Networks

Connect containers across multiple VPS instances without complex overlay network setups:

# Run ZeroTier inside a container
docker run -d \
  --name zerotier \
  --cap-add NET_ADMIN \
  --cap-add SYS_ADMIN \
  --device /dev/net/tun \
  -v /var/lib/zerotier-one:/var/lib/zerotier-one \
  zerotier/zerotier:latest

# Join the network
docker exec zerotier zerotier-cli join <NETWORK_ID>

# Check assigned IP
docker exec zerotier zerotier-cli listnetworks
Tip: When using Docker Swarm or Kubernetes across VPS nodes, connect the nodes via ZeroTier first, then build your overlay network on top of ZeroTier IPs — much simpler than opening inter-datacenter ports.

Verify ZeroTier is Working Correctly

# Check service status
sudo systemctl status zerotier-one

# Check node status and version
sudo zerotier-cli status

# List all joined networks
sudo zerotier-cli listnetworks

# List connected peers
sudo zerotier-cli listpeers

# Show ZeroTier interface
ip addr show | grep zt

# Test ping over ZeroTier IP
ping -c 4 10.147.17.X

# Check routes
ip route | grep zt
Tip: If peers show RELAY instead of DIRECT, check that UDP port 9993 is open in your firewall — ZeroTier uses this port for direct P2P connections.

Troubleshooting Common Issues

Error: "zerotier-cli: unable to connect to ZeroTier service"

The service is not running or the socket is not ready.

# Start the service
sudo systemctl start zerotier-one
sudo systemctl enable zerotier-one

# If still failing, remove the lock file and restart
sudo rm -f /var/lib/zerotier-one/*.lck
sudo systemctl restart zerotier-one

Node joined but received no IP address

The node must be manually authorized in the ZeroTier dashboard.

# Check network status
sudo zerotier-cli listnetworks
# If you see ACCESS_DENIED or REQUESTING_CONFIG, authorization is pending

# Go to my.zerotier.com → select network → Members
# Find the NodeID and tick the Auth checkbox

Peers show RELAY causing high latency

UDP port 9993 is blocked by the firewall.

# Open port 9993 UDP
sudo ufw allow 9993/udp

# Or with iptables
sudo iptables -A INPUT -p udp --dport 9993 -j ACCEPT

# Verify peers show DIRECT after opening the port
sudo zerotier-cli listpeers | grep DIRECT

Error: "Unable to configure virtual network port"

The tun kernel module is not loaded.

# Load the tun module
sudo modprobe tun
echo 'tun' | sudo tee -a /etc/modules

# Verify
lsmod | grep tun

Cannot ping between nodes

Managed Routes or client Allow flags are not configured.

# Check that the network has a subnet covering your nodes
sudo zerotier-cli listnetworks

# On client, check allow flags
sudo zerotier-cli set <NETWORK_ID> allowGlobal=true
sudo zerotier-cli set <NETWORK_ID> allowDefault=true

Frequently Asked Questions

Is ZeroTier secure enough for production use?

ZeroTier uses Curve25519 for key exchange and AES-256-GCM for traffic encryption — security comparable to WireGuard. For production, consider self-hosting the network controller to avoid depending on ZeroTier Inc., and deploy a private Moon to bootstrap without going through the company's planet servers.

How does ZeroTier differ from Tailscale?

Both are mesh VPNs, but Tailscale uses WireGuard as its transport layer for slightly better performance. ZeroTier uses its own SDN-focused protocol with native Layer 2 bridging support — something Tailscale doesn't offer. Tailscale's free tier is limited to 3 users while ZeroTier allows 25 nodes for free.

Does ZeroTier work on Raspberry Pi or ARM devices?

Yes — ZeroTier supports ARM, ARM64, MIPS, and x86. The same installer script works on Raspberry Pi OS, Armbian, and Ubuntu ARM without any modifications.