production-openbsd/scripts/install.sh
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

69 lines
2.5 KiB
Bash
Executable file

#!/bin/sh
# install.sh — runs on the edge box (called by provision.sh)
#
# Copies repo's etc/* into /etc/, validates configs, restarts services.
# Idempotent: re-running just refreshes configs.
set -eu
cd "$(dirname "$0")/.."
REPO_DIR="$(pwd)"
echo "[install] running from $REPO_DIR"
# === Backup existing configs once ===
BACKUP_DIR=/var/backups/production-openbsd-pre-install
if [ ! -d "$BACKUP_DIR" ]; then
echo "[install] backing up current configs to $BACKUP_DIR"
mkdir -p "$BACKUP_DIR"
for f in /etc/pf.conf /etc/relayd.conf /etc/acme-client.conf /var/unbound/etc/unbound.conf /etc/ssh/sshd_config /etc/doas.conf; do
[ -f "$f" ] && cp "$f" "$BACKUP_DIR/" || true
done
fi
# === Copy configs ===
echo "[install] installing configs"
install -m 600 "$REPO_DIR/etc/pf.conf" /etc/pf.conf
install -m 600 "$REPO_DIR/etc/relayd.conf" /etc/relayd.conf
install -m 600 "$REPO_DIR/etc/acme-client.conf" /etc/acme-client.conf
install -m 644 "$REPO_DIR/etc/unbound.conf" /var/unbound/etc/unbound.conf
install -m 600 "$REPO_DIR/etc/sshd_config" /etc/ssh/sshd_config
install -m 600 "$REPO_DIR/etc/doas.conf" /etc/doas.conf
# WG: only copy if /etc/hostname.wg0 doesn't already exist
if [ ! -f /etc/hostname.wg0 ]; then
echo "[install] WARN: /etc/hostname.wg0 not present"
echo "[install] Copy etc/hostname.wg0.example, generate keys, paste nullstone pubkey"
echo "[install] See its header for steps. Skipping wg0 enable for now."
fi
# === Validate configs ===
echo "[install] validating configs"
pfctl -nf /etc/pf.conf
relayd -nf /etc/relayd.conf
unbound-checkconf /var/unbound/etc/unbound.conf
# === Enable services ===
echo "[install] enabling services"
rcctl enable pf relayd acme-client unbound sshd
[ -f /etc/hostname.wg0 ] && rcctl set wg flags || true
# === Reload services ===
echo "[install] reloading services"
rcctl reload pf || pfctl -f /etc/pf.conf
rcctl restart relayd
rcctl restart unbound
rcctl restart sshd
# === Cron for acme-client renewal (weekly) ===
CRON_FILE=/var/cron/tabs/root
if ! grep -q '/usr/local/sbin/cert-renew-check.sh' "$CRON_FILE" 2>/dev/null; then
echo "[install] adding weekly cert-renew cron"
install -m 755 "$REPO_DIR/scripts/cert-renew-check.sh" /usr/local/sbin/
( crontab -l 2>/dev/null; echo '15 3 * * 0 /usr/local/sbin/cert-renew-check.sh' ) | crontab -
fi
echo "[install] DONE"
echo "[install] verify:"
echo " pfctl -sr | head"
echo " rcctl ls on"
echo " acme-client -v s8n.ru # request first cert (DNS-01 manual for now)"