{ "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", "logs": "Logs", "backups": "Backups", "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", "live": "Live-Log", "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": "0–256. 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 →" }, "backups": { "title": "Backups", "intro": "Sicherungen der PostgreSQL-Datenbank + /var/lib/edgeguard (Setup, License, JWT, ACME-Account). Täglicher Auto-Job + manueller Trigger.", "scopeTitle": "Was wird gesichert?", "scopeDesc": "DB-Dump (pg_dump --clean), setup.json, license_key, license.cache, .jwt_fingerprint, acme-account/. Konfig-Dateien (haproxy.cfg, nft, …) sind aus der DB regenerierbar und werden NICHT mitgesichert.", "runNow": "Backup jetzt erstellen", "created": "Backup erstellt: {{file}}", "failed": "Backup fehlgeschlagen", "deleted": "Backup gelöscht", "download": "Download", "restore": "Wiederherstellen", "restoreOk": "Restore starten", "restoreDone": "Restore abgeschlossen — Seite wird neu geladen.", "restoreFailed": "Restore fehlgeschlagen", "restoreRunning": "Restore läuft …", "restoreHint": "edgeguard-api startet automatisch neu; die UI lädt nach Restart neu.", "confirmRestoreTitle": "Backup wiederherstellen?", "confirmRestoreDesc": "DB-Inhalt wird durch {{file}} ersetzt + State-Dateien zurückgespielt. edgeguard-api + scheduler restarten. Aktuelle Änderungen seit dem Backup gehen verloren.", "step": { "extract": "Tar entpacken", "psql": "DB-Restore (psql)", "render": "Configs re-rendern", "restart": "Services neu starten" }, "downloadTooltip": "tar.gz herunterladen", "refreshTooltip": "Liste neu laden", "confirmDelete": "Backup {{file}} wirklich löschen?", "empty": "Noch keine Backups. Klicke „Backup jetzt erstellen\" oder warte den nächsten Auto-Tick ab.", "failedTag": "FEHLER", "col": { "time": "Zeit", "file": "Datei", "kind": "Typ", "status": "Status", "size": "Größe", "duration": "Dauer" } }, "logs": { "title": "System-Logs", "intro": "Aggregierter Blick auf alle Service-Journals + audit_log. Multi-Source-Auswahl, Level-Filter, Freitext-Suche, Zeit-Range, Auto-Refresh (5s).", "autoOn": "Auto", "autoOff": "Manuell", "refresh": "Aktualisieren", "refreshTooltip": "Einmalig neu laden", "export": "CSV", "exportTooltip": "Aktuelle Tabelle als CSV exportieren", "exportEmpty": "Keine Einträge zum Exportieren", "found": "{{n}} Einträge", "limit": "Limit", "empty": "Keine Einträge gefunden. Quellen-Auswahl ändern oder Zeit-Range erweitern.", "col": { "time": "Zeit", "source": "Quelle", "level": "Level", "message": "Nachricht" }, "filter": { "sources": "Quellen wählen (alle wenn leer)", "levels": "Level filtern", "grep": "Volltext-Suche" } }, "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.", "start": "Live-Log starten", "stop": "Stop", "notStartedTitle": "Live-Log ist aus", "notStartedDesc": "Standardmäßig pausiert — Klick zum Verbinden lässt Events live einfließen.", "live": "Live", "disconnected": "verbinde …", "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" } } }