4.5 Dienstabhängigkeiten untersuchen* Ein Dienst kann korrekt gestartet sein und trotzdem nicht funktionieren, wenn eine benötigte Abhängigkeit fehlt oder fehlerhaft arbeitet. Solche Abhängigkeiten können vom Betriebssystem ausdrücklich konfiguriert oder nur innerhalb der Anwendung hinterlegt sein. Grundsatz: Ein abhängiger Dienst kann nur so zuverlässig funktionieren wie die gesamte Kette seiner benötigten Komponenten. Ziele dieser Seite Nach dieser Seite sollst du: formale und versteckte Dienstabhängigkeiten unterscheiden können, erforderliche und optionale Abhängigkeiten erkennen können, Startreihenfolge und echte Abhängigkeit auseinanderhalten können, vorwärts und rückwärts gerichtete Abhängigkeiten ermitteln können, DNS-, Netzwerk-, Speicher-, Datenbank- und Authentifizierungsabhängigkeiten prüfen können, Fehler entlang einer Dienstkette eingrenzen können, gemeinsame Abhängigkeiten bei mehreren gestörten Diensten erkennen können, Auswirkungen eines Dienstneustarts auf abhängige Systeme bewerten können. 1. Formale und funktionale Abhängigkeiten unterscheiden Art Beschreibung Beispiel Formale Dienstabhängigkeit In der Betriebssystem-Dienstverwaltung eingetragen Webdienst benötigt einen lokalen Datenbankdienst Startreihenfolge Legt fest, was vorher oder nachher gestartet wird Anwendung startet nach dem Netzwerkziel Netzwerkabhängigkeit Externes System muss über das Netzwerk erreichbar sein Anwendung verbindet sich mit Datenbankserver Namensauflösung Dienst benötigt funktionierendes DNS Backend wird über Hostnamen angesprochen Speicherabhängigkeit Lokales oder entferntes Dateisystem muss verfügbar sein Anwendung benötigt SMB- oder NFS-Freigabe Authentifizierungsabhängigkeit Identitätsdienst wird benötigt Anmeldung über Active Directory oder LDAP Zertifikatsabhängigkeit Vertrauenskette und Gültigkeit müssen stimmen TLS-Verbindung zu einer API Zeitabhängigkeit Systemuhren müssen ausreichend synchron sein Kerberos oder Zertifikatsprüfung Ressourcenabhängigkeit CPU, RAM, Speicherplatz oder Dateideskriptoren werden benötigt Datenbank kann keine Dateien mehr schreiben Anwendungsabhängigkeit Andere Anwendung oder API muss funktionieren Warenwirtschaft greift auf Zahlungsdienst zu Konfigurationsabhängigkeit Datei, Variable oder Secret muss vorhanden sein Datenbank-URL aus Umgebungsvariable Infrastrukturabhängigkeit Plattformkomponente stellt Laufzeit bereit Container-Runtime, Hypervisor oder Cluster Betriebssystemwerkzeuge zeigen normalerweise nur die formal registrierten Abhängigkeiten. Externe Datenbanken, DNS-Server, APIs oder Netzwerkspeicher erscheinen dort häufig nicht. 2. Eine Dienstkette darstellen Eine Anwendung kann beispielsweise folgende Kette besitzen: Benutzer → Client → DNS → Netzwerk und Firewall → Loadbalancer → Reverse Proxy → Webserver → Anwendungsdienst → Datenbank → Verzeichnisdienst → Netzwerkspeicher → externe API Für jede Verbindung sollten folgende Informationen erfasst werden: Eigenschaft Beispiel Quellsystem Anwendungsserver Zielsystem Datenbankserver Zielname srv-db01.example.local Zielport TCP 5432 Protokoll PostgreSQL Authentifizierung Dienstkonto Verschlüsselung TLS Zeitüberschreitung 10 Sekunden Kritikalität Erforderlich Verhalten bei Ausfall Anmeldung nicht möglich Überwachung TCP- und Datenbankabfrage Verantwortlichkeit Datenbankbetrieb Praktische Dokumentationsform: Quelle Abhängigkeit Ziel Port/Protokoll Kritisch Nachweis Webserver Namensauflösung DNS-Server UDP/TCP 53 Ja DNS-Abfrage Webserver Anwendung App-Server TCP 8443 Ja HTTPS-Test App-Server Datenbank DB-Server TCP 5432 Ja Datenbankabfrage App-Server Anmeldung LDAP-Server TCP 636 Ja LDAPS-Test App-Server Dateispeicher Fileserver SMB 445 Nein Freigabetest 3. Erforderliche und optionale Abhängigkeiten unterscheiden Abhängigkeitstyp Verhalten bei Ausfall Zwingend erforderlich Dienst kann nicht starten oder Hauptfunktion fällt aus Optional Nur Zusatzfunktion fällt aus Bedingt erforderlich Nur bestimmte Benutzer oder Vorgänge sind betroffen Redundant Andere Instanz kann übernehmen Zwischengespeichert Funktioniert vorübergehend mit vorhandenen Cache-Daten Asynchron Anfragen werden zunächst in eine Warteschlange geschrieben Startabhängig Nur während des Starts erforderlich Laufzeitabhängig Während des gesamten Betriebs erforderlich Verwaltungsabhängig Nur für Administration oder Monitoring erforderlich Beispiele: Eine Webanwendung kann ihre Startseite ohne Datenbank ausliefern, aber keine Benutzer anmelden. Ein Maildienst kann Nachrichten zwischenspeichern, obwohl das Zielsystem vorübergehend nicht erreichbar ist. Ein Cluster kann beim Ausfall einer Instanz weiterarbeiten. Ein Dienst kann starten, obwohl ein optionales Monitoring-Backend fehlt. Eine Anwendung kann nach dem Start weiterarbeiten, obwohl der Konfigurationsdienst später ausfällt. Der Ausfall einer Abhängigkeit führt nicht immer zum vollständigen Dienststillstand. Teilfunktionen und verzögerte Fehler müssen deshalb ausdrücklich geprüft werden. 4. Windows-Dienstabhängigkeiten mit PowerShell prüfen muss durch den internen Dienstnamen ersetzt werden. Dienst und erforderliche Systemdienste anzeigen: [RO] Get-Service -Name "" -RequiredServices Nur die erforderlichen Dienste übersichtlich anzeigen: [RO] (Get-Service -Name "").ServicesDependedOn | Select-Object Name, DisplayName, Status Dienste anzeigen, die vom untersuchten Dienst abhängen: [RO] Get-Service -Name "" -DependentServices Abhängige Dienste übersichtlich anzeigen: [RO] (Get-Service -Name "").DependentServices | Select-Object Name, DisplayName, Status Dienst und beide Abhängigkeitsrichtungen erfassen: [RO] $service = Get-Service -Name "" $service | Select-Object Name, DisplayName, Status "Benötigte Dienste:" $service.ServicesDependedOn | Select-Object Name, DisplayName, Status "Abhängige Dienste:" $service.DependentServices | Select-Object Name, DisplayName, Status Wichtig: ServicesDependedOn zeigt Dienste, die der untersuchte Dienst benötigt. DependentServices zeigt Dienste, die den untersuchten Dienst benötigen. Beide Richtungen sind vor einem Stopp oder Neustart relevant. Nicht jede funktionale Anwendungsabhängigkeit ist beim Service Control Manager registriert. 5. Windows-Dienstabhängigkeiten mit sc.exe prüfen Konfiguration einschließlich eingetragener Abhängigkeiten anzeigen: [RO][SENS] sc.exe qc "" Relevant ist insbesondere der Abschnitt: DEPENDENCIES Direkt abhängige Dienste anzeigen: [RO] sc.exe enumdepend "" Erweiterte Dienstinformationen anzeigen: [RO] sc.exe queryex "" Interpretation: Abfrage Richtung sc.exe qc → DEPENDENCIES Welche Dienste benötigt der untersuchte Dienst? sc.exe enumdepend Welche Dienste hängen vom untersuchten Dienst ab? sc.exe qc kann Programmpfade, Dienstkonten und interne Konfigurationsinformationen anzeigen. Die Ausgabe sollte deshalb als potenziell sensibel behandelt werden. 6. Zustand aller formalen Windows-Abhängigkeiten prüfen Benötigte Dienste samt Startart und Konto untersuchen: [RO] $requiredServices = (Get-Service -Name "").ServicesDependedOn foreach ($requiredService in $requiredServices) { Get-CimInstance Win32_Service ` -Filter "Name='$($requiredService.Name)'" | Select-Object Name, DisplayName, State, StartMode, StartName, ProcessId, ExitCode } Mögliche Auffälligkeiten: erforderlicher Dienst ist beendet, erforderlicher Dienst ist deaktiviert, Dienst hängt in StartPending , Dienst läuft unter einem falschen Konto, Dienstprozess besitzt keine PID, Exitcode ist ungleich null, benötigter Dienst wird wiederholt neu gestartet, Abhängigkeitsdefinition enthält einen nicht mehr vorhandenen Dienst. Ein laufender erforderlicher Dienst kann trotzdem funktional gestört sein. Nach dem Status müssen Listener, Protokoll und tatsächliche Funktion geprüft werden. 7. Abhängigkeiten unter Linux mit systemd anzeigen Direkte und indirekte Abhängigkeiten anzeigen: [RO] systemctl list-dependencies "" --no-pager Nur unmittelbare Abhängigkeiten anzeigen: [RO] systemctl list-dependencies \ --plain \ --no-pager \ "" Rückwärts gerichtete Abhängigkeiten anzeigen: [RO] systemctl list-dependencies \ --reverse \ --no-pager \ "" Abhängigkeiten und Reihenfolgenbeziehungen strukturiert anzeigen: [RO] systemctl show "" \ --property=Requires,Wants,Requisite,BindsTo,PartOf,After,Before,Conflicts Wirksame Unit-Konfiguration anzeigen: [RO][FILE][SENS] systemctl cat "" Status abhängiger Units prüfen: [RO] systemctl --failed --no-pager systemctl list-dependencies zeigt systemd-Units. Eine in der Anwendung konfigurierte Datenbank oder API wird nur dann sichtbar, wenn dafür ausdrücklich eine systemd-Beziehung definiert wurde. 8. systemd-Beziehungen richtig interpretieren Direktive Grundbedeutung Requires= Starke Anforderungsbeziehung zu einer anderen Unit Wants= Schwächere Anforderungsbeziehung Requisite= Andere Unit muss bereits aktiv sein; sie wird dadurch nicht automatisch gestartet BindsTo= Engere Bindung an den Aktivzustand einer anderen Unit PartOf= Bestimmte Stop- und Neustartaktionen werden weitergegeben After= Diese Unit wird nach der genannten Unit gestartet Before= Diese Unit wird vor der genannten Unit gestartet Conflicts= Units sollen nicht gleichzeitig aktiv sein OnFailure= Andere Unit wird bei einem Fehlschlag aktiviert Besonders wichtig: Requires= ist nicht dasselbe wie After= Wants= ist nicht dasselbe wie After= After= legt Reihenfolge fest, aber keine zwingende Anforderung Before= legt Reihenfolge fest, aber keine zwingende Anforderung Beispiel: [Unit] Requires=postgresql.service After=network-online.target postgresql.service Mögliche Interpretation: Der Dienst besitzt eine starke Anforderung an postgresql.service . Er soll nach postgresql.service gestartet werden. Er soll außerdem nach network-online.target gestartet werden. Das Erreichen von network-online.target beweist nicht, dass eine bestimmte entfernte Datenbank tatsächlich erreichbar ist. Für eine zuverlässige Bewertung müssen Anforderungs- und Reihenfolgedirektiven gemeinsam betrachtet werden. 9. Abhängigkeitsbaum unter systemd in beide Richtungen lesen Vorwärts gerichtete Frage: Was benötigt dieser Dienst? [RO] systemctl list-dependencies "" --no-pager Rückwärts gerichtete Frage: Welche Units benötigen diesen Dienst? [RO] systemctl list-dependencies \ --reverse \ --no-pager \ "" Nur Abhängigkeiten vor einem Neustart prüfen: [RO] systemctl show "" \ --property=RequiredBy,WantedBy,ConsistsOf,PartOf Bewertung vor einer Maßnahme: Feststellung Bedeutung Viele rückwärtige Abhängigkeiten Neustart kann mehrere Dienste beeinflussen PartOf= vorhanden Neustart- oder Stoppaktionen können gekoppelt sein BindsTo= vorhanden Ausfall kann abhängige Unit ebenfalls deaktivieren Gemeinsame Datenbankabhängigkeit Datenbankfehler kann mehrere Anwendungen betreffen Gemeinsames Netzwerkmount Speicherfehler kann mehrere Dienste blockieren Gemeinsames Target Nicht jede aufgeführte Unit ist zwingend funktional abhängig 10. Abhängigkeiten unter macOS mit launchd untersuchen launchd besitzt laut Apple kein allgemeines ausdrückliches Abhängigkeitsmodell wie systemd. Dienstinteraktionen sollen möglichst über bedarfsgesteuerte IPC-Mechanismen gelöst werden. Deshalb müssen mehrere Informationsquellen kombiniert werden. Systemweiten Dienst anzeigen: [RO] launchctl print "system/