feat(routes): Static-Routes-Management + Live-View (Networks-Tab)
Migration 0019: static_routes (id, destination, gateway, dev, metric,
table_name, active, comment).
internal/services/staticroutes/:
- CRUD-Repo
- Generator schreibt /etc/edgeguard/routes.conf (pipe-format) und
triggert `sudo systemctl restart edgeguard-routes.service`
- LiveAll() ruft `ip -j route show table all` und parsed JSON
internal/handlers/routes.go:
GET /api/v1/routes — managed (DB)
POST/PUT/DELETE — CRUD (re-render + apply on mutate)
GET /api/v1/routes/live — kernel-state via ip(8)
postinst:
- /usr/sbin/edgeguard-apply-routes (root-owned shell-script). Liest
routes.conf, flusht `proto 250` (= edgeguard), setzt neue Routen
mit proto 250. Andere Quellen (kernel/dhcp/manuell) bleiben
unangetastet.
- /etc/systemd/system/edgeguard-routes.service (Type=oneshot,
After=network-online.target). Beim Boot automatisch via
multi-user.target.
- /etc/iproute2/rt_protos.d/edgeguard.conf — Symbol "edgeguard" =
250 damit `ip route show proto edgeguard` funktioniert.
(Debian 13 hat kein /etc/iproute2 default → .d-Pattern statt
rt_protos-Anhängen.)
- sudoers: edgeguard ALL=(root) NOPASSWD: /usr/bin/systemctl
restart edgeguard-routes.service
UI: Networks-Page jetzt mit Tabs (Interfaces + Routen). Routes-Tab
hat zwei Cards:
- Live-Routen (read-only, 30s refresh, `proto edgeguard` farblich
hervorgehoben)
- Verwaltete Routen (CRUD-Tabelle, Add/Edit-Modal mit destination/
gateway/dev/metric/table/active/comment)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -93,6 +93,9 @@ edgeguard ALL=(root) NOPASSWD: /usr/bin/apt-get update
|
||||
# Backup-Pfad: pg_dump als postgres-User. Whitelist exakt mit
|
||||
# --clean --if-exists --no-owner --no-acl + dem festen DB-Namen.
|
||||
edgeguard ALL=(postgres) NOPASSWD: /usr/bin/pg_dump --clean --if-exists --no-owner --no-acl edgeguard
|
||||
# Static-Routes: API ruft `sudo systemctl restart edgeguard-routes.service`
|
||||
# nach jedem Mutate, damit das apply-Skript die neue routes.conf anwendet.
|
||||
edgeguard ALL=(root) NOPASSWD: /usr/bin/systemctl restart edgeguard-routes.service
|
||||
# Self-Upgrade-Pfad (handlers/system.go → /system/upgrade). Whitelist
|
||||
# nur die exakte Unit-Form, damit edgeguard NICHT beliebige systemd-
|
||||
# Units anlegen darf.
|
||||
@@ -297,6 +300,78 @@ LOGROTATE
|
||||
echo "postinst: ulogd2.service not installed — install ulogd2 to enable firewall log" >&2
|
||||
fi
|
||||
|
||||
# ── Static-routes apply-script + systemd unit ────────────────
|
||||
# Verwaltet aus /etc/edgeguard/routes.conf. `proto edgeguard`
|
||||
# markiert die Routen damit das flush keine fremden Routen
|
||||
# tötet (kernel/dhcp/static manuell gesetzt).
|
||||
cat > /usr/sbin/edgeguard-apply-routes <<'APPLYROUTES'
|
||||
#!/bin/bash
|
||||
# Managed by edgeguard — DO NOT EDIT.
|
||||
# Reads /etc/edgeguard/routes.conf (pipe-format) and applies via ip(8).
|
||||
set -e
|
||||
CONF=/etc/edgeguard/routes.conf
|
||||
|
||||
# Existierende edgeguard-Routen weg, bevor wir neue setzen. Andere
|
||||
# Quellen (kernel/dhcp/manuell ohne proto) bleiben intakt.
|
||||
ip route flush proto 250 2>/dev/null || true
|
||||
|
||||
[ -f "$CONF" ] || exit 0
|
||||
|
||||
while IFS='|' read -r dest gw dev metric table; do
|
||||
[ -z "$dest" ] && continue
|
||||
case "$dest" in '#'*) continue;; esac
|
||||
args=("$dest")
|
||||
[ -n "$gw" ] && args+=("via" "$gw")
|
||||
[ -n "$dev" ] && args+=("dev" "$dev")
|
||||
[ -n "$metric" ] && args+=("metric" "$metric")
|
||||
if [ -n "$table" ] && [ "$table" != "main" ]; then
|
||||
args+=("table" "$table")
|
||||
fi
|
||||
args+=("proto" "250")
|
||||
if ! ip route add "${args[@]}"; then
|
||||
echo "edgeguard-routes: failed to add: ip route add ${args[*]}" >&2
|
||||
# weitermachen — eine fehlende Route soll nicht alle anderen
|
||||
# blockieren.
|
||||
fi
|
||||
done < "$CONF"
|
||||
APPLYROUTES
|
||||
chmod 0755 /usr/sbin/edgeguard-apply-routes
|
||||
chown root:root /usr/sbin/edgeguard-apply-routes
|
||||
|
||||
# rt_protos-Eintrag für `proto edgeguard` (Symbolname statt
|
||||
# numerisch). Debian 13 hat /etc/iproute2 nicht als Default,
|
||||
# also conf.d-Pattern: /etc/iproute2/rt_protos.d/edgeguard.conf
|
||||
# überlagert die /usr/share/iproute2/rt_protos.
|
||||
install -d /etc/iproute2/rt_protos.d
|
||||
echo "250 edgeguard" > /etc/iproute2/rt_protos.d/edgeguard.conf
|
||||
chmod 0644 /etc/iproute2/rt_protos.d/edgeguard.conf
|
||||
|
||||
cat > /etc/systemd/system/edgeguard-routes.service <<'ROUTESUNIT'
|
||||
[Unit]
|
||||
Description=EdgeGuard static-routes apply
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/sbin/edgeguard-apply-routes
|
||||
RemainAfterExit=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
ROUTESUNIT
|
||||
systemctl daemon-reload
|
||||
systemctl enable edgeguard-routes.service >/dev/null 2>&1 || true
|
||||
# Initialer Apply — leere /etc/edgeguard/routes.conf ist ok
|
||||
# (Skript exitet einfach ohne irgendwas zu tun).
|
||||
systemctl start edgeguard-routes.service 2>/dev/null || true
|
||||
|
||||
# Initialer Stub damit `cat` im Skript nicht klagt
|
||||
if [ ! -f /etc/edgeguard/routes.conf ]; then
|
||||
: > /etc/edgeguard/routes.conf
|
||||
chown "$EG_USER":"$EG_USER" /etc/edgeguard/routes.conf
|
||||
fi
|
||||
|
||||
# ── 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
|
||||
|
||||
Reference in New Issue
Block a user