7 Commits

Author SHA1 Message Date
Debian
7611572062 refactor(cluster): promote auf Logical-Replication umgestellt + internal/proxy-Stub entfernt — v1.2.99
Code-Altlasten aus dem Architektur-Audit bereinigt:
- internal/proxy: leerer .gitkeep-Stub (geplanter Write-Proxy nie implementiert) entfernt — keine Go-Referenzen.
- promote.go: war reines Physical-Replication-Failover (standby.signal + pg_ctlcluster promote + pg_is_in_recovery) und damit auf dem Logical-Setup TOT (ein Subscriber hat kein standby.signal / ist nie in recovery → Abbruch bei Schritt 1). Neu Logical-aware: Idempotenz-Check (schon Publisher ohne Subscription → fertig) → Subscription lösen (DISABLE+slot_name=NONE+DROP, hängt nicht am toten Publisher) → setupReplicationPrimary (Publisher werden) → ha_nodes.pg_role=primary → keepalived MASTER. Toter KeyDB-Update (cluster:pg-primary-url, wurde nie gelesen) entfernt.
- setupReplicationPrimary + dropSubscriptionIfExists aus cluster-init-replication/cluster-setup-standby extrahiert (DRY, bewährte SQL wiederverwendet). WICHTIG: setupReplicationPrimary stellt jetzt sicher dass wal_level=logical AKTIV ist — PG-RESTART falls nötig (reload reicht für wal_level/max_wal_senders nicht; Secondary hat wal_level=replica). Idempotent: Restart nur wenn wal_level != logical.
- Doku (CLAUDE.md + architecture.md) auf den bereinigten Stand gezogen.
Hinweis: echtes Cross-Node-Failover ist nur im Drill testbar; Build/vet/Tests grün, Bausteine sind die bereits produktiv genutzten SQL-Primitive.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 18:26:52 +02:00
Debian
3b5bf578a0 docs(architecture): Cluster/HA-Abschnitte an Ist-Stand angeglichen (code-verifiziert)
architecture.md war Entwurfsstand; Cluster/HA wich stark vom Code ab. Per 5 parallelen Code-Audits verifiziert + korrigiert:
- Replikation: Streaming/physisch → LOGICAL (edgeguard_shared/edgeguard_sub, wal_level=logical, copy_data=true); localOnlyTables dokumentiert; pg_basebackup nur Legacy.
- VIP/Ingress (§9): 'Floating-IP statt VRRP' war invertiert → real keepalived/VRRP (prio aus pg_role, VIPs aus ip_addresses); kein Hoster-API/promote-this-node.
- KeyDB (§7): Active-Active-State-Layer NICHT umgesetzt (kein Redis-Client in go.mod); Cluster-State/Heartbeat/Locks in PostgreSQL; KeyDB optional (Recommends). license-leader/acme:lock/cluster:nodes = nur Kommentare.
- Write-Path: internal/proxy ist leerer Stub; kein Write-Proxy → Writes am Primary.
- Plattform: nur Debian 13 trixie (Pipeline), Ubuntu/noble nicht implementiert.
- §1/§5/§8 + Strukturbaum/Depends/Units an reale Renderer (keepalived/chrony/kea/freeradius/crowdsec/waf) angeglichen. Offene Punkte: Code-Altlasten (proxy-Stub, standby.signal in promote.go).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 17:46:56 +02:00
Debian
bf211ca273 docs: Feature-Stand nachgezogen — WAF/IDS-IPS/DHCP/RADIUS/OIDC/2FA umgesetzt
CLAUDE.md + architecture.md spiegelten noch den ursprünglichen v1-Scope (WAF/IDS/IPS/DHCP/RADIUS als Nicht-Ziele) wider. Real umgesetzt: WAF (Coraza+SPOE), IDS/IPS (CrowdSec, managed-wenn-installiert), DHCP (Kea), RADIUS (FreeRADIUS), OIDC-SSO, 2FA, IPv6-FW. Nicht-Ziele bereinigt (verbleibend: Suricata-Network-IDS, Docker, Mail, Multi-Tenant, ISO, Debian-only). Stack-Tabelle + Paket-Tabelle/Depends an control angeglichen; edgeguard-waf als Binary im edgeguard-api-Paket dokumentiert. KeyDB als optional (Recommends) korrigiert; Cluster-Primary-Ermittlung via pg_publication/setup.json statt KeyDB; Doku-Drift internal/proxy (nicht vorhanden) markiert.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 17:34:10 +02:00
Debian
914538eed1 feat(configgen): Phase 2 Config-Generator + nginx → HAProxy-only Pivot
Architektur-Pivot: nginx fällt komplett weg. HAProxy 2.8+ übernimmt
TLS-Termination, L7-Routing per Host-Header und LB. ACME-Webroot
und Management-UI werden von edgeguard-api ausgeliefert (Phase 3
implementiert die zugehörigen Handler); HAProxy proxied
/.well-known/acme-challenge/* und Management-FQDN-Traffic an
127.0.0.1:9443. Eine Distro-Abhängigkeit weniger, ein Renderer
weniger, sauberere Trennung.

Renderer (alle mit Embed-Templates + Tests):
* internal/configgen/  — atomic write + systemctl reload helpers
* internal/haproxy/    — :80 + :443, ACME-ACL, Host-Header-Routing,
                         Stats-Frontend, api_backend Fallback
* internal/firewall/   — default-deny input, stateful baseline,
                         SSH-Rate-Limit, :80/:443 accept,
                         Cluster-Peer-Set für mTLS :8443,
                         Custom-Rules aus PG
* internal/{squid,wireguard,unbound}/ — Stubs (ErrNotImplemented)

Orchestrator + CLI:
* internal/services/configorch/  — fester Reihenfolge-Run, Stubs
                                   sind soft-skip statt fatal
* cmd/edgeguard-ctl render-config [--no-reload] [--only=svc1,svc2]

Packaging:
* postinst: /etc/edgeguard/nginx raus, /var/lib/edgeguard/acme rein,
  self-signed _default.pem via openssl req (damit HAProxy startet
  bevor certbot etwas issuet hat)
* control: Depends nginx raus, openssl rein
* edgeguard-ui: dependency auf nginx weg, "Served by edgeguard-api
  gin StaticFS"

Live-Smoke: render-config gegen lokale PG schreibt /etc/edgeguard/
haproxy/haproxy.cfg + nftables.d/ruleset.nft korrekt; CRUD-Test aus
Phase 2 läuft weiter unverändert.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 10:59:52 +02:00
Debian
b307a7b1f7 feat(db): Phase 1 — DB-Schema, goose-Migrations, GORM-Models
Initialer Schema-Set (8 Migrationen, 13 Tabellen) für EdgeGuard v1:
users + audit_log + system_settings, ha_nodes, backends/domains/
routing_rules/tls_certs, forward_proxy_acls, wireguard_peers,
firewall_rules, dns_zones/dns_records, licenses. Migrations liegen
in internal/database/migrations/ (analog mail-gateway) und werden
per //go:embed ins Binary gepackt — keine separate SQL-Dateien im
.deb. ValidateMigrations + Test schützen vor Duplicate-Versionen
(mail-gateway 2026-05-08-Vorfall). GORM-Models für alle Tabellen,
sensible Felder (password_hash, private_key_enc) sind json:"-".

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 23:44:44 +02:00
Debian
9f75eec756 refactor: Angie → nginx + Unbound (DNS Forwarder + Cluster-Split-Horizon)
Reverse-Proxy von Angie (eigenes APT-Repo) auf nginx (Distro) umgestellt
— vereinfacht Bootstrap (kein angie.software-Repo mehr), reduziert
Offene-Punkte (arm64-Verfügbarkeit entfällt). Neuer Service Unbound
übernimmt zwei Rollen: Caching-Forwarder mit DNSSEC und Cluster-internes
Split-Horizon (Local-Zone eg.cluster, Peer-Adressen aus PG ha_nodes,
Reload via unbound-control). Architektur-Spec §7.5 dokumentiert beide
Rollen + Config-Schichtung.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 23:06:56 +02:00
Felix Netzel
0ceab4c814 chore: initial skeleton
- docs/architecture.md: native rewrite plan (5 services + control plane,
  Active-Active cluster like nmg, Floating-IP for HTTP ingress)
- cmd/edgeguard-{api,scheduler,ctl}: minimal Gin + CLI stubs
- packaging/debian/edgeguard-{api,ui,meta}: control + maintainer scripts
- deploy/systemd/edgeguard-api.service + edgeguard-scheduler.service
  with hardening defaults
- Makefile: build / cross-compile (amd64+arm64) / deb / publish targets
- scripts/install.sh + scripts/apt-repo/build-package.sh stubs
2026-05-08 18:45:41 +02:00