WireGuard --------- * Migration 0013: wireguard_interfaces (server|client mode, key envelope- encrypted) + wireguard_peers (per-server roster). Drop old empty 0005-Schema (Option-A peer_type, kein Iface-FK), neuer Aufbau mit zwei Tabellen + FK. * internal/services/secrets: Box mit AES-256-GCM, Master-Key in /var/lib/edgeguard/.master_key (lazy-create, 0600). Sealed/Open für PrivateKey + PSK. * internal/services/wireguard: KeyGen (Curve25519 mit clamping), PublicFromPrivate (für Import), InterfacesRepo, PeersRepo, Importer (parst /etc/wireguard/*.conf, server vs. client heuristisch nach ListenPort + Peer-Anzahl). * internal/wireguard: Renderer schreibt /etc/edgeguard/wireguard/<iface>.conf (0600), restartet wg-quick@<iface> via sudo (sudoers im postinst erweitert). Idempotent — re-render nur wenn content geändert. * internal/handlers/wireguard.go: REST CRUD für interfaces+peers, /generate-keypair, /peers/:id/config (text/plain wg-quick conf), /peers/:id/qr (PNG via go-qrcode). Auto-reload nach Mutation. * edgeguard-ctl wg-import [--path /etc/wireguard]: liest existierende conf-Files in die DB. Idempotent (überspringt vorhandene Iface-Namen). Shared UI components (proxy-lb-waf design pattern) -------------------------------------------------- * PageHeader: icon + title + subtitle + extras row, einheitlich oben auf jeder Page. * ActionButtons: Edit + Delete combo mit Popconfirm + Tooltip. * StatusDot: AntD Badge pattern statt "Yes/No" — schneller scanbar in dichten Tabellen. * DataTable: pageSizeOptions [20,50,100,200] + extraActions-Alias + optional renderMobileCard für Card-Liste auf < md Breakpoint. * enterprise.css: .page-header* + .datatable-toolbar Klassen. Frontend WireGuard ------------------ * /vpn/wireguard mit zwei Tabs (Server / Client) im neuen Pattern. * Server-Tab: Modal mit Generate-Keypair-Toggle, Peer-Roster im Drawer per Server. Pro Peer: QR-Code-Modal + .conf-Download. * Client-Tab: Upstream-Card im Modal, full-tunnel-Default (0.0.0.0/0,::/0), Keepalive 25. * i18n DE/EN für wg.* Block + common.* Erweiterung. Misc ---- * Sidebar: WireGuard unter Security-Sektion. * Nav-i18n: "Firewall (v2)" → "Firewall". * Version 1.0.8 → 1.0.11. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
134 lines
6.2 KiB
Bash
Executable File
134 lines
6.2 KiB
Bash
Executable File
#!/bin/bash
|
|
# postinst for edgeguard-api — creates system user, filesystem layout,
|
|
# initialises PostgreSQL (role + db + migrations), enables systemd
|
|
# units. Each step idempotent; safe to re-run on every upgrade.
|
|
set -e
|
|
|
|
export LC_ALL=C
|
|
export LANG=C
|
|
|
|
EG_USER="edgeguard"
|
|
EG_HOME="/var/lib/edgeguard"
|
|
|
|
case "$1" in
|
|
configure)
|
|
# ── System user ──────────────────────────────────────────────
|
|
if ! getent passwd "$EG_USER" >/dev/null; then
|
|
adduser --system --group --home "$EG_HOME" \
|
|
--shell /usr/sbin/nologin --no-create-home \
|
|
--gecos "EdgeGuard daemon" "$EG_USER"
|
|
fi
|
|
|
|
# ── Directories ──────────────────────────────────────────────
|
|
for d in /etc/edgeguard /var/lib/edgeguard /var/log/edgeguard \
|
|
/etc/edgeguard/haproxy /etc/edgeguard/squid \
|
|
/etc/edgeguard/wireguard /etc/edgeguard/unbound \
|
|
/etc/edgeguard/nftables.d /etc/edgeguard/tls \
|
|
/var/lib/edgeguard/acme; do
|
|
install -d -m 0750 -o "$EG_USER" -g "$EG_USER" "$d"
|
|
done
|
|
# ACME-Account-Dir 0700 — hält den lego-Account-Schlüssel,
|
|
# gehört nur edgeguard.
|
|
install -d -m 0700 -o "$EG_USER" -g "$EG_USER" /var/lib/edgeguard/acme-account
|
|
|
|
# ── sudoers: HAProxy reload + (later) systemd-networkd reload
|
|
# Damit edgeguard-api nach einer SSL- oder Netzwerk-Mutation
|
|
# selbst reloaden kann ohne root zu sein. NOPASSWD ist auf
|
|
# genau dieses Kommando beschränkt.
|
|
cat > /etc/sudoers.d/edgeguard <<'SUDOERS'
|
|
edgeguard ALL=(root) NOPASSWD: /usr/bin/systemctl reload haproxy.service
|
|
edgeguard ALL=(root) NOPASSWD: /bin/systemctl reload haproxy.service
|
|
edgeguard ALL=(root) NOPASSWD: /usr/sbin/nft -f /etc/edgeguard/nftables.d/ruleset.nft
|
|
edgeguard ALL=(root) NOPASSWD: /usr/bin/systemctl start wg-quick@*.service
|
|
edgeguard ALL=(root) NOPASSWD: /usr/bin/systemctl restart wg-quick@*.service
|
|
edgeguard ALL=(root) NOPASSWD: /usr/bin/systemctl stop wg-quick@*.service
|
|
edgeguard ALL=(root) NOPASSWD: /bin/systemctl start wg-quick@*.service
|
|
edgeguard ALL=(root) NOPASSWD: /bin/systemctl restart wg-quick@*.service
|
|
edgeguard ALL=(root) NOPASSWD: /bin/systemctl stop wg-quick@*.service
|
|
SUDOERS
|
|
chmod 0440 /etc/sudoers.d/edgeguard
|
|
|
|
# ── Self-signed default cert so HAProxy starts cleanly ───────
|
|
# HAProxy `bind :443 ssl crt /etc/edgeguard/tls/` needs at least
|
|
# one PEM in the directory to come up. Operator runs certbot
|
|
# later; until then, browsers see an unverified cert which is
|
|
# the expected first-boot UX.
|
|
DEFAULT_PEM="/etc/edgeguard/tls/_default.pem"
|
|
if [ ! -f "$DEFAULT_PEM" ]; then
|
|
HOSTNAME_FQDN="$(hostname -f 2>/dev/null || hostname)"
|
|
TMP_KEY="$(mktemp)"
|
|
TMP_CRT="$(mktemp)"
|
|
openssl req -x509 -nodes -newkey rsa:2048 \
|
|
-keyout "$TMP_KEY" -out "$TMP_CRT" \
|
|
-days 3650 \
|
|
-subj "/CN=$HOSTNAME_FQDN" \
|
|
-addext "subjectAltName = DNS:$HOSTNAME_FQDN,DNS:localhost" \
|
|
>/dev/null 2>&1
|
|
cat "$TMP_CRT" "$TMP_KEY" > "$DEFAULT_PEM"
|
|
chown "$EG_USER:$EG_USER" "$DEFAULT_PEM"
|
|
chmod 0640 "$DEFAULT_PEM"
|
|
rm -f "$TMP_KEY" "$TMP_CRT"
|
|
fi
|
|
|
|
# ── Pre-flight: validate embedded migration set ──────────────
|
|
# Catches duplicate version prefixes BEFORE we touch the DB,
|
|
# so a broken upgrade can't half-apply migrations and leave
|
|
# the cluster wedged (mail-gateway 2026-05-08 incident).
|
|
if ! /usr/bin/edgeguard-ctl migrate check; then
|
|
echo "postinst: embedded migrations failed validation — aborting" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# ── PostgreSQL: ensure role + database exist ─────────────────
|
|
# Requires postgresql-16 (or -17) running locally — guaranteed
|
|
# by Depends. Idempotent — re-runs on upgrade are no-ops.
|
|
if ! /usr/bin/edgeguard-ctl initdb; then
|
|
echo "postinst: edgeguard-ctl initdb failed — aborting" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# ── Apply pending schema migrations ──────────────────────────
|
|
if ! sudo -n -u "$EG_USER" /usr/bin/edgeguard-ctl migrate up; then
|
|
echo "postinst: edgeguard-ctl migrate up failed — aborting" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# ── Render initial service configs ───────────────────────────
|
|
# Writes /etc/edgeguard/haproxy/haproxy.cfg + nftables.d/
|
|
# ruleset.nft from the (just-migrated, empty) PG state.
|
|
# --no-reload because haproxy isn't pointed at our config yet
|
|
# — the drop-in below does that, then we restart.
|
|
if ! sudo -n -u "$EG_USER" /usr/bin/edgeguard-ctl render-config --no-reload; then
|
|
echo "postinst: edgeguard-ctl render-config failed — aborting" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# ── HAProxy systemd drop-in: read EdgeGuard config ───────────
|
|
# Keeps the distro /etc/haproxy/haproxy.cfg untouched (it's a
|
|
# conffile of the haproxy package). Drop-in is reversible by
|
|
# removing the file + daemon-reload.
|
|
install -d /etc/systemd/system/haproxy.service.d
|
|
if [ -f /etc/edgeguard/systemd/haproxy-edgeguard.conf ]; then
|
|
install -m 0644 /etc/edgeguard/systemd/haproxy-edgeguard.conf \
|
|
/etc/systemd/system/haproxy.service.d/edgeguard.conf
|
|
fi
|
|
|
|
# ── systemd: pick up new units + restart haproxy with our cfg
|
|
systemctl daemon-reload
|
|
systemctl restart haproxy.service || true
|
|
systemctl enable --now edgeguard-api.service edgeguard-scheduler.service || true
|
|
;;
|
|
|
|
abort-upgrade|abort-remove|abort-deconfigure)
|
|
;;
|
|
|
|
*)
|
|
echo "postinst called with unknown argument \`$1'" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
#DEBHELPER#
|
|
|
|
exit 0
|