Descripción de la condición
Me encontré con una condición extraña con systemd y ssh en Ubuntu 18.04.3 LTS
Verifiqué el estado de la ssh.socket
unidad:
$ systemctl status ssh.socket
● ssh.socket - OpenBSD Secure Shell server socket
Loaded: loaded (/lib/systemd/system/ssh.socket; disabled; vendor preset: enabled)
Active: inactive (dead)
Listen: [::]:22 (Stream)
Accepted: 0; Connected: 0
Y estaba inactivo, sin embargo, inicié sesión con ssh al mismo tiempo y el servicio en sí se estaba ejecutando, y el socket de SSH y el puerto correspondiente estaban abiertos:
$ lsof -P -i -n | grep sshd
sshd 26785 root 3u IPv4 14858764 0t0 TCP 10.200.130.28:22->10.100.40.141:42188 (ESTABLISHED)
sshd 26875 xxx_root 3u IPv4 14858764 0t0 TCP 10.200.130.28:22->10.100.40.141:42188 (ESTABLISHED)
sshd 63859 root 3u IPv4 238437 0t0 TCP *:22 (LISTEN)
sshd 63859 root 4u IPv6 238439 0t0 TCP *:22 (LISTEN)
Entonces miré el archivo unitario de ssh.socket en /lib/systemd/system/ssh.socket
:
[Unit]
Description=OpenBSD Secure Shell server socket
Before=ssh.service
Conflicts=ssh.service
ConditionPathExists=!/etc/ssh/sshd_not_to_be_run
[Socket]
ListenStream=22
Accept=yes
[Install]
WantedBy=sockets.target
Debido a la Before=ssh.service
directiva, debe iniciarse antes que el servicio ssh y la Conflicts=ssh.service
directiva hará que se detenga cuando se inicie el servicio ssh.
Lo que explica por qué sucede en el aspecto de los archivos unitarios, pero plantea otras preguntas.
Preguntas
¿Por qué el estado inactivo de la unidad ssh.socket no tiene ningún efecto en el socket ssh real?
¿Por qué los mantenedores agregaron la Conflict
directiva? Por ejemplo, si verifica que el archivo de unidad docker.socket
no esté configurado para entrar en conflicto con el archivo docker.service
. ¿En qué se diferencia el caso de sshd?
información adicional
También verifiqué esto en una vieja estación de trabajo Fedora 30. Tiene la misma condición, con pequeñas diferencias: usa sshd.service
y sshd.socket
como nombres de unidad y no hay ninguna Before
directiva en el sshd.socket
archivo de unidad.
En ambos sistemas no he notado ningún problema resultante de esta condición y sospecho que tiene algún propósito, pero no puedo encontrarlo.
Respuesta1
Un socket systemd es un tipo especial de unidad que hace que systemd se vincule al puerto (u otro recurso, como la ruta de un archivo de socket de dominio Unix) y genere una nueva instancia de un servicio para cualquier conexión. Con ssh.service habilitado, es sshd el que se ejecuta continuamente y se vincula al socket, como muestra su lsof. Tener ssh.socket activado en su lugar significaría que sshd no se ejecuta continuamente, sino que se invoca una instancia solo para manejar un cliente. Y, por el contrario, mostraría que systemd escucha en el puerto 22. Debido a que systemd y sshd no pueden escuchar ambos en el mismo puerto, ssh.socket especifica ssh.service como conflictivo.
Respuesta2
Lo importante que debes entender es que lo que estás viendo es un uso específico de las unidades de "zócalo", en total, haytres:http://0pointer.de/blog/projects/inetd.html
Entonces, en el caso específico de ssh.socket
, este es el equivalente al estilo antiguo.invocación tipo inetd(configuración de la unidad de socket central:) Accept=yes
, donde cada solicitud entrante en el puerto 22 (administrado por systemd) provoca el inicio de una[email protected]
instancia.
Consulte también la página de manual de systemd.socket:https://www.freedesktop.org/software/systemd/man/systemd.socket.html
Si se establece Aceptar=yes, una plantilla de servicio[correo electrónico protegido]debe existir a partir del cual se crean instancias de servicios para cada conexión entrante
Entonces, hay en total dos formas diferentes de iniciar sshd:
ssh.service
(sshd.service
es solo un alias) inicia el proceso sshd principal y de ahí en adelante el proceso maneja todas las conexiones entrantes, genera procesos secundarios, etc., etc.ssh.socket
+[email protected]
, aquí systemd conecta cada conexión entrante desde el puerto administrado por socket a una nueva instancia de[correo electrónico protegido], estilo inetd. Es por esto que en el servicio de plantillas,StandardInput=socket
yExecStart=/usr/sbin/sshd
tiene la-i
opción.
Obviamente, sólo se puede utilizar un enfoque a la vez, por lo que Conflicts=
se garantiza que ambos no se ejecuten simultáneamente. (Por cierto: la ubicación real de la Conflicts=
estrofa no es importante, se podría haber escrito una estrofa equivalente en ssh.service, pero una es suficiente)