production-openbsd/docs/setup-checklist.md
obsidian-ai be77f1eb2f feat: production-openbsd v0.1 scaffold
Sister to s8n/production-deb. Edge-box config + provision script for
running the OpenBSD-edge role per s8n/production-setup-audit Topology 02.

v0.1 = stock OpenBSD install ISO (interactive, 5 min) + scripted provision
from onyx. Autoinstall ISO build deferred to v0.2.

Layout:
  README.md                    workflow + service mapping (Debian → OpenBSD)
  flash.sh                     burn stock install76.iso to USB
  etc/                         pf / relayd / acme-client / unbound /
                               hostname.wg0.example / sshd_config / doas.conf
  scripts/
    provision.sh               from onyx: SSH+git clone+run install.sh
    install.sh                 on edge: copy /etc/*, validate, restart, cron
    cert-renew-check.sh        weekly LE renewal
    read-logs.sh               pull /var/log/* for offline diagnostics
  docs/
    setup-checklist.md         7-phase first-time install walkthrough

Hardware target: Dell Precision T5600 per
  s8n/production-setup-audit/hardware/dell-t5600.md

WG mesh: 10.10.10.0/29 between edge (.1) and nullstone (.2). UDP 51820.
Keys generated per-host (NEVER committed to repo).

Public traffic flow after migration:
  Internet → router → edge T5600 (relayd TLS term) → wg0 →
  nullstone Traefik (10.10.10.2:8443, private only)

CVE delta vs single-host Debian: regreSSHion + xz backdoor mitigated;
public IP runs OpenBSD base only — no systemd, no glibc, no Docker.
2026-05-08 14:10:29 +01:00

3.8 KiB

Setup checklist — first-time edge box install

Prerequisites

  • Dell T5600 powered on, NICs cabled (em0 to WAN-side, em1 to LAN switch)
  • OpenBSD 7.x install ISO burned to USB (install76.iso, ~600 MB)
  • Onyx has SSH pubkey ready: ~/.ssh/id_ed25519.pub
  • WG pubkey of nullstone on hand (run wg show wg0 public-key on nullstone after apt install wireguard-tools and key generation)

Phase 1 — install OpenBSD (interactive, ~5 min)

  1. Boot Dell from USB
  2. At (I)nstall, (U)pgrade, (A)utoinstall, or (S)hell? choose I
  3. Hostname: flintstone (or chosen edge codename)
  4. Network — pick em0 (or whichever is WAN-side), use DHCP for now
  5. Set FDE: yes. Choose strong passphrase (don't use 123 here — this passphrase is typed at every boot and protects all data at rest)
  6. Sets to install: bsd bsd.mp base76 comp76 man76 (skip xenocara, xfont, xserv, xshare)
  7. Set timezone Europe/London
  8. Add user: user, full name user, password (strong)
  9. Allow root SSH: no (we'll harden via sshd_config in Phase 3)
  10. Set primary boot disk: yes
  11. Reboot

Phase 2 — first login + SSH key

  1. Log in at console as user
  2. Find IP: ifconfig em0 inet | awk '/inet / {print $2}' — record this
  3. From onyx: ssh-copy-id user@<edge-ip> to push your pubkey
  4. From onyx: ssh user@<edge-ip> to confirm key auth works

Phase 3 — provision (from onyx)

cd ~/projects/production-openbsd
./scripts/provision.sh user@<edge-ip>

This runs install.sh on the edge box, which:

  • Installs acme-client wireguard-tools git rsync
  • Backs up current /etc configs
  • Copies repo's etc/* into /etc/
  • Validates with pfctl -n, relayd -n, unbound-checkconf
  • Enables + reloads pf, relayd, unbound, sshd
  • Adds weekly cron for cert-renew

Verify on edge:

ssh user@<edge-ip> 'doas pfctl -sr | head; doas rcctl ls on'

Phase 4 — WireGuard mesh setup (manual key exchange)

On the edge box:

doas mkdir -p /etc/wg && doas chmod 700 /etc/wg
cd /tmp && openssl rand -base64 32 > edge.key
wg pubkey < edge.key > edge.pub
doas mv edge.{key,pub} /etc/wg/
cat /etc/wg/edge.pub        # → paste this into nullstone's wg config

On nullstone (Debian):

sudo apt install wireguard-tools
sudo mkdir -p /etc/wireguard && sudo chmod 700 /etc/wireguard
cd /tmp && openssl rand -base64 32 > nullstone.key
wg pubkey < nullstone.key > nullstone.pub
sudo mv nullstone.{key,pub} /etc/wireguard/
cat /etc/wireguard/nullstone.pub      # → paste this into edge's hostname.wg0

On edge box:

doas cp /tmp/production-openbsd/etc/hostname.wg0.example /etc/hostname.wg0
doas vi /etc/hostname.wg0
# → replace NULLSTONE_PUB_KEY_HERE with nullstone.pub content
doas sh /etc/netstart wg0
ifconfig wg0          # confirm interface up with 10.10.10.1
ping 10.10.10.2       # should reach nullstone after its config goes up

On nullstone, configure peer side (sister steps; see s8n/production-deb/docs/wg-mesh.md once that's written).

Phase 5 — first cert

Once WG up + relayd running:

ssh user@<edge-ip> 'doas acme-client -v s8n.ru'
ssh user@<edge-ip> 'doas acme-client -v veilor.uk'
ssh user@<edge-ip> 'doas rcctl reload relayd'
curl -I https://s8n.ru

Phase 6 — switch public traffic

On the GL.iNet router admin: change port-forwards 80/443 from 192.168.0.100 (nullstone) to edge T5600 LAN IP.

Test from external: curl -I https://s8n.ru should now hit edge relayd, which terminates TLS, forwards over wg0 to nullstone Traefik on 8443.

Phase 7 — clean up nullstone public bind

On nullstone Traefik: change listen interfaces from *:80,*:443 to 10.10.10.2:8443. Restart Traefik. Verify with ss -ltnp | grep 8443.

Done. Public traffic now: Internet → router → edge T5600 (OpenBSD relayd) → WG tunnel → nullstone Traefik → Docker stack.