Quick Start¶
This walks from a fresh gateway to rotating exit IPs. It assumes the gateway already has its two WireGuard interfaces up (wg-operator on 51820 for operators, wg-nodes on 51821 for exit nodes) - those are configured declaratively by fleet-nix. See DESIGN.md for the interface and subnet scheme.
1. Provision a VPS¶
Use vpsctl to create a KVM VPS on a provider with an ASN you don't already have in the fleet, and note its public IP.
2. Deploy and register in one command¶
From the gateway:
deploy does everything: it picks the next free management IP in 10.100.0.0/24, mints a WireGuard keypair for the node, installs hardened NixOS with nixos-anywhere (kexec into RAM, wipe the provider disk, install the fleet-nix exit-node config with the keypair and gateway info baked in), then registers the node as a wg-nodes peer.
Within 30 seconds the convergence daemon creates the node's IPIP tunnel, resolves its ASN via whois, and adds it to the ECMP pool. Repeat for as many nodes as you want.
Pointing deploy at a local fleet-nix
deploy fetches the exit-node config from github:StrongWind1/fleet-nix by default. Override it for local development:
3. Generate an operator config¶
Still on the gateway, print a WireGuard config for your operator station (pass the operator's tunnel IP, .2-.9):
Edit the file to paste your operator private key in place of REPLACE_WITH_OPERATOR_PRIVATE_KEY, register the matching public key on the gateway's wg-operator interface, then bring the tunnel up on the operator station:
The generated config uses Table = off with an explicit split-tunnel rule set so SSH to the gateway stays direct while everything else exits through the fleet. See Networking Internals.
4. Confirm rotation¶
From the operator station:
exitfleet test
# 1/10: 203.0.113.50 (BuyVM, AS53667)
# 2/10: 198.51.100.22 (Hetzner, AS24940)
# 3/10: 192.0.2.88 (Vultr, AS20473)
# ...
Different connections leave from different node IPs across different ASNs. On the gateway, exitfleet status shows every node's tunnel, ASN, and health.
5. Scan¶
Bind your tools to the tunnel so their traffic is sourced from the tunnel IP - that is what the split-tunnel policy rule matches to send it through the fleet. Traffic from your real interface stays direct (so SSH to the gateway is unaffected). See Networking Internals.
curl --interface wg-exitfleet https://target/
nmap -e wg-exitfleet -sS target
masscan -e wg-exitfleet -p1-65535 target
Traffic is forwarded at layer 3, so raw-socket techniques (SYN scans, custom stacks) work unmodified. For operations that need every packet from one source (nmap -O), pin first: