buildbot/nix-eval Build done.
buildbot/nix-build Build started.
buildbot/nix-build gitea:greg/nixos#checks.x86_64-linux.nixos-exodus Build done.
buildbot/nix-build gitea:greg/nixos#checks.x86_64-linux.hm-exodus Build done.
buildbot/nix-build gitea:greg/nixos#checks.x86_64-linux.nixos-genesis Build done.
buildbot/nix-build gitea:greg/nixos#checks.x86_64-linux.nixos-isaiah Build done.
buildbot/nix-build gitea:greg/nixos#checks.x86_64-linux.nixos-jeremiah Build done.
Nebula PKI Bootstrap Guide
This directory holds the Nebula CA certificate, host certificates, and
agenix-encrypted private keys for the nebula.thehellings.com overlay network.
CIDR
10.157.0.0/16
Host IP Assignments
| Host | Nebula IP | Role |
|---|---|---|
| linode | 10.157.0.1 | Lighthouse + relay |
| genesis | 10.157.0.2 | LAN router (unsafe) |
| hosea | 10.157.0.3 | Regular node |
| isaiah | 10.157.0.4 | Regular node |
| jeremiah | 10.157.0.5 | Regular node |
| zeke | 10.157.0.6 | Regular node |
| exodus | 10.157.0.7 | Regular node (laptop) |
Step 1 — Install nebula-cert
nix shell nixpkgs#nebula
Step 2 — Create the CA
Run once; keep ca.key offline/safe (do NOT commit it):
nebula-cert ca -name "thehellings.com" -out-crt ca.crt -out-key ca.key
Commit ca.crt (public) to the repo at secrets/nebula/ca.crt.
Store ca.key securely (password manager / offline).
Step 3 — Sign host certificates
For most hosts (no subnet routing):
nebula-cert sign -ca-crt ca.crt -ca-key ca.key \
-name <hostname> \
-ip <nebulaIp>/16 \
-out-crt secrets/nebula/<hostname>.crt \
-out-key secrets/nebula/<hostname>.key
For genesis (routes the home LAN 10.42.0.0/16), add -subnets:
nebula-cert sign -ca-crt ca.crt -ca-key ca.key \
-name genesis \
-ip 10.157.0.2/16 \
-subnets '10.42.0.0/16' \
-out-crt secrets/nebula/genesis.crt \
-out-key secrets/nebula/genesis.key
Commit *.crt files (public) to the repo.
Do NOT commit raw *.key files — encrypt them first (Step 4).
Step 4 — Encrypt private keys with agenix
From the repo root:
cd nixos
for host in linode genesis hosea isaiah jeremiah zeke exodus; do
agenix -e secrets/nebula/${host}.key.age < secrets/nebula/${host}.key
rm secrets/nebula/${host}.key # remove plaintext key
done
The secrets/secrets.nix file already declares the .key.age recipients.
Step 5 — Configure linode's public DNS / firewall
- Add a DNS A record:
linode.nebula.thehellings.com→ linode's public IP - Open UDP port
4242in linode's firewall / Linode Cloud Firewall rules
Step 6 — Deploy
colmena apply --on linode # lighthouse first
colmena apply # rest of the fleet
Verifying
# From any host, ping another by Nebula IP
ping 10.157.0.2 # genesis
# From any host, reach home LAN via unsafe_routes
ping 10.42.1.1 # UDM Pro (via genesis)
Notes
ca.crtis public and lives in the repo unencrypted.*.crt(host certs) are public and live in the repo unencrypted.*.key.ageare agenix-encrypted private keys (insecrets/nebula/).- The NixOS module (
modules/nixos/nebula.nix) references these paths directly. - The lighthouse (
linode) hasisLighthouse = trueandisRelay = true. genesishasroutesSubnet = "10.42.0.0/16"which enables IP forwarding and nftables masquerade so Nebula peers can reach the home LAN.- All other hosts have
unsafeRoutespointing to genesis (10.157.0.2) for the 10.42.0.0/16 subnet.