Nichtübereinstimmung des Bereitschaftsprotokolls
Wie Wieland angedeutet hat, ist Type
der Service wichtig. Diese Einstellung gibt an, von welchem Bereitschaftsprotokoll systemd erwartet, dass der Dienst spricht. Es simple
wird davon ausgegangen, dass ein Service sofort bereit ist. Ein forking
Dienst wird als bereit angesehen, nachdem sein anfänglicher Prozess ein Kind gegabelt und dann beendet hat. Ein dbus
Dienst gilt als bereit, wenn ein Server auf dem Desktop Bus angezeigt wird. Und so weiter.
Wenn Sie nicht das Bereitschaftsprotokoll erhalten, das in der Serviceeinheit für die Serviceleistungen deklariert ist, läuft die Sache schief. Nicht übereinstimmende Bereitschaftsprotokolle führen dazu, dass Dienste nicht ordnungsgemäß gestartet werden oder (in der Regel) von systemd als fehlerhaft (falsch) diagnostiziert werden. Wenn festgestellt wird, dass ein Dienst nicht gestartet werden kann, stellt systemd sicher, dass alle verwaisten zusätzlichen Prozesse des Dienstes , die möglicherweise als Teil des Fehlers ausgeführt wurden (aus seiner Sicht), abgebrochen werden, um den Dienst ordnungsgemäß wieder inaktiv zu machen Zustand.
Du machst genau das.
Zuallererst das einfache Zeug: sh -c
passt nicht Type=simple
oder Type=forking
.
In dem simple
Protokoll wird der anfängliche Prozess als der Dienstprozess angenommen. Tatsächlich führt ein sh -c
Wrapper das eigentliche Dienstprogramm als untergeordneten Prozess aus . Also MAINPID
geht schief und ExecReload
hört auf zu arbeiten, für den Anfang. Bei der Verwendung Type=simple
muss man entweder verwenden sh -c 'exec …'
oder nicht verwenden sh -c
. Letzteres ist häufiger der richtige Kurs als manche denken.
sh -c
passt auch nicht Type=forking
. Das Bereitschaftsprotokoll für einen forking
Dienst ist sehr spezifisch. Der anfängliche Prozess muss ein Kind verzweigen und dann beenden. systemd wendet eine Zeitüberschreitung auf dieses Protokoll an. Wenn der anfängliche Prozess nicht innerhalb der zugewiesenen Zeit stattfindet, ist es ein Fehler, bereit zu werden. Wenn der anfängliche Prozess nicht innerhalb der vorgegebenen Zeit beendet wird, ist dies ebenfalls ein Fehler.
das unnötige Grauen das ist ossec-control
Das bringt uns zu den komplexen Dingen: dem ossec-control
Drehbuch.
Es stellt sich heraus, dass es sich um ein System 5- rc
Skript handelt, das zwischen 4 und 10 Prozesse abspaltet, die sich selbst in ihrer Abzweigung befinden und auch beendet werden. Es ist eines dieser System 5- rc
Skripte, die versuchen, eine ganze Reihe von Serverprozessen in einem einzigen Skript zu verwalten, mit for
Schleifen, Race-Bedingungen, willkürlichen sleep
s, um sie zu vermeiden. und all die anderen Schrecken, die Menschen dazu gebracht haben, Dinge wie den AIX System Resource Controller und daemontools vor zwei Jahrzehnten zu erfinden. Und vergessen wir nicht das versteckte Shell-Skript in einem Binärverzeichnis, das es im laufenden Betrieb neu schreibt, um Eigenheiten enable
und disable
Verben zu implementieren .
Also, wenn Sie, /bin/sh -c '/var/ossec/bin/ossec-control start'
was passiert, ist das:
- systemd gibt an, was der Serviceprozess sein soll.
- Das ist die Schale, die sich gabelt
ossec-control
.
- Das wiederum gabelt zwischen 4 und 10 Enkelkindern.
- Die Enkelkinder gabelten sich alle und gingen der Reihe nach ab.
- Die Urenkel gabelten sich alle und gingen parallel ab.
ossec-control
Ausgänge.
- Die erste Shell wird beendet.
- Die Serviceprozesse waren die Ur-Ur- Enkelkinder, aber da diese Arbeitsweise weder mit dem Bereitschaftsprotokoll
forking
noch mit dem simple
Bereitschaftsprotokoll übereinstimmt , betrachtet systemd den gesamten Service als fehlgeschlagen und fährt ihn herunter.
Keiner dieser Horror ist unter systemd überhaupt notwendig. Nichts davon.
eine systemd template service unit
Stattdessen schreibt man eine sehr einfache Vorlageneinheit :
[Einheit]
Description = Der OSSEC HIDS% i Server
After = network.target
[Bedienung]
Typ = einfach
ExecStartPre = / usr / bin / env / var / ossec / bin /% p-% i -t
ExecStart = / usr / bin / env / var / ossec / bin /% p-% i -f
[Installieren]
WantedBy = multi-user.target
Speichern Sie dies als /etc/systemd/system/ossec@.service
.
Die verschiedenen tatsächlichen Dienste sind Instanziierungen dieser Vorlage mit dem Namen:
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
Die Funktion zum Aktivieren und Deaktivieren wird direkt vom Service-Management-System (mit behobenem RedHat-Fehler 752774 ) bereitgestellt , ohne dass versteckte Shell-Skripte erforderlich sind.
systemctl enable ossec @ dbd ossec @ agentlessd ossec @ csyslogd ossec @ maild ossec @ execd ossec @ analysisd ossec @ logcollector ossec @ remoted ossec @ syscheckd ossec @ monitord
Darüber hinaus lernt systemd jeden tatsächlichen Service direkt kennen und nachverfolgen. Es kann ihre Protokolle mit filtern journalctl -u
. Es kann wissen, wann ein einzelner Dienst ausgefallen ist. Es weiß, welche Dienste aktiviert und ausgeführt werden sollen.
Übrigens: Type=simple
und die -f
Option ist hier genauso richtig wie in vielen anderen Fällen. Nur sehr wenige Dienste im wilden Signal tatsächlich ihre Bereitschaft , vermöge der exit
, und diese sind hier nicht solche Fälle nicht. Aber genau das forking
bedeutet der Typ. Dienstleistungen in freier Wildbahn in der Hauptsache nur Gabelung und Ausfahrt wegen einer irrtümlich empfangenen Weisheitsvorstellung, dass dies das ist, was Dæmons tun sollen. In der Tat ist es nicht. Es ist nicht seit den 1990er Jahren gewesen. Es ist Zeit aufzuholen.
Weitere Lektüre