falta de coincidencia del protocolo de preparación
Como Wieland implicó, Type
la prestación del servicio es importante. Esa configuración indica qué protocolo de preparación systemd espera que el servicio hable. Se simple
supone que un servicio está listo de inmediato. Se considera forking
que un servicio está listo después de que su proceso inicial bifurca a un niño y luego se cierra. Se considera dbus
que un servicio está listo cuando aparece un servidor en el Bus de escritorio. Etcétera.
Si no logra que el protocolo de preparación declarado en la unidad de servicio coincida con lo que hace el servicio, entonces las cosas salen mal. Los desajustes del protocolo de preparación hacen que los servicios no se inicien correctamente o (más comúnmente) sean diagnosticados (erróneamente) por systemd como fallidos. Cuando se considera que un servicio no puede iniciar systemd, se garantiza que todos los procesos adicionales huérfanos del servicio que podrían haberse dejado como parte de la falla (desde su punto de vista) se eliminan para que el servicio vuelva correctamente al estado inactivo. estado.
Estás haciendo exactamente esto.
En primer lugar, las cosas simples: sh -c
no coincide Type=simple
o Type=forking
.
En el simple
protocolo, el proceso inicial se toma para ser el proceso de servicio. Pero, de hecho, un sh -c
contenedor ejecuta el programa de servicio real como un proceso secundario . Entonces MAINPID
sale mal y ExecReload
deja de funcionar, para empezar. Cuando se usa Type=simple
, uno debe usar sh -c 'exec …'
o no usar sh -c
en primer lugar. Este último es más a menudo el curso correcto de lo que algunas personas piensan.
sh -c
tampoco coincide Type=forking
. El protocolo de preparación para un forking
servicio es bastante específico. El proceso inicial tiene que bifurcar a un niño y luego salir. systemd aplica un tiempo de espera a este protocolo. Si el proceso inicial no se bifurca dentro del tiempo asignado, es un fracaso estar listo. Si el proceso inicial no sale dentro del tiempo asignado, eso también es un fracaso.
el horror innecesario que es ossec-control
Lo que nos lleva a las cosas complejas: ese ossec-control
guión.
Resulta que es un rc
script del Sistema 5 que desvía entre 4 y 10 procesos, que a su vez se bifurcan y salen también. Es uno de esos rc
scripts del Sistema 5 que intenta administrar un conjunto completo de procesos del servidor en un solo script, con for
bucles, condiciones de carrera, sleep
s arbitrarios para tratar de evitarlos, modos de falla que pueden ahogar el sistema en un estado medio iniciado, y todos los otros horrores que hicieron que las personas inventaran cosas como el Controlador de recursos del sistema AIX y las herramientas demoníacas hace dos décadas. Y no olvidemos el script de shell oculto en un directorio binario que reescribe sobre la marcha, para implementar idiosincrásicos enable
y disable
verbos.
Entonces, cuando lo /bin/sh -c '/var/ossec/bin/ossec-control start'
que sucede es que:
- systemd bifurca lo que espera que sea el proceso de servicio.
- Ese es el caparazón, que se bifurca
ossec-control
.
- Eso, a su vez, desembolsa entre 4 y 10 nietos.
- Los nietos se bifurcan y salen a su vez.
- Los bisnietos se bifurcan y salen en paralelo.
ossec-control
salidas
- Sale el primer caparazón.
- Los procesos de servicio fueron los grandes-estupendo, nietos, sino porque esta forma de partidos de trabajo ni el
forking
ni el simple
protocolo de preparación, systemd considera el servicio como un todo para han fracasado y se cierra de nuevo hacia abajo.
Nada de este horror es realmente necesario bajo systemd en absoluto. Nada de eso.
una unidad de servicio de plantilla systemd
En cambio, uno escribe una unidad de plantilla muy simple :
[Unidad]
Descripción = El servidor OSSEC HIDS% i
Después = network.target
[Servicio]
Tipo = simple
ExecStartPre = / usr / bin / env / var / ossec / bin /% p-% i -t
ExecStart = / usr / bin / env / var / ossec / bin /% p-% i -f
[Instalar en pc]
WantedBy = multi-user.target
Guarda esto como /etc/systemd/system/ossec@.service
.
Los diversos servicios reales son instancias de esta plantilla, llamada:
ossec@dbd.service
ossec@agentlessd.service
ossec@csyslogd.service
ossec@execd.service
ossec@agentd.service
ossec@logcollector.service
ossec@syscheckd.service
ossec@maild.service
ossec@analysisd.service
ossec@remoted.service
ossec@monitord.service
Luego, la función de habilitar y deshabilitar viene directamente del sistema de administración de servicios (con el error RedHat 752774 corregido), sin necesidad de scripts de shell ocultos.
systemctl enable ossec @ dbd ossec @ agentlessd ossec @ csyslogd ossec @ maild ossec @ execd ossec @ analysisd ossec @ logcollector ossec @ remoted ossec @ syscheckd ossec @ monitord
Además, systemd conoce y realiza un seguimiento de cada servicio real directamente. Puede filtrar sus registros con journalctl -u
. Puede saber cuándo un servicio individual ha fallado. Sabe qué servicios se supone que están habilitados y en ejecución.
Por cierto: Type=simple
y la -f
opción es tan correcta aquí como en muchos otros casos. Muy pocos servicios en la naturaleza en realidad señalan su preparación a fuerza de exit
, y estos tampoco son tales casos. Pero eso es lo que forking
significa el tipo. Los servicios en la naturaleza en general solo se bifurcan y salen debido a una noción errónea de sabiduría recibida de que eso es lo que se supone que deben hacer los demonios. De hecho, no lo es. No ha sido desde la década de 1990. Es hora de ponerse al día.
Otras lecturas