ZeroTier SDN: CLI, Network Membership and Managed Routes - 夜莺博客

ZeroTier SDN: CLI, Network Membership and Managed Routes

ZeroTier builds a peer-to-peer Layer 2/Layer 3 overlay between hosts without a central concentrator, and it is a practical answer to "I need my lab reachable from anywhere" and "I need these three sites on one flat network". The client CLI manages node and network membership; the controller — hosted or self-run — defines the network itself. This guide covers the CLI, the client-side settings that cause most connectivity confusion, the controller API for central membership, and the routes worth defining.

Node status and peer inspection

sudo zerotier-cli status
# 200 info 8056c2e21c000001 1.14.2 ONLINE

zerotier-cli listpeers
# 200 listpeers <ztaddr> <ver> <role> <lat> <path> <version>

The node ID is the address your controller authorises. ONLINE means the client can reach the global root infrastructure; OFFLINE means it cannot reach the roots and will keep retrying. Extended OFFLINE states are almost always a local firewall blocking outbound UDP 9993 rather than a problem with the service.

listpeers shows other nodes: peers with the role LEAF are ordinary devices (laptops, servers, controllers) and peers with role PLANET are root servers. Seeing unknown leaves is normally harmless — they are part of the infrastructure or other members of a network you have joined.

Join and leave networks

sudo zerotier-cli join 8056c2e21c000001
# 200 join OK

sudo zerotier-cli listnetworks
sudo zerotier-cli leave 8056c2e21c000001

Join status codes carry the diagnosis:

  • OK — up and running on the network.
  • REQUESTING_CONFIGURATION — negotiating with the controller. A minute is normal; much longer means the controller is unreachable or the member is not authorised.
  • NOT_FOUND — a typo in the 16-character network ID.
  • ACCESS_DENIED — the network is private and this member has not been authorised.

The most common "it joined but there is no IP" case is a private network with the member listed but unauthorised. Check the controller, not the client.

Client-side settings that change everything

zerotier-cli get 8056c2e21c000001 mtu
zerotier-cli set 8056c2e21c000001 allowManaged true
zerotier-cli set 8056c2e21c000001 allowGlobal false
zerotier-cli set 8056c2e21c000001 allowDefault false
zerotier-cli set 8056c2e21c000001 allowDNS false
  • allowManaged — lets the controller assign addresses and routes to this interface. Turn it off when you are configuring the interface statically, which is exactly what a bridge setup requires.
  • allowGlobal — permits routes outside the RFC1918 space. Leave it off unless the controller must push public prefixes.
  • allowDefault — accepts a 0.0.0.0/0 default route. Turning this on sends all your traffic through the overlay; useful for a full-tunnel design, disastrous if enabled on a server by accident.
  • allowDNS — lets the controller set DNS servers. Convenient in managed fleets, worth disabling when the host's DNS is managed by configuration management.

These four are the settings to check first when behaviour differs between two hosts that appear identically configured.

Controller membership through the API

TOKEN=$(cat /var/lib/zerotier-one/authtoken.secret)
NWID=8056c2e21c000001
MEMID=1c2f3d4e5a

# inspect a member
curl "http://localhost:9993/controller/network/${NWID}/member/${MEMID}" \
     -H "X-ZT1-AUTH: ${TOKEN}"

# authorise
curl -X POST "http://localhost:9993/controller/network/${NWID}/member/${MEMID}" \
     -H "X-ZT1-AUTH: ${TOKEN}" -d '{"authorized": true}'

# deauthorise before deleting
curl -X POST "http://localhost:9993/controller/network/${NWID}/member/${MEMID}" \
     -H "X-ZT1-AUTH: ${TOKEN}" -d '{"authorized": false}'

Deauthorise before you delete: a deleted member will reappear in the list on its next join attempt if the node is still running. Authorisation is the real control, deletion is housekeeping. Back up the controller's state directory as well — the member database and network definitions live there, and rebuilding them by hand is unpleasant.

Bridging a physical LAN

The classic use case is extending a physical subnet onto the overlay. The requirements are strict and worth restating because breaking networking on the bridge host is the normal outcome of getting them wrong:

  1. Cancel address management on the ZeroTier interface: zerotier-cli set $NETWORK_ID allowManaged=0.
  2. Enable Allow Bridging and Do Not Auto Assign for the member in the controller.
  3. Bridge the physical interface and the zt* interface into one bridge with a static address on the bridge, using systemd-networkd or equivalent.
  4. Keep the ZeroTier auto-assign pool in the same subnet as the physical LAN, outside the DHCP range.
  5. Test from a device that is not the bridge host.

If you are comparing overlay options, the mesh-VPN operational notes in Tailscale and WireGuard mesh VPN operations cover the same design space with a different trust model, and if you simply need two fixed sites connected, the approach in WireGuard site-to-site VPN configuration may be less machinery than an overlay.

原文链接:https://docs.zerotier.com/cli