Weiterführende Literatur

Weiterführende Literatur

man 7 daemon

Wenn ein herkömmlicher SysV-Daemon gestartet wird, sollte er im Rahmen der Initialisierung die folgenden Schritte ausführen. Beachten Sie, dass diese Schritte für Daemons neuen Stils (siehe unten) nicht erforderlich sind und nur ausgeführt werden sollten, wenn die Kompatibilität mit SysV unbedingt erforderlich ist.

[...]

6. Rufen Sie im untergeordneten Element setsid() auf, um die Verbindung zu allen Terminals zu trennen und eine unabhängige Sitzung zu erstellen.

7. Rufen Sie im Kind erneut fork() auf.um sicherzustellen, dass der Daemon nie wieder ein Terminal abrufen kann.

Aber vergleichen Sie dies mit Prozessen, die ohne jegliche SysV-Kompatibilität gestartet wurden:

$ ps -efj
UID        PID  PPID  PGID   SID  C STIME TTY          TIME CMD
root         1     0     1     1  0 May10 ?        00:06:44 /sbin/init
...
root       185     1   185   185  0 May10 ?        00:09:48 /lib/systemd/systemd-journald
root     16434     1 16434 16434  0 May26 ?        00:00:11 /usr/sbin/rsyslogd -n

Die Prozesse für beide rsyslog.servicesind systemd-journal.serviceSitzungsleiter (SID = PID).

Es scheint, dass solche Programme, wenn sie so konfiguriert sind, dass sie sich bei einem TTY anmelden, das TTY als Steuerterminal erhalten und ein unerwünschtes/schwerwiegendes Signal erhalten, wenn das TTY aufgelegt wird bzw. Strg+C empfängt. Es sei denn, sie denken daran, beim Öffnen der TTY-Datei O_NOCTTY festzulegen.

Dies scheint eine kleine Falle zu sein, wenn Sie ein Programm schreiben oder konvertieren, das als systemd-Dienst ohne SysV-Kompatibilität ausgeführt werden soll, wenn Ihr Programm das Schreiben von Nachrichten in benutzerdefinierte Dateien unterstützt. In diesem Dokument, das den systemd-Stil befürwortet, wird dies anscheinend nicht erwähnt. Das Dokument impliziert eher das Gegenteil, indem es darauf besteht, dass Double-Fork erforderlich ist, um dies auf SysV zu vermeiden, und dies dann bei der Beschreibung der Schritte, die ein nativer systemd-Dienst verwenden würde, nicht als Problem erwähnt wird.

Ist das richtig? Bietet systemd einen Schutz dagegen, den ich übersehen habe, oder wird das Problem an anderer Stelle im systemd-Dokument erwähnt?

Antwort1

Bietet systemd einen gewissen Schutz dagegen […]?

Sie gehen davon aus, dass dies der Fall ist. Im Gegenteil, betrachten Sie Einstellungen wie TTYPathund Dienste wie [email protected]. Die Möglichkeit, ein Kontrollterminal zu erhalten, ist tatsächlichnotwendig, damit die Dienstverwaltung TTY-Anmeldedienste umfassen kann, die genau das tun müssen.

Was tatsächlich davor schützt, ist die Abkehr von der automatischen Zuweisung eines Steuerterminals bei open()und die Abschaffung der alten Semantik. Oderwürdedagegen schützen. Dies ist unter Linux nicht der Fall, aber unter FreeBSD, NetBSD, OpenBSD und Hurd ist das O_NOCTTYFlag heutzutage open()völlig überflüssig. DasnurMöglichkeit, ein Steuerterminal zu erhalten, besteht darin, es explizit anzufordern, mit ioctl(…TIOSCTTY). Dies ist tatsächlich seit fast einem Vierteljahrhundert der Fall, seit den Tagen von 4.4BSD.

In der Zwischenzeit sollte man sich unter Linux die Gewohnheit aneignen, die es schon lange gab, lange vor systemd:O_NOCTTYüberall. ☺

(Ja, die GNU- und musl-C-Bibliotheken bieten Ihnen dies nicht an fopen(). Dies ist einer von mehreren Gründen, warum es fdopen()dennoch ein nützlicher Mechanismus ist.)

Die Dienstverwaltung mit dem Nosh-Toolset service-managerverfolgt diesbezüglich einen etwas anderen Ansatz. Anstatt Dæmon-Prozesse immer zu Sitzungsleitern zu machen und jedem Dienst sein eigenes Kernel-Sitzungsobjekt zuzuweisen, das dann nicht verwendet wird, werden nur bestimmte Dienste setsidexplizit durchgekettet; beispielsweise Dienste, die verwenden , Dienste, bei denen natürlich das steuernde Terminal festgelegt wird, und Dienste. (Wie in der Dienstquelle vermerkt, ruft sich selbst auf.)ttylogin@*open-controlling-ttyagetty@*agettygetty@*mgettysetsid()

Weiterführende Literatur

Antwort2

systemd schützt Serviceprogramme nicht vor dem Zugriff auf ein steuerndes Terminal. Sie müssen sich selbst schützen, wenn sie benutzerdefinierte Protokolldateien öffnen, indem sie das O_NOCTTYFlag verwenden.

$ rpm -q systemd
systemd-238-8.git0e0aa59.fc28.x86_64

$ systemctl cat test
# /etc/systemd/system/test.service
[Service]
Type=simple
ExecStart=/bin/sh -c "exec cat </dev/tty10 >/dev/tty10"

$ systemctl status test
● test.service
   Loaded: loaded (/etc/systemd/system/test.service; static; vendor preset: disabled)
   Active: active (running) since Fri 2018-06-01 11:28:41 BST; 1min 35s ago
 Main PID: 12173 (cat)
    Tasks: 1 (limit: 4915)
   Memory: 180.0K
   CGroup: /system.slice/test.service
           └─12173 cat

Jun 01 11:28:41 alan-laptop systemd[1]: Started test.service.

$ ps -ejf
UID        PID  PPID  PGID   SID  C STIME TTY          TIME CMD
...
root     12173     1 12173 12173  0 11:28 tty10    00:00:00 cat

Ich habe auch bestätigt, dass das Umschalten auf tty10 und das Drücken von Strg+C den catVorgang stoppt.

verwandte Informationen