19 KiB
Sicherheit
Dieses Dokument beschreibt das Bedrohungsmodell der DDI-Suite, die Verwaltung der Schlüssel, ihre Rotation, Härtungshinweise und – ebenso wichtig – was das System nicht schützt. Grundlage sind Brief §8 und §9 sowie die ADRs 0007, 0008, 0009, 0015, 0016, 0020, 0023 und 0024. Betrieb und Abläufe stehen in OPERATIONS.md, Voraussetzungen und Ports in SYSTEM-REQUIREMENTS.md.
Namen und Pfade (ddi-suite, /etc/ddi-suite, ddi-server …) sind die Standardwerte der zentralen Benennung (ADR 0018).
1. Schutzgüter
| Schutzgut | Warum schützenswert | Wo es liegt |
|---|---|---|
| Datenebene (DNS-Antworten, DHCP-Vergabe) | Wer sie verfälscht, lenkt Clients um oder legt das Netz lahm. | BIND und Kea auf den Agent-Hosts |
| Soll-Konfiguration (Revisionen) | Wer sie fälscht, steuert alle DNS- und DHCP-Server. | PostgreSQL, signierte Bundles |
| Master-Key | Entschlüsselt alle Geheimnisse in der Datenbank. | /etc/ddi-suite/master.key (nur Server) |
| Agent-CA-Schlüssel | Stellt Agent- und Serverzertifikate aus. | Datenbank, mit dem Master-Key versiegelt |
| Bundle-Signaturschlüssel (Ed25519) | Unterschreibt jede Konfiguration, der ein Agent vertraut. | Datenbank, versiegelt |
| TSIG-Schlüssel, HA-Zugangsdaten | Erlauben Zonentransfers, dynamische Updates, Steuerung des Kea-Partners. | Datenbank (versiegelt), Bundles, Dateien auf den Agent-Hosts |
| Benutzerkonten, Sitzungen, TOTP-, OIDC-Secret | Zugang zur Verwaltung. | Datenbank (Passwörter als Argon2id-Hash, Sitzungen als SHA-256-Hash, TOTP- und OIDC-Secret versiegelt) |
| Agent-Identität (privater Schlüssel, Zertifikat) | Erlaubt, sich gegenüber dem Server als dieser Agent auszugeben. | /var/lib/ddi-suite/agent-<rolle>/identity/ (Modus 0700) |
| IPAM-Daten, Audit-Log | Inventar des Netzes, Nachvollziehbarkeit. | Datenbank |
| Lizenzstatus | Wirtschaftliches Interesse des Herstellers (Soft-Control, §9). | Datenbank (versiegelt) |
2. Vertrauensgrenzen
Browser ──HTTPS 8443──▶ Management-Server ──Unix-Socket──▶ PostgreSQL
│ ▲
│ └── HTTPS 443 ausgehend ──▶ Keygen (Lizenz)
│
gRPC/mTLS 8444 ◀─┘ (Agent verbindet sich ausgehend)
│
┌──────────┴───────────┐
▼ ▼
DNS-Agent ──rndc 127.0.0.1──▶ BIND DHCP-Agent ──Unix-Socket──▶ Kea
│ 53/tcp TSIG ▲ │ HTTP+Basic-Auth (HA, ohne TLS)
▼ │ ▼
Secondary ────────┘ Kea-Partner
| Grenze | Angreifer könnte … | Schutz |
|---|---|---|
| Browser ↔ Server | Sitzungen stehlen, Anfragen fälschen (CSRF), Skripte einschleusen (XSS), Passwörter raten. | TLS ≥ 1.2, HSTS, Content-Security-Policy, X-Frame-Options: DENY; Sitzungscookie Secure, HttpOnly, SameSite=Lax; CSRF-Token pro Sitzung plus Origin/Sec-Fetch-Site-Prüfung; Login-Ratenbegrenzung pro IP und Benutzer; Argon2id; optional TOTP; OIDC mit PKCE, state, nonce; RBAC pro Route (Viewer, Operator, Admin). |
| Server ↔ Agent | Sich als Server ausgeben, als Agent ausgeben, Konfiguration fälschen oder alte wieder einspielen. | TLS 1.3 mit gegenseitigen Zertifikaten der internen CA. Enrollment nur mit Einmal-Token (24 h, in der DB nur als Hash) und vorab bekanntem CA-Fingerprint (--ca-hash). Agent-Zertifikate 14 Tage, der Server akzeptiert nur die aktuelle Seriennummer je Agent und prüft die Sperre bei jedem Aufruf. Bundles sind mit einem eigenen Ed25519-Schlüssel signiert (nicht der CA); der Agent wendet nur Revisionen an, die größer als die zuletzt angewendete sind. |
| Agent ↔ Daemon | Über den Steuerkanal BIND/Kea umkonfigurieren. | rndc nur auf 127.0.0.1 mit Schlüssel; Kea-Control-Socket als Unix-Socket in einem Verzeichnis mit Modus 0750. Der Agent läuft als Benutzer des Dienstes (bind/named bzw. _kea/kea), nicht als root. Jede Konfiguration wird vor dem Aktivieren geprüft (named-checkconf -z, named-checkzone, kea-dhcp4 -t). |
| Primary ↔ Secondary (DNS) | Zonen abziehen, gefälschte Zonen unterschieben. | allow-transfer nur mit dem TSIG-Transferschlüssel des Clusters (hmac-sha256), NOTIFY nur an die Secondaries, Secondaries holen nur mit diesem Schlüssel. |
| Kea ↔ Kea (HA) | HA-Befehle senden, Leases manipulieren. | HTTP mit Basic-Auth; Benutzer und Passwort je Cluster zufällig erzeugt, nur in Dateien (Modus 0640). Ohne TLS – siehe Abschnitt 6. |
| Server ↔ Keygen | Lizenzantworten fälschen. | HTTPS, jede Antwort mit Ed25519 signiert (Account-Schlüssel beim Build eingebettet), Digest, Request-Target, Datum ≤ 5 min, nonce bei der Validierung. |
| Server ↔ PostgreSQL | Datenbank lesen oder ändern. | Installer: Peer-Authentifizierung über den Unix-Socket, kein Passwort, kein TCP nötig. Geheimnisse sind zusätzlich mit dem Master-Key versiegelt (AES-256-GCM, Zeilenkontext als Associated Data). |
| Installer ↔ Release-Server | Manipulierte Binaries ausliefern. | SHA256SUMS und, falls der öffentliche Schlüssel im Installer gesetzt ist, die Ed25519-Signatur SHA256SUMS.sig (Abschnitt 7). |
3. Bedrohungen und ihre Folgen
| Ereignis | Folge | Begrenzung |
|---|---|---|
| Server-Host kompromittiert (root oder Dienstbenutzer) | Vollständige Kontrolle: Master-Key und Datenbank geben alle Geheimnisse frei, der Bundle-Schlüssel signiert beliebige Konfigurationen für alle Agents. | Server isoliert betreiben, Zugang streng begrenzen (Abschnitt 5). Agents prüfen jede Konfiguration syntaktisch, fremde Dateipfade sind im Bundle-Format ausgeschlossen. |
| Datenbank oder Backup gestohlen (ohne Master-Key) | IPAM-Daten und Audit-Log lesbar, Geheimnisse nicht; Passwort-Hashes (Argon2id) offline angreifbar; Sitzungen nicht übernehmbar (nur Hashes). | Backups verschlüsselt und getrennt vom Master-Key aufbewahren. |
| Master-Key gestohlen (ohne Datenbank) | Für sich wertlos. | Getrennte Aufbewahrung. |
| Agent-Host kompromittiert | Der Angreifer kontrolliert diesen DNS- bzw. DHCP-Dienst, kennt dessen TSIG- bzw. HA-Geheimnisse und kann sich als dieser Agent beim Server melden (Status, Leases). Andere Agents und der Server sind nicht betroffen; gefälschte Lease-Meldungen erzeugen höchstens dynamic-Einträge. |
Agent in der Oberfläche sperren (wirkt sofort), Transferschlüssel des Clusters und betroffene TSIG-Schlüssel rotieren. |
| Enrollment-Token abgefangen | Wer es vor dem rechtmäßigen Agent nutzt, registriert einen eigenen Agent dieser Rolle und erhält deren Konfiguration samt Geheimnissen. | Kurze Laufzeit, einmalig; nur über vertrauliche Kanäle weitergeben; unbekannte Agents in der Oberfläche prüfen und sperren. |
| Transportweg Agent ↔ Server manipuliert | Ohne CA-Schlüssel kein gültiges Serverzertifikat, ohne Bundle-Schlüssel keine gültige Konfiguration. | – |
| Administratorkonto übernommen | Volle Verwaltung, Ausrollen beliebiger (gültiger) Konfiguration. | TOTP oder OIDC mit MFA, Audit-Log prüfen, Sitzungen per Passwortwechsel beenden. |
4. Schlüsselverwaltung
| Schlüssel | Erzeugt von | Liegt | Schutz | Rotation |
|---|---|---|---|---|
| Master-Key (AES-256, Datei mit Schlüssel-ID) | ddi-server gen-master-key (Installer) |
/etc/ddi-suite/master.key |
Der Server startet nur, wenn die Datei weder für Gruppe noch für andere lesbar ist (Modus 0400 oder 0600, Eigentümer Dienstbenutzer). Nie in der Datenbank. | Teilweise, siehe 4.1 |
| Agent-CA (ECDSA P-256, 10 Jahre) | Server beim ersten Start | Datenbank, versiegelt | Master-Key | Nicht umgesetzt (ADR 0008/0021); bei Kompromittierung neue Installation der PKI, siehe 4.2 |
| Serverzertifikat Agent-Port (1 Jahr) | Server bei jedem Start aus der CA | nur im Speicher | – | Automatisch bei jedem Neustart |
| Agent-Zertifikate (ECDSA P-256, 14 Tage) | Agent erzeugt Schlüssel und CSR, Server signiert | /var/lib/ddi-suite/agent-<rolle>/identity/ |
Modus 0700, Dienstbenutzer | Automatisch ab halber Laufzeit, neuer Schlüssel |
| Bundle-Signaturschlüssel (Ed25519) | Server beim ersten Start | Datenbank, versiegelt; öffentlicher Teil bei jedem Agent | Master-Key | Vorgesehen (neuer Schlüssel vom alten signiert, ADR 0009), nicht umgesetzt |
TSIG-Schlüssel (hmac-sha256/384/512) |
Server (Zufall, Länge = Hash-Länge) | Datenbank versiegelt, im Bundle, auf den DNS-Hosts in ddi-suite-keys.conf (0640) |
Master-Key; API zeigt sie nur Admins über GET /tsig-keys/{id}/secret (auditiert) |
POST /tsig-keys/{id}/rotate, siehe 4.3 |
| HA-Zugangsdaten (Benutzer + Passwort je DHCP-Cluster) | Server beim Anlegen des Clusters | Datenbank versiegelt, im Bundle, auf den Kea-Hosts in ddi-suite-ha-user/ddi-suite-ha-password (0640) |
Master-Key; nie in der API | Kein eigener Befehl, siehe 4.3 |
rndc-Schlüssel |
Paket bzw. Installer (rndc-confgen) |
/etc/bind/rndc.key |
Distribution (0640 root:bind) | rndc-confgen -a erneut, BIND neu starten |
| Sitzungen | Server (256 Bit Zufall) | Cookie; in der DB nur SHA-256 | – | Laufzeit 12 h, Leerlauf 1 h; Logout und Passwortwechsel beenden sie |
| TOTP-Secret, OIDC-Client-Secret | Benutzer bzw. Administrator | Datenbank, versiegelt | Master-Key | TOTP ab- und wieder einschalten; OIDC-Secret beim Identity-Provider erneuern und in der Oberfläche eintragen |
| Enrollment-Token | Administrator in der Oberfläche | in der DB nur SHA-256 | einmalig, 24 h | Unbenutzte Tokens löschen |
| Release-Signaturschlüssel (Ed25519) | Hersteller | Secret RELEASE_SIGNING_KEY der CI |
nur der Release-Workflow; privater Schlüssel offline | Neues Paar, Secret ersetzen, öffentlichen Schlüssel in scripts/install.sh tauschen; ältere Installer lehnen Releases mit dem neuen Schlüssel ab (RELEASE.md) |
4.1 Master-Key
Die Datei enthält eine Zeile <schlüssel-id> <base64> je Schlüssel. Der erste Schlüssel verschlüsselt, alle Schlüssel entschlüsseln; jeder Chiffretext trägt die ID seines Schlüssels.
Umgesetzt ist damit: einen neuen Schlüssel als erste Zeile eintragen und den Server neu starten. Neue und geänderte Geheimnisse werden ab dann mit dem neuen Schlüssel versiegelt, bestehende bleiben mit dem alten lesbar. Nicht umgesetzt ist das Neuverschlüsseln aller bestehenden Werte; der alte Schlüssel darf deshalb nicht entfernt werden. Ein gestohlener alter Master-Key bleibt damit gefährlich, solange Werte unter ihm liegen. Ablauf und Grenzen: OPERATIONS.md §8.
Master-Key verloren = Geheimnisse verloren. Ohne ihn lassen sich CA, Bundle-Schlüssel, TSIG-Schlüssel, HA-Passwörter, TOTP- und OIDC-Secret nicht mehr entschlüsseln; der Server startet mit falschem Schlüssel nicht. Er gehört in jedes Backup – getrennt von der Datenbanksicherung aufbewahrt.
4.2 Agent-CA und Bundle-Schlüssel
Beide werden beim ersten Start erzeugt und haben keine Rotationsfunktion. Ist einer von beiden kompromittiert (praktisch nur zusammen mit Datenbank und Master-Key, also mit dem Server-Host), bleibt nur der Neuaufbau: neue Server-Installation mit neuer Datenbank oder gezieltes Entfernen der Schlüssel in pki_keys (Server erzeugt neue beim Start), anschließend alle Agents neu registrieren. Die Datenebene läuft während dessen mit der letzten Konfiguration weiter.
4.3 TSIG und HA
- TSIG-Schlüssel (auch der Transferschlüssel eines Clusters) werden mit „Erneuern“ bzw.
POST /tsig-keys/{id}/rotateneu erzeugt; wirksam mit der nächsten Revision. Primary und Secondaries aktivieren sie nicht exakt gleichzeitig, kurz kann ein Secondarytsig indicates errormelden, NOTIFY holt den Transfer danach nach. Clients, die pernsupdatemit dem Schlüssel aktualisieren (z. B. DHCP-Server von Domain Controllern), müssen das neue Geheimnis erhalten. - HA-Zugangsdaten werden beim Anlegen des DHCP-Clusters erzeugt; eine Erneuerung per Knopf gibt es nicht. Wer sie erneuern muss, legt den Cluster neu an (Mitglieder entfernen, Cluster löschen, neu anlegen, Netze zuordnen, ausrollen). Kea arbeitet in dieser Zeit als Einzelserver weiter.
5. Härtung
Systemdienste (ADR 0024)
- Eigene Benutzer: Server als
ddi-suite; DNS-Agent als BIND-Benutzer (bind/named), DHCP-Agent als Kea-Benutzer (_kea/kea). Ein kompromittierter Agent hat damit die Rechte des Dienstes, den er ohnehin konfiguriert – nicht mehr. Kein Dienst läuft als root. - systemd-Hardening in allen Units:
NoNewPrivileges,ProtectSystem=strictmit gezieltenReadWritePaths,ProtectHome,PrivateTmp,PrivateDevices,ProtectKernel*,ProtectControlGroups,ProtectClock,ProtectHostname,RestrictAddressFamilies,RestrictNamespaces,RestrictSUIDSGID,LockPersonality,MemoryDenyWriteExecute,SystemCallFilter=@system-service, leereCapabilityBoundingSet,UMask=0027. Prüfen mitsystemd-analyze security ddi-server. - Dateirechte:
/etc/ddi-suite/server.yaml0640 root:ddi-suite,master.key0400 (Eigentümerddi-suite), Agent-Identität 0700, geheime BIND/Kea-Dateien 0640, Kea-Socket-Verzeichnis 0750.
Netzwerk
- Ports und Richtungen: SYSTEM-REQUIREMENTS.md §5. Auf Agent-Hosts muss für den Server kein Port offen sein.
- Port 8443 nur aus den Verwaltungsnetzen erreichbar machen, Port 8444 nur aus den Netzen der Agents.
/metricsliegt am selben Listener wie die Oberfläche und ist ohne Anmeldung abrufbar: per Reverse-Proxy oder Firewall auf das Monitoring beschränken. - Ein eigenes TLS-Zertifikat (
--tls-cert/--tls-key) statt des selbstsignierten verwenden; TLS ≥ 1.2 ist fest eingestellt (Agent-Port TLS 1.3). - HA-Verkehr zwischen den Kea-Partnern über ein eigenes, nicht von Clients erreichbares Netz (VLAN) oder einen Tunnel (WireGuard, IPsec) führen.
- BIND: Rekursion ist standardmäßig aus (rein autoritativ). Wer Rekursion einschaltet, begrenzt
allow-recursionauf die eigenen Netze.
PostgreSQL
- Der Installer richtet Peer-Authentifizierung über den Unix-Socket ein: kein Datenbankpasswort, kein offener TCP-Port.
listen_addresseskann auflocalhostbleiben. - Wer eine entfernte Datenbank nutzt: TLS (
sslmode=verify-full) unddatabase.url_filemit Modus 0640, damit das Passwort nicht in der Hauptkonfiguration steht.
Konten
- Das erste Admin-Passwort ist einmalig und muss geändert werden. Für Administratoren TOTP aktivieren oder OIDC mit MFA beim Identity-Provider verwenden.
- Rollen sparsam vergeben: Viewer für Leser, Operator für das Tagesgeschäft, Admin nur für Benutzer, Lizenz, OIDC, Cluster und Schlüssel.
Lieferkette
- Go- und npm-Abhängigkeiten sind gepinnt, die CI prüft mit
govulncheckundnpm audit; externe Actions sind per Commit-SHA gepinnt. - Reproduzierbarer Release-Build (
-trimpath, feste Build-Zeit aus dem Commit), statische Binaries (CGO_ENABLED=0).
6. Was nicht geschützt ist
- Kea-HA ohne TLS. Die HA-Verbindung nutzt HTTP mit Basic-Auth. Wer den Verkehr zwischen den Partnern mitlesen kann, sieht die Zugangsdaten und kann danach HA-Befehle an beide senden (z. B. Leases ändern, Zustand umschalten). Abhilfe bis zur TLS-Unterstützung: getrenntes Netz oder Tunnel (Abschnitt 5).
- Dynamische Updates per IP-Adresse.
allow_updatemit Adressen vertraut der Absenderadresse eines UDP-Pakets; im selben Netz lässt sie sich fälschen. Wo möglich TSIG verwenden, IP-Freigaben auf einzelne Adressen (/32) der Domain Controller beschränken. - GSS-TSIG (Kerberos-gesicherte Updates von Active Directory) wird nicht unterstützt (ACTIVE-DIRECTORY.md).
- DHCP selbst ist nicht authentifiziert. Gefälschte DHCP-Server, Adress-Erschöpfung durch viele MAC-Adressen und MAC-Spoofing gegen Reservierungen lassen sich nur im Netz verhindern (DHCP-Snooping, Port-Security, 802.1X).
- Keine DNSSEC-Signierung der Zonen (für M7 vorgesehen); Antworten von BIND sind nicht signiert.
- Geheimnisse liegen auf den Agent-Hosts im Klartext (TSIG-Schlüssel in
ddi-suite-keys.conf, HA-Zugangsdaten), weil BIND und Kea sie so brauchen. Geschützt nur durch Dateirechte. - Keine Rotation von Agent-CA und Bundle-Schlüssel, kein Neuverschlüsseln mit neuem Master-Key (Abschnitt 4).
- Login-Ratenbegrenzung im Speicher des Servers: Ein Neustart setzt sie zurück. Sie ersetzt keine starken Passwörter oder MFA.
- Server-Host = Vertrauensanker. Wer ihn kontrolliert, kontrolliert alle verwalteten DNS- und DHCP-Server (Abschnitt 3).
- Audit-Log ist nicht manipulationssicher gegen Datenbank-Administratoren; wer revisionssichere Protokolle braucht, exportiert es regelmäßig (
GET /audit/export) in ein getrenntes System.
7. Release-Signatur
Jedes Release enthält SHA256SUMS über alle Tarballs und Pakete (.deb, .rpm); ist im Release-Workflow das Secret RELEASE_SIGNING_KEY gesetzt, zusätzlich SHA256SUMS.sig, eine binäre Ed25519-Signatur (64 Byte) über SHA256SUMS. Weil SHA256SUMS alle Artefakte abdeckt, sichert diese eine Signatur auch die Pakete. Der private Schlüssel gehört offline aufbewahrt; wer ihn hat, kann Releases signieren, die jeder Installer annimmt. Prüfen von Hand: scripts/sign-release.sh verify SHA256SUMS SHA256SUMS.sig release-signing.pub.pem, danach sha256sum -c SHA256SUMS. Der Installer enthält den zugehörigen öffentlichen Schlüssel im Variablenblock: Ist er gesetzt, muss die Signatur gültig sein, sonst bricht er ab; ist er leer, prüft er nur die Prüfsummen und weist darauf hin. Manuelle Prüfung und Schlüsselverwaltung: RELEASE.md.
Den Installer selbst vor dem Ausführen herunterladen und lesen, nicht per curl | sudo bash starten (INSTALL.md).
8. Lizenzprüfung ist ein Soft-Control
Der Management-Server prüft seine Lizenz gegen Keygen, verifiziert jede Antwort mit dem beim Build eingebetteten öffentlichen Schlüssel und lässt sich nicht per Konfiguration auf einen anderen Lizenzserver umlenken (LICENSING.md). Das verhindert das bequeme Umgehen über Konfiguration, gefälschte Antworten oder einen Proxy.
Es ist aber keine technische Garantie: Wer die Software auf eigener Hardware betreibt, kann das Binary verändern, die Prüfung entfernen oder die Uhr verstellen. Eine Lizenzprüfung in selbst gehosteter Software ist eine vertragliche und organisatorische Maßnahme mit technischer Unterstützung, kein Kopierschutz. Unabhängig davon gilt: Die Lizenz beeinträchtigt nie die Datenebene – Agents prüfen keine Lizenz, DNS und DHCP laufen bei abgelaufener Lizenz unverändert weiter.
9. Schwachstellen melden
Sicherheitsprobleme bitte nicht als öffentliches Issue, sondern direkt an den Betreiber des Repositorys melden (Kontakt im Gitea-Profil von beug.k).