
man 7 daemon
Cuando se inicia un demonio SysV tradicional, debe ejecutar los siguientes pasos como parte de la inicialización. Tenga en cuenta que estos pasos son innecesarios para demonios de nuevo estilo (ver más abajo) y solo deben implementarse si la compatibilidad con SysV es esencial.
[...]
6. En el niño, llame a setsid() para desconectarse de cualquier terminal y crear una sesión independiente.
7. En el niño, llame a fork() nuevamente,para garantizar que el demonio nunca pueda volver a adquirir una terminal.
pero compare esto con procesos iniciados sin vestigios de compatibilidad con SysV:
$ 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
Los procesos para ambos rsyslog.service
y systemd-journal.service
son líderes de sesión (SID = PID).
Parece que si dichos programas estuvieran configurados para iniciar sesión en un TTY, obtendrían el TTY como terminal de control y recibirían una señal no deseada/fatal cuando el TTY se cuelga/recibe Ctrl+C, respectivamente. A menos que recuerden configurar O_NOCTTY al abrir el archivo TTY.
Parece que esto es un pequeño inconveniente al escribir o convertir un programa para que se ejecute como un servicio systemd sin compatibilidad con SysV, si su programa admite la escritura de mensajes en archivos personalizados. No parece señalarlo este documento que defiende el estilo systemd. El documento más bien implica lo contrario, al insistir en que es necesario realizar una doble bifurcación para evitar esto en SysV, y luego no mencionar esto como un problema al describir los pasos que usaría un servicio systemd nativo.
¿Es eso correcto? ¿Systemd proporciona alguna protección contra esto que he pasado por alto o el problema se señala en otra parte del documento de systemd?
Respuesta1
¿Systemd proporciona alguna protección contra esto […]?
Estás asumiendo que debería ser así. Por el contrario, considere configuraciones TTYPath
y servicios como [email protected]
. La capacidad de obtener una terminal de control es en realidadnecesario, para que la gestión de servicios pueda abarcar servicios de inicio de sesión TTY, que deben hacer precisamente eso.
Lo que realmente protege contra esto es alejarse de la asignación automática de una terminal de control en open()
y descartar la antigua semántica. Oharíaprotegerse contra ello. No es el caso en Linux, pero en FreeBSD, NetBSD, OpenBSD y Hurd hoy en día la O_NOCTTY
bandera open()
es completamente superflua. ElsoloLa forma de adquirir un terminal de control es exigiéndolo explícitamente, con ioctl(…TIOSCTTY)
. En realidad, este ha sido el caso durante casi un cuarto de siglo, desde los días de 4.4BSD.
Mientras tanto, el hábito de adquirir Linux es el hábito que también existe desde hace mucho tiempo, mucho antes de systemd:O_NOCTTY
en todos lados. ☺
(Sí, las bibliotecas GNU y musl C no le brindan esto fopen()
. Esta es una de varias razones por las que fdopen()
sigue siendo un mecanismo útil).
La gestión de servicios con el conjunto de herramientas Nosh service-manager
adopta un enfoque ligeramente diferente al respecto. En lugar de convertir siempre los procesos demonio en líderes de sesión, a cada servicio se le asigna su propio objeto de sesión del núcleo que luego no ve ningún uso, solo servicios específicos también se encadenan setsid
explícitamente; tales como servicios que utilizan , servicios donde, por supuesto, se configura el terminal de control y servicios. (Como se indica en la fuente del servicio, se llama a sí mismo).ttylogin@*
open-controlling-tty
agetty@*
agetty
getty@*
mgetty
setsid()
Otras lecturas
- Jonathan de Boyne Pollard (2018).
setsid
.Guía de comida. Softwares. - Jonathan de Boyne Pollard (2018).
open-controlling-tty
.Guía de comida. Softwares. - Jonathan de Boyne Pollard (2015). "La herencia y la falacia de la demonización
".No más problemas con el
service
comando.. propaganda de comida. Softwares. - Jonathan de Boyne Pollard (2001). "No
fork()
para "poner al demonio en un segundo plano".".Errores a evitar al diseñar programas demonio Unix. Respuestas dadas con frecuencia. - Jonathan de Boyne Pollard. "Inicio de sesión en terminal virtual".Guía de comida. Softwares.
- Jonathan de Boyne Pollard. "Inicio de sesión en terminal real".Guía de comida. Softwares.
- http://git.musl-libc.org/cgit/musl/tree/src/stdio/__fmodeflags.c
- https://github.com/lattera/glibc/blob/a2f34833b1042d5d8eeb263b4cf4caaea138c4ad/libio/fileops.c#L274
Respuesta2
systemd no protege los programas de servicio contra la adquisición de una terminal de control. Tienen que protegerse al abrir archivos de registro especificados por el usuario mediante el uso de la O_NOCTTY
bandera.
$ 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
También confirmé que cambiar a tty10 y presionar Ctrl+C detiene el cat
proceso.