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
This commit is contained in:
384
docs/architecture.md
Normal file
384
docs/architecture.md
Normal file
@@ -0,0 +1,384 @@
|
||||
# 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`](../../mail-gateway/docs/architecture.md) (`nmg`); UI-Pattern und Bootstrap-Onliner stammen aus [`netcell-webpanel`](../../netcell-webpanel/CLAUDE.md) (`enconf`).
|
||||
|
||||
---
|
||||
|
||||
## 0. Leitplanken (nicht verhandelbar)
|
||||
|
||||
- **Kein Docker.** Alle Dienste nativ unter `systemd`, installiert via `apt`. Distro-Pakete für Drittsoftware (HAProxy, Angie, Squid, WireGuard, 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-Onliner `curl -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` |
|
||||
| **Angie** | Reverse-Proxy, vHost-Routing, ACME-Webroot | eigenes APT-Repo (`angie`) | aus PG generiert, `systemctl reload angie` |
|
||||
| **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` |
|
||||
| **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/`, Angie 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/
|
||||
│ ├── 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
|
||||
│ ├── angie/ # Angie-Config-Generator (vHosts, Upstreams, ACME)
|
||||
│ ├── squid/ # Squid-Config-Generator (squid.conf + squid.d/*)
|
||||
│ ├── wireguard/ # WireGuard-Config-Generator (wg-quick + wg syncconf)
|
||||
│ ├── 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
|
||||
│ ├── angie/ # nginx.conf.tpl, sni-map.tpl
|
||||
│ ├── squid/ # squid.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
|
||||
├── migrations/ # SQL-Migrations (goose-Format)
|
||||
├── 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`, `angie`, `haproxy`, `squid`, `wireguard-tools`, `nftables`, `certbot` |
|
||||
| `edgeguard-ui` | all | `/usr/share/edgeguard/ui/` (statische Build-Artefakte), Angie-Site | `edgeguard-api (= ${binary:Version})`, `angie` |
|
||||
| `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.
|
||||
|
||||
**Angie-Herkunft:** Eigenes APT-Repo bei `angie.software` — `edgeguard-api` `Depends: angie`. Im `install.sh` wird das Angie-Repo zusätzlich zu unserem hinzugefügt.
|
||||
|
||||
**Build-Werkzeug:** **direkter `dpkg-deb`-Build** analog WebPanel/EdgeGuardOS-Pattern. **Nicht** `dh_make`/`debhelper`, **nicht** `fpm`. Konsistenz mit existierendem Workflow.
|
||||
|
||||
**postinst (`edgeguard-api`):**
|
||||
1. User `edgeguard` anlegen (`adduser --system --group --home /var/lib/edgeguard`).
|
||||
2. `/etc/edgeguard/`, `/var/lib/edgeguard/`, `/var/log/edgeguard/` mit `0750`, `chown edgeguard:edgeguard`.
|
||||
3. Default-Configs nur anlegen wenn nicht vorhanden (`conffiles` verhindert Überschreiben).
|
||||
4. PostgreSQL: `edgeguard-ctl initdb` (idempotent — prüft DB/User).
|
||||
5. DB-Migration: `edgeguard-ctl migrate up`.
|
||||
6. `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)
|
||||
├── angie/ # vHosts + sni-map (generiert)
|
||||
├── squid/ # squid.conf-Fragmente
|
||||
├── wireguard/ # wg0.conf etc. (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/angie/squid/wireguard/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, Angie, Squid, WireGuard via `wg-quick@.service`, 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). Angie 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 in `migrations/`). **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.
|
||||
|
||||
---
|
||||
|
||||
## 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. |
|
||||
| **Angie** | 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 |
|
||||
| **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/Angie/Squid/WireGuard) 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:
|
||||
1. **Provider-Floating-IP** (gewünscht): API-Call schaltet IP um. EdgeGuard exponiert `POST /api/v1/cluster/promote-this-node`, das die Hoster-API aufruft.
|
||||
2. **DNS-RR mit kurzer TTL (60s)** als Notlösung wenn keine Floating-IP verfügbar.
|
||||
3. **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`):
|
||||
|
||||
1. **OS-Detection** (`/etc/os-release`): nur Trixie *oder* Noble, sonst Abbruch.
|
||||
2. **Arch-Detection**: nur amd64 *oder* arm64.
|
||||
3. **Base-Deps:** `curl gnupg ca-certificates apt-transport-https`.
|
||||
4. **APT-Keyrings:**
|
||||
- `https://apt.netcell-it.de/edgeguard/repository.key` → `/etc/apt/keyrings/netcell-edgeguard.gpg`
|
||||
- Angie-Repo-Key (für `angie`-Paket)
|
||||
5. **APT-Sources:** `/etc/apt/sources.list.d/netcell-edgeguard.list` + Angie-List.
|
||||
6. **Install:** `apt-get install -y edgeguard` (Meta-Paket).
|
||||
7. **Auto-Security-Updates:** `unattended-upgrades` + `apt-listchanges` (nach enconf-Muster).
|
||||
8. **Setup-Modus:** `edgeguard-api` läuft im Setup-Modus bis Admin-User existiert. UI leitet alle Anfragen auf `/setup` um. 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` → pro `edgeguard-*`-Paket `{name, installed, available, reboot_required}`.
|
||||
- **Upgrade-Trigger:** `POST /api/v1/system/upgrade` startet `systemd-run --unit=edgeguard-upgrade.service --collect …` (HTTP-Response geht VOR dem Upgrade raus, weil API beim Self-Update stirbt — Pattern aus `netcell-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 Angie-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 Angie-/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.md`
|
||||
- `netcell-webpanel/docs/design.md`
|
||||
- `netcell-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:
|
||||
|
||||
1. **Frische Installation** auf Test-VM via `install.sh`.
|
||||
2. **Config-Export** aus altem Stack (`edgeguard-ctl export --from-docker`) — liest aus alter PG, schreibt in neues Format.
|
||||
3. **Validierung** Side-by-Side (alter Stack auf einem Server, neuer Stack auf anderem, Traffic vergleichen).
|
||||
4. **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.
|
||||
- **Angie-Repo-Verfügbarkeit** für arm64 prüfen.
|
||||
- **WireGuard-State-Replication** in der Praxis testen (Handshake-Latenz nach Floating-IP-Switch messen).
|
||||
- **`get.edgeguard.netcell-it.de`** anlegen oder Übergangs-URL auf `apt.netcell-it.de/edgeguard/install.sh` nutzen.
|
||||
Reference in New Issue
Block a user