Nichtübereinstimmung des Bereitschaftsprotokolls
Wie Wieland angedeutet hat, ist Typeder Service wichtig. Diese Einstellung gibt an, von welchem Bereitschaftsprotokoll systemd erwartet, dass der Dienst spricht. Es simplewird davon ausgegangen, dass ein Service sofort bereit ist. Ein forkingDienst wird als bereit angesehen, nachdem sein anfänglicher Prozess ein Kind gegabelt und dann beendet hat. Ein dbusDienst 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 -cpasst nicht Type=simpleoder Type=forking.
In dem simpleProtokoll wird der anfängliche Prozess als der Dienstprozess angenommen. Tatsächlich führt ein sh -cWrapper das eigentliche Dienstprogramm als untergeordneten Prozess aus . Also MAINPIDgeht schief und ExecReloadhört auf zu arbeiten, für den Anfang. Bei der Verwendung Type=simplemuss man entweder verwenden sh -c 'exec …'oder nicht verwenden sh -c . Letzteres ist häufiger der richtige Kurs als manche denken.
sh -cpasst auch nicht Type=forking. Das Bereitschaftsprotokoll für einen forkingDienst 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-controlDrehbuch.
Es stellt sich heraus, dass es sich um ein System 5- rcSkript 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- rcSkripte, die versuchen, eine ganze Reihe von Serverprozessen in einem einzigen Skript zu verwalten, mit forSchleifen, Race-Bedingungen, willkürlichen sleeps, 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 enableund disableVerben 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 simpleBereitschaftsprotokoll ü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=simpleund die -fOption 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 forkingbedeutet 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