incompatibilidade de protocolo de prontidão
Como Wieland sugeriu, Type
o serviço é importante. Essa configuração indica qual protocolo de prontidão o systemd espera que o serviço fale. simple
Presume-se que um serviço esteja imediatamente pronto. Um forking
serviço é levado para ficar pronto depois que seu processo inicial bifurca uma criança e sai. Um dbus
serviço é considerado pronto quando um servidor aparece no Desktop Bus. E assim por diante.
Se você não conseguir que o protocolo de prontidão declarado na unidade de serviço corresponda ao que o serviço faz, as coisas darão errado. As incompatibilidades do protocolo de prontidão fazem com que os serviços não iniciem corretamente ou (geralmente) sejam diagnosticados incorretamente pelo systemd como falhas. Quando um serviço é visto como falhando ao iniciar o systemd, garante que todo processo adicional órfão do serviço que pode ter sido deixado em execução como parte da falha (do ponto de vista dele) seja eliminado, a fim de trazer o serviço corretamente de volta ao inativo Estado.
Você está fazendo exatamente isso.
Primeiro de tudo, as coisas simples: sh -c
não correspondem Type=simple
ou Type=forking
.
No simple
protocolo, o processo inicial é levado para ser o processo de serviço. Mas, de fato, um sh -c
wrapper executa o programa de serviço real como um processo filho . Então MAINPID
dá errado e ExecReload
para de funcionar, para começar. Ao usar Type=simple
, é preciso usar sh -c 'exec …'
ou não usar sh -c
em primeiro lugar. Este último é mais frequentemente o curso correto do que algumas pessoas pensam.
sh -c
também não corresponde Type=forking
. O protocolo de prontidão para um forking
serviço é bastante específico. O processo inicial precisa bifurcar um filho e sair. O systemd aplica um tempo limite a este protocolo. Se o processo inicial não bifurcar dentro do tempo alocado, é uma falha para ficar pronto. Se o processo inicial não sair dentro do tempo alocado, isso também será uma falha.
o horror desnecessário que é ossec-control
O que nos leva a coisas complexas: esse ossec-control
script.
Acontece que é um rc
script do System 5 que executa entre 4 e 10 processos, que por sua vez bifurcam e saem também. É um daqueles rc
scripts do Sistema 5 que tenta gerenciar todo um conjunto de processos do servidor em um único script, com for
loops, condições de corrida, sleep
s arbitrários para tentar evitá-los, modos de falha que podem sufocar o sistema em um estado semi-iniciado, e todos os outros horrores que levaram as pessoas a inventar coisas como o AIX System Resource Controller e daemontools duas décadas atrás. E não vamos esquecer o script de shell oculto em um diretório binário que ele reescreve em tempo real, para implementar idiossincráticos enable
e disable
verbos.
Então, quando você o /bin/sh -c '/var/ossec/bin/ossec-control start'
que acontece é o seguinte:
- O systemd bifurca o que espera ser o processo de serviço.
- Essa é a concha, que bifurca
ossec-control
.
- Isso, por sua vez, bifurca-se entre 4 e 10 netos.
- Todos os netos bifurcam e saem por sua vez.
- Todos os bisnetos bifurcam e saem em paralelo.
ossec-control
saídas.
- O primeiro shell sai.
- Os processos de serviços foram os grandes-grande- netos, mas porque esta maneira de partidas de trabalho nem o
forking
nem o simple
protocolo de prontidão, systemd considera o serviço como um todo para falharam e fecha-lo de volta para baixo.
Nada desse horror é realmente necessário no systemd. Nada disso.
uma unidade de serviço de modelo systemd
Em vez disso, escreve-se uma unidade de modelo muito simples :
[Unidade]
Descrição = O servidor OSSEC HIDS% i
Depois = network.target
[Serviço]
Tipo = simples
ExecStartPre = / usr / bin / env / var / ossec / bin /% p-% i-t
ExecStart = / usr / bin / env / var / ossec / bin /% p-% i -f
[Instalar]
WantedBy = multi-user.target
Salve isso como /etc/systemd/system/ossec@.service
.
Os vários serviços reais são instanciações deste modelo, denominadas:
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
A função habilitar e desabilitar vem diretamente do sistema de gerenciamento de serviços (com o bug 752774 do RedHat corrigido), sem a necessidade de scripts shell ocultos.
systemctl enable ossec @ dbd ossec @ agentlessd ossec @ csyslogd ossec @ maild ossec @ execd ossec @ analysisd ossec @ logcollector ossec @ remota ossec @ syscheckd ossec @ monitord
Além disso, o systemd conhece e rastreia cada serviço real diretamente. Ele pode filtrar seus logs com journalctl -u
. Ele pode saber quando um serviço individual falhou. Ele sabe quais serviços devem estar habilitados e em execução.
A propósito: Type=simple
e a -f
opção é tão aqui quanto em muitos outros casos. Muito poucos serviços na natureza realmente sinalizam sua prontidão pela força do exit
, e esses aqui também não são esses casos. Mas é isso que o forking
tipo significa. Serviços na natureza, principalmente, apenas bifurcam e saem por causa de alguma noção errônea de sabedoria recebida de que é isso que os daemons devem fazer. De fato, não é. Não é desde a década de 1990. É hora de recuperar o atraso.
Leitura adicional