Introduction to ZeroTier VPN
ZeroTier is a decentralized virtual networking platform that allows you to create secure, software-defined networks (SDNs) over the public internet. Unlike traditional VPNs that route all traffic through a central server, ZeroTier uses a peer-to-peer mesh architecture that enables direct, encrypted connections between devices wherever they are in the world.
Whether you need to connect development servers across multiple cloud providers, access a homelab from your laptop, or build a secure overlay network for a distributed team, ZeroTier provides a lightweight, fast, and remarkably easy solution. This guide walks you through everything from installation to advanced configuration.
What ZeroTier Is and Why It Matters
At its core, ZeroTier is a network virtualization layer that operates at Layer 2 (Ethernet) and Layer 3 (IP) of the OSI model. Each ZeroTier network is assigned a unique 16-digit network ID, and any device that joins that network receives a virtual IP address, allowing it to communicate with other members as if they were on the same local switch.
Key Advantages Over Traditional VPNs
- Peer-to-peer mesh: Traffic flows directly between devices when possible, avoiding the bottleneck of a central relay server.
- Layer 2 support: Because it operates at Layer 2, protocols like mDNS, ARP, and even non-IP traffic work transparently.
- Cross-platform: Runs on Linux, macOS, Windows, iOS, Android, FreeBSD, and even embedded systems.
- Zero configuration: No port forwarding, firewall changes, or public IP addresses are required on client devices.
- Free tier: Up to 25 devices per network on the free plan, which is more than enough for personal and small team use.
How ZeroTier Works
ZeroTier combines two key technologies: a global root server infrastructure for peer discovery, and a cryptographic identity system for authentication. When two devices on the same network want to communicate, ZeroTier's root servers help them discover each other's public IP addresses. Once discovered, the devices negotiate a direct encrypted UDP connection. If NAT or firewalls prevent a direct connection, ZeroTier falls back to encrypted relay servers (called "moons" or planetary roots) to ensure traffic still flows.
Each device generates a 40-bit ZeroTier address derived from its public key. This address becomes the device's identity on the network and is used for routing decisions within the virtual network.
Installing ZeroTier
Linux Installation
The easiest way to install ZeroTier on most Linux distributions is through the official install script:
curl -s https://install.zerotier.com | sudo bash
On Ubuntu or Debian, you can also use the official repository:
sudo apt-get install -y gnupg curl
curl -s https://raw.githubusercontent.com/zerotier/ZeroTierOne/master/official-hostnames/zerotier.com.gpg | sudo gpg --dearmor -o /usr/share/keyrings/zerotier.com.gpg
echo "deb [signed-by=/usr/share/keyrings/zerotier.com.gpg] http://download.zerotier.com/debian/bookworm bookworm main" | sudo tee /etc/apt/sources.list.d/zerotier.list
sudo apt-get update
sudo apt-get install zerotier-one
Start and enable the service:
sudo systemctl enable --now zerotier-one
macOS Installation
On macOS, you can install via Homebrew or download the official app:
brew install zerotier-one
sudo brew services start zerotier-one
Windows Installation
Download the installer from the official ZeroTier website and run it. The installer includes both the service and a system tray application for easy management.
Docker Container Installation
For containerized environments, ZeroTier provides an official Docker image:
docker run -d \
--name zerotier \
--device=/dev/net/tun \
--net-admin \
--cap-add=NET_ADMIN \
--cap-add=SYS_ADMIN \
-v /var/lib/zerotier-one:/var/lib/zerotier-one \
zerotier/zerotier:latest
Creating Your First Network
Networks are managed through the ZeroTier Central web interface at my.zerotier.com. After creating a free account, follow these steps:
- Click "Create A Network" to generate a new network with a unique 16-digit ID.
- Open the network settings to configure the IP address range (e.g.,
10.147.17.0/24). - Choose the access control mode: Private (requires manual authorization) or Public (auto-authorizes any joining device).
- Note the Network ID for use on your devices.
Joining Devices to a Network
Once your network is created, join devices using the ZeroTier CLI. Replace the network ID below with your actual network ID:
sudo zerotier-cli join 1d71939404a3b1e2
Check the status of your connection:
sudo zerotier-cli listnetworks
You should see output similar to this:
200 listnetworks <nwid> <name> <mac> <status> <type> <dev> <ZT assigned ips>
200 listnetworks 1d71939404a3b1e2 mynet 7a:9e:1b:2c:3d:4e OK PRIVATE zt0 10.147.17.3/24
If your network is set to Private, you must authorize the device in the ZeroTier Central dashboard under the "Members" section. Toggle the "Auth" checkbox next to the new member to grant access.
Verifying Connectivity
Once two or more devices are joined and authorized, verify connectivity by pinging another device using its ZeroTier-assigned IP address:
ping 10.147.17.5
You can also inspect the peer connections to see whether traffic is flowing directly or through a relay:
sudo zerotier-cli listpeers -j | python3 -m json.tool
Look for the paths array in the output. If it contains entries with active: true and a direct IP address, your connection is peer-to-peer. If only relay paths are present, NAT traversal is being used.
Advanced Configuration
Managed Routes and Subnet Routing
One of ZeroTier's most powerful features is the ability to route traffic to entire subnets through a single member device. This is useful for accessing a corporate LAN or cloud VPC from remote devices. To configure this, you need a gateway device on the target subnet that is also a member of your ZeroTier network.
First, enable IP forwarding on the gateway device (Linux):
echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
Configure NAT so that traffic from the ZeroTier network can reach the local subnet:
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
sudo iptables -A FORWARD -i zt0 -o eth0 -j ACCEPT
sudo iptables -A FORWARD -i eth0 -o zt0 -m state --state RELATED,ESTABLISHED -j ACCEPT
Make the rules persistent using iptables-persistent:
sudo apt-get install iptables-persistent
sudo netfilter-persistent save
Then, in the ZeroTier Central dashboard, add a managed route under the network's "Advanced" section:
Destination: 192.168.1.0/24
Via: 10.147.17.3
Here, 192.168.1.0/24 is the target LAN subnet, and 10.147.17.3 is the ZeroTier IP of your gateway device. After saving, all members of the ZeroTier network can reach devices on 192.168.1.0/24 through the gateway.
Setting Up a Moon Server
By default, ZeroTier uses planetary root servers hosted by ZeroTier, Inc. For improved latency and reliability, you can host your own "moon" — a dedicated root server that acts as a discovery and relay point. This is particularly useful in regions with poor connectivity to the default roots.
On a server with a public IP address, generate and orbit a moon:
sudo zerotier-idtool initmoon /var/lib/zerotier-one/identity.public > moon.json
Edit moon.json to include your server's public IP address:
{
"id": "000000abcd123456",
"objtype": "world",
"roots": [
{
"identity": "abcd1234:0:...",
"stableEndpoints": ["203.0.113.50/9993"]
}
],
"signingKey": "...",
"signingKey_SECRET": "...",
"updatesMustBeSignedBy": "...",
"worldType": "moon"
}
Generate the moon file and place it in the moons directory:
sudo zerotier-idtool genmoon moon.json
sudo mkdir -p /var/lib/zerotier-one/moons.d
sudo cp 000000abcd123456.moon /var/lib/zerotier-one/moons.d/
sudo systemctl restart zerotier-one
On client devices, orbit the moon using the moon ID and the server's IP:
sudo zerotier-cli orbit abcd123456 abcd123456 203.0.113.50/9993
Verify the moon connection:
sudo zerotier-cli listmoons
Identity Management and Backup
Each ZeroTier node has a unique identity stored in /var/lib/zerotier-one/identity.secret. This file is critical — losing it means losing your node's identity and any authorization associated with it. Always back up this file securely:
sudo cp /var/lib/zerotier-one/identity.secret ~/zerotier-identity-backup.secret
sudo chmod 600 ~/zerotier-identity-backup.secret
To restore a node on a new machine, copy the identity.secret and identity.public files into the ZeroTier data directory before starting the service.
Automation with the API
ZeroTier Central provides a REST API for programmatic network management. This is invaluable for provisioning networks in CI/CD pipelines or managing large deployments. First, generate an API token from your account settings page.
List all networks in your account:
curl -s -H "Authorization: token YOUR_API_TOKEN" \
https://api.zerotier.com/api/v1/network
Authorize a new member programmatically:
curl -s -X POST \
-H "Authorization: token YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"config": {"authorized": true}}' \
https://api.zerotier.com/api/v1/network/1d71939404a3b1e2/member/abcd123456
Here is a Python script that automates member authorization for a given network:
import requests
API_TOKEN = "YOUR_API_TOKEN"
NETWORK_ID = "1d71939404a3b1e2"
BASE_URL = "https://api.zerotier.com/api/v1"
headers = {
"Authorization": f"token {API_TOKEN}",
"Content-Type": "application/json"
}
def list_unauthorized_members():
response = requests.get(
f"{BASE_URL}/network/{NETWORK_ID}/member",
headers=headers
)
response.raise_for_status()
members = response.json()
return [m for m in members if not m.get("config", {}).get("authorized")]
def authorize_member(member_id):
response = requests.post(
f"{BASE_URL}/network/{NETWORK_ID}/member/{member_id}",
headers=headers,
json={"config": {"authorized": True}}
)
response.raise_for_status()
print(f"Authorized member: {member_id}")
if __name__ == "__main__":
for member in list_unauthorized_members():
authorize_member(member["nodeId"])
Best Practices
- Use private networks: Always set networks to Private and manually authorize each member. Public networks allow anyone with the network ID to join, which is a significant security risk.
- Prune inactive members: Regularly review the member list in ZeroTier Central and remove devices that are no longer in use to reduce your attack surface.
- Back up identity files: Store
identity.secretfiles in a secure password manager or encrypted backup. Without them, you cannot restore a node's membership. - Use managed routes carefully: When configuring subnet routing, ensure there is no IP range overlap between your ZeroTier network and the target subnets to avoid routing conflicts.
- Monitor peer connections: Use
zerotier-cli listpeersperiodically to verify that critical connections are direct (P2P) rather than relayed, as relays add latency. - Deploy a moon for production: For production environments, host at least one moon server to reduce dependency on ZeroTier's public infrastructure and improve connection reliability.
- Keep software updated: ZeroTier releases regular updates with security patches and performance improvements. Subscribe to release notifications and update promptly.
- Segment networks by purpose: Instead of putting all devices on a single network, create separate networks for different purposes (e.g., development, production, monitoring) to enforce isolation.
Troubleshooting Common Issues
If a device cannot connect, first check the service status:
sudo systemctl status zerotier-one
If the service is running but the network shows as ACCESS_DENIED, the member has not been authorized in ZeroTier Central. Log in and authorize the device.
If the network status is REQUESTING_CONFIGURATION, verify that the network ID is correct. A typo in the 16-digit ID is the most common cause.
For connectivity issues between two authorized members, check whether UDP port 9993 is being blocked. ZeroTier uses UDP for all traffic, and restrictive firewalls can prevent direct connections. You can test this with:
sudo zerotier-cli info
sudo zerotier-cli listpeers
If all peers show only relay paths, consider deploying a moon server or configuring port forwarding for UDP 9993 on your gateway.
Conclusion
ZeroTier is a versatile and powerful tool that simplifies secure networking across distributed environments. Its peer-to-peer architecture eliminates the need for complex VPN server setups, while its Layer 2 operation ensures broad protocol compatibility. By following the installation steps, configuring managed routes for subnet access, and adhering to best practices around network privacy and identity backup, you can build a robust virtual network that scales from a personal homelab to a multi-region production infrastructure. Whether you are connecting remote developers to shared resources or bridging cloud VPCs across providers, ZeroTier provides a fast, reliable, and developer-friendly foundation for modern networking.