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>
23 KiB
EdgeGuard — Architektur
Status: v0.1 (Entwurf) · Stand: 2026-05-08 · Ziel-Plattformen: Debian 13 (Trixie) + Ubuntu 24.04 LTS (Noble Numbat), Architekturen amd64 + arm64.
EdgeGuard ist die native Neufassung des bisherigen Docker-basierten Reverse-Proxy/Loadbalancer/Forward-Proxy/VPN-Stacks. Vorbild für Architektur, Build-System und Cluster-Modell ist mail-gateway (nmg); UI-Pattern und Bootstrap-Onliner stammen aus netcell-webpanel (enconf).
0. Leitplanken (nicht verhandelbar)
- Kein Docker. Alle Dienste nativ unter
systemd, installiert viaapt. Distro-Pakete für Drittsoftware (HAProxy, nginx, Squid, WireGuard, Unbound, PostgreSQL, KeyDB, certbot), eigene.deb-Pakete für EdgeGuard-Code (api, ui, ctl). - Plattform-Matrix: Debian 13 (Trixie) und Ubuntu 24.04 LTS (Noble Numbat), je amd64 + arm64. Alle vier Targets gleichberechtigt.
- Auslieferung: signierte
.deb-Pakete + Meta-Paket via APT. Bootstrap ist der enconf-analoge curl-Onlinercurl -fsSL https://get.edgeguard.netcell-it.de | sudo bash. - HA nativ als Cluster: N symmetrische Peers, KeyDB Active-Active für Shared State + PostgreSQL Streaming Replication (single writer, transparenter API-Write-Proxy) + Floating-IP des Hosters für HTTP/HTTPS-Ingress (nicht VRRP, nicht DNS-RR).
- Kein WAF, kein IDS, kein DHCP, kein RADIUS, keine Mail-Funktion in v1. Mail-Gateway ist eigenes Produkt (
nmg); WAF/CrowdSec/Suricata kommen ggf. in v2. - Migrations:
goose(SQL-Dateien), nicht GORM AutoMigrate.
Nicht-Ziele (ausdrücklich): kein WAF, kein Network-IDS (Suricata), kein IPS (CrowdSec), kein DHCP-Server (Kea), kein RADIUS, keine Mail-Verarbeitung, keine Multi-Tenant-GuardZones in v1, keine ISO-Builds (kein EdgeGuardOS-Klon — nur APT).
1. Scope — fünf Daten-Services + Control-Plane
| Service | Rolle | Distro-Paket | Config-Quelle |
|---|---|---|---|
| HAProxy | Public-Ingress (80/443), interner LB (8081), TLS-PassThrough | haproxy (Debian/Ubuntu) |
aus PG generiert, systemctl reload haproxy |
| nginx | Reverse-Proxy, vHost-Routing, ACME-Webroot | nginx (Debian/Ubuntu) |
aus PG generiert, systemctl reload nginx |
| Squid | Forward-Proxy mit ACL/Auth | squid |
aus PG generiert, systemctl reload squid |
| WireGuard | Site-to-Site- + Road-Warrior-VPN | wireguard-tools (Kernel-Modul ab Kernel 5.6) |
aus PG generiert, wg syncconf |
| Unbound | Caching-Forwarder mit DNSSEC + Cluster-internes Split-Horizon (siehe §7.5) | unbound (Debian/Ubuntu) |
aus PG generiert, unbound-control reload |
| nftables | Firewall (Input + Forward + NAT) | nftables |
aus PG generiert, nft -f /etc/nftables.conf |
Control-Plane:
| Komponente | Rolle |
|---|---|
edgeguard-api |
Go/Gin REST-API, bindet 127.0.0.1:9443, Reads aus lokaler PG, Writes an Cluster-Primary |
edgeguard-scheduler |
Cron-artige Jobs (ACME-Renewal-Hook, Backup, Health-Aggregation, License-Heartbeat) |
edgeguard-ctl |
CLI für Setup/Wartung (initdb, migrate, cluster-join, promote, dump-config) |
management-ui |
React 19 + AntD 6 + Vite, statisch unter /usr/share/edgeguard/ui/, nginx liefert aus |
| PostgreSQL 16 | Single Source of Truth — Domains, Backends, Routing-Rules, ACLs, Peers, etc. |
| KeyDB (Redis-kompatibel) | Active-Active-Replication, Cluster-State, Locks, Rate-Counter, Pub/Sub für Config-Reload |
2. Package-Layout (Repo)
/var/www/edgeguard-native/
├── cmd/ # Go-Binary-Entry-Points
│ ├── edgeguard-api/ # Management-API (HTTP, 127.0.0.1:9443)
│ ├── edgeguard-scheduler/ # Cron-artige Jobs
│ └── edgeguard-ctl/ # CLI für Setup/Wartung
├── internal/
│ ├── database/ # pgxpool + goose-Runner, migrations/ via go:embed
│ │ └── migrations/ # 0001_*.sql … (goose-Format, embedded)
│ ├── models/ # GORM-Models (domain, backend, routing_rule, acl, peer, …)
│ ├── handlers/ # HTTP-Handler (REST)
│ ├── services/ # Business-Logik (config-render, health-check, cluster-sync)
│ ├── haproxy/ # HAProxy-Config-Generator
│ ├── nginx/ # nginx-Config-Generator (vHosts, Upstreams, ACME)
│ ├── squid/ # Squid-Config-Generator (squid.conf + squid.d/*)
│ ├── wireguard/ # WireGuard-Config-Generator (wg-quick + wg syncconf)
│ ├── unbound/ # Unbound-Config-Generator (Forwarder + Cluster-DNS)
│ ├── firewall/ # nftables-Ruleset-Generator
│ ├── cluster/ # Join/Promote/Peer-Discovery, KeyDB-Replication-Setup, pg_basebackup
│ ├── proxy/ # API-Write-Proxy-Middleware (Replica → Primary), mTLS-Calls
│ ├── aggregator/ # Cluster-View-APIs (alle Backends, alle Peers, alle Health-States)
│ └── license/ # License-Validation, License-Leader-Election (KeyDB-Lock)
├── management-ui/ # React 19 + AntD 6 + Vite (Struktur 1:1 wie netcell-webpanel/management-ui/)
├── packaging/
│ └── debian/
│ ├── edgeguard-api/ # control, postinst, postrm, conffiles, systemd-Units
│ ├── edgeguard-ui/
│ └── edgeguard-meta/ # nur Depends, keine Dateien
├── deploy/
│ ├── systemd/ # *.service, *.target, *.timer
│ ├── haproxy/ # haproxy.cfg.tpl
│ ├── nginx/ # nginx.conf.tpl, sni-map.tpl
│ ├── squid/ # squid.conf.tpl
│ ├── unbound/ # unbound.conf.tpl
│ └── nftables/ # ruleset.nft.tpl
├── scripts/
│ ├── apt-repo/ # build-package.sh, publish.sh, setup-repo.sh
│ ├── install.sh # Bootstrap-Onliner
│ └── release.sh # CI Release-Helper
├── docs/
├── Makefile
├── go.mod # module git.netcell-it.de/projekte/edgeguard-native
└── go.sum
Go-Module-Name: git.netcell-it.de/projekte/edgeguard-native
Build-System: Makefile (POSIX-kompatibel). Targets: build, test, lint, deb, clean, install-local, release.
3. Debian-Pakete
Drei Pakete + Meta — analog nmg, kein WAF-Paket weil kein WAF in v1.
| Paket | Arch | Inhalt | Depends |
|---|---|---|---|
edgeguard-api |
amd64, arm64 | /usr/bin/edgeguard-{api,scheduler,ctl}, Unit-Files, Migrations, Default-Configs |
postgresql-16, keydb-server, nginx, haproxy, squid, wireguard-tools, unbound, nftables, certbot |
edgeguard-ui |
all | /usr/share/edgeguard/ui/ (statische Build-Artefakte), nginx-Site |
edgeguard-api (= ${binary:Version}), nginx |
edgeguard-meta |
all | keine Dateien, nur Depends |
edgeguard-api, edgeguard-ui |
Pro Release: 1 arch-spezifisch × 2 Dists × 2 Arches = 4 .deb + 2 arch-agnostische × 2 Dists = 4 .deb → 8 Artefakte je Release.
KeyDB-Herkunft: KeyDB ist weder in trixie noch noble in den offiziellen Repos. Wir bauen es aus Source (amd64 + arm64), veröffentlichen es parallel im eigenen APT-Repo. edgeguard-api Depends: keydb-server löst aus unserem Repo aus.
Build-Werkzeug: direkter dpkg-deb-Build analog WebPanel/EdgeGuardOS-Pattern. Nicht dh_make/debhelper, nicht fpm. Konsistenz mit existierendem Workflow.
postinst (edgeguard-api):
- User
edgeguardanlegen (adduser --system --group --home /var/lib/edgeguard). /etc/edgeguard/,/var/lib/edgeguard/,/var/log/edgeguard/mit0750,chown edgeguard:edgeguard.- Default-Configs nur anlegen wenn nicht vorhanden (
conffilesverhindert Überschreiben). - PostgreSQL:
edgeguard-ctl initdb(idempotent — prüft DB/User). - DB-Migration:
edgeguard-ctl migrate up. systemctl daemon-reload && systemctl enable --now edgeguard-api.service edgeguard-scheduler.service.
postrm (purge): DB + User nur bei purge, niemals bei remove.
4. Verzeichnis-Layout auf Zielsystem
/etc/edgeguard/
├── edgeguard.yaml # Hauptconfig (conffile)
├── api.env # API-Secrets (mode 0600, edgeguard:edgeguard)
├── haproxy/ # haproxy.cfg-Fragmente (von edgeguard-api generiert)
├── nginx/ # vHosts + sni-map (generiert)
├── squid/ # squid.conf-Fragmente
├── wireguard/ # wg0.conf etc. (generiert)
├── unbound/ # unbound.conf + cluster-zone.conf (generiert)
├── nftables.d/ # Ruleset-Fragmente
└── tls/ # ACME-verwaltete Zertifikate (0750, edgeguard:edgeguard)
/var/lib/edgeguard/
├── state/ # Migrations-Marker, Cluster-Cursor
├── trial.json # Lizenz-Trial-File
├── .jwt_fingerprint # JWT-Secret-Fingerprint (analog enconf — Schutz vor Rotation)
└── backups/ # lokale PG-Dumps (vor Migration)
/var/log/edgeguard/
├── api.log
├── scheduler.log
└── audit.log
/usr/bin/
├── edgeguard-api
├── edgeguard-scheduler
└── edgeguard-ctl
/usr/share/edgeguard/
├── ui/ # statische React-Build-Artefakte
└── templates/ # Config-Templates für haproxy/nginx/squid/wireguard/unbound/nftables
Entspricht FHS — keine Überraschungen für Admins, Lintian-clean.
5. systemd-Units
| Unit | Typ | Depends-on | User | Restart |
|---|---|---|---|---|
edgeguard-api.service |
simple |
postgresql.service, keydb-server.service |
edgeguard |
on-failure, RestartSec=5 |
edgeguard-scheduler.service |
simple |
edgeguard-api.service |
edgeguard |
on-failure |
edgeguard-cert-deploy.path |
path |
— | — | — |
edgeguard-firewall.service |
oneshot, RemainAfterExit=true |
— | root | — |
edgeguard.target |
target |
api+scheduler | — | — |
Hardening-Defaults pro Unit (außer edgeguard-firewall, das braucht CAP_NET_ADMIN):
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
PrivateTmp=true
PrivateDevices=true
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
SystemCallFilter=@system-service
ReadWritePaths=/var/lib/edgeguard /var/log/edgeguard /etc/edgeguard
Drittsoftware (HAProxy, nginx, Squid, WireGuard via wg-quick@.service, Unbound, nftables) läuft als Distro-Units. EdgeGuard generiert deren Config + signalisiert Reload, übernimmt aber die Service-Verwaltung nicht.
API bindet auf 127.0.0.1:9443 (nicht öffentlich). nginx terminiert TLS auf :443 und proxied an die API.
6. Datenbank-Setup
- PostgreSQL 16, Distro-Paket
postgresql-16. - Verbindung: Unix-Socket (
/var/run/postgresql) für lokale Reads + Writes der API. TCP/5432 mit TLS-Client-Cert nur zwischen Cluster-Peers für Streaming Replication. - Topologie: ein logischer Primary zu jedem Zeitpunkt, N Read-Replicas. Lokale API liest immer aus lokaler PG; Writes routet die API-Write-Proxy-Middleware transparent an den aktuellen Primary (KeyDB-Key
cluster:pg-primary-url). - Migrations:
goose(SQL-Dateien ininternal/database/migrations/, via//go:embedins Binary gepackt). Nicht GORM AutoMigrate.
GORM bleibt als ORM für Query-Komfort; nur das Schema-Management wechselt zu goose.
7. KeyDB Active-Active
KeyDB ersetzt Redis. Active-Active Replication (Multi-Master, operation-basiert, split-brain-tolerant).
Verwendung:
cluster:pg-primary-url— wer ist aktueller PG-Primary?cluster:license-leader— Lock für License-Heartbeat (SET … NX EX 60)cluster:license-status— Cache des Lizenz-Validate-Ergebnisses (TTL 24 h)cluster:nodes:<node-id>— Heartbeat-Marker (TTL 2 min)ratelimit:<scope>:<key>— Rate-Counter (HINCRBY-Ops mergen korrekt)acme:lock:<domain>— verhindert Parallel-Issue auf zwei Nodes- Pub/Sub:
edgeguard:config-changed— alle Nodes regenerieren Config
KeyDB hört nur auf 127.0.0.1:6379 für lokale Clients und <node-ip>:16379 (TLS) für Peer-Replication.
7.5 Unbound — DNS Forwarder + Cluster-DNS
Unbound erfüllt zwei Rollen, beide aus PG generiert:
Rolle 1 — Caching-Forwarder mit DNSSEC
- Forwardet rekursive Queries an Upstream-Resolver (default
1.1.1.1,9.9.9.9; per UI/PG konfigurierbar). - DNSSEC-Validation aktiv (
auto-trust-anchor-file). - Lokaler Cache (TTL nach Upstream-Antwort).
- Listen:
127.0.0.1:53für die EdgeGuard-Box selbst und<node-internal-ip>:53für VPN- und LAN-Clients (über nftables-ACL gefiltert). - Genutzt von
edgeguard-api,edgeguard-scheduler(License-Heartbeat, ACME), Squid (für Forward-Proxy-Resolutions), HAProxy/nginx (Backend-Health-Checks).
Rolle 2 — Cluster-internes Split-Horizon
- Local-Zone
eg.cluster.enthält A/AAAA-Records aller Cluster-Peers (Node-Hostnamen aus PGha_nodes). - Beispiel:
node1.eg.cluster → 10.42.0.11,node2.eg.cluster → 10.42.0.12. - Wird bei jedem Node-Join/-Leave aus PG regeneriert + via
edgeguard:config-changedPub/Sub auf allen Peers neu geladen (unbound-control reload). - Cluster-interner Traffic (PG-Replication, KeyDB-Replication, mTLS-API-Calls, Cert-Push) löst Peer-Adressen ausschließlich über diese Zone auf — kein DNS-Roundtrip ins öffentliche Internet, keine
/etc/hosts-Synchronisation. <node-name>.eg.clusterist nicht extern erreichbar (nur über Unbound der Cluster-Peers).
Config-Schichten
/etc/edgeguard/unbound/unbound.conf ist Distro-Konfig-Datei. Generator schreibt drei Includes:
# /etc/edgeguard/unbound/forwarders.conf — Upstream-Resolver
# /etc/edgeguard/unbound/cluster-zone.conf — Local-Zone eg.cluster
# /etc/edgeguard/unbound/access.conf — access-control: pro CIDR
Reload via unbound-control reload (kein Restart, keine Cache-Invalidierung außer für die geänderte Zone — unbound-control auth_zone_reload eg.cluster).
8. Cluster-Topologie & HA pro Service
N symmetrische Peers (1 … N Nodes, jeder vollwertig). Keine VRRP, keine Master/Backup-Rollen für Daten-Services. Public-IP: Floating-IP des Hosters (siehe §9).
| Service | HA-Strategie |
|---|---|
| HAProxy | stateless, pro Node identisch. Floating-IP zeigt zum aktuellen aktiven Node; bei Node-Ausfall API-Call zum Hoster (oder manueller Switch) reicht. |
| nginx | stateless, pro Node identisch. ACME-Issue nur auf License-Leader (KeyDB-Lock); Zerts werden via PG/mTLS an alle verteilt. |
| Squid | stateless (Cache lokal, kein Sync nötig). Pro Node identische ACL-Config. |
| WireGuard | siehe §8.1 |
| Unbound | stateless (Cache lokal). Pro Node identische Forwarder-Config + identische Cluster-internen Local-Zones (siehe §7.5). |
| nftables | pro Node identisch, Ruleset aus PG generiert. crowdsec_blocklist/threat_intel_blocklist-Sets entfallen in v1 (kein CrowdSec). |
| edgeguard-api | pro Node, Reads lokal, Writes via Proxy zu Primary. |
| edgeguard-ui | statisch, pro Node identisch. |
| PostgreSQL | Streaming Replication, manueller Promote (siehe nmg §6.2). |
| KeyDB | Active-Active. |
8.1 WireGuard im Cluster
Drei Optionen, für v1 wählen wir Option A:
- A — Geteilte Server-Identität (gewählt): alle Peers haben denselben Server-Privatkey + dasselbe Listen-Port. Floating-IP routet UDP zum aktiven Node. Bei Failover: Floating-IP wandert, Clients schicken Pakete zum neuen Node, neuer Handshake (~1–2s Latenz beim ersten Paket). Replay-Protection-Counter werden nicht repliziert — beim Failover macht der Client neuen Handshake, alte Counter sind irrelevant.
- B — Pro Node eigene Identität, Client kennt alle: Client-Configs haben mehrere
[Peer]-Blöcke. Aufwendiger zu provisionieren, kein Failover-Vorteil. - C — Aktiv/Standby per License-Leader-Pattern: nur ein Node hat WireGuard aktiv, andere idle. Verschwendet Kapazität.
Begründung A: Privatkey ist in PG (verschlüsselt mit edgeguard.key), wird beim Cluster-Join an neue Peers verteilt. WireGuard handelt selbständig neue Sessions aus, kein State-Sync nötig. Operation-Tools (Peer hinzufügen/entfernen) wirken auf alle Nodes via edgeguard:config-changed Pub/Sub + lokales wg syncconf.
8.2 Manual Promote (PG-Primary-Failover)
1:1 nmg-Pattern (siehe mail-gateway/docs/architecture.md §6.2). Bei Ausfall des Primary antworten Config-Writes mit 503 + actionable Error. Admin promotet via UI/CLI. Datenebene (HAProxy/nginx/Squid/WireGuard/Unbound) läuft unbeeinträchtigt weiter, weil jeder Node eine lokale PG-Replica hat.
8.3 License-Leader-Election
Ein einziger Node kontaktiert license.netcell-it.com (KeyDB-Lock, 60-s-TTL). Ergebnis cluster-weit in cluster:license-status (TTL 24 h). active_servers-Verbrauchswert = Count der Peers mit Heartbeat < 2 min.
9. Public-Ingress — Floating-IP statt VRRP
Problem: HTTP-Clients machen kein automatisches Failover bei DNS-RR (anders als MTAs). Ein toter A-Record = 50% Fehler bis DNS-TTL.
Entscheidung: Floating-IP des Hosters. Der Hoster bietet eine API zum Umroute der IP zwischen Servern (z. B. via REST oder DNS-Update bei dynamischer Anycast-Lösung). Failover dauert Sekunden, kein VRRP-Drama, kein "VIP verschwindet"-Problem aus dem alten Setup.
Optionen pro Hoster:
- Provider-Floating-IP (gewünscht): API-Call schaltet IP um. EdgeGuard exponiert
POST /api/v1/cluster/promote-this-node, das die Hoster-API aufruft. - DNS-RR mit kurzer TTL (60s) als Notlösung wenn keine Floating-IP verfügbar.
- Anycast/BGP als Premium-Variante (für Enterprise).
v1-Default: Single-Node mit fest zugewiesener Floating-IP. Cluster-Erweiterung kommt mit Phase 2.
⚑ OFFEN: Welcher Hoster ist Standard? API-Spec dokumentieren sobald geklärt.
10. Erst-Einrichtung — curl-Onliner
curl -fsSL https://get.edgeguard.netcell-it.de | sudo bash
Schritte (idempotent, analog netcell-webpanel/install.sh):
- OS-Detection (
/etc/os-release): nur Trixie oder Noble, sonst Abbruch. - Arch-Detection: nur amd64 oder arm64.
- Base-Deps:
curl gnupg ca-certificates apt-transport-https. - APT-Keyrings:
https://apt.netcell-it.de/edgeguard/repository.key→/etc/apt/keyrings/netcell-edgeguard.gpg
- APT-Sources:
/etc/apt/sources.list.d/netcell-edgeguard.list. - Install:
apt-get install -y edgeguard(Meta-Paket). - Auto-Security-Updates:
unattended-upgrades+apt-listchanges(nach enconf-Muster). - Setup-Modus:
edgeguard-apiläuft im Setup-Modus bis Admin-User existiert. UI leitet alle Anfragen auf/setupum. Wizard: Admin-Account, FQDN, ACME-Email, Lizenz oder Trial.
Cluster-Join (zusätzlicher Peer):
curl -fsSL https://get.edgeguard.netcell-it.de | sudo bash -s -- \
--join https://<existing-node-fqdn> \
--token <cluster-join-token>
edgeguard-ctl cluster-join führt aus: PG-Basebackup vom Primary, KeyDB-Replication-Setup, Node-Registrierung in ha_nodes, TLS-Cert-Pull via mTLS, Config-Regeneration, Service-Start.
11. Update-Pfad (apt-Repo)
- Primärquelle: Gitea Package Registry (
https://git.netcell-it.de/api/packages/projekte/debian). - Kunden-Mirror:
https://apt.netcell-it.de/edgeguard/(rsync von Gitea). - Suiten:
stable·testing·security— pro Codename (trixie,noble). - Signatur: GPG-Key
netcell-edgeguard-signing, ausgeliefert in/etc/apt/keyrings/. - Update-Check-API:
GET /api/v1/system/package-versions→ proedgeguard-*-Paket{name, installed, available, reboot_required}. - Upgrade-Trigger:
POST /api/v1/system/upgradestartetsystemd-run --unit=edgeguard-upgrade.service --collect …(HTTP-Response geht VOR dem Upgrade raus, weil API beim Self-Update stirbt — Pattern ausnetcell-webpanel/management-agent/internal/handlers/update.go:105).
Build-/Release-Scripts identisch zu mail-gateway/scripts/apt-repo/.
12. Lizenz & ACME
12.1 Lizenz
1:1 nach netcell-webpanel/docs/licensing-integration.md. Verbrauchswert: active_domains (Anzahl konfigurierter EdgeGuard-Domains).
- Lizenzserver:
https://license.netcell-it.com(öffentlich, kein API-Key). - Verify-Endpoint:
GET /api/v1/licenses/{key}/verify?system_id={fp}&system_name={host}&active_domains={n}. - Fingerprint:
SHA256(/etc/machine-id + erste-aktive-MAC + hostname). - Caching: Live → KeyDB
cluster:license-status(TTL 24h) →/var/lib/edgeguard/trial.json(30 Tage) →expired. - Leader-Election wie nmg §6.3.
12.2 ACME
- certbot (Distro-Paket) mit
--webroot-Plugin für nginx-vHosts. - Lock vor Issue:
acme:lock:<domain>in KeyDB verhindert Parallel-Issue auf zwei Nodes. - Deploy-Hook: schreibt Sentinel-Datei →
edgeguard-cert-deploy.path-Unit triggert nginx-/HAProxy-Reload. - Cert-Verteilung im Cluster: Issuing-Node pushed via mTLS-API an alle Peers, Zerts landen in
/etc/edgeguard/tls/.
13. UI — 100% enconf-WebPanel-Pattern
Komponentenbibliothek, Theme, Layouts, Navigations-Struktur, Form-Patterns, i18n-Setup vollständig 1:1 aus netcell-webpanel/management-ui/. Keine eigenen Design-Entscheidungen.
Pflichtlektüre:
netcell-webpanel/docs/design-system.mdnetcell-webpanel/docs/design.mdnetcell-webpanel/docs/frontend-reference.md
Stack: React 19 + TypeScript strict, Vite, Ant Design 6.x, TanStack Query 5, axios, i18next (de/en), @uiw/react-codemirror, recharts, ESLint flat config.
Seiten v1: Dashboard · Domains · Backends · Routing-Rules · SSL · ForwardProxy (Squid) · VPN (WireGuard) · Firewall · Cluster · Logs · Settings · Setup-Wizard.
14. Plattform-Matrix
| Distribution | Codename | Arch | Status v1 |
|---|---|---|---|
| Debian 13 | trixie | amd64 | Tier 1 |
| Debian 13 | trixie | arm64 | Tier 1 |
| Ubuntu 24.04 LTS | noble | amd64 | Tier 1 |
| Ubuntu 24.04 LTS | noble | arm64 | Tier 1 |
Andere Distributionen (Debian 12, Ubuntu 22.04, RHEL/Rocky) sind nicht unterstützt. Installer bricht hart ab.
15. Migration vom Docker-Stand
EdgeGuard-Native ist eigenes Repo (git.netcell-it.de/projekte/edgeguard-native), parallel zum bestehenden proxy-lb-waf. Migration:
- Frische Installation auf Test-VM via
install.sh. - Config-Export aus altem Stack (
edgeguard-ctl export --from-docker) — liest aus alter PG, schreibt in neues Format. - Validierung Side-by-Side (alter Stack auf einem Server, neuer Stack auf anderem, Traffic vergleichen).
- Cutover via Floating-IP-Switch.
Der alte proxy-lb-waf-Code bleibt für Bestandskunden im Wartungsmodus, keine neuen Features.
Offene Punkte
- Hoster + Floating-IP-API (§9): Spec dokumentieren.
- WireGuard-State-Replication in der Praxis testen (Handshake-Latenz nach Floating-IP-Switch messen).
get.edgeguard.netcell-it.deanlegen oder Übergangs-URL aufapt.netcell-it.de/edgeguard/install.shnutzen.