Files
edgeguard-native/management-ui/src/i18n/locales/de/common.json
Debian 66187e5b77 feat(firewall-log): Phase 3 — UI /firewall-live mit WS-Stream + Filter + CSV
Neue Page management-ui/src/pages/FirewallLive — Live-Tail der NFLOG-
Events aus /api/v1/firewall/log/live (WebSocket). Features:

- Status-Indicator (Live/getrennt), Auto-Reconnect alle 2s nach Drop
- Filter-Bar (action/proto/src/dst/rule_id) — bei Änderung wird der
  WS neu verbunden, Server schickt frischen Snapshot
- Pause-Toggle: während Pause werden Events gebuffert (max 1000),
  beim Resume in die Tabelle gemerged
- CSV-Export der aktuellen Tabelle (timestamp/rule/action/proto/src/
  dst/iface/size)
- Color-coded Action-Tags (ACCEPT=grün, DROP=rot, REJECT=orange)
- Ring-Buffer 1000 im UI damit die DOM-Last bei Hochlast bleibt
- Sidebar-Eintrag "Firewall-Log" unter Sicherheit (Eye-Icon)
- DE/EN i18n

haproxy: backend api_backend bekommt `timeout tunnel 1h` damit der
WebSocket-Stream nicht nach `timeout server 60s` ohne Events stirbt.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 21:14:43 +02:00

657 lines
29 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"app": {
"title": "EdgeGuard",
"subtitle": "Native Reverse-Proxy / VPN / Firewall"
},
"nav": {
"dashboard": "Dashboard",
"domains": "Domains",
"backends": "Backends",
"routing": "Routing",
"networks": "Netzwerk-Interfaces",
"ipAddresses": "IP-Adressen",
"ssl": "SSL-Zertifikate",
"vpn": "VPN",
"wireguard": "WireGuard",
"forwardProxy": "Forward-Proxy",
"dns": "DNS",
"ntp": "Zeit (NTP)",
"firewall": "Firewall",
"firewallLive": "Firewall-Log",
"cluster": "Cluster",
"license": "Lizenz",
"settings": "Einstellungen",
"section": {
"overview": "Übersicht",
"routing": "Routing",
"network": "Netzwerk",
"security": "Sicherheit",
"system": "System"
}
},
"fw": {
"title": "Firewall",
"intro": "Fortigate-Style: Regeln aus Zonen × Adress-Objekten/Gruppen × Services/Service-Gruppen × Action. NAT separat. Top-down, first-match.",
"tabs": {
"rules": "Regeln",
"nat": "NAT",
"zones": "Zonen",
"addrObj": "Adress-Objekte",
"addrGrp": "Adress-Gruppen",
"services": "Services",
"svcGrp": "Service-Gruppen"
},
"zone": {
"name": "Name",
"description": "Beschreibung",
"builtin": "vordefiniert",
"builtinHint": "Vordefinierte Zonen können nicht gelöscht werden — Renderer und Anti-Lockout-Regeln verlassen sich darauf.",
"builtinNameLocked": "Name vordefiniert — kann nicht geändert werden, weil bestehende Regeln und Interfaces ihn referenzieren.",
"namePattern": "Nur Kleinbuchstaben, Ziffern, _ und -; muss mit Buchstaben beginnen, max. 32 Zeichen.",
"add": "Zone hinzufügen",
"edit": "Zone bearbeiten",
"deleteConfirm": "Zone {{name}} wirklich löschen?"
},
"ao": {
"name": "Name", "kind": "Typ", "value": "Wert", "description": "Beschreibung",
"add": "Adress-Objekt hinzufügen", "edit": "Adress-Objekt bearbeiten",
"deleteConfirm": "Adress-Objekt {{name}} wirklich löschen?"
},
"ag": {
"name": "Name", "members": "Mitglieder", "description": "Beschreibung",
"add": "Adress-Gruppe hinzufügen", "edit": "Adress-Gruppe bearbeiten",
"selectMembers": "Adress-Objekte wählen",
"deleteConfirm": "Adress-Gruppe {{name}} wirklich löschen?"
},
"svc": {
"name": "Name", "proto": "Protokoll", "ports": "Ports",
"portStart": "Port (Start)", "portEnd": "Port (Ende)",
"description": "Beschreibung", "builtinHint": "Vordefiniert — nicht editierbar",
"add": "Service hinzufügen", "edit": "Service bearbeiten",
"deleteConfirm": "Service {{name}} wirklich löschen?"
},
"sg": {
"name": "Name", "members": "Mitglieder", "description": "Beschreibung",
"add": "Service-Gruppe hinzufügen", "edit": "Service-Gruppe bearbeiten",
"selectMembers": "Services wählen",
"deleteConfirm": "Service-Gruppe {{name}} wirklich löschen?"
},
"rule": {
"name": "Name", "priority": "Priority", "enabled": "Aktiv", "log": "Logging",
"action": "Aktion", "src": "Quelle", "dst": "Ziel", "service": "Service",
"srcZone": "Quell-Zone", "dstZone": "Ziel-Zone",
"srcKind": "Quell-Typ", "dstKind": "Ziel-Typ",
"object": "Adress-Objekt", "group": "Adress-Gruppe",
"serviceKind": "Service-Typ", "serviceGroup": "Service-Gruppe",
"comment": "Kommentar",
"add": "Regel hinzufügen", "edit": "Regel bearbeiten",
"deleteConfirm": "Diese Regel wirklich löschen?"
},
"nat": {
"name": "Name", "priority": "Priority", "kind": "Typ", "enabled": "Aktiv",
"match": "Match", "target": "Ziel",
"inZone": "Eingangs-Zone", "outZone": "Ausgangs-Zone", "proto": "Protokoll",
"matchSrcCidr": "Source-CIDR (Match)", "matchDstCidr": "Dest-CIDR (Match)",
"matchDstCidrHint": "leer = jede dest-IP (z.B. öffentliche IP der Box)",
"dportStart": "Port (Start)", "dportEnd": "Port (Ende)",
"targetAddr": "Ziel-Adresse", "targetPortStart": "Ziel-Port (Start)", "targetPortEnd": "Ziel-Port (Ende)",
"comment": "Kommentar",
"add": "NAT-Regel hinzufügen", "edit": "NAT-Regel bearbeiten",
"deleteConfirm": "Diese NAT-Regel wirklich löschen?"
},
"sys": {
"title": "System-Regeln (immer aktiv)",
"chain": "Chain", "match": "Match", "action": "Aktion", "note": "Hinweis",
"policy": "Default-Policy",
"policyValue": "Eingang DROP — alles muss explizit erlaubt werden.",
"order": "Auswertung",
"orderValue": "System-Regeln zuerst, danach Operator-Regeln top-down (priority asc, first-match).",
"lockout": "Anti-Lockout",
"lockoutValue": "SSH (22) und Management-UI (443) sind immer erreichbar — können auch vom Operator nicht versehentlich gesperrt werden."
}
},
"networks": {
"title": "Netzwerk-Interfaces",
"intro": "Verwalte WAN-, LAN-, VLAN- und Bond-Interfaces. Read-only-Discovery der Kernel-Interfaces oben; deklarierte Konfiguration unten — runtime-Apply via systemd-networkd folgt in einem späteren Release.",
"systemDiscovered": "System-Interfaces (read-only)",
"addInterface": "Interface hinzufügen",
"editInterface": "Interface bearbeiten",
"name": "Name",
"type": "Typ",
"parent": "Parent-Interface",
"selectParent": "Parent wählen",
"vlan": "VLAN",
"vlanId": "VLAN-ID",
"composition": "Zusammensetzung",
"members": "Member-Interfaces",
"selectMembers": "Physische Interfaces wählen",
"membersRequired": "Mindestens ein Member-Interface erforderlich",
"membersHintBridge": "Eine Bridge bündelt mehrere physische Ports auf L2 — typisch zwei Ports für einen Software-Switch.",
"membersHintBond": "Ein Bond aggregiert mehrere physische Ports zu einem logischen Link (LACP / active-backup).",
"role": "Zone",
"roleHint": "Zonen kommen aus Firewall → Zonen. Eigene Zonen (z.B. iot, guest) lassen sich dort anlegen.",
"mtu": "MTU",
"active": "Aktiv",
"description": "Beschreibung",
"actions": "Aktionen",
"deleteConfirm": "Interface {{name}} wirklich löschen?"
},
"ips": {
"title": "IP-Adressen",
"intro": "Adressen, die das Betriebssystem zeigt (Read-only oben) plus die Adressen, die EdgeGuard zusätzlich verwaltet — inklusive VIPs für Cluster-Failover.",
"systemDiscovered": "Adressen am Kernel (read-only)",
"managedTitle": "Verwaltete Adressen",
"family": "Familie",
"addAddress": "Adresse hinzufügen",
"editAddress": "Adresse bearbeiten",
"interface": "Interface",
"selectInterface": "Interface wählen",
"address": "Adresse",
"prefix": "Prefix",
"vip": "VIP",
"vipFlag": "Als VIP markieren",
"vipPriority": "VIP-Priorität (Cluster-Failover)",
"active": "Aktiv",
"description": "Beschreibung",
"actions": "Aktionen",
"deleteConfirm": "Adresse {{addr}} wirklich löschen?"
},
"auth": {
"loginTitle": "Anmelden",
"email": "E-Mail",
"password": "Passwort",
"login": "Anmelden",
"logout": "Abmelden",
"loginFailed": "Anmeldung fehlgeschlagen",
"loggedInAs": "Angemeldet als"
},
"setup": {
"title": "Erst-Einrichtung",
"intro": "Lege den Admin-Account an, gib die öffentliche FQDN an und optional einen Lizenzschlüssel. Ohne Lizenz startet eine 30-Tage-Trial.",
"adminEmail": "Admin-E-Mail",
"adminPassword": "Admin-Passwort",
"passwordRule": "Mindestens 12 Zeichen.",
"fqdn": "Öffentliche FQDN",
"acmeEmail": "ACME-/Let's-Encrypt-E-Mail",
"licenseKey": "Lizenzschlüssel (optional)",
"submit": "Setup abschließen",
"successTitle": "Setup abgeschlossen",
"successHint": "Du wirst zur Anmeldung weitergeleitet."
},
"dashboard": {
"title": "Dashboard",
"welcomeHint": "Übersicht aller laufenden EdgeGuard-Komponenten."
},
"domains": {
"title": "Domains",
"intro": "Verwalte FQDNs, die HAProxy terminiert. Optionales Primary-Backend als Catch-all; Pfad-Routing via Routing-Regeln.",
"addDomain": "Domain hinzufügen",
"editDomain": "Domain bearbeiten",
"name": "Name",
"active": "Aktiv",
"primaryBackend": "Primary-Backend",
"primaryBackendHint": "Catch-all-Backend für Requests, die kein Routing-Regel-Match haben. Optional — leer lassen, wenn alles über Routing-Regeln läuft.",
"selectBackend": "Backend wählen",
"noBackend": "kein Backend",
"httpToHttps": "HTTP→HTTPS",
"hsts": "HSTS",
"notes": "Notizen",
"actions": "Aktionen",
"edit": "Bearbeiten",
"delete": "Löschen",
"deleteConfirm": "Domain {{name}} wirklich löschen?"
},
"backends": {
"title": "Backends",
"intro": "Upstream-Pools (Backend = N Server). HAProxy verteilt laut LB-Algorithmus; Health-Check-Pfad aktiviert HTTP-Probes alle 5s pro Server.",
"addBackend": "Backend-Pool hinzufügen",
"editBackend": "Backend-Pool bearbeiten",
"name": "Name",
"scheme": "Schema",
"target": "Ziel",
"healthCheck": "Health-Check-Pfad",
"active": "Aktiv",
"usedBy": "Genutzt von",
"noDomain": "keine Domain",
"attachedDomains": "Domains",
"attachedDomainsHint": "Domains, die dieses Backend als Primary verwenden. Auswahl umkonfiguriert die Domains direkt — gleiche Quelle wie der Backend-Picker im Domain-Modal.",
"selectDomains": "Domains wählen",
"lbAlgo": "Load-Balancing",
"lbAlgoHint": "roundrobin = gleichmäßig, leastconn = an den Server mit wenigsten Verbindungen, source = sticky per Client-IP (für stateful Apps ohne shared session).",
"websocket": "WebSocket-Support",
"websocketHint": "An: erlaubt langlebige WebSocket-/Long-Poll-Verbindungen (z. B. Proxmox-Console, SSH-WS, AsyncAPI) — Tunnel-Idle 1h statt 60s. Aus: strikte HTTP-Timeouts.",
"servers": "Server",
"noServers": "kein Server",
"nServers": "{{n}} Server",
"serversIn": "Server in „{{name}}\"",
"serverHintCreate": "Speichern legt nur den Pool an. Server kommen im nächsten Schritt — Pool öffnen → „Server hinzufügen\".",
"actions": "Aktionen",
"deleteConfirm": "Backend-Pool {{name}} wirklich löschen? Alle Server im Pool werden mitentfernt.",
"server": {
"intro": "Upstream-Server im Pool. Reihenfolge in HAProxy egal — der LB-Algorithmus entscheidet.",
"add": "Server hinzufügen",
"edit": "Server bearbeiten",
"name": "Server-Name",
"address": "Adresse",
"port": "Port",
"target": "Endpoint",
"weight": "Gewicht",
"weightHint": "0256. Höher = mehr Traffic. 100 = Standard.",
"backup": "Backup",
"backupHint": "Backup-Server werden nur angesprochen, wenn alle primären Server (non-backup) down sind.",
"empty": "Noch keine Server im Pool. „Server hinzufügen\" startet damit.",
"deleteConfirm": "Server {{name}} wirklich löschen?"
}
},
"routing": {
"title": "Routing-Regeln",
"intro": "Pfad-Präfix → Backend-Mapping pro Domain. Niedrige Priority gewinnt; Catch-all per Domain.primary_backend.",
"addRule": "Regel hinzufügen",
"editRule": "Regel bearbeiten",
"domain": "Domain",
"pathPrefix": "Pfad-Präfix",
"backend": "Backend",
"priority": "Priorität",
"active": "Aktiv",
"actions": "Aktionen",
"selectDomain": "Domain wählen",
"selectBackend": "Backend wählen",
"deleteConfirm": "Diese Routing-Regel wirklich löschen?"
},
"cluster": {
"title": "Cluster",
"intro": "{{count}} Node(s) registriert. Multi-Node-Cluster (KeyDB Active-Active + PG Streaming Replication) folgt in einem späteren Release.",
"id": "Node-ID",
"fqdn": "FQDN",
"role": "Rolle",
"joinedAt": "Beigetreten",
"self": "diese Node"
},
"ssl": {
"title": "SSL-Zertifikate",
"intro": "TLS-Zertifikate verwalten — entweder per Let's Encrypt automatisch ausstellen oder eigene PEMs hochladen. HAProxy lädt nach jeder Änderung automatisch neu.",
"tabLE": "Let's Encrypt",
"tabUpload": "Eigenes Zertifikat",
"leIntro": "Domain wählen, Issue klicken — EdgeGuard löst HTTP-01 über die ACME-Webroot, schreibt das PEM nach /etc/edgeguard/tls/ und reloaded HAProxy.",
"uploadIntro": "Eigenes Zertifikat hochladen. Format: PEM-encoded. Cert + optional Chain + Private Key. EdgeGuard prüft die Cert/Key-Übereinstimmung vor dem Schreiben.",
"uploadHint": "Tipp: bei Let's-Encrypt-Renewals nicht hier hochladen — den LE-Tab nutzen.",
"domain": "Domain",
"selectDomain": "Domain wählen oder eintippen",
"domainExtra": "Inkludiert Management-FQDN (aus Setup), Cluster-Knoten und Operator-Domains. Du kannst auch eine andere Domain tippen, sofern DNS schon auf die Box zeigt.",
"fqdnHintMgmt": "Management-FQDN",
"fqdnHintCluster": "Cluster · {{role}}",
"issuer": "Issuer",
"status": "Status",
"expiresIn": "Gültig noch",
"expiredAgo": "abgelaufen vor {{days}} Tagen",
"actions": "Aktionen",
"issueButton": "Zertifikat anfordern",
"uploadButton": "Hochladen",
"issueSuccess": "Zertifikat ausgestellt + installiert.",
"uploadSuccess": "Zertifikat hochgeladen + installiert.",
"deleteConfirm": "Zertifikat für {{domain}} löschen? HAProxy fällt für diese Domain auf das Default-Cert zurück.",
"installedTitle": "Installierte Zertifikate",
"certPem": "Zertifikat (PEM)",
"chainPem": "Chain (PEM, optional)",
"keyPem": "Private Key (PEM)"
},
"settings": {
"title": "Einstellungen",
"intro": "System-Information und Setup-Status. Bearbeitbare Werte folgen in einem späteren Release.",
"systemInfo": "System",
"version": "Version",
"status": "Status",
"setupInfo": "Setup",
"adminEmail": "Admin-E-Mail",
"fqdn": "FQDN",
"setupCompleted": "Setup abgeschlossen"
},
"update": {
"available": "Update verfügbar: Version {{version}}",
"multiPackageHint": "{{count}} Pakete werden aktualisiert.",
"applyNow": "Jetzt installieren",
"confirmTitle": "Update jetzt installieren?",
"confirmDesc": "Pakete werden auf Version {{version}} aktualisiert. edgeguard-api + scheduler restarten (~2-5s), HAProxy/nft/WG/Squid/Unbound/Chrony laufen durch.",
"checkNow": "Auf Updates prüfen",
"checkDone": "Update verfügbar",
"noUpdate": "Keine neuen Updates",
"checkFailed": "Update-Check fehlgeschlagen",
"running": "Update läuft …",
"waitHint": "Bitte warten — die Seite lädt automatisch neu sobald die neue Version live ist.",
"success": "Update auf {{version}} abgeschlossen.",
"failed": "Update fehlgeschlagen",
"stepDownload": "Pakete laden",
"stepInstall": "Installation",
"stepRestart": "Service-Restart",
"stepVerify": "Verifizierung"
},
"wg": {
"title": "WireGuard",
"intro": "VPN-Tunnel über WireGuard. Server-Modus = wir lauschen für Peers; Client-Modus = wir verbinden zu einem festen Upstream. Privater Schlüssel liegt verschlüsselt in der DB.",
"tabs": { "servers": "Server-Tunnel", "clients": "Client-Tunnel" },
"serverIntro": "Server-Tunnel hosten ein Peer-Roster — z.B. Mitarbeiter-Geräte oder Niederlassungen. Pro Peer bekommt der Operator eine .conf zum Download (oder QR-Code für Mobile).",
"clientIntro": "Client-Tunnel verbinden EdgeGuard zu einem fremden WireGuard-Server (z.B. HQ-Datacenter). Allowed-IPs steuert, welcher Traffic durch den Tunnel geroutet wird.",
"iface": {
"name": "Name",
"namePattern": "wg gefolgt von Kleinbuchstaben/Ziffern/-, max. 15 Zeichen",
"nameExtra": "Empfehlung: wg0, wg1, wg-hq …",
"address": "Adresse (CIDR)",
"addressExtra": "Tunnel-IP der Box, z.B. 10.99.0.1/24 für /24-Pool",
"listenPort": "Listen-Port",
"publicKey": "Public-Key",
"privateKey": "Private-Key (paste)",
"privateKeyExtra": "Nur ausfüllen wenn nicht generieren — base64 32 Byte. Wird verschlüsselt gespeichert.",
"peerEndpoint": "Peer-Endpoint",
"peerPublicKey": "Peer Public-Key",
"peerPSK": "Pre-Shared-Key (PSK)",
"peerPSKExtra": "Optional, zusätzliche Schicht",
"allowedIPs": "Allowed IPs",
"allowedIPsExtra": "Was durch den Tunnel geroutet wird. Default = full-tunnel.",
"keepalive": "Persistent Keepalive (sec)",
"mtu": "MTU",
"zone": "Firewall-Zone",
"description": "Beschreibung",
"addServer": "Server-Tunnel hinzufügen",
"editServer": "Server-Tunnel bearbeiten",
"addClient": "Client-Tunnel hinzufügen",
"editClient": "Client-Tunnel bearbeiten",
"upstream": "Upstream-Peer",
"deleteConfirm": "Tunnel {{name}} wirklich löschen? wg-quick wird gestoppt.",
"keys": "Schlüssel",
"generateExtra": "Wenn an: Server erzeugt ein neues Curve25519-Keypair beim Speichern.",
"generateOn": "Server generiert",
"generateOff": "Manuell paste",
"editKeyWarning": "Achtung: neue Schlüssel = bestehende Peer-Configs ungültig. Nur ändern wenn explizit gewollt."
},
"peers": {
"button": "Peers",
"drawerTitle": "Peer-Roster"
},
"peer": {
"name": "Name",
"publicKey": "Public-Key",
"publicKeyExtra": "Wird vom Peer-Gerät erzeugt; hier nur paste-bar wenn der Peer schon ein Key-Pair hat.",
"allowedIPs": "Allowed IPs",
"allowedIPsExtra": "Welche Tunnel-IPs darf dieser Peer benutzen. Typisch /32 = eine IP.",
"keepalive": "Keepalive (sec)",
"keepaliveExtra": "0 = aus. Empfohlen 25 hinter NAT.",
"lastHandshake": "Letzter Handshake",
"never": "nie",
"description": "Beschreibung",
"add": "Peer hinzufügen",
"edit": "Peer bearbeiten",
"deleteConfirm": "Peer {{name}} wirklich entfernen?",
"keys": "Schlüssel",
"generateExtra": "Wenn an: Server erzeugt für diesen Peer ein Keypair und kann die Config / QR-Code ausliefern. Wenn aus: nur den Public-Key paste-en — keine Config-Download möglich.",
"pskExtra": "Wenn an: Server generiert einen 32-Byte PSK für diesen Peer.",
"pskOn": "PSK generieren",
"pskOff": "kein PSK",
"downloadConf": "wg-quick.conf herunterladen",
"qrTitle": "WireGuard-QR",
"qrHint": "Mit der WireGuard-App (iOS/Android) scannen: \"Tunnel hinzufügen\" → \"QR-Code scannen\". Endpoint im Download-Conf bitte vor Verwendung anpassen.",
"online": "Online",
"offline": "Offline",
"traffic": "Traffic"
}
},
"dashboard": {
"title": "Dashboard",
"welcomeHint": "EdgeGuard-Übersicht — Health, Counts, Live-Status der wichtigsten Dienste.",
"kpi": {
"domains": "Domains",
"backends": "Backends",
"ifaces": "Interfaces",
"fwRules": "FW-Regeln",
"natRules": "NAT-Regeln",
"wg": "WG-Verbindungen"
},
"wgCard": {
"title": "WireGuard",
"empty": "Noch kein WG-Tunnel angelegt."
},
"firewallCard": {
"title": "Firewall",
"zones": "Zonen",
"activeRules": "{{rules}} aktive Regeln · {{nat}} NAT"
},
"sslCard": {
"title": "SSL-Zertifikate",
"total": "Verwaltete Zertifikate",
"expiringSoon": "{{count}} läuft bald ab (< 30 Tage)",
"allFresh": "Alle Zertifikate haben > 30 Tage Restlaufzeit."
},
"clusterCard": {
"title": "Cluster",
"nodes": "Knoten"
},
"routingCard": {
"title": "Routing",
"domains": "Domains",
"backends": "Backends",
"attached": "{{count}}/{{total}} Domains haben einen Primary-Backend"
},
"systemCard": {
"title": "System",
"version": "Version",
"api": "API",
"ifaces": "Interfaces",
"wg": "WireGuard"
},
"servicesCard": {
"title": "Service-Status (live, 10s)"
},
"activityCard": {
"title": "Letzte Aktivität (Audit-Log)",
"empty": "Noch keine Aktivität — Mutationen werden hier protokolliert."
},
"haproxyCard": {
"title": "HAProxy-Backends (live)",
"empty": "Keine Backend-Stats erreichbar (HAProxy down oder admin.sock-permission)."
},
"resCard": {
"load": "Load",
"memory": "Memory",
"disk": "Disk /",
"free": "frei",
"conntrack": "Conntrack",
"uptime": "Uptime"
}
},
"ntp": {
"title": "Zeitserver (Chrony)",
"intro": "Chrony als Time-Sync-Daemon (NTP). Quellen oben, Listen-/Serve-Konfig im Settings-Tab. Wenn 'serve_clients' aktiv und LAN-IPs gebound sind, wird die Box selbst zum NTP-Server für das LAN.",
"tabs": { "pools": "Quellen", "settings": "Settings" },
"pool": {
"kind": "Typ",
"kindPool": "pool — DNS-Round-Robin (mehrere Server aus A-Records)",
"kindServer": "server — einzelner Host",
"address": "Adresse / Host",
"addressExtra": "FQDN (für pool: 0.de.pool.ntp.org) oder IP.",
"iburst": "iburst",
"prefer": "prefer",
"minpoll": "min-poll",
"maxpoll": "max-poll",
"options": "Optionen",
"description": "Beschreibung",
"add": "Quelle hinzufügen",
"edit": "Quelle bearbeiten",
"deleteConfirm": "NTP-Quelle {{addr}} wirklich löschen?"
},
"settings": {
"intro": "Globale Chrony-Settings. Save reloaded chrony automatisch.",
"serveClients": "Als NTP-Server für Clients arbeiten",
"serveClientsExtra": "Wenn aus: chrony agiert nur als Client (port 0). Wenn an + Listen-IP: bindet UDP/123.",
"listenAddresses": "Listen-Adressen",
"listenAddressesPlaceholder": "IPs wählen (oder eintippen)",
"listenAddressesExtra": "Auf welchen IPs chrony :123/UDP bindet. 127.0.0.1+::1 = nur lokal; LAN-IPs öffnen für LAN-Clients (FW-Rule wird automatisch generiert).",
"allowACL": "Allow-ACL (CIDRs)",
"allowACLExtra": "Wer darf NTP-Time anfragen.",
"makestepSecs": "makestep secs",
"makestepSecsExtra": "Erlaube step (statt slew) wenn offset > N sec.",
"makestepLimit": "makestep limit",
"rtcsync": "RTC mit System-Time syncen",
"rtcsyncExtra": "Hardware-Clock alle 11 min synchron halten — nach Reboot ist die Zeit grob korrekt.",
"leapsectz": "Leap-Sec TZ",
"leapsectzExtra": "Optional, z.B. 'right/UTC' für leap-sec über tzdata."
}
},
"dns": {
"title": "DNS (Unbound)",
"intro": "Unbound-Resolver auf :53. Lokale Zonen (authoritativ aus DNS-Records) und Forward-Zonen (per stub-zone weiter zu fremden Resolvern). Default-Forwarder für alles andere.",
"tabs": { "zones": "Zonen", "settings": "Resolver-Settings" },
"zone": {
"name": "Zone-Name",
"nameExtra": "FQDN ohne führenden/abschließenden Punkt — z.B. internal.netcell-it.de",
"type": "Typ",
"typeLocal": "local — authoritativ (records hier)",
"typeForward": "forward — stub-zone zu fremdem Resolver",
"forwardTo": "Upstream-Resolver",
"forwardToExtra": "Komma-separierte IP-Liste — z.B. '10.0.0.53, 8.8.8.8'",
"description": "Beschreibung",
"records": "Records …",
"add": "Zone hinzufügen",
"edit": "Zone bearbeiten",
"deleteConfirm": "Zone {{name}} mit allen Records wirklich löschen?"
},
"record": {
"name": "Name",
"nameExtra": "Relativ zur Zone (z.B. 'mailcow') oder FQDN mit abschließendem Punkt.",
"type": "Typ",
"value": "Wert",
"valueExtra": "RDATA in Textform: A → IP, CNAME → FQDN, MX → 'priority host', TXT → 'string'.",
"ttl": "TTL (sec)",
"drawerTitle": "DNS-Records",
"add": "Record hinzufügen",
"edit": "Record bearbeiten",
"deleteConfirm": "Record {{name}} wirklich löschen?"
},
"settings": {
"intro": "Globale Resolver-Settings. Änderungen hier reloaden Unbound automatisch.",
"listenAddresses": "Listen-Adressen",
"listenAddressesPlaceholder": "IPs wählen (oder eintippen)",
"listenAddressesRequired": "Mindestens eine Adresse erforderlich.",
"listenAddressesExtra": "Mehrfachauswahl aus den IPs die der Kernel kennt. 127.0.0.1 + ::1 = nur lokal; weitere LAN-Iface-IPs (z.B. 10.10.20.3) öffnen den Resolver für LAN-Clients. Eigene IPs lassen sich auch eintippen (Enter).",
"listenPort": "Port",
"upstreamForwards": "Default-Forwarders",
"upstreamForwardsExtra": "Wo geht alles hin was nicht lokal ist. Default 1.1.1.1 + 9.9.9.9.",
"accessACL": "Access-ACL (CIDRs)",
"accessACLExtra": "Wer darf diesen Resolver benutzen.",
"dnssec": "DNSSEC validieren",
"qnameMin": "QName-Minimisation (privacy)",
"cacheMin": "Cache min-TTL",
"cacheMax": "Cache max-TTL"
}
},
"fwd": {
"title": "Forward-Proxy (Squid)",
"intro": "Squid-basierter Forward-Proxy auf :3128. ACLs werden top-down nach Priority ausgewertet — first-match wins. Wenn keine Regel passt, gewinnt der Default: nur localnet (10/8, 172.16/12, 192.168/16) darf raus.",
"helpTitle": "Tipp zur ACL-Reihenfolge",
"helpBody": "Höhere Priority = wird zuerst geprüft. Beispiel: 'deny .badsite.com' (priority 200) vor 'allow .com' (priority 100). Werte können Listen sein (mehrere Zeilen), Regex je nach acl_type.",
"name": "Name",
"nameExtra": "Squid-konformer Bezeichner — Kleinbuchstaben + _, kein Leerzeichen.",
"aclType": "Typ",
"aclTypeExtra": "Was Squid prüft (Quelle, Domain, Port, …).",
"value": "Wert",
"valueExtra": "Format hängt vom Typ ab — IPs/CIDRs für src/dst, Domain mit führendem . für dstdomain (.example.com matcht auch sub.example.com), Regex für *_regex-Typen.",
"action": "Aktion",
"priority": "Priority",
"priorityExtra": "Höher = wird zuerst geprüft.",
"comment": "Kommentar",
"add": "ACL hinzufügen",
"edit": "ACL bearbeiten",
"deleteConfirm": "ACL {{name}} wirklich löschen?"
},
"common": {
"yes": "Ja",
"no": "Nein",
"save": "Speichern",
"cancel": "Abbrechen",
"loading": "Lädt …",
"error": "Fehler",
"edit": "Bearbeiten",
"delete": "Löschen",
"deleteConfirm": "Wirklich löschen?",
"search": "Suchen …",
"totalRows": "{{count}} Einträge",
"active": "Aktiv",
"inactive": "Inaktiv",
"noData": "Keine Einträge",
"actions": "Aktionen",
"add": "Hinzufügen",
"download": "Download",
"copy": "Kopieren",
"copied": "Kopiert"
},
"license": {
"title": "Lizenz",
"status": "Status",
"product": "Produkt",
"key": "Lizenz-Schlüssel",
"noKey": "Kein Schlüssel hinterlegt",
"validUntil": "Gültig bis",
"expired": "Abgelaufen",
"daysLeft": "noch {{days}} Tage",
"lastVerifiedAt": "Letzte Verifizierung",
"verifiedBy": "Verifiziert von",
"limits": "Limits",
"unlimited": "Unbegrenzt",
"features": "Features",
"reverify": "Erneut prüfen",
"reverified": "Lizenz erfolgreich verifiziert",
"enterKey": "Schlüssel eingeben",
"replaceKey": "Schlüssel ersetzen",
"enterKeyHint": "Lizenz-Schlüssel aus dem Self-Service-Portal von license.netcell-it.com einfügen.",
"activate": "Aktivieren",
"saved": "Lizenz gespeichert und verifiziert",
"savedButVerifyFailed": "Schlüssel gespeichert, aber Server-Verifizierung fehlgeschlagen",
"clearKey": "Schlüssel entfernen",
"cleared": "Lizenz entfernt — System fällt auf Trial zurück",
"confirmClear": "Lizenz-Schlüssel wirklich entfernen?",
"confirmClearHint": "System fällt auf Trial-Modus zurück, sobald der Schlüssel gelöscht wird.",
"lastVerifyFailed": "Letzte Server-Verifizierung fehlgeschlagen",
"trialExpiring": "Trial läuft in {{days}} Tag(en) ab",
"trialExpiringHint": "Lizenz aktivieren, bevor die Trial-Periode endet."
},
"licenseBanner": {
"expired": "Lizenz abgelaufen oder ungültig.",
"trialExpiring": "Trial läuft in {{days}} Tag(en) ab.",
"verifyFailed": "Lizenz-Verifizierung fehlgeschlagen",
"cta": "Jetzt aktivieren →",
"openPage": "Lizenz-Seite öffnen →"
},
"fwlog": {
"title": "Firewall-Log (Live)",
"intro": "Pakete, die in nft-Regeln mit aktivem Log-Flag matchen, fließen via NFLOG → ulogd2 → JSONL hierher. WebSocket-Stream zeigt Live-Events; Ring-Buffer (1000) hält die letzten Treffer auch nach Reconnect.",
"live": "Live",
"disconnected": "getrennt",
"pause": "Pause",
"resume": "Fortsetzen",
"queued": "wartend",
"clear": "Leeren",
"clearTooltip": "Tabelle leeren (Server-Ringbuffer bleibt unverändert)",
"export": "CSV",
"exportTooltip": "Aktuelle Tabelle als CSV exportieren",
"exportEmpty": "Keine Events zum Exportieren",
"connError": "WebSocket-Fehler — versuche erneut",
"empty": "Noch keine Events. Aktiviere bei einer Firewall-Regel den Log-Schalter, dann fließen Treffer hier hinein.",
"connecting": "Verbinde …",
"col": {
"time": "Zeit",
"action": "Aktion",
"rule": "Rule",
"proto": "Proto",
"src": "Quelle",
"dst": "Ziel",
"iface": "Interface",
"size": "Größe"
},
"filter": {
"action": "Action filtern",
"proto": "Proto filtern",
"src": "Quell-IP",
"dst": "Ziel-IP",
"rule": "Rule-ID"
}
}
}