Otras lecturas

Otras lecturas

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.servicey systemd-journal.serviceson 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 TTYPathy 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_NOCTTYbandera 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_NOCTTYen 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-manageradopta 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 setsidexplí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-ttyagetty@*agettygetty@*mgettysetsid()

Otras lecturas

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_NOCTTYbandera.

$ 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 catproceso.

información relacionada