factograf
DE
Anmelden

Hintergrundprogramm (Daemon) für Linux-Systeme

systemd

Systemd


systemd ist eine Sammlung von Programmen, Hintergrundprogrammen (Daemons) und Bibliotheken für Linux-Betriebssysteme. Ihr zentraler Bestandteil ist der systemd init-Prozess, der als erster Prozess (Prozess-ID 1) zum Starten, Überwachen und Beenden weiterer Prozesse dient. Es bietet aber auch andere Systemkomponenten an, deren Bandbreite vom Booten („systemd-boot“) bis zum Logging („journald“) reichen. Systemd wurde von Lennart Poettering, Kay Sievers (Red Hat Inc.) und anderen in C programmiert und wird als freie Software unter der GNU Lesser General Public License (LGPL) veröffentlicht.

Der Name entspricht mit dem abschließenden „d“ dem für Daemons üblichen Namensschema: systemd ist der Daemon, der das System startet und betreut.

Geschichte

Die Ideen und Konzepte zu systemd entstanden aus der Betrachtung von bereits bestehenden modernisierten init-Systemen wie launchd von macOS und SMF (Service Management Facility) von Solaris. Es wurde am 10. April 2010 veröffentlicht. Von 2011 bis 2015 sind die größten Distributionen auf systemd umgestiegen:

Die wichtigsten Distributionen, die systemd bewusst gar nicht oder nicht standardmäßig nutzen, sind:

Ab Version 221 enthält systemd sd-bus, eine unabhängige D-Bus-Programmierschnittstelle, die bei der Komplexität zwischen libdbus und GDBus angesiedelt ist. sd-bus unterstützt sowohl das klassische dbus1 im Userspace als auch kdbus als Backend und soll so den reibungslosen Übergang zur Interprozesskommunikation im Kernel ermöglichen.

In Version 260 wurde die Abwärtskompatibilität zu SysVinit-Skripten entfernt.

Technik

Abhängigkeiten zwischen allen Target-Units
Abhängigkeiten zwischen allen Target-Units

Da systemd bewusst Features benutzt, die nur unter Linux zur Verfügung stehen, nicht aber auf anderen unixoiden Betriebssystemen, kann es nur auf Systemen mit Linux-Kernel laufen.

Ziele

systemd soll in seiner Kernfunktion die gegenseitigen Abhängigkeiten von Prozessen und anderen Aspekten des Systemzustands organisieren. Dazu gehört insbesondere die verlässliche sowohl Steuerung der Systemkomponenten als auch Erkennung von deren Statusänderungen und das Auslösen von Reaktionen darauf. Ebenfalls von großer Bedeutung ist die leichte Nutzbarkeit auch komplizierter Konfigurationsmöglichkeiten (systemd hat inklusive der optionalen Systemdienste etwa 1.500 Konfigurationsdirektiven). Das flexiblere Abhängigkeitssystem kann zu stärkerer Parallelisierung beim Systemstart und somit einer kürzeren Bootzeit führen als das klassische SysVinit oder das überwiegend nur noch bei ChromeOS zum Einsatz kommende Upstart. Über die Steuerung der Systemkomponenten hinaus hat systemd einige Systemdienste neu implementiert, deren Nutzung mal mehr, mal weniger optional ist.

Units

systemd verwaltet nicht nur Dienste, sondern auch weitere wichtige Komponenten eines Linux-Systems. Diese Verwaltung erfolgt über so genannte Units, von denen es unterschiedliche Typen gibt und die als Textdateien konfiguriert werden, die an Windows-INI-Dateien angelehnt sind. Die Typen, die vom Kern von systemd verwendet werden, sind:

  • .target: Gruppierung von Units für das gemeinsame Starten (analog zu Runleveln, s. u.).
  • .mount: Einhängepunkt
  • .service: Daemonen, sowohl für das System als auch für die Benutzer
  • .timer: Die systemd-Variante von Cronjobs. Wenn eine .timer-Unit ausgelöst wird, startet sie eine Unit.
  • .device: Hardware (Sysfs-Einträge, udev)
  • .socket: Sockets (v. a. IP oder UNIX Domain Sockets)
  • .swap: Auslagerungsspeicher
  • .automount: Automounter (Einhängen von Dateisystemen erst bei Bedarf)
  • .path: Überwachung von Dateisystempfaden, überwiegend mittels inotify: Starten einer Unit, wenn die konfigurierte Veränderung eintritt.
  • .slice: hierarchische Zusammenfassung von Units zur Ressourcensteuerung (cgroups)
  • .scope: Zusammenfassung von Prozessen, die nicht von systemd erzeugt wurden, etwa der Prozessbaum eines SSH-Logins

.target-Units

Das Starten von foo.target startet Units, falls dort welche definiert sind, die noch nicht laufen; strenggenommen kann eine .target-Unit auch laufende Units beenden (Conflicts=), aber das ist unüblich. Das Stoppen von foo.target beendet normalerweise (Ausnahme: PartOf=) keine der Units, die zuvor durch diese Unit gestartet wurden oder hätten gestartet werden können. Mit systemctl isolate name.target kann nicht nur eine bestimmte, dafür (mit AllowIsolate=yes) freigeschaltete .target-Unit gestartet werden; das Kommando beendet alle Units (sofern sie nicht mit IgnoreOnIsolate=yes geschützt sind), zu denen keine direkte oder indirekte Abhängigkeit besteht, d. h., die nicht gestartet würden, wenn in die fragliche .target-Unit gebootet würde. Beispiel: Wenn in multi-user.target gebootet wurde, danach foo.target manuell gestartet wurde, was nur den Start von a.service und b.service ausgelöst hat, dann führt systemctl isolate multi-user.target dazu, dass a.service und b.service beendet werden.

Wenn man ohne systemctl isolate eine Gruppe von Units gemeinsam starten und stoppen will, dann benötigt man zwei .target-Units: eine normale (foo.target), die die Units startet, und eine zum Beenden (foo-base.target), die nichts aktiv tut, aber zu der die anderen eine BindsTo=-Abhängigkeit haben. Dann startet systemctl start foo.target die Units a.service und b.service, und systemctl stop foo-base.target beendet sie:

kombinierte .target-Units zum gemeinsamen Starten und Stoppen
Unit Wants= / Requires= BindsTo= Bemerkungen
foo.target a.service b.service foo-base.target wird manuell (oder automatisch z. B. durch Einbindung in multi-user.target) gestartet
foo-base.target wird von foo.target / a.service / b.service gestartet
a.service foo-base.target wird von foo.target gestartet
b.service foo-base.target wird von foo.target gestartet

Unit-Dateien

Die Konfiguration fast aller Parameter über die Unit-Dateien ist nicht nur deutlich einfacher, weil komplexe Sachverhalte und Kommandoaufrufe zu häufig einer einzigen Zuweisung eingedampft werden, sondern spart auch Ressourcen, weil der Aufruf externer Kommandos aus einem Script durch wenige Systemaufrufe ersetzt werden.

Units müssen nicht zwingend in Unit-Dateien erstellt werden. Für etablierte Arten, Dinge zu konfigurieren, die in systemd als Unit abgebildet werden, gibt es systemd-Unit-Generatoren (die bei jedem Laden der systemd-Konfiguration laufen und nur flüchtige Units erzeugen). Die wichtigsten sind:

  • systemd-fstab-generator: Erzeugt aus den /etc/fstab-Einträgen .mount-Units
  • systemd-cryptsetup-generator: Erzeugt instanziierte .service-Units zum Entschlüsseln von Blockgeräten, die in /etc/crypttab konfiguriert sind
  • Vor systemd 260 gab es einen Generator, der aus SysVinit-Scripten .service-Units erzeugte.

Änderungen an den Unit-Dateien, die über systemctl ausgeführt werden (z. B. edit, enable, mask), werden automatisch wirksam. Wenn Unit-Dateien erzeugt, umbenannt, verändert oder gelöscht werden oder eine Quelle eines systemd-Unit-Generators verändert wird (z. B. /etc/fstab), muss diese Änderung über systemctl daemon-reload aktiviert werden.

Drop-in-Dateien

Wenn man die von der Distribution oder dem Softwareanbieter bereitgestellte Unit ändern möchte, kann man diese ersetzen, was zu Konflikten bei Updates führen kann (wenn entweder die eigene Änderung überschrieben wird oder man wichtige Änderungen verpasst). Man kann stattdessen einzelne oder mehrere Direktiven in gesonderten Dateien setzen oder ändern. systemd fügt diese Dateien mit der Unit-Datei zusammen. Die Drop-In-Dateien für die Unit ssh.service befinden sich ggf. in ssh.service.d/*.conf. Dies kann man auch nutzen, um gemeinsame Konfigurationen aus einer Quelldatei in mehrere Units einzubinden (per Symlink).

Unit-Verzeichnisse

Für die Administration des Systems sind zwei Verzeichnise überwiegend relevant: Die Distributions-Pakete legen ihre Unit-Dateien in /usr/lib/systemd/system/ ab (Nicht-Distributions-Software sollte sie in /usr/local/lib/systemd/system/ ablegen). Das Überschreiben und Maskieren von Paket-Dateien sowie das Anlegen paketunabhängiger Units erfolgen in /etc/systemd/system/.

Änderungen, die auf die Laufzeit des Systems beschränkt sein sollen (Option --runtime für systemctl edit/enable), erfolgen in /run/systemd/system. Es gibt weitere Verzeichnisse, die von systemd-Unit-Generatoren, für via Dbus erzeugte/veränderte Units und für transiente Units (systemd-run) genutzt werden, aber mit diesen haben Administratoren kaum zu tun.

Eine gleichnamige Unit-Datei in einem Verzeichnis höherer Priorität ersetzt alle entsprechenden Dateien in anderen Verzeichnissen. Drop-In-Dateien in unterschiedlichen Verzeichnissen mit unterschiedlichen Namen werden dagegen gleichzeitig verwendet. Dies ist die Prioritätsrangfolge der Verzeichnisse (höchste zuerst):

  1. /etc/systemd/system/
  2. /run/systemd/system/
  3. /usr/local/lib/systemd/system/
  4. /usr/lib/systemd/system/

Abhängigkeiten

Start-Stopp-Abhängigkeiten und Reihenfolge

Es gibt in systemd zwei Arten von Abhängigkeiten, die auf nicht offensichtliche Weise unabhängig voneinander sind und deshalb typischerweise (um eine Startvoraussetzung zu erreichen) kombiniert werden müssen:

  • Start-Stopp-Abhängigkeiten (v. a. Wants=, Requires=, BindsTo=, Conflicts=)
  • Reihenfolge-Abhängigkeiten (After=, Before=)

Der Start einer Unit kann das Starten oder Stoppen anderer Units auslösen. Das Booten (das eine .target-Unit hat) ist diesbezüglich nicht grundsätzlich verschieden vom späteren manuellen Starten einer einzelnen Unit:

  1. Es werden rekursiv die Abhängigkeiten zwischen allen involvierten Units erfasst.
  2. Für alle zu startenden Units werden Transaktionen mit Start-Jobs erstellt.
  3. Alle wartenden Start-Jobs, für die alle Startvoraussetzungen erfüllt sind, werden gleichzeitig gestartet. Wenn der Start einer Unit fehlschlägt, werden alle Start-Jobs, für die diese Unit eine Startvoraussetzung ist, abgebrochen.

Die Abhängigkeiten einer einzelnen Unit kann man sich mit systemctl list-dependencies anzeigen lassen. Eine grafische Gesamtansicht aller Abhängigkeiten im System kann man mit systemd-analyze dot erstellen.

Um den erfolgreichen Start der Unit srv.mount zu einer Startvoraussetzung für die Unit apache2.service zu machen, benötigt apache2.service zweierlei:

  • eine zwingende Start-Stopp-Abhängigkeit (Requires=, BindsTo=), also eine, deren Fehlschlagen nicht akzeptiert wird (anders als bei Wants=)
  • eine Reihenfolge-Abhängigkeit (After=, Before=)

Ohne die Reihenfolge-Abhängigkeit würden beide Units gleichzeitig gestartet und hätte das Fehlschlagen von srv.mount (innerhalb von systemd) keine Auswirkungen auf apache2.service (außer bei BindsTo=). Wenn nur die Reihenfolge-Abhängigkeit konfiguriert ist, wird srv.mount womöglich gar nicht gestartet (es sei denn, eine andere Unit löst dies aus). Wenn die Unit zufällig doch gestartet wird, wartet systemd mit dem Start von apache2.service, bis der Start von srv.mount geglückt oder fehlgeschlagen ist, und startet dann in jedem Fall apache2.service.

Startvoraussetzung und Reihenfolge von apache2.service
- - keine Start-Stopp-Abhängigkeit Wants= Requires= BindsTo= Conflicts=
keine Reihenfolge-Abhängigkeit srv.mount läuft startet(1) startet startet startet startet(2)
srv.mount scheitert startet(1) startet startet startet, aber wird nach dem Fehlschlagen von srv.mount beendet startet(2)
After= srv.mount läuft startet(1) nach srv.mount startet nach srv.mount startet nach srv.mount startet nach srv.mount startet(2) nach dem Beenden von srv.mount
srv.mount scheitert startet(1) nach srv.mount startet nach srv.mount startet nicht startet nicht startet(2) nach dem Beenden von srv.mount
  • (1) aber srv.mount wird möglicherweise gar nicht gestartet
  • (2) und löst (ggf. vor dem eigenen Start) die Beendigung der anderen Unit aus

Bei einer Conflicts=-Beziehung ist egal, ob eine After=- oder Before=-Reihenfolge konfiguriert ist, weil Stopp-Jobs immer vor Start-Jobs ausgeführt werden. Nur wenn gar keine Reihenfolge konfiguriert ist, wartet systemd mit dem Start nicht, bis die andere Unit beendet wurde.

systemd erfasst und steuert also die Übergänge von einem Systemzustand (Gesamtheit der Zustände aller Units) zum nächsten, wogegen SysVinit nur die Start- und Stoppreihenfolge von Scripten organisiert und diese dann unabhängig von dabei auftretenden Fehlern ausführt.

Ziel-Unit beim Booten

systemd aktiviert beim normalen Booten die Unit default.target. Dies ist üblicherweise ein Symlink auf die echte .target-Unit. Abfragen und setzen kann man das Ziel von default.target mit systemctl get-default bzw. systemctl set-default.

Man kann default.target beim Booten über Parameter der Kernel-Kommandozeile überschreiben: systemd.unit=. Vorgesehene .target-Units für diesen Fall sind etwa emergency.target und rescue.target. Allerdings startet keine von beiden SSH. Wenn man eine .target-Unit mit virtuellen Konsolen und SSH, aber ohne die Dienste aus multi-user.target haben will – getty-ssh.target –, kann man diese leicht erstellen (in der Datei /etc/systemd/system/getty-ssh.target). Damit man diese Unit nicht nur beim Booten, sondern auch im laufenden Betrieb (via systemctl isolate getty-ssh.target) genutzt werden kann, ist zusätzlich die Direktive AllowIsolate=yes erforderlich:

[Unit]
Description=%n: To be called from the kernel command line: systemd.unit=getty-ssh.target
Wants=basic.target getty.target network-online.target ssh.service
AllowIsolate=yes

Wenn man keine solche Unit vorbereitet hat, kann man auch alle explizit zu startenden Units auf der Kernel-Kommandozeile angeben: systemd.unit=ssh.service systemd.wants=basic.target systemd.wants=network-online.target systemd.wants=getty.target Das Ergebnis ist dasselbe, egal, welche der Units für systemd.unit= angegeben wird.

Erkennung eines erfolgreichen Unit-Starts

Der erfolgreiche Start von .service-Units, dessen Zeitpunkt wichtig ist, weil ab dann die Startvoraussetzung für andere Units erfüllt sein kann (die man so früh wie möglich starten möchte), wird für die einzelnen Untertypen dieser Unit unterschiedlich erkannt. Die Varianten sind:

  • Type=oneshot: Die Unit ist erst aktiv, wenn sich der darin konfigurierte Prozess aktiv beendet hat; hier kontrolliert der Prozess also den Start abhängiger systemd-Units
  • Type=dbus: Die Unit ist aktiv, sobald der D-Bus-Name registriert ist.
  • Type=notify: Dies ist nur möglich, wenn die Anwendung an systemd angepasst ist. Sie meldet direkt an systemd, wann sie einsatzbereit ist.
  • alle anderen: Die Unit ist aktiv, sobald der konfigurierte Prozess gestartet wurde. Das hat die Nachteile,
    • dass der Prozess bei der Initialisierung abstürzen kann
    • dass bei Prozessen, die lange für ihre Initialisierung brauchen, später gestartete Units versuchen, auf diesen Dienst zuzugreifen, bevor er erreichbar ist

Beschleunigung durch Socket-Abhängigkeit

Für Dienste, die entsprechend an systemd angepasst sind, kann der Startvorgang beschleunigt werden, indem die .service-Unit um eine .socket-Unit ergänzt wird. Wenn dann die Startvoraussetzung für abhängende Units auf die .socket-Unit geändert wird (After= nur für die .socket-Unit, Requires= ebenso oder für beide), kann die abhängige Unit gestartet werden, sobald systemd den Socket eingerichtet hat. Spätestens wenn eine Verbindung zu dem Socket aufgebaut wird, übergibt systemd den Socket an den Dienst. Dies ähnelt der Inetd-Vorgehensweise. Die .service-Unit kann entweder gleichzeitig mit der .socket-Unit gestartet werden (was die spätere Latenz reduziert) oder erst dann, wenn eine Verbindung aufgebaut wird (wodurch der Prozess erst mal keine Ressourcen verbraucht und wichtigere Dienste früher oder schneller starten können).

Automatische Abhängigkeiten

Nicht alle Abhängigkeiten, die man mit systemctl list-dependencies a.service oder systemctl -p Conflicts show a.service sehen kann, sind in den betroffenen Units ausdrücklich konfiguriert. Es gibt zwei Arten von automatischen Abhängigkeiten, die systemd erzeugt:

  • implizite Abhängigkeiten
  • Standardabhängigkeiten
Implizite Abhängigkeiten

Implizite Abhängigkeiten sind diejenigen, ohne die eine Unit keinen Sinn ergibt (sie können deshalb auch nicht deaktiviert werden). Wenn es die Mount-Units var.mount und var-log.mount gibt, die beide gestartet werden, dann ist es für das erwartete Ergebnis zwingend erforderlich, dass var.mount vor var-log.mount gestartet wird (und var-log.mount nur nach einem erfolgreichen Start von var.mount gestartet wird). Die impliziten Abhängigkeiten unterscheiden sich von einem Unit-Typ zum anderen.

Standardabhängigkeiten

Standardabhängigkeiten müssen nicht explizit vorgenommen werden, weil sie im allgemeinen sinnvoll sind; sie können aber deaktiviert werden (mit DefaultDependencies=no). Auch Standardabhängigkeiten unterscheiden sich von einem Unit-Typ zum anderen. Beispiele:

  • .target-Units
    • Wenn in der .target-Unit eine Abhängigkeit konfiguriert ist (mit Wants= oder Requires=), dann wird After= automatisch ergänzt: Die .target-Unit wird also erst als gestartet betrachtet, wenn alle von ihr gestarteten Units ihren Startvorgang beendet haben (ob erfolgreich oder nicht). Umgekehrt (Wants=a.target in a.service) passiert dies nicht; man muss also After= oder Before= in die .target-Unit oder in die .service-Unit aufnehmen.
  • .service-Units
    • Requires=sysinit.target
    • After=sysinit.target
    • After=basic.target
    • Conflicts=shutdown.target
    • Before=shutdown.target

Visualisierung der Abhängigkeiten

Mit systemd-analyze dot kann man sich eine Textausgabe erstellen lassen, die die Abhängigkeiten beschreibt und aus der mit dem Programm dot eine Grafik erzeugt werden kann.

$ systemd-analyze dot --from-pattern='sshd.service' --to-pattern='sysinit.target'
digraph systemd {
        "sshd.service"->"sysinit.target" [color="green"];
        "sshd.service"->"sysinit.target" [color="black"];
}
   Color legend: black     = Requires
                 dark blue = Requisite
                 gold      = BindsTo
                 dark grey = Wants
                 red       = Conflicts
                 green     = After
-- You probably want to process this output with graphviz' dot tool.
-- Try a shell pipeline like 'systemd-analyze dot | dot -Tsvg > systemd.svg'!

Mit systemd-analyze dot --from-pattern='*.target' --to-pattern='*.target' kann man sich die Abhängigkeiten zwischen allen .target-Units anzeigen lassen.

Komponenten

Dienste

systemd besteht aus der oben beschriebenen init-Kernfunktion und einigen optionalen Komponenten. Einige davon werden allerdings auf quasi allen systemd-Systemen verwendet.

Grad der Verwendung der systemd-Komponenten (Dienste)
Komponente Bestandteile der Komponente
systemd-Kernfunktionen init / PID 1 systemctl; Erzeugung und Konfiguration der Linux-Objekte, denen die Units entsprechen; Erfassung und Änderung von deren Zustand
fast überall genutzte Komponenten systemd-journald journalctl; Logging der Kernel- und systemd-Meldungen und der Ausgabe (stdout, stderr) von .service-Units
systemd-logind Sitzungs- und Seat-Verwaltung (Hardwarezugriff); Herunterfahren und Ruhezustand via Hardware- oder Software-Auslöser
systemd-udevd udevadm (nicht systemd-spezifisch); udevd wurde ins systemd-Projekt übertragen; Units können über udev-Regeln gestartet werden
auch praktisch optionale Komponenten systemd-machined machinectl; Erfassung laufender VMs und Container; Integration in ps: ps -eo pid,machine,cmd
systemd-networkd networkctl; .link-, .netdev- und .network-Dateien
systemd-resolved resolvectl; DNS mit Erweiterungen
systemd-timesyncd NTP-Client
systemd-homed homectl; pam_systemd_home; Handhabung von portablen, potentiell verschlüsselten Homeverzeichnissen mit signierten User-Informationen
systemd-hostnamed hostnamectl; Änderung diverser Varianten des Hostnamens via D-Bus und Polkit
systemd-importd importctl; Import, Export und Download von VM und Container-Images
systemd-localed localectl; Einstellungen der System-Locale und der Tastaturbelegung
systemd-nsresourced transiente Zuweisung eines UID-GID-Bereichs für einen User-Namensraum
systemd-oomd oomctl; Beenden entsprechend konfigurierter Units, wenn RAM knapp wird, um dem weniger flexiblem OOM-Killer des Kernels zuvorzukommen
systemd-portabled portablectl; Systemdienst zum Anhängen, Abhängen und Untersuchen von portablen Dienste-Abbildern
systemd-socket-proxyd bidirektionaler Proxy zwischen lokalen Sockets und anderen (möglicherweise nichtlokalen) Sockets
systemd-timedated timedatectl; Konfiguration von Uhrzeit und Zeitzone
systemd-userdbd userdbctl; nss-systemd; flexiblere Bereitstellung von User- und Gruppendaten im JSON-Format aus mehreren Quellen, aber auch via nsswitch

Werkzeuge

Neben den systemd-Daemonen gibt es eine Vielzahl an systemd-Werkzeugen, teils für systemd(-Dienste) selber, teils als Alternative für Werkzeuge, die mit systemd nichts zu tun haben. Einige dieser Werkzeuge dienen der leichteren Einrichtung von Systemen von einem Image. Dafür kann systemd auch SMBIOS Type 11 vendor strings vom Hypervisor übernehmen.

systemd-Werkzeuge (keine Dienste)
Kommando Funktion
Werkzeuge für systemd systemd-analyze u. a.: Auswertung des Bootvorgangs (Zeiten); Prüfung der Konsistenz der Abhängigkeiten
systemd-cat Weiterleitung der Ausgabe eines Kommandos an das systemd-Journal
systemd-cgls Anzeige der cgroups: .slice-, .scope- und .service-Units mit den enthaltenen Prozessen
systemd-cgtop Anzeige der Ressourcen (RAM, CPU- und I/O-Last) für die einzelnen Units
systemd-creds Verwaltung von Service-Zugangsdaten
systemd-delta Anzeige der Unit-Änderungen über Pfadhierarchien und Drop-In-Dateien
systemd-escape (Un)Escape für Pfade und Unit-Namen, v.a Bindestriche in Instanznamen: /dev/mapper/foo-bar → dev-mapper-foo\x2dbar
systemd-inhibit Handhabung von Anforderungen, das System neu zu starten, herunterzufahren oder in den Ruhezustand zu versetzen und der Hardware, die sie auslöst (z. B. Power-Knopf, Laptop zuklappen)
systemd-notify Übermittlung von Zustandsinformationen eines Dienstes an den Service-Manager, insbesondere zur Überführung einer .service-Unit in den Zustand aktiv.
systemd-nspawn Starten eines Containers
systemd-path Anzeige der von systemd verwendeten Pfade
systemd-run Ausführung von transienten Kommandos via systemd (mit quasi beliebigen Unit-Direktiven inklusive der Startzeit)
systemd-vmspawn Starten einer virtuellen Maschine
verbreitet genutzte Werkzeuge systemd-tmpfiles Anlegen, Metadatenanpassung und Löschung von Dateien und Verzeichnissen
systemd-sysusers Anlegen von Usern und Gruppen
systemd-modules-load Laden von Kernelmodulen aus /etc/modules-load.d
systemd-sysctl Setzen der Laufzeit-Kernelkonfiguration aus /etc/sysctl.d
systemd-cryptsetup Einrichtung und Aufhebung verschlüsselter Blockgeräte
systemd-ask-password Client-Interface für TTY-Passwortabfragen
systemd-tty-ask-password-agent System-Interface für TTY-Passwortabfragen
systemd-ac-power Erkennung des Stromversorgungszustands
systemd-binfmt Registrierung von Formaten ausführbarer Dateien (für transparente Ausführung via QEMU)
systemd-cryptenroll Nutzung von Krypto-Hardware (TPM oder externe Hardware) für LUKS-Verschlüsselung
systemd-detect-virt Erkennung virtualisierter Umgebungen
systemd-hwdb Verwaltung der Hardware-Datenbank
systemd-integritysetup Einrichtung von Blockgeräten mit dm-integrity-Integritätssicherung
systemd-veritysetup Einrichtung von Blockgeräten mit dm-verity-Integritätssicherung
Werkzeuge zur initialen Einrichtung eines Systems systemd-firstboot Initialisierung / Zurücksetzen diverser Systemparameter
systemd-growfs Vergrößern eines Dateisystems
systemd-machine-id-setup Generierung der ID in /etc/machine-id
systemd-makefs Formatierung
systemd-mkswap Einrichtung von Auslagerungsspeicher
systemd-repart Partitionierung
nicht allgemein genutzte Werkzeuge bootctl Installation und Verwaltung von systemd-boot und EFI-Boot-Konfiguration
busctl Abfrage von D-Bus
kernel-install Installation von Kernel-Images und initramfs-Dateien
run0 sudo-Alternative mit polkit-Authentifizierung
systemd-bless-boot markiert den aktuellen Bootvorgang als erfolgreich
systemd-boot EFI-Bootmanager
systemd-bsod Systemstart-Notfallprotokollmeldungen im Vollbild darstellen
systemd-confext (de)aktiviert (insbesondere unveränderbare) Systemerweiterungsabbilder (/etc)
systemd-dissect Handhabung von Dateisystem-Betriebssystemabbildern, insbesondere DDIs
systemd-export Export von Container-Abbildern
systemd-id128 Erzeugt sd-id128-UUIDs oder zeigt die des Systems an
systemd-import Import von Container-Abbildern
systemd-import-fs importiert einen Verzeichnisbaum in den Speicher von systemd-machined
systemd-keyutil Aktionen auf privaten Schlüsseln und X.509-Zertifikaten
systemd-pull Download von VM-/Container-Abbildern
systemd-sbsign erzeugt Signaturen für EFI Secure Boot
systemd-socket-activate Test-Socket-Aktivierung von Daemons
systemd-ssh-proxy SSH-Verbindung über lokale Sockets (ohne IP)
systemd-stdio-bridge Proxy zwischen STDIN/STDOUT und D-Bus
systemd-storagetm lokale Blockgeräte als NVMe-TCP-Massenspeichergeräte offenlegen
systemd-sysext (de)aktiviert (insbesondere unveränderbare) Systemerweiterungsabbilder (/usr & /opt)
systemd-vpick Auswahl einer passenden Version aus versionierten.v/-Verzeichnissen
ukify Erzeugung von Unified Kernel Images (UKIs)
varlinkctl Abfrage von Varlink-Diensten

Kritik

Systemd polarisierte die Community in der Anfangszeit stark. Es kam zu Flame-Wars und Shitstorms seitens der Befürworter und Gegner, die zum Teil jedoch auch gegen die Person der Entwickler selbst, insbesondere Poettering und Sievers, gerichtet waren. Die Diskussion, ob man in Debian weiter SysVinit verwenden oder auf systemd oder aber ein anderes Init-System umsteigen sollte, führte zu monatelangen Streitereien und schließlich zu einer Abstimmung („General Resolution“), zahlreichen Rücktritten und einem Fork unter dem Namen Devuan, der gänzlich ohne systemd auskommt.

Der Hauptkritikpunkt an systemd liegt in seinem Anspruch, deutlich mehr verschiedene Aufgaben als das alte SysVinit erledigen zu wollen, was es recht kompliziert und fehleranfällig mache und überdies die Unix-Philosophie verletze (Ein Programm soll nur ein Problem lösen, dieses aber möglichst gut). Viele Entwickler äußerten die Sorge, systemd schränke durch zu starke Festlegungen der Systemumgebung Freiheit und Flexibilität ein. Vielfach wurde bemängelt, dass systemd Log-Dateien im Binärformat und nicht als einfache Textdateien speichert. Ein weiterer Kritikpunkt besteht in der Entscheidung, systemd explizit nur für Linux zu entwickeln. Wiederholt wurde kritisiert, die Entwickler würden dazu neigen, Programmierfehler zu ignorieren oder zu bestreiten. Die Devuan-Entwickler äußerten die Befürchtung, Debian und die anderen Großdistributionen seien nun von Red Hat in einem „Vendor-Lock-in“ gefangen.

Theodore Ts’o kritisierte die zu starke Ausrichtung auf die Gnome-Desktop-Umgebung; es bestehe die Gefahr, dass viele Systemkomponenten mit anderen Desktops nicht mehr funktionieren würden. Dies könne langfristig zur völligen Unbenutzbarkeit anderer Desktops führen, wenn es keine Alternative zu systemd mehr gebe. Die Devuan-Entwickler spekulierten darüber, dass es langfristig zu einer Übernahme von Debian durch das Gnome-Projekt kommen könne. Linus Torvalds gab an, er habe keine feste Meinung zu systemd; einige Eigenschaften wie binäre Logs seien irrsinnig, aber das seien Detailfragen und keine grundsätzlichen Probleme. Die systemd-Entwickler hätten generell eine zu großzügige Haltung gegenüber Programmfehlern und Kompatibilitätsproblemen. InfoWorld berichtete, systemd-Entwickler hätten Programmierfehler ignoriert und Bugreports geschlossen, ohne die Fehler zu beheben, was dazu geführt habe, dass Torvalds mit Kay Sievers einen der führenden systemd-Entwickler von der Kernel-Entwicklung ausgeschlossen habe. In der Gesamtschau sei durch systemd eine Spaltung der Linux-Community eingetreten, die Linux langfristig schaden werde. Mark Shuttleworth bezeichnete systemd im Oktober 2013 als „höchst invasiv und kaum gerechtfertigt“, um dann doch nur wenige Monate später als „freundlicher Verlierer“ die Unterstützung Ubuntus für systemd bekanntzugeben. Ende Oktober 2015 berichtete Slashdot, BusyBox-Entwickler Denys Vlasenko habe die systemd-Unterstützung aus BusyBox entfernt. Vlasenko erklärte, die für systemd Verantwortlichen seien unfreundlich zum Rest der Welt, somit gebe es für den Rest der Welt keinen Anlass, mit ihnen zu kooperieren. Linus Torvalds äußerte im Juli 2017 auf der Linux-Kernel-Mailingliste „LKML.org“, er könne nicht mehr darauf vertrauen, dass „init“ das Richtige tue.

Einbindung von Google-Diensten in den Code

Im September 2014 wurde bekannt, dass eine Komponente des systemd in bestimmten Fällen DNS-Anfragen an die Google-Nameserver weiterleitet, ohne dass der Administrator dies eingestellt hat, was zu Diskussionen um die Vertraulichkeit, Sicherheit und Integrität von Nutzerdaten führte. Der zuständige Debian-Maintainer wies die Kritik zurück. Dieser Sachverhalt wurde im Juli 2015 erneut festgestellt. Poettering verteidigte diese Einstellung mit der Begründung, er wolle ein funktionsfähiges System sicherstellen.

Ebenfalls im Juli 2015 wurde auf GitHub moniert, dass Google-Zeitserver als default bzw. fallback fest in den Code des systemd eingebunden sind. Auch diese Entscheidung wurde von Poettering verteidigt, obwohl er einräumte, dass die Google-Server ungenaue Daten lieferten. Ein Google-Entwickler kritisierte diese Einstellung.

Sicherheitslücken

Im September 2016 wurde ein Bug bekannt, der jedem unprivilegierten Benutzer eine DoS-Attacke auf systemd und die damit verbundenen Prozesse ermöglicht. Der Musl-Entwickler Rich Felker sagte dazu, systemd sei ein großer monolithischer Prozess, der bei einem Fehler nicht teilweise ausfalle, sondern das ganze System zum Absturz bringe. Der entdeckte Bug sei weniger ein ernstes Sicherheitsproblem, sondern zeige vielmehr einen grundlegenden Designfehler auf.

Anfang 2017 entwickelte sich eine Diskussion darüber, dass systemd Daemons mit Root-Rechten ausführt, wenn in der Konfiguration des Daemons ein mit einer Ziffer beginnender Benutzername angegeben ist. Die Sicherheitslücke wurde unterschiedlich bewertet. Seitens der Entwickler wurde erklärt, es handele sich um keinen Programmierfehler, denn derartige Benutzernamen seien auf Linux-Systemen unzulässig und es läge in der Verantwortung des Administrators, sie nicht zuzulassen. Darüber hinaus müsse ein Angreifer auf dem betroffenen System bereits Root-Rechte besitzen, um derartige Benutzernamen anlegen zu können. Der Bugreport wurde zunächst geschlossen. Später wurde ein Patch eingebaut, der bewirkt, dass fehlerhafte Parameter bei sicherheitskritischen Optionen nicht mehr ignoriert werden, sondern dazu führen, dass der Prozess nicht geladen wird.

Im Juni 2017 wurde eine seit 2015 bestehende Verwundbarkeit in systemd-resolved entdeckt. Diese erlaubt es, systemd durch einen kompromittierten DNS-Server zur Ausführung von Schadprogrammen zu veranlassen, wodurch der Dienst zum Absturz gebracht oder durch externe Angreifer übernommen werden könne. Über die Sicherheitslücke wurde zuerst von Canonical-Mitarbeiter Chris Coulson berichtet. Demnach sind seit 2015 die Versionsnummern 223 bis 233 betroffen. Red Hat teilte mit, das von ihnen vertriebene Red Hat Enterprise Linux 7 sei nicht verwundbar. Debian erklärte, das kürzlich erschienene Debian 9 (Codename „Stretch“) sei ebenfalls nicht betroffen, da systemd-resolved standardmäßig nicht aktiviert sei. Ein Patch schloss die Sicherheitslücke in den betroffenen Versionen.

Im Oktober 2018 wurde bekannt, dass ein Programmierfehler im IPv6-DHCP-Client von systemd dazu missbraucht werden kann, verwundbare Linux-Systeme mit manipulierten DHCP-Paketen zu übernehmen.

Das US-amerikanische IT-Sicherheitsunternehmen Qualys berichtete im Januar 2019 über einen Fehler in der systemd-Komponente journald, der es Benutzern erlaube, auf einem System root-Rechte zu erlangen. Dies gelang auf einem x86-System innerhalb von zehn, auf einem amd64-System innerhalb von 70 Minuten.

Weiterlesen

In 27 Sprachen

Text aus der Wikipedia, CC BY-SA 4.0 · Quellartikel