GNU/Linux >> Tutoriales Linux >  >> Cent OS

Centos:¿Systemd elimina el servicio inmediatamente después del inicio?

Estoy escribiendo systemd archivos unitarios para OSSEC HIDS. El problema es que cuando systemd inicia los servicios, los detiene inmediatamente.

Cuando uso el siguiente ExecStart directiva todo funciona bien.

ExecStart=/var/ossec/bin/ossec-control start

Pero cuando hago esto después de una pequeña mejora, encuentro en los registros OSSEC que recibe SIG 15 después del inicio.

ExecStart=/bin/sh -c '${DIRECTORY}/bin/ossec-control start'

Si hago otro pequeño cambio, el servicio recibirá SIG 15 después de 20 segundos.

ExecStart=/bin/sh -c '${DIRECTORY}/bin/ossec-control start && sleep 20'

Entonces, supongo que systemd mata a /bin/sh proceso después del inicio del servicio, y /bin/sh luego mata a OSSEC .

¿Cómo puedo solucionar este problema?

Respuesta aceptada:

discordancia del protocolo de preparación

Como insinuó Wieland, el Type del servicio es importante. Esa configuración indica qué protocolo de preparación systemd espera que el servicio hable. Un simple se supone que el servicio está listo inmediatamente. Una forking Se considera que el servicio está listo después de que su proceso inicial bifurca a un niño y luego sale. Un dbus se considera que el servicio está listo cuando aparece un servidor en el Desktop Bus. Y así sucesivamente.

Si no obtiene el protocolo de preparación declarado en la unidad de servicio para que coincida con lo que hace el servicio, entonces las cosas salen mal. Las discrepancias en el protocolo de preparación hacen que los servicios no se inicien correctamente o (más generalmente) que systemd diagnostique (erróneamente) que fallan. Cuando se considera que un servicio no se inicia, systemd garantiza que todos los procesos adicionales huérfanos del servicio que podría haberse dejado en ejecución como parte de la falla (desde su punto de vista) se cancela para que el servicio vuelva correctamente al estado inactivo.

Estás haciendo exactamente esto.

En primer lugar, las cosas simples:sh -c no coincide con Type=simple o Type=forking .

En el simple protocolo, el proceso inicial se lleva a be el proceso de servicio. Pero de hecho un sh -c wrapper ejecuta el programa de servicio real como un proceso secundario . Entonces MAINPID sale mal y ExecReload deja de funcionar, para empezar. Al usar 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 no coincide con Type=forking o. El protocolo de preparación para un forking El 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 para estar listo. Si el proceso inicial no finaliza dentro del tiempo asignado, eso también es una falla.

el horror innecesario que es ossec-control

Lo que nos lleva a las cosas complejas:ese ossec-control guión.

Resulta que es un System 5 rc script que se bifurca entre 4 y 10 procesos, que a su vez también se bifurcan y salen. Es uno de esos System 5 rc scripts que intentan administrar un conjunto completo de procesos de servidor en un solo script, con for bucles, condiciones de carrera, sleep arbitrario s para tratar de evitarlos, los modos de falla que pueden ahogar el sistema en un estado medio iniciado y todos los demás horrores que hicieron que la gente inventara cosas como el controlador de recursos del sistema AIX y los daemontools hace dos décadas. Y no olvidemos el script de shell oculto en un directorio binario que reescribe sobre la marcha, para implementar enable idiosincrásico y disable verbos.

Relacionado:Debian:¿cómo averiguar cómo se instaló un paquete en particular?

Así que cuando /bin/sh -c '/var/ossec/bin/ossec-control start' lo que pasa es que:

  1. systemd bifurca lo que espera que sea el proceso de servicio.
  2. Ese es el caparazón, que bifurca ossec-control .
  3. Eso a su vez da entre 4 y 10 nietos.
  4. Todos los nietos se bifurcan y salen por turnos.
  5. Todos los bisnietos se bifurcan y salen en paralelo.
  6. ossec-control salidas.
  7. El primer caparazón sale.
  8. Los procesos de servicio fueron los gran-gran- nietos, sino porque esta forma de trabajar no la forking ni el simple protocolo de preparación, systemd considera que el servicio como un todo ha fallado y lo vuelve a apagar.

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 :

[Unit]
Description=The OSSEC HIDS %i server
After=network.target 

[Service]
Type=simple
ExecStartPre=/usr/bin/env /var/ossec/bin/%p-%i -t
ExecStart=/usr/bin/env /var/ossec/bin/%p-%i -f

[Install]
WantedBy=multi-user.target

Guárdelo como /etc/systemd/system/[email protected] .

Los diversos servicios reales son instancias de esta plantilla, denominada:

  • [email protected]
  • [email protected]
  • [email protected]
  • [email protected]
  • [email protected]
  • [email protected]
  • [email protected]
  • [email protected]
  • [email protected]
  • [email protected]
  • [email protected]

Luego, habilitar y deshabilitar la función viene directamente del sistema de administración de servicios (con el error 752774 de RedHat solucionado), sin necesidad de scripts de shell ocultos.

 systemctl enable [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected]

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 deben estar habilitados y en ejecución.

Por cierto:Type=simple y el -f opciones son tan correctas aquí como lo son en muchos otros casos. Muy pocos servicios en la naturaleza realmente señalan su preparación a fuerza de exit , y estos de aquí tampoco son tales casos. Pero de eso se trata la forking tipo significa. Los servicios en la naturaleza en general simplemente se bifurcan y salen debido a una noción de sabiduría recibida errónea de que eso es lo que se supone que deben hacer los demonios. De hecho, no lo es. No lo ha sido desde la década de 1990. Es hora de ponerse al día.

Lecturas adicionales

  • Jonathan de Boyne Pollard (2015). Problemas de protocolo de preparación con demonios Unix . Respuestas frecuentes.

Cent OS
  1. ¿Por qué Systemd detiene el servicio inmediatamente después de iniciarlo?

  2. Centos:no se pudo iniciar el servidor Apache Http:¿Httpd.service falló?

  3. CentOS / RHEL 7:Cómo configurar serial getty con systemd

  4. No se puede iniciar el servicio Nagios (CentOS/RHEL)

  5. Systemd:Uso de After y Requires

Cómo iniciar el servicio en el arranque con RHEL 8 / CentOS 8 Linux

Cómo iniciar, detener o reiniciar servicios en CentOS 8

CentOS / RHEL 7:Guía para principiantes de unidades de servicio systemd

systemd:SIGTERM inmediatamente después del inicio

No se puede iniciar el servicio postgresql en CentOS 7

No se puede iniciar el servicio de red CentOS 7