main

lutece — Scaleway Dedibox VPS (VPS-START-2-S, Paris)

NixOS VPS at 64.31.63.130, installed with nixos-anywhere + disko. Two roles:

  • homelab mesh client on wg0 (10.100.0.3), peer of carthage
  • travel exit node on wg1 (10.101.0.0/24) — full tunnel giving a French IP from abroad, plus access to the homelab

Why no Terraform

Dedibox is on the legacy Online.net platform and has no resources in the scaleway/scaleway Terraform provider (its scaleway_baremetal_server is Elastic Metal, a different product). It is scriptable through the dedibox/v1 API (scw dedibox ...), but a VPS on monthly commitment is a pet, ordered once by hand. The declarative part lives in systems/lutece/.

Hardware facts (verified on the running host)

Disk /dev/vda, 30 GB, virtio
Firmware BIOS (GPT + EF02 boot partition, GRUB)
CPU / RAM 2 vCPU / 1.9 GB + 4 GB swapfile
IPv4 64.31.63.130/24, gw 64.31.63.1 — static, no DHCP
IPv6 2a11:840:72:1b::/64 via SLAAC; stable address ends :216:3eff:fea8:6cf3

The static IPv4 is the important one: a DHCP assumption leaves the box unreachable after reboot. IPv6 is intentionally not pinned — its gateway is the provider router’s link-local address.

Reinstall

nix run github:nix-community/nixos-anywhere -- \
  --flake .#lutece --build-on local root@64.31.63.130

Run it from a host whose key is in the VPS’s authorized_keys (set at order time in the Dedibox console). It must be usable non-interactively, so a Yubikey/touch key will not do. Keep an IPv4 reachable — nixos-anywhere has known failures on IPv6-only Scaleway targets (nix-community/nixos-anywhere#227).

Note the two keys under /etc/wireguard/ are not in the Nix store and do not survive a reinstall; regenerate them as below.

WireGuard keys (manual, once)

# mesh identity (wg0) — public key goes to globals.machines.lutece.net.vpn.pubkey
umask 077; wg genkey > /etc/wireguard/private.key; wg pubkey < /etc/wireguard/private.key

# travel server identity (wg1) — public key goes into travel client configs
umask 077; wg genkey > /etc/wireguard/travel.key; wg pubkey < /etc/wireguard/travel.key

Travel tunnel

Peers are declared in globals.net.travel.peers (name → travel IP); their public keys are reused from the machine’s mesh identity in globals.machines.<name>.net.vpn.pubkey.

Client config, e.g. for hokkaido:

[Interface]
PrivateKey = <the device's existing mesh private key>
Address = 10.101.0.5/32
DNS = 1.1.1.1
MTU = 1340

[Peer]
PublicKey = d28ha+85FlP188kDkCDMX6I8iM20PtbTy6kj0sHvHwo=
Endpoint = travel.sbr.pm:51820
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25

Only Address changes per device:

Device mesh travel
hokkaido 10.100.0.5 10.101.0.5/32
osaka (Boox tablet) 10.100.0.64 10.101.0.64/32
suzu 10.100.0.65 10.101.0.65/32
houbeb-makcbook-pro 10.100.0.71 10.101.0.71/32

AllowedIPs = 0.0.0.0/0 is what makes it a full tunnel: web traffic exits in Paris with a French IP, and 10.100.0.0/24 reaches the homelab through lutece’s wg0.

How the return path works: lutece masquerades 10.101.0.0/24 on POSTROUTING with no output interface, so homelab hosts see traffic as coming from 10.100.0.3 and need no route for the travel subnet. That is why adding this feature required no change to rhea/aion/carthage’s config.

Caveat: this is a hosting IP range, not residential. Geo-restricted services that block datacenter ranges may still refuse it.

Deploy order

  1. Generate /etc/wireguard/travel.key on lutece (above).
  2. Deploy lutece: nixos-rebuild switch --flake .#lutece --target-host root@64.31.63.130
  3. Redeploy carthage so it accepts lutece as a mesh peer.
  4. Add the travel tunnel to the device and test: curl ifconfig.me should show 64.31.63.130.

Open items

  • Root only accepts touch-required keys, so nothing can manage lutece non-interactively. Add an aomi-tpm entry for lutece in globals.ssh.vincent if automation is wanted.
  • SSH is still public; restrict it to the VPN address once the mesh is up (see the TODO in systems/lutece/extra.nix).
  • Travel peers currently reuse their mesh keypair. Separate keys would be cleaner; it means provisioning a new keypair per device.