Files
edgeguard-native/CLAUDE.md
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

209 lines
7.7 KiB
Markdown

# ⚠️ GOLDENE REGEL — NIEMALS RATEN. IMMER LESEN.
**Nicht verhandelbar. Keine Ausnahmen.**
Vor jeder Entscheidung über Feldwerte, API-Shapes, Dateinamen, Funktions-Signaturen, Konfigurationsparameter oder Architektur-Details: **erst Original lesen, dann arbeiten**.
- **Referenz-Backend** (Go-Patterns, Migrations, Cluster, Packaging) → `ac_search_code(project_id=6)` oder direkt `/var/www/mail-gateway`
- **Referenz-UI/Bootstrap** (React/AntD, i18n, Design-System, Install-Onliner) → `ac_search_code(project_id=5)` oder direkt `/var/www/netcell-webpanel`
- **Alter Docker-Stack** (nur für Feature-Scope-Referenz!) → `ac_search_code(project_id=3)` oder `/var/www/proxy-lb-waf`
- **Im Zweifel → Rückfrage statt Annahme.**
---
# EdgeGuard Native (`eg`)
> Native Neufassung des Docker-basierten EdgeGuard-Stacks. Kein Docker, kein WAF in v1. Zielplattform: **Debian 13 (Trixie), amd64 + arm64**. Auslieferung als signiertes `.deb`.
---
## Repository & Server
- **Gitea:** https://git.netcell-it.de/projekte/edgeguard-native
- **SSH-Clone:** `ssh://git@git.netcell-it.de:1922/projekte/edgeguard-native.git`
- **Lokal (Dev):** `/var/www/edgeguard-native` · `ssh linux@89.163.205.87`
- **Architect Center:** Projekt ID **8**
- **Git-Server:** git.netcell-it.de · SSH Port 1922 · `git push origin main`
---
## Arbeitsweise — Senior Engineer + MCP (PFLICHT)
### Session-Bindung
Sessions: `EdgeGuardNative-1` · project_id **8** · `$ARCHITECT_SESSION` im Env · MCP-Server `architect` verfügbar
### Code-Suche — AUTOMATISCH nutzen
Bei JEDER Code-bezogenen Frage **zuerst** `ac_search_code` aufrufen:
```
ac_search_code(query="<stichworte>", project_id=8, session_name=$(printenv ARCHITECT_SESSION), limit=6)
```
**Referenzen:**
- Backend-Pattern → `project_id=6` (mail-gateway)
- UI/Bootstrap-Pattern → `project_id=5` (netcell-webpanel)
- Feature-Scope (was alt-EG konnte) → `project_id=3` (proxy-lb-waf)
**Verboten:** direkt `grep` oder `read` ohne vorheriges `ac_search_code` bei Code-Fragen.
---
## Stack
| Schicht | Technologie |
|---------|-------------|
| **API** | Go 1.25, Gin, GORM (Queries), goose (Migrations) |
| **UI** | React 19, TypeScript strict, Vite, Ant Design 6, TanStack Query 5 |
| **DB** | PostgreSQL 16 (Distro-Paket), goose-Migrations in `migrations/` |
| **State/HA** | KeyDB Active-Active (Redis-kompatibel) |
| **Proxy/LB** | HAProxy (Distro), nginx (Distro) |
| **VPN** | WireGuard (Kernel-Modul ab 5.6, `wireguard-tools`) |
| **DNS** | Unbound (Distro) — Forwarder+Cache mit DNSSEC, Cluster-internes Split-Horizon |
| **FW** | nftables (Distro) |
| **Forward-Proxy** | Squid (Distro) |
| **TLS** | certbot + webroot-Plugin |
| **Packaging** | dpkg-deb (direkt, wie mail-gateway + netcell-webpanel) |
| **Plattform** | Debian 13 Trixie · amd64 + arm64 |
---
## Nicht-Ziele (v1)
- **Kein Docker** — alle Dienste nativ unter systemd
- **Kein WAF** (kein Coraza, kein ModSecurity)
- **Kein IDS/IPS** (kein Suricata, kein CrowdSec)
- **Kein DHCP-Server** (kein Kea)
- **Kein RADIUS** (kein FreeRADIUS)
- **Keine Mail-Verarbeitung** (eigenes Produkt: mail-gateway)
- **Nur Debian 13** — kein Ubuntu, kein Debian 12, kein RHEL
---
## Binaries & Ports
| Binary | Beschreibung | Bindet | User |
|--------|-------------|--------|------|
| `edgeguard-api` | REST Management-API | `127.0.0.1:9443` | `edgeguard` |
| `edgeguard-scheduler` | Cron-Jobs (ACME-Renew, Backup, Health) | — | `edgeguard` |
| `edgeguard-ctl` | CLI: `initdb migrate cluster-join promote dump-config` | — | root/edgeguard |
nginx terminiert TLS auf `:443` und proxied an `127.0.0.1:9443`.
---
## Build
```bash
make build # Host-Architektur (amd64)
make test # go test ./...
make lint # golangci-lint
make deb # amd64 + arm64 .deb
make publish # deb + Upload Gitea Package Registry
make install-local # direkt auf Dev-Server installieren (kein .deb)
# UI
cd management-ui && bun install && bun run build
```
---
## Dev-Server Quickstart
```bash
# Abhängigkeiten installieren
sudo apt-get install -y postgresql-16 haproxy nginx wireguard-tools squid unbound nftables certbot
# API starten (ohne systemd, für Entwicklung)
go run ./cmd/edgeguard-api/
# UI Dev-Server
cd management-ui && bun run dev
```
---
## Projektstruktur
```
/var/www/edgeguard-native/
├── cmd/
│ ├── edgeguard-api/ # Management-API (Gin, 127.0.0.1:9443)
│ ├── edgeguard-scheduler/ # Cron-Jobs
│ └── edgeguard-ctl/ # CLI
├── internal/
│ ├── database/ # pgxpool + goose-Runner; migrations/ via go:embed
│ │ └── migrations/ # SQL (goose-Format) — embedded ins Binary
│ ├── models/ # GORM-Models
│ ├── handlers/ # HTTP-Handler (REST)
│ ├── services/ # Business-Logik
│ ├── haproxy/ # Config-Generator
│ ├── nginx/ # Config-Generator
│ ├── squid/ # Config-Generator
│ ├── wireguard/ # Config-Generator
│ ├── unbound/ # Config-Generator (Forwarder + Cluster-DNS)
│ ├── firewall/ # nftables-Generator
│ ├── cluster/ # Join/Promote/Peer-Discovery
│ ├── proxy/ # Write-Proxy → Cluster-Primary
│ ├── aggregator/ # Cluster-View APIs
│ └── license/ # Lizenz-Validierung
├── management-ui/ # React 19 + AntD 6 (1:1 enconf-Pattern)
├── packaging/debian/ # control, postinst, postrm, systemd-Units
├── deploy/
│ ├── systemd/ # *.service, *.target, *.timer
│ ├── haproxy/ # haproxy.cfg.tpl
│ ├── nginx/ # vhost.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
│ └── install.sh # Bootstrap curl-Onliner
├── docs/
│ └── architecture.md # Vollständige Architektur-Spec
├── go.mod
├── Makefile
├── CLAUDE.md # Diese Datei
└── agent.md # Agent-Factory Pipeline
```
---
## Key Conventions
### Go-Code
- **Migrations:** goose SQL-Dateien in `internal/database/migrations/`, via `//go:embed` ins Binary — NICHT GORM AutoMigrate
- **ORM:** GORM für Queries, nicht für Schema-Verwaltung
- **Config-Generierung:** Template-Datei in `deploy/*/`, Generator in `internal/*/`
- **Config-Reload:** `systemctl reload <service>` nach Config-Schreiben
- **Cluster-Writes:** immer über `internal/proxy` → Primary-URL aus KeyDB `cluster:pg-primary-url`
### Packaging
- `dpkg-deb` direkt (wie mail-gateway) — kein dh_make/debhelper/fpm
- postinst: User anlegen → Dirs → initdb (idempotent) → migrate → systemctl
- postrm purge: nur bei `purge` DB + User entfernen
### UI
- 100% enconf-Pattern (netcell-webpanel/management-ui/) — keine eigenen Design-Entscheidungen
- `import type` für alle Type-Imports (verbatimModuleSyntax!)
- AntD 6, kein Tailwind, kein Material UI
### Auth
- JWT-basiert (analog enconf), Secret in `/var/lib/edgeguard/.jwt_fingerprint`
- Admin-Check: immer aus DB-User-Row, nie aus JWT-Payload
---
## Vollständige Architektur
`docs/architecture.md`
---
## Vor jeder Änderung
1. Referenz-Pattern in mail-gateway oder netcell-webpanel lesen
2. `ac_search_code` vor neuem Code — Pattern existiert meist schon
3. `make test` nach Backend-Änderungen
4. `cd management-ui && npx tsc --noEmit` nach Frontend-Änderungen