Commit Graph

18 Commits

Author SHA1 Message Date
Debian
f1f7df74f7 feat(crowdsec): UI-Schalter „vertrauenswürdiges Admin-Panel" → gerenderte CrowdSec-Whitelist — v1.3.19
Pro-Domain-Flag crowdsec_trusted (Migration 0048). Ist es gesetzt, rendert der
neue crowdsec-whitelist-Generator den Hostname host-genau in
/etc/crowdsec/parsers/s02-enrich/edgeguard-admin-hosts-whitelist.yaml
(evt.Parsed.http_host) und reloadet crowdsec. Löst das Problem, dass Admin-SPAs
(viele /api/-Requests pro Aktion) http-crawl-non_statics triggern und die
Admin-IP bannen — jetzt im Frontend steuerbar statt manueller Node-Datei.

- Generator internal/crowdsec/whitelist.go (configgen.Generator, no-op ohne
  CrowdSec), registriert in edgeguard-ctl render-config + in den Domains-Reloader
  komponiert (Domain-Edit → Whitelist re-render). Aus der replizierten DB
  gerendert → überlebt Node-Neuaufbau (Ersatz für die manuelle Node-Datei).
- postinst: sudoers reload crowdsec + edgeguard-owned Whitelist-Datei anlegen
  (dir root-owned → Generator überschreibt nur die vorab-chownte Datei) +
  Initial-Render.
- UI: Switch „Vertrauenswürdiges Admin-Panel" im Domain-Detail.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-06 22:23:30 +02:00
Debian
79cd68e460 feat(domains): 301-Weiterleitung Domain→Domain (redirect_to) — v1.2.108
Neue Domain kann per 301 auf eine andere Domain/URL umgeleitet werden, statt
auf ein Backend zu routen (Use-Case: kvs.netcell-it.de → https://zkm.netcell-it.de,
inkl. HTTPS). Variante (a): immer auf Ziel-Root (`redirect location`), pfad-
unabhängig.

- Migration 0043: domains.redirect_to text NOT NULL DEFAULT ''
- Model + domains-Service (SELECT/INSERT/UPDATE/scan)
- HAProxy-Generator: buildRedirectTo() sanitisiert (nur http(s), kein
  Whitespace/Quotes → sonst kein Redirect statt kaputter Config); Template
  emittiert `http-request redirect location <url> code 301 if hdr(host)`.
  Terminiert vor use_backend → Redirect-Domain routet auf kein Backend.
  http→https läuft über den vorhandenen :80-Redirect (zwei Hops, inkl. TLS).
- UI: Feld „Weiterleitung (301) nach" im Domain-Formular (de/en)
- Tests: Render-Zeile + buildRedirectTo-Sanitisierung

Hinweis: Die Redirect-Domain braucht weiterhin ein eigenes TLS-Zert (ACME).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 19:23:37 +02:00
Debian
0cbc781d4f feat(domains): cert error Tooltip mit last_error im Domain-Detail
Abgelaufene und fehlerhafte Zertifikate zeigen jetzt beim Hover den
Fehlertext (last_error) aus der DB. TLSCertLite um last_error erweitert.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 09:25:33 +02:00
Debian
9dee904169 fix(backends): Adress-Validierung für Backend-Server + Quick-Backend (v1.1.140)
Pattern-Validator lehnt offensichtlich ungültige Adressen (Sonderzeichen,
Leerzeichen) schon im Frontend ab, bevor sie HAProxy-Config-Generierung
zerstören können. Gilt für Backend-Server-Modal und Domain-Quick-Backend.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 21:13:24 +02:00
Debian
22528a54a9 fix(domains): backend column showed (undefined:undefined) instead of scheme
BackendLite interfaces in Domains list and Detail declared address/port
fields that don't exist on the Backend model (those live on BackendServer).
Every backend tag rendered as "name (undefined:undefined)". Fixed by
replacing the phantom fields with scheme, so tags show e.g. "my-app (https)".

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 21:12:06 +02:00
Debian
0856c2fc10 feat(rbac): RBAC-Audit abschliessen — Viewer-Sperre für alle verbleibenden Seiten (1.1.93)
Domains, Backends (inkl. ServerPanel), Backups/History und Alerts:
isViewer-Check + disabled Switches, Tooltip-wrapped Add-Buttons,
bedingte Delete/Restore-Render (Viewer → disabled Tooltip statt Popconfirm).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 16:39:24 +02:00
Debian
2d027b3044 fix(rbac): Viewer-Rolle in Detail-Pages + ActionButtons — Edit ebenfalls sperren
- ActionButtons: Edit-Button wird für Viewer wie Delete gesperrt (Tooltip zeigt Reason)
- Domains/Detail: isViewer-Flag an alle Sub-Panels weitergegeben; Save-, TLS-Cert-,
  Routing-Rules- und Headers-Buttons für Viewer disabled
- Backends/Detail: Save-Button + ServerPanel Add-Button für Viewer disabled
- i18n: domains.backendUp/backendDown Keys (waren noch hardkodiert)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 13:10:29 +02:00
Debian
6e52dc0620 fix(ui): fehlende onError-Handler + i18n in Backends/Domains/Dashboard
- Backends: create + del Mutations bekommen onError; 'Backup'-Tag → t()
- Domains: create + del Mutations bekommen onError
- Dashboard: LicenseChip-Texte ('License OK', 'Trial') in t() überführt;
  useTranslation() direkt in der Komponente verwendet
- en/de: dashboard.licenseOk/licenseTrial/licenseTrialDays ergänzt

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 12:42:37 +02:00
Debian
e419eceab8 feat(ui): Quick-Toggles überall vervollständigt
NTP-Pools, User-Accounts, Backend-Server im Detail-Panel und
Routing-Rules im Domain-Detail-Panel — alle aktiv-Felder sind
jetzt inline schaltbar, kein Modale nötig.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 11:09:48 +02:00
Debian
99982ef9d1 feat(ui): Quick-Toggles, Config-Preview, Dashboard-Alerts, Domain-Detail-Health
Quick-Toggle-Switches (kein Modal nötig) für: Backends, Backend-Server,
DNS-Zonen, DNS-Records, Domains (active), Firewall-Rules, NAT-Rules,
Forward-Proxy ACLs, Routing-Rules.

Dashboard: Alert-Banner für komplett ausgefallene Backends (HAProxy-Stats)
und Domains im Maintenance-Mode.

Domain-Detail: HAProxy-Live-Health-Badge (15s Polling), TLS-Cert
ausstellen/erneuern direkt aus dem Detail, Routing-Rules-Panel inline.

Config-Preview (Settings): alle 4 Generatoren (haproxy, nftables, squid,
unbound) rendern via RenderToString ohne Disk-Write — GET /system/config-preview.

ActionButtons: Viewer-Rolle blendet Delete aus (RBAC-Ergänzung).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 08:55:22 +02:00
Debian
8293783fe6 feat(backends+domains): HTTP-Protokoll-Flags — force_http1 + disable_h3
Backend: force_http1 (bool, default false) — zwingt HAProxy auf der
Backend-Verbindung zu HTTP/1.1 statt h2,http/1.1 zu verhandeln.
Nötig für Legacy-Apps die kein h2 sprechen.

Domain: disable_h3 (bool, default false) — unterdrückt Alt-Svc-
Response-Header für diese Domain. Browser erhalten keinen h3/QUIC-
Hinweis und bleiben auf h2/http1.1.

Migration 0027, Model+Service+HAProxy-Template+UI+i18n.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 07:18:48 +02:00
Debian
e7fc6b989b fix(domains): unused ResponseHeader interface entfernen
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 09:06:02 +02:00
Debian
711e9446e6 feat(domains): Domain-Detailseite + Response-Headers-Panel
Statt aller 15+ Felder in einem Modal gibt es jetzt eine eigene Seite
unter /domains/:id. Der Create-Flow bleibt im Modal (Name, Backend, Active,
HTTP→HTTPS), ein Hinweistext führt nach dem Speichern auf die Detailseite
weiter.

Die Detailseite enthält links das vollständige Settings-Formular (HSTS,
Rate-Limit, Maintenance, Max-Body, Notes, WWW-Redirect) und rechts das
HeadersPanel zum Verwalten custom HTTP-Response-Header.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 09:04:41 +02:00
Debian
35b7308ce2 feat: umfangreiches UI+API-Polish (v1.1.36–1.1.42)
Backend:
- Audit-Log: Search-Endpoint mit ILIKE-Filter (actor/action/subject/date)
- NTP: /ntp/status via chronyc tracking (Stratum, Offset, Quelle)
- System: /service-restart mit Allowlist (haproxy/squid/unbound/chrony/scheduler)
- Domain-Response-Headers + Rate-Limit (Migration 0024)
- Join-Tokens (Migration 0025), Cluster-mTLS, Aggregator-Fan-Out
- apt-Service für Update-Banner (apt-get update + Versionsprüfung)
- Backup-Retry mit exponential backoff (retry_apt 3×)
- publish.sh fail-fast + cleanup-old.sh (max 10 Versionen)

Frontend:
- Audit-Log-Page (/audit) mit Filter + Pagination
- ErrorBoundary an React-Root + Vite build-target festgenagelt (iOS 15+)
- Storage-Schema-Stamp: auto-wipe bei Versions-Mismatch (blank-page-Fix)
- EmptyState-Komponente überall ausgerollt
- SSL: Aggregate-Karte (total/expiring/expired/errors)
- Backups: Aggregate-Karte (letzter Backup/Größe/Fehlschläge 24h) + Backup-Now
- NTP: Sync-Status-Karte (chronyc tracking live)
- Domains: Backend-UP/DOWN-Chip aus HAProxy-Stats
- Backends: HAProxy-Status-Spalte (UP/DEGRADED/DOWN)
- Settings: Service-Neustart-Karte (haproxy/squid/unbound/chrony/scheduler)
- Settings: Upgrade-Status-Card, Wartungsmodus, Auto-Update, Retention
- Dashboard: Recent-Alerts, Cluster-Health, License-Chip, Onboarding-Hint
- System-Regeln im Firewall als eigener Tab

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 16:18:41 +02:00
Debian
fd294a273e feat(ui): Pages auf neues Design + Dashboard + WG-Live-Status + Routing-Rules-Verstecken
Pages auf PageHeader/StatusDot/ActionButtons-Pattern migriert:
* Dashboard — Komplett-Rewrite. KPI-Tiles (Domains, Backends, Iface,
  FW-Rules, NAT, WG), Detail-Cards (WireGuard live status, Firewall
  zone overview, SSL expiring soon, Cluster nodes, Routing summary,
  System info). Polled queries pro Card.
* Domains, Backends, RoutingRules, Networks, IPAddresses, SSL,
  Cluster, Settings, Firewall (index) — alle inline Action-Buttons
  → ActionButtons; alle Yes/No-Renders → StatusDot; Add-Button in
  DataTable.extraActions; PageHeader oben.

WireGuard
---------
* Neuer /wireguard/status-Endpoint parsed `wg show all dump`,
  liefert {iface, peer_pubkey, endpoint, last_handshake_unix, rx, tx}.
  Sudoers im postinst um `wg show` erweitert.
* Server-Drawer Peer-Liste zeigt jetzt Live-Status (Online/Offline-
  Dot, "vor Xs", Traffic-Counter) per 10s-Polling. Importierte
  "Unify Home" peer kann jetzt im UI verifiziert werden.
* Importer-Bug fixed: nextName ("# Unify Home" comment) wurde beim
  Sektionswechsel zu früh geresettet — jetzt nur nach echtem
  flushPeer.

Routing-Rules
-------------
* Aus Sidebar entfernt. URL bleibt funktional, aber für 90% der
  Setups reicht domains.primary_backend_id (das HAProxy ohnehin
  als default_backend rendert). Path-basiertes Routing ist ein
  Advanced-Feature und kommt später als Domain-Modal-Tab zurück.
* nav.routing-Sidebar-Eintrag + BranchesOutlined-Import entfernt.

Misc
----
* "Firewall (v2)" → "Firewall" im Nav (DE).
* Dashboard-i18n Block in DE+EN.
* Version 1.0.11 → 1.0.12.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 21:07:38 +02:00
Debian
51ea1fc802 feat: Zonen als first-class Entity + Domain↔Backend-Verknüpfung sichtbar
* Migration 0012: firewall_zones (id, name UNIQUE, description, builtin),
  Seed wan/lan/dmz/mgmt/cluster als builtin. CHECK-Constraints auf
  network_interfaces.role + firewall_rules.{src,dst}_zone +
  firewall_nat_rules.{in,out}_zone gedroppt — Validation lebt jetzt
  app-side (Handler prüft Existenz in firewall_zones).
* Backend: firewall.ZonesRepo (CRUD + Exists + References-Lookup),
  /api/v1/firewall/zones, builtin geschützt (Name nicht änderbar,
  Delete blockiert), Rename eines Custom-Zone aktuell ohne Cascade
  (Handler-Sorge bei Rules/NAT/Networks).
* Handler-Validation in CreateRule/UpdateRule/CreateNAT/UpdateNAT +
  NetworksHandler: Zone-Existence-Check pro Mutation, 400 bei Tippfehler.
* Frontend: Firewall-Tab "Zonen" (CRUD mit builtin-Schutz). Networks-
  Form lädt Rollen aus /firewall/zones (statt hardcoded Liste); Rules-
  und NAT-Forms ziehen die Zone-Auswahl ebenfalls aus der API.
* Domain-Form bekommt Primary-Backend-Picker (Field war im Modell,
  fehlte im UI). Backends-Tabelle zeigt umgekehrt welche Domains
  darauf zeigen — bidirektionale Sicht ohne Schemaänderung.
* HAProxy-Renderer: safeID-FuncMap escaped Server-Namen mit Whitespace
  ("Control Master 1" → "Control_Master_1"). Vorher ist haproxy beim
  Reload an Spaces im Backend-Namen kaputt gegangen.
* Version 1.0.3 → 1.0.6.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 18:05:27 +02:00
Debian
0de0a1580a feat(ui): generischer DataTable-Wrapper + Version 1.0.0
DataTable (components/DataTable.tsx) gibt jeder CRUD-Tabelle drei
Baseline-Features auf einmal:
* Search-Input (Volltext über alle string-Felder, case-insensitive)
* Pagination 25/Seite mit showSizeChanger
* Auto-sorter pro Spalte mit dataIndex (string→localeCompare,
  number→subtract, boolean→bool→Number) — Spalten mit eigenem
  sorter behalten den.

Sweep aller 13 CRUD-Pages auf <DataTable>: Domains, Backends,
Routing-Rules, Networks, IP-Addresses, SSL, Cluster, sechs Firewall-
Tabs. Kleine Sub-Tabellen (System-Discovered IP-Card) bleiben
auf <Table> — read-only ohne CRUD braucht keine Pagination.

i18n: common.search, common.totalRows.

Version-Bump auf 1.0.0 (User-Direktive: ohne -dev): VERSION-Datei,
Go-Literale in cmd/edgeguard-{api,ctl,scheduler}/main.go,
package.json, Sidebar-Konstante. Live deployed auf 89.163.205.6 als
edgeguard 1.0.0 (api + ui + meta).

Memory: project_versioning.md hält die Patch-Bump-Konvention fest
(Gitea Package Registry 409't bei Doppel-Upload — bei jedem Release
zuerst die VERSION inkrementieren).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 13:48:27 +02:00
Debian
b507d2a7d5 feat(ui): Frontend MVP — React 19 + AntD 6 + Vite + StaticFS-Wiring
Scaffold und Core-Infrastruktur 1:1 nach enconf-Pattern (netcell-
webpanel/management-ui), reduziert auf EdgeGuard-Scope (kein reseller/
customer-Roles, keine codemirror/extensions). Stack: React 19 + AntD 6
+ TS strict + Vite + TanStack-Query + zustand + react-i18next.

Layout: AppLayout (Sider+Header+Content), Sidebar (Dashboard/Domains),
Header (User-Dropdown + Logout). i18n mit de/en common.json.

Pages: Login (POST /auth/login), Setup-Wizard (POST /setup/complete),
Dashboard (Health-Polling + Statistics), Domains (volles CRUD via
TanStack-Query gegen /domains-API). UpdateBanner-Komponente
(/system/package-versions, alle 5 min poll, /system/upgrade trigger)
ist von Tag 1 wie vom User gefordert eingebaut.

API-Wiring: cmd/edgeguard-api/main.go mountUI() — gin StaticFS für
/usr/share/edgeguard/ui/ (overridebar via EDGEGUARD_UI_DIR), echte
Files werden direkt geserved, alle nicht-API-Pfade fallen via
NoRoute auf index.html für React-Router-SPA. Wenn dist/ fehlt:
HTML-Placeholder mit Build-Hinweis.

Verifiziert: bun install + npx tsc -b strict (0 errors) + bun run
build (12 chunks). End-to-end gegen /tmp/eg-api: / serviert echte
React-index.html, /domains SPA-Fallback, /api/v1/* JSON, /assets/*
direkt, /api/v1/nonexistent korrekt 404.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 11:16:04 +02:00