Skip to content

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.

vpsctl node create <provider_id>
# -> 203.0.113.10

2. Deploy and register in one command

From the gateway:

exitfleet deploy 203.0.113.10

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:

EXITFLEET_FLAKE="path:/root/projects/fleet/fleet-nix" exitfleet deploy 203.0.113.10

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):

exitfleet client-config 10.100.1.2 > ~/wg-exitfleet.conf

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:

wg-quick up ~/wg-exitfleet.conf

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:

exitfleet pin 11      # all traffic exits node 11 until you unpin
exitfleet unpin       # back to ECMP rotation