Install ZeroTier Mesh VPN on Linux VPS

September 17, 2026 · 12 min read · Linux, Networking, VPN

ZeroTier Mesh VPN on Linux VPS

ZeroTier is an open-source software-defined networking tool that lets you build a virtual LAN across the internet in minutes — effectively connecting multiple VPS instances from different data centers as if they shared a single physical switch, with no firewall rules or port-forwarding required on either end.

Unlike WireGuard or OpenVPN which require a dedicated gateway server, ZeroTier operates as a full mesh network where every node can connect directly to every other node using peer-to-peer connections with built-in NAT traversal. All traffic is encrypted with Curve25519/AES-256-GCM.

How ZeroTier Works

ZeroTier consists of three layers:

ComponentRoleLocation
Planet / MoonRoot server for peer bootstrap and discoverymy.zerotier.com (or self-hosted)
ControllerManages Network IDs and member authorizationmy.zerotier.com or local ZeroTierOne
Node (Member)Each VPS or device joining the networkYour servers

When two nodes join the same network, ZeroTier first attempts a direct P2P tunnel. If NAT prevents this, it falls back to a relay server — but in both cases traffic is end-to-end encrypted. You can run your own Moon (relay) server to reduce dependency on ZeroTier's infrastructure.

Prerequisites

You need at least two VPS instances (or one VPS + a local machine) running Ubuntu 22.04/24.04 or Debian 11/12:

Tip: ZeroTier is free for networks with up to 25 members. Above that, you need a paid plan or a self-hosted controller.

Step 1: Create a ZeroTier Network

Go to my.zerotier.com → click Create A Network. The dashboard will generate a 16-character hex Network ID (e.g., a09acf02337b9b1c).

Configure the new network:

Step 2: Install ZeroTier on Each VPS

Repeat these steps on every VPS you want to connect:

# Install ZeroTier (supports Ubuntu, Debian, RHEL, Alpine, and more)
curl -s https://install.zerotier.com | sudo bash

# Verify the service is running
sudo systemctl status zerotier-one

# Check your node's ZeroTier address
sudo zerotier-cli info

The zerotier-cli info command will output something like:

200 info 1a2b3c4d5e 1.14.0 ONLINE

The 10-character hex string (1a2b3c4d5e) is this node's Node ID. Note it down — you'll need it to authorize the node in the next step.

Step 3: Join Your Network

On each VPS, run the following command replacing NETWORK_ID with your actual Network ID:

sudo zerotier-cli join a09acf02337b9b1c

Then go to my.zerotier.com → select your network → scroll to Members. Your new node will appear — tick the Auth checkbox to authorize it.

Tip: On a Private network, nodes must be authorized before they receive an IP address and can communicate with other members. This is the key access-control layer.

Step 4: Verify Peer Connectivity

After authorization, verify that ZeroTier has assigned an IP and that peers can communicate:

# Show your ZeroTier IP and interface
ip addr show | grep zt
# or
sudo zerotier-cli listnetworks

# List all peers and connection type
sudo zerotier-cli peers

The listnetworks output should look like:

200 listnetworks a09acf02337b9b1c  OK  PRIVATE  zt7xxxxxxx  172.22.0.1/16

Step 5: Test Connectivity

From the first VPS, test connection to the second VPS using its ZeroTier IP:

# Ping via ZeroTier IP
ping 172.22.0.2

# SSH directly over ZeroTier
ssh [email protected]

# Benchmark bandwidth
iperf3 -s            # on VPS 2
iperf3 -c 172.22.0.2  # on VPS 1

Using ZeroTier as a Private Network for Databases

One of the most practical uses of ZeroTier is keeping databases off the public internet. Instead of binding to 0.0.0.0, bind only to the ZeroTier interface:

# Configure MariaDB/MySQL to bind only to the ZeroTier IP
sudo nano /etc/mysql/mariadb.conf.d/50-server.cnf

# Change bind-address to your ZeroTier IP
bind-address = 172.22.0.1

sudo systemctl restart mariadb

# Test from the app server (over ZeroTier)
mysql -h 172.22.0.1 -u myuser -p

Configure UFW to Allow ZeroTier Traffic

If you use UFW, add rules for the ZeroTier interface:

# Allow traffic on the ZeroTier network interface
sudo ufw allow in on ztxxxxxxxx
sudo ufw allow out on ztxxxxxxxx

# Or allow the entire ZeroTier subnet
sudo ufw allow from 172.22.0.0/16

# Verify
sudo ufw status verbose

Self-Hosted Relay with a ZeroTier Moon

To eliminate dependency on ZeroTier's cloud infrastructure, you can run your own Moon (relay) server on a VPS with a public IP:

# On the VPS that will become the Moon
cd /var/lib/zerotier-one
sudo zerotier-idtool initmoon identity.public > moon.json

# Edit moon.json — add your VPS's real public IP to stableEndpoints
sudo nano moon.json
# "stableEndpoints": ["203.0.113.10/9993"]

# Generate the .moon file
sudo zerotier-idtool genmoon moon.json
# Creates: 000000xxxxxxxxxx.moon

# Get your Moon ID
sudo zerotier-cli info | awk '{print $3}'
# On every node that should use this Moon
sudo mkdir -p /var/lib/zerotier-one/moons.d
sudo cp 000000xxxxxxxxxx.moon /var/lib/zerotier-one/moons.d/
sudo systemctl restart zerotier-one

# Verify the Moon is orbited
sudo zerotier-cli listpeers | grep MOON

Verifying ZeroTier Works Correctly

# Check service status
sudo systemctl status zerotier-one

# List all joined networks
sudo zerotier-cli listnetworks

# Show all peers with connection type (DIRECT or RELAY)
sudo zerotier-cli peers

# Show ZeroTier interfaces and IPs
ip addr show | grep zt

# Test ping over ZeroTier
ping -c 4 172.22.0.2

# Follow logs in real time
sudo journalctl -u zerotier-one -f
Tip: In the peers output, DIRECT means a true peer-to-peer connection (low latency), while RELAY means traffic is going through ZeroTier's relay servers (higher latency). Setting up a Moon server on your own VPS is the best fix for persistent relay connections.

Troubleshooting Common Issues

Error: "Unable to connect to ZeroTier service"

The ZeroTier daemon is not running or its socket is unresponsive:

# Check and restart the service
sudo systemctl status zerotier-one
sudo systemctl restart zerotier-one

# Verify socket file exists
ls -la /var/lib/zerotier-one/zerotier-one.port

Node joins but stays at REQUESTING_CONFIGURATION — no IP assigned

This almost always means the node hasn't been authorized yet in the web dashboard:

# Check current network status
sudo zerotier-cli listnetworks

# Authorized shows:  OK  PRIVATE
# Unauthorized shows: ACCESS_DENIED  PRIVATE

Ping works but latency is very high (>100ms)

The connection is going through a relay instead of peer-to-peer. Usually caused by symmetric NAT or a firewall blocking UDP 9993:

# Check connection type
sudo zerotier-cli peers
# RELAY = via relay server, DIRECT = peer-to-peer

# Open UDP 9993 outbound
sudo ufw allow 9993/udp

# If behind strict NAT, set up a Moon server

Error: "zerotier-cli: command not found" after install

The binary may be in a different path depending on the distribution:

which zerotier-cli
ls /usr/sbin/zerotier-cli

# Reinstall if not found
curl -s https://install.zerotier.com | sudo bash

ZeroTier interface disappears after reboot

The service is not configured to start automatically:

sudo systemctl enable zerotier-one
sudo systemctl start zerotier-one

Frequently Asked Questions

How does ZeroTier compare to WireGuard?

WireGuard requires a central gateway server with a public IP — all nodes route traffic through it, and you must manually exchange keys. ZeroTier creates a full mesh where nodes connect directly to each other, has zero manual key exchange, and handles NAT traversal automatically. WireGuard has marginally lower overhead and higher raw throughput for simple hub-and-spoke topologies, while ZeroTier is far easier to manage for dynamic, multi-node networks.

Is ZeroTier production-ready?

Yes. ZeroTier uses Curve25519 for key exchange and AES-256-GCM for encryption — both are industry-standard cryptographic primitives. Many enterprises use ZeroTier in production for multi-cloud and hybrid infrastructure. Always use Private networks and regularly audit the member list.

How do I achieve full self-hosting with ZeroTier?

Set up a Moon on your own VPS as described above to eliminate relay dependency. For full controller self-hosting, run ztncui (ZeroTier Network Controller UI) or a compatible open-source alternative. This means traffic metadata never touches ZeroTier's cloud servers.