
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.service
sind systemd-journal.service
Sitzungsleiter (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 TTYPath
und 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_NOCTTY
Flag 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-manager
verfolgt 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 setsid
explizit 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-tty
agetty@*
agetty
getty@*
mgetty
setsid()
Weiterführende Literatur
- Jonathan de Boyne Pollard (2018).
setsid
.nosh-Anleitung. Software. - Jonathan de Boyne Pollard (2018).
open-controlling-tty
.nosh-Anleitung. Software. - Jonathan de Boyne Pollard (2015). "Vererbung und der Dämonisierungsirrtum
".Keine Probleme mehr mit dem
service
Befehl. Nosh-Klappentext. Software. - Jonathan de Boyne Pollard (2001).Tun Sie dies nicht,
fork()
um den Dæmon in den Hintergrund zu drängen.".Zu vermeidende Fehler beim Entwurf von Unix-Dämon-Programmen. Häufig gestellte Fragen. - „Jonathan de Boyne Pollard.Anmeldung am virtuellen Terminal".nosh-Anleitung. Software.
- „Jonathan de Boyne Pollard.Echte Terminalanmeldung".nosh-Anleitung. Software.
- http://git.musl-libc.org/cgit/musl/tree/src/stdio/__fmodeflags.c
- https://github.com/lattera/glibc/blob/a2f34833b1042d5d8eeb263b4cf4caaea138c4ad/libio/fileops.c#L274
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_NOCTTY
Flag 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 cat
Vorgang stoppt.