Sicherheit

Welche Schutzmaßnahmen Nova mitbringt, welche Aufgaben bei dir als Betreiber liegen, wie PHP und fail2ban die Hosts härten und wie du einen verlorenen zweiten Faktor zurücksetzt.

Überblick

Dieses Kapitel beschreibt, was Nova für dich erledigt und was du selbst tun musst. Punkte mit Betreiber sind deine Aufgaben.

Control Plane

  • Eigene Webserver-Instanz. Ab Profil v26 laufen das Panel, die Operations-Bridge und alle internen Listener in apache2@nova (Konfiguration /etc/apache2-nova, Laufidentität nova-controlpanel-web, ohne PHP-Modul). Der Kunden-Webserver apache2 läuft als www-data und kann die PHP-FPM-Sockets der Control Plane (0660, Besitzer nova-controlpanel-web) nicht erreichen. Eine kompromittierte Kunden-Website kann deshalb nicht mit dem PHP-Pool des Panels sprechen.
  • Panel-Port. Standard ist 8443. Betreiber: Beschränke ihn in der Firewall auf vertrauenswürdige Quelladressen, wenn deine Benutzer das zulassen. Mit dem SNI-Router teilt sich das Panel Port 443 mit den Kunden-Websites; dort ist keine Beschränkung pro Name möglich.
  • Panel-TLS. Verwende ein Zertifikat einer öffentlichen CA für listen.server_name. Das Panel setzt Session-Cookies (NOVA_SESSID) mit Secure, HttpOnly und SameSite=Strict und prüft bei jedem Schreibvorgang Origin und Sec-Fetch-Site gegen trusted_origin. Betreiber: Ersetze das Zertifikat vor Ablauf mit nova-panel-certificate.sh replace (geprüft, neu geladen, bei Fehler zurückgerollt); siehe Zertifikate.
  • Nur-Loopback-Endpunkte. Für die Operations-Bridge (127.0.0.1:9443) und das Panel-Backend des SNI-Routers (127.0.0.1:10443) wird geprüft, dass sie nur auf Loopback lauschen.

Fleet-Netz

  • Coordinator, Secret-Lease-Listener und Workspace-Gateway binden nur an die Fleet-Adresse (127.0.0.1 oder eine RFC-1918-Adresse). verify und accept verweigern eine Installation, bei der einer dieser Ports woanders lauscht.
  • Der gesamte Fleet-Verkehr läuft über Mutual TLS mit einer privaten CA pro Zweck. Private Schlüssel der Nodes verlassen den Node nie; übertragen werden nur Zertifikatsanfragen.
  • Node Agents erhalten Secrets nur über zweckgebundene Leases (user-access, web, mail, database, dns), nie in Befehlen oder in Dateien, die ein Betreiber kopiert.
  • Betreiber: Halte das private Netz privat. Erlaube die internen Ports nur von den Fleet-Hosts. Bewahre $PKI (Agent-CA) und den Workspace-CA-Schlüssel offline oder mindestens nur für root lesbar auf dem Control-Host auf; verschiebe die Workspace-PKI nach der Registrierung auf Offline-Speicher.

Secrets

  • Das Installationsprofil enthält Pfade, nie Secret-Werte. Jede Eingabe ist eine Datei mit 0600 root. Installierte Secrets liegen in /etc/nova-controlpanel/secrets/ (0640 root:nova-controlpanel).
  • Schlüssel werden durch ein normales Update nie rotiert; der Installer verweigert geändertes Schlüsselmaterial. secrets.dns_encryption_key_source_file versiegelt jedes TSIG-Secret: Geht diese Datei verloren, sind die Schlüssel verloren.
  • Betreiber: Sichere $IN (das Eingabeverzeichnis) und $PKI verschlüsselt auf Offline-Speicher. Ohne sie kannst du weder zurückrollen noch upgraden noch Nodes registrieren. Gib Secrets nie auf der Kommandozeile an.

Kunden-Websites

Für jede Website erzeugt Nova:

  • eine PHP-Runtime (PHP-FPM-Pool oder mod_fcgid), die unter dem eigenen Benutzer und der eigenen Gruppe der Website läuft, mit security.limit_extensions = .php und optionalem Chroot;
  • gesperrte PHP-Funktionen (siehe unten), als Admin-Werte gesetzt, die ini_set() und .user.ini nicht aufheben können;
  • ein verwaltetes Standard-open_basedir und ein eigenes Temporär- und Session-Verzeichnis der Website;
  • PHP-Einstellungen nur für Administratoren: php.open_basedir und jede PHP.ini-Ergänzung außerhalb der Kunden-Erlaubnisliste;
  • Options SymLinksIfOwnerMatch (Apache) bzw. disable_symlinks if_not_owner (Nginx) und eine gesperrte Dokumentbasis, sodass ein Kunde keinem Symlink in die Dateien eines anderen Kunden folgen kann;
  • eine Erlaubnisliste für .htaccess statt AllowOverride All: AllowOverride None plus AllowOverrideList, begrenzt auf Auth, Limit, Index, File-Info und ein gedeckeltes Options (Indexes, MultiViews, SymLinksIfOwnerMatch). Handler-, SetEnv-, php_*- und Proxy-Direktiven sind nie erlaubt;
  • eine Festplattenquota pro Benutzer auf dem Quota-Volume des Web-Nodes.

Betreiber:

  • Bestehende Websites erhalten die gesperrten Funktionen, das verwaltete open_basedir und das eigene Session-Verzeichnis beim nächsten Apply (jede Änderung oder POST /web/sites/{id}/reconciliations). Ihre offenen PHP-Sitzungen enden dabei einmalig. Prüfe Anwendungen, die exec() und Verwandte aufrufen oder außerhalb der Website lesen, und vergib bei Bedarf Ausnahmen oder ein Administrator-open_basedir.
  • Websites, die vor diesem Release mit einem open_basedir oder einer nicht erlaubten PHP.ini-Zeile gespeichert wurden, werden beim Apply abgelehnt, bis ein Administrator sie einmal öffnet und speichert (oder die Werte entfernt). Liste sie vor dem Upgrade auf.
  • Biete PHP-Modi, Chroot-Modi und PHP-Funktionsausnahmen in Plänen bewusst an (web.php-modes, access.ssh-chroots, web.php-function-exceptions).

PHP-Härtung im Detail

Gesperrte PHP-Funktionen

Jede PHP-Runtime einer Website (PHP-FPM-Pool und mod_fcgid-Starter) sperrt:

exec, passthru, pcntl_exec, popen, proc_open, putenv, shell_exec, system

Der Node Agent setzt sie als php_admin_value[disable_functions] (FPM) bzw. -d disable_functions= (mod_fcgid); weder ini_set() noch .user.ini heben sie auf.

  • Ausnahmen pro Website. php.enabled_functions gibt einzelne Funktionen dieser Liste für eine Website wieder frei (etwa für eine Anwendung, die proc_open braucht). Die Liste oben ist abschließend; alles andere wird mit 422 WEB_PHP_FUNCTION_NOT_ALLOWED (Feld php.enabled_functions) abgelehnt.
  • Wer sie setzen darf. Administratoren immer. Kunden und Reseller nur, wenn der Plan das Merkmal PHP-Funktionsausnahmen (web.php-function-exceptions) freigibt; sonst nennt 422 WEB_FEATURE_NOT_ALLOWED das Feld php.enabled_functions. Eine Ausnahme zu entfernen ist immer erlaubt. Pläne aus früheren Versionen lesen das Merkmal als deaktiviert.
  • Nur strenger, nie schwächer. Eine Zeile disable_functions = … in den PHP.ini-Ergänzungen der Website (oder in einer Administrator-PHP-Direktive) fügt Funktionen hinzu; eine verwaltete Funktion gibt sie nie frei.
  • Panel. Website-Formular, Abschnitt PHP, TLS und Routing: Gesperrte PHP-Funktionen: für diese Website freigeben. Für Kunden, deren Plan keine Ausnahmen erlaubt, sind die Kontrollkästchen gesperrt.
  • Bestehende Websites erhalten die Liste beim nächsten Apply. Prüfe Anwendungen, die exec() und Verwandte aufrufen (Bildwerkzeuge, manche Backup-Plugins), und vergib bei Bedarf Ausnahmen.

open_basedir und PHP.ini-Ergänzungen

php.open_basedir und jede Zeile der PHP.ini-Ergänzungen (php.custom_ini), deren Direktive nicht auf der Kunden-Erlaubnisliste steht, sind Administrator-Einstellungen. Die Erlaubnisliste enthält Ressourcenlimits, Fehler- und Session-Verhalten und Ähnliches, zum Beispiel memory_limit, max_execution_time, post_max_size, upload_max_filesize, date.timezone, display_errors, session.cookie_secure und disable_functions (das nur Funktionen hinzufügen kann). Alles andere ist Administrator-Einstellung, insbesondere open_basedir, disable_classes, allow_url_include, auto_prepend_file, auto_append_file, sendmail_path, mail.force_extra_parameters, upload_tmp_dir, session.save_path, extension, zend_extension, ffi.enable und error_log – ebenso ein Kundenwert mit $, geschweiften Klammern, Backslash oder Backtick (ini-Expansion).

  • Kunden (Clients und Reseller) können Administrator-Einstellungen weder setzen noch ändern noch entfernen: 422 WEB_PHP_SETTING_NOT_ALLOWED nennt php.open_basedir oder php.custom_ini. Alle anderen Website-Felder bleiben bearbeitbar, solange die Administrator-Einstellungen unverändert mitgeschickt werden (das Panel erledigt das).
  • Administratoren setzen sie frei. Die API vermerkt das serverseitig als php.admin_authority: true an der Website (bei jedem Schreibvorgang berechnet, nie aus der Anfrage übernommen, entfernt, sobald keine Administrator-Einstellung mehr übrig ist). Von der Legacy-Basis importierte Websites tragen den Vermerk ebenfalls.
  • Node Agent (zusätzliche Verteidigungslinie). PHP-FPM-Pool und mod_fcgid-Starter übernehmen Administrator-Einstellungen nur mit php.admin_authority. Ohne den Vermerk lässt der Renderer nur erlaubte Zeilen zu (sonst NOVA_WEB_PHP_INI_NOT_ALLOWED) und open_basedir-Pfade nur innerhalb des eigenen Baums der Website (sonst NOVA_WEB_PHP_OPEN_BASEDIR_NOT_ALLOWED); der Apply scheitert, und der Node behält seine letzte bekannte gute Konfiguration. Plattform-PHP-Direktiven gehören den Administratoren und sind nie eingeschränkt.
  • Vor diesem Release gespeicherte Websites behalten Werte, Formular und Revision, tragen aber keinen Vermerk; unbekannt ist also, wer die Werte gesetzt hat. Sie werden nicht stillschweigend angewendet: Der nächste Apply wird wie oben abgelehnt, ebenso ein Kunden-Schreibvorgang, der sie auf einer aktiven Website beibehält. Ein Administrator öffnet die Website und speichert sie einmal (das markiert die Werte als Administrator-Einstellungen) oder entfernt sie. Liste betroffene Websites vor dem Upgrade auf: jede native Website mit nicht leerem php.open_basedir oder einer PHP.ini-Zeile außerhalb der Erlaubnisliste.

Verwaltetes Standard-open_basedir

Jede Website mit PHP läuft mit einem open_basedir. Ohne php.open_basedir setzt der Node Agent einen verwalteten Standard in den PHP-FPM-Pool (php_admin_value[open_basedir]) und den mod_fcgid-Starter (-d open_basedir=):

EintragNative WebsiteÜbernommenes (importiertes) Root
Web-Verzeichnis (Web-Root, Domain-Roots, Statistik, Fehlerseiten)<documents>/<storage>/web/<document_root>/
Temporärverzeichnis der Website<documents>/<storage>/tmp/innerhalb von <document_root>/ (dessen tmp/), kein eigener Eintrag
private/ der Website (Daten und Konfiguration außerhalb des ausgelieferten Baums)<documents>/<storage>/private/innerhalb von <document_root>/ (dessen private/), kein eigener Eintrag
PHP-Bibliotheken der Distribution (Standard-include_path)/usr/share/php//usr/share/php/
  • <documents> ist /var/www/nova-controlpanel. Jeder Eintrag endet mit /: open_basedir vergleicht Präfixe, so lässt das Verzeichnis einer Website nie ein Nachbarverzeichnis zu, dessen Name gleich beginnt.
  • Bewusst nicht im Standard: das System-/tmp (alle temporären Pfade zeigen in die Website) und /dev/urandom (random_bytes(), random_int() und Session-IDs nutzen den Kernel-Aufruf getrandom(), den open_basedir nicht einschränkt; eine Anwendung, die /dev/urandom selbst öffnet, braucht einen Administratorwert).
  • Lesbare Pfade brauchen keinen Eintrag. Die Aliase /var/www/<domain>, /var/www/clients/<customer>/<domain> und bei umgezogenen Websites /var/www/clients/clientN/webN (Tagesbetrieb) sind root-eigene Symlinks auf <documents>/<storage>. PHP prüft den aufgelösten echten Pfad; über einen Alias wird nichts außer den eigenen Verzeichnissen der Website erreichbar.
  • PHP-FPM-Chroot. Das Jail enthält nur die Website; der Standard ist daher die Jail-Sicht /web/:/tmp/:/private/ oder /, wenn das Jail selbst das Web-Verzeichnis ist (Website mit Web-Root-Ordner). Host-Pfade, auch die lesbaren Aliase, gibt es im Jail nicht.

Temporär- und Session-Verzeichnis. Unabhängig von open_basedir lenken beide Runtimes upload_tmp_dir, sys_temp_dir, session.save_path und die Umgebungsvariablen TMP/TMPDIR/TEMP in das eigene Verzeichnis der Website: native Websites nach <documents>/<storage>/tmp (neben web/, also weder ausgeliefert noch Teil eines Website-Backups), übernommene Roots nach <document_root>/tmp, ein PHP-FPM-Chroot nach /tmp im Jail. Der Speicher legt das native Verzeichnis (Website-Benutzer und Mandantengruppe, 0750) bei jedem Apply einer Website mit PHP an. Ein übernommenes Root muss tmp/ bereits enthalten (sonst NOVA_WEB_ADOPTION_INSTALLATION_INVALID). Da der Session-Cleaner der Distribution nur /var/lib/php/sessions aufräumt, sammelt die Runtime ihre abgelaufenen Sitzungen selbst ein (session.gc_probability = 1 gegen session.gc_divisor des Hosts); eine PHP.ini-Ergänzung kann beides anpassen. Ein verwalteter Pfad mit einem Zeichen, das der ini-Scanner nicht wörtlich liest (:, ;, Leerzeichen, Anführungszeichen, $, geschweifte Klammern, = …), wird mit NOVA_WEB_RENDER_PATH_INVALID abgelehnt; der Node behält seine letzte bekannte gute Konfiguration.

Explizite Werte ersetzen den Standard vollständig.

  • Ein Administrator setzt php.open_basedir (Website-Formular, Feld open_basedir, oder API-Schreibvorgang als Administrator). Die Pfade werden genau so gesetzt, ohne die Standardeinträge. Nimm das tmp/ der Website auf (oder die Pfade einer Administrator-Zeile upload_tmp_dir bzw. session.save_path), sonst scheitern Uploads und Sitzungen. / hebt die Einschränkung für eine Website auf. Wird der Wert entfernt, gilt wieder der Standard.
  • Ein unmarkierter Wert innerhalb des eigenen Baums der Website (gespeichert, bevor es den Administrator-Vermerk gab) schränkt die Website weiterhin nur ein und ersetzt den Standard; jeder andere unmarkierte Wert wird abgelehnt.

Bestehende Websites erhalten Standard, Temporärverzeichnis und Session-Einstellungen beim nächsten Apply; eine Migration gibt es nicht. Native fast-cgi-Websites wechseln von web/tmp nach <documents>/<storage>/tmp, PHP-FPM-Websites ihre Sitzungen von /var/lib/php/sessions; offene Sitzungen enden dabei einmalig, und das alte web/tmp bleibt als Mandantendaten liegen. Gib Websites, die außerhalb ihres Verzeichnisses lesen (gemeinsame Bibliotheken unter /opt oder /srv, /dev/urandom), einen Administratorwert.

Mail

  • Dovecot authentifiziert nur Novas Mail-Benutzer. Der Node-Agent-Installer deaktiviert mit activate-nova-dovecot-auth.sh die auth-system.conf.ext der Distribution (PAM und Systembenutzer); der Mail-Publisher veröffentlicht nicht, solange eine andere passdb/userdb aktiv ist. Betreiber: Hat der Installer Dovecot system authentication is still enabled ausgegeben, führe activate-nova-dovecot-auth.sh activate aus und prüfe status.
  • Die Postfachquota setzt Dovecot pro Benutzer durch.
  • Wiederherstellungs-, Sicherheits- und Support-Mails gehen nur an eine verifizierte Wiederherstellungsadresse, über verifiziertes TLS.

DNS

  • Zonentransfers und NOTIFY zwischen Novas DNS-Nodes verwenden einen TSIG-Schlüssel pro Primary/Secondary-Paar. Die Schlüssel kommen über den dns-Lease in root-eigene Keyrings. Betreiber: Rotiere sie mit POST /dns-tsig-keys/rotations, wenn du ein Leck vermutest oder einen Node entfernst.
  • Externe Master von Secondary-Zonen können einen TSIG-Schlüssel verwenden (in der API nur schreibbar).
  • Kunden dürfen keine privaten oder reservierten Adressen als externe Master eintragen.

Firewall-Verwaltung

Nova ändert eine Host-Firewall nur mit einem unabhängigen Wiederherstellungsweg: einem Ed25519-Schlüsselpaar, dessen geheimer Schlüssel nicht auf dem Panel-Host liegt, und einer signierten Bestätigung für jede Regelsatz-Revision. Ohne sie werden Firewall-Schreibvorgänge abgelehnt. Einrichtung: Anleitungen.

Brute-Force-Schutz mit fail2ban

Der Node-Agent-Installer richtet Novas fail2ban-Jails auf jedem Host ein, auf dem fail2ban vorhanden ist (/opt/nova-controlpanel-node-agent/deploy/nova-fail2ban.sh install). Ein Host ohne fail2ban bleibt unberührt; NOVA_NODE_FAIL2BAN=off überspringt den Schritt auf einem Host, dessen fail2ban ein Betreiber selbst verwaltet.

JailWannQuellePortsVersuche / Fenster / Sperre
sshdimmerJournal (ssh.service, sshd, sshd-session) oder /var/log/auth.logPorts aus sshd_config (Standard 22)5 / 10 min / 1 h, wachsend bis 1 Woche
nova-controlpanel-panelControl-Host/var/log/apache2-nova/access.log: 401 auf den Anmelderouten von Panel und PostfachPanel-Port (443 hinter dem SNI-Router)10 / 10 min / 30 min
dovecotMail-HostJournal oder /var/log/mail.log110, 143, 993, 995, 41908 / 10 min / 1 h
postfix-saslMail-HostJournal (postfix@-.service) oder /var/log/mail.log25, 465, 5878 / 10 min / 1 h
pure-ftpdFTP-HostJournal oder /var/log/syslog218 / 10 min / 1 h
  • Die Sperraktion ist nftables-multiport, wenn nft installiert ist, sonst iptables-multiport.
  • Das Journal wird genutzt, wenn python3-systemd installiert ist; sonst die Logdateien der Distribution. Ein Jail ohne Logquelle wird übersprungen (die Installationsausgabe listet es unter skipped).
  • Der kombinierte Host erhält fail2ban und python3-systemd mit dem Paket-Bundle (Debian 13 und Ubuntu 24.04); ein installierter Host bekommt python3-systemd mit seinem nächsten Update. Ein separater Node erhält fail2ban nur, wenn du es installierst – installiere dort auch python3-systemd.
  • Das Panel hat zusätzlich eine eigene Anmeldedrosselung (Limits pro Challenge für MFA, Sperren für Wiederherstellung und die Prüfung von Wiederherstellungsadressen).

Wichtig: Sperr keine Administratoren aus. Loopback wird immer ignoriert. Trage die Netze ein, die Administratoren und die Fleet nutzen. Die Liste wird gespeichert und bleibt bei späteren Installationen (Node-Agent-Updates) erhalten; --ignore-ip=none leert sie.

sh
sh /opt/nova-controlpanel-node-agent/deploy/nova-fail2ban.sh install --ignore-ip=198.51.100.0/24 --ignore-ip=10.90.0.0/24

Befehle (als root auf dem Host):

BefehlWirkung
install [--ignore-ip=…]erzeugen, fail2ban-client -t, neu laden, jedes Jail muss laufen; bei Fehler kehren die vorherigen Dateien zurück und fail2ban wird neu geladen
verifyDateien entsprechen der Erzeugung und jedes Jail läuft (auch Teil von verify-nova-node-agent.py)
statusJSON: jedes Nova-Jail mit seinen aktuell gesperrten Adressen
unban ADDRESS [JAIL]Sperre in einem oder allen Nova-Jails aufheben
rollbackDateien aus der Zeit vor der ersten Installation wiederherstellen und neu laden

Scheitert die Jail-Installation, scheitert die Node-Agent-Installation und wird zurückgerollt; fail2ban behält seine vorherigen Jails. Die Jails hängen nicht vom Node-Agent-Release ab, ein Node-Agent-Rollback lässt sie also bestehen.

Sperren im Panel und per API

Betrieb & Diagnose → Fleet & Agenten → fail2ban-Sperren: Server wählen, Gesperrte Adressen abrufen listet die gesperrten Adressen pro Nova-Jail (höchstens 100 pro Jail, mit Gesamtzahl), Entsperren hebt eine Sperre auf und lädt die Liste neu. Der Server antwortet über seinen Node Agent; die Liste kommt daher nach einem Agent-Poll.

Route (/api/next/v1)CapabilityWirkung
POST /host-security/fail2ban/observations {node_id}security.fail2ban.read202 mit Operations-ID
POST /host-security/fail2ban/unbans {node_id, address, jail} (jail null: alle Nova-Jails)security.fail2ban.unban202 mit Operations-ID
GET /host-security/fail2ban/operations/{op_id}security.fail2ban.readqueued, failed oder succeeded mit der Antwort

Nur für native Administrator-Principals (security_admin hat beide Capabilities, read_only_admin das Lesen). Beide POSTs brauchen Plattform-Schreibrechte, das CSRF-Token der Plattformverwaltung, Same-Origin-JSON und einen Idempotency-Key; sie werden als host-security.fail2ban.observe|unban mit Node, Adresse und Jail auditiert. Der Node führt über die Root-Engine der Plattformverwaltung nur sein Jail-Werkzeug aus (nova-fail2ban.sh status|unban).

Pro Node aktivieren: Trage host-security.fail2ban.v1 in NOVA_AGENT_WRITE_CAPABILITIES in /etc/nova-controlpanel-node-agent/runtime.env ein. Bei einem früher registrierten Node führst du zusätzlich nova-agent-fabric.sh node-register auf dem Control-Host erneut aus, damit Operations die neue Capability erfasst. Ohne das antwortet die Anfrage mit 503.

Konten und Anmeldung

  • MFA und Step-up sind für Schreibvorgänge Pflicht. Der Installer verweigert jedes Profil, das einen nativen Schreibvorgang aktiviert, solange nicht native_identity_mfa.enabled, native_identity_mfa.enrollment_enabled und native_capability_elevation.enabled eingeschaltet sind.
  • Step-up. Die 23 Step-up-Capabilities (Firewall, Serverkonfiguration, Dienste, Adressen und PHP, Aufgeben von Fleet-Nodes, Systemkonfiguration, Lizenzinstallation, Identitätsverwaltung und Gruppen, Remote-Benutzer, Erweiterungen, Operations execute/approve, Anzeigen von Blueprint-Zugangsdaten) verlangen unmittelbar vor der Aktion Passwort plus TOTP. Das Panel fragt automatisch danach; API-Clients senden die Freigabe in X-Capability-Elevation. Eine Freigabe gilt 5 Minuten und für einen akzeptierten Versuch. Wird die Anfrage vor jeder Wirkung mit einem 4xx (außer 401) abgelehnt, steht die Freigabe erneut zur Verfügung.
  • Betreiber: Richte TOTP für den Owner und jeden Administrator ein, bevor sie eine geschützte Aktion nutzen, und bewahre die Wiederherstellungscodes offline auf.
  • Erzwungener Passwortwechsel (required_password_change_enabled) verlangt bei der nächsten Anmeldung ein neues Passwort.
  • Passwort-Wiederherstellung funktioniert nur mit verifizierter Wiederherstellungsadresse; der Link gilt 30 Minuten und einmal.
  • API-Clients erhalten ihr Secret genau einmal; speichere es beim Anlegen oder Rotieren. Jeder Schreibvorgang braucht einen Idempotency-Key aus 16 bis 128 Zeichen aus A-Z a-z 0-9 . _ : -, beginnend mit Buchstabe oder Ziffer (eine UUID passt); alles andere ergibt vor jeder Wirkung 422 VALIDATION_REQUEST_INVALID. Wiederhole eine verlorene Antwort mit demselben Schlüssel; ein neuer Schlüssel ist eine neue Anfrage.

Zweiten Faktor im Notfall zurücksetzen

Dieses Notfallverfahren gilt für einen Nova-Administrator, auch den Plattform-Owner, der sowohl den Authenticator (TOTP) als auch alle Wiederherstellungscodes verloren hat. Nutze zuerst die normalen Wege:

  • Authenticator verloren, Wiederherstellungscodes vorhanden: mit einem Wiederherstellungscode anmelden und den Authenticator unter Einstellungen > Sicherheit ersetzen (ein Wiederherstellungscode gilt als vorhandener Nachweis).
  • Ein anderer Administrator kann einen Faktor im Panel nicht zurücksetzen. Der folgende Break-Glass-Reset ist der einzige Weg.

Voraussetzungen

  • Root-Shell auf dem Control-Host (dem Host, auf dem die Application läuft). Jeden anderen Benutzer lehnt das Werkzeug ab (Exit 77), bevor es eine Datei liest.
  • Native MFA ist in /etc/nova-controlpanel/application-runtime.json aktiviert.
  • Der Principal existiert, ist active, und sein Anmeldekonto ist aktiviert und nicht gesperrt. Ein gesperrtes Konto entsperrst du vorher über die normale Verwaltung.
  • Eine Vorfall- oder Ticketreferenz für die Begründung.
  • Die Identität der anfragenden Person ist über einen unabhängigen Kanal bestätigt. Der Reset setzt das Konto auf reine Passwortanmeldung zurück; das Passwort muss also noch geheim sein. Könnte es jemand anderem bekannt sein, setze es nach dem MFA-Reset und vor allem anderen über die Passwort-Wiederherstellung neu.

Ausführen

sh
php /opt/nova-controlpanel/application/current/src/api/application/bin/nova-identity-mfa-break-glass.php \
    reset <login-name|prn_id> 'INC-4711 owner lost authenticator and recovery codes'

Die Argumente sind fest: das Unterkommando reset, ein Login-Name oder eine native Principal-ID und eine Begründung aus 8 bis 200 Zeichen (Buchstaben, Ziffern, Leerzeichen und ._,:;()/#-). Das Werkzeug liest Konfiguration, Datenbankpasswort und MFA-Keyring nur aus den root-eigenen Runtime-Dateien, nimmt nie ein Secret aus argv oder der Umgebung entgegen und gibt nie eines aus. Bei Erfolg gibt es eine JSON-Zeile aus:

json
{"schema":"nova.identity-mfa-break-glass.v1","state":"reset","principal_id":"prn_...","factor_revoked":true,"recovery_codes_revoked":10,"challenges_revoked":0,"sessions_revoked":1,"elevations_revoked":0,"reauthentications_revoked":0,"request_id":"req_breakglass_..."}
Exit-CodeBedeutung
0Reset erfolgt.
1Konfigurations-, Datenbank- oder Audit-Fehler. Nichts geändert.
3Abgelehnt: NATIVE_MFA_BREAK_GLASS_PRINCIPAL_UNAVAILABLE (unbekannt, gesperrt oder deaktiviert), NATIVE_MFA_BREAK_GLASS_NOT_ENROLLED (kein zweiter Faktor vorhanden) oder NOVA_MFA_BREAK_GLASS_MFA_DISABLED. Nichts geändert.
64Aufruffehler.
77Nicht root unter Linux.

Was sich ändert

Alles in einer Datenbanktransaktion unter der Sperre des Principals:

  1. Der TOTP-Faktor wird widerrufen und sein verschlüsseltes Secret gelöscht.
  2. Alle Wiederherstellungscodes und offenen MFA-Challenges werden widerrufen.
  3. Die Anmelderichtlinie kehrt zu reiner Passwortanmeldung zurück; die Widerrufs-Epoche des Principals wird erhöht.
  4. Alle Browser-Sitzungen des Principals werden widerrufen.
  5. Alle offenen Step-up-Freigaben und Reauthentifizierungs-Challenges verfallen.
  6. Ein Audit-Event identity.mfa.break-glass-reset wird mit dem Akteur host-root, der Begründung und den Zählern geschrieben. Ein abgelehnter Versuch wird als denied auditiert.

Lässt sich das Audit nicht schreiben, wird der gesamte Reset zurückgerollt.

Danach

  1. Die Person meldet sich nur mit dem Passwort an.
  2. Sie öffnet Einstellungen > Sicherheit und richtet einen neuen Authenticator ein. Bis dahin antwortet jede Step-up-geschützte Aktion (Server, Firewalls, Konfiguration, Identitätsverwaltung, API-Clients …) mit CAPABILITY_STEP_UP_FACTOR_MISSING.
  3. Sie bewahrt die neuen Wiederherstellungscodes sicher auf.
  4. Du hältst die request_id aus der Ausgabe im Vorfall fest.

Hinweis: Der Reset schickt dem Kontoinhaber keine Sicherheits-E-Mail. Informiere ihn über den bestätigten Kanal.

Audit

  • Jeder Schreibvorgang der Application erzeugt in derselben Transaktion einen Audit-Eintrag; scheitert der Audit-Schreibvorgang, scheitert die Anfrage.
  • Das Panel zeigt den Audit-Strom unter Betrieb & Diagnose.
  • Support-Bundles werden bereinigt und vor dem Schreiben auf Secrets geprüft (Fehlersuche).

Sicherheits-Checkliste

PunktErledigt, wenn
Panel-Port beschränktdie Firewall lässt 8443 nur aus vertrauenswürdigen Netzen zu (wo möglich)
Panel-Zertifikat vertrauenswürdigBrowser zeigen keine Warnung
MFA für Owner und Administratorenjedes Admin-Konto hat einen bestätigten Faktor; Wiederherstellungscodes liegen offline
Wiederherstellungsadresse verifiziertOwner und Administratoren haben eine verifizierte Adresse
Interne Portsnova-fleet-network.py check-exposure gelingt; privates Netz gefiltert
Dovecot-Authentifizierungactivate-nova-dovecot-auth.sh status gelingt auf Mail-Nodes
fail2bannova-fail2ban.sh verify gelingt auf jedem Host; Admin- und Fleet-Netze in --ignore-ip
Zertifikatenova-agent-fabric.sh status ... --fail-on-warning und nova-panel-certificate.sh status --fail-on-warning im Monitoring
Alte PHP-Einstellungennach dem Upgrade keine Website mit WEB_PHP_SETTING_NOT_ALLOWED abgelehnt
Eingaben und PKI gesichertverschlüsselte Offline-Kopie von $IN, $PKI und der Workspace-PKI
Betriebssystem-Updatesunattended-upgrades oder eine regelmäßige Update-Routine