Ich schreibe eine System-Unit-Datei für OSSEC HIDS. Das Problem ist, dass systemd beim Starten des Dienstes diese sofort stoppt.
Wenn ich diese ExecStart-Direktive verwende, funktioniert alles einwandfrei.
ExecStart=/var/ossec/bin/ossec-control start
Aber wenn ich kleine Verbesserungen mache, geht es mir gut in OSSEC-Protokollen, dass es SIG 15 nach dem Start erhält.
ExecStart=/bin/sh -c '${DIRECTORY}/bin/ossec-control start'
Wenn ich einen anderen kleinen Geldwechselservice mache, wird nach 20 Sekunden SIG 15 empfangen.
ExecStart=/bin/sh -c '${DIRECTORY}/bin/ossec-control start && sleep 20'
Ich vermute also, dass systemd / bin / sh nach dem Start des Dienstes beendet und bin / sh dann OSSEC beendet.
Wie kann ich dieses Problem lösen?
Antworten:
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. Essimple
wird davon ausgegangen, dass ein Service sofort bereit ist. Einforking
Dienst wird als bereit angesehen, nachdem sein anfänglicher Prozess ein Kind gegabelt und dann beendet hat. Eindbus
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 nichtType=simple
oderType=forking
.In dem
simple
Protokoll wird der anfängliche Prozess als der Dienstprozess angenommen. Tatsächlich führt einsh -c
Wrapper das eigentliche Dienstprogramm als untergeordneten Prozess aus . AlsoMAINPID
geht schief undExecReload
hört auf zu arbeiten, für den Anfang. Bei der VerwendungType=simple
muss man entweder verwendensh -c 'exec …'
oder nicht verwendensh -c
. Letzteres ist häufiger der richtige Kurs als manche denken.sh -c
passt auch nichtType=forking
. Das Bereitschaftsprotokoll für einenforking
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, mitfor
Schleifen, Race-Bedingungen, willkürlichensleep
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 Eigenheitenenable
unddisable
Verben zu implementieren .Also, wenn Sie,
/bin/sh -c '/var/ossec/bin/ossec-control start'
was passiert, ist das:ossec-control
.ossec-control
Ausgänge.forking
noch mit demsimple
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 :
Speichern Sie dies als
/etc/systemd/system/[email protected]
.Die verschiedenen tatsächlichen Dienste sind Instanziierungen dieser Vorlage mit dem Namen:
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
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.
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 derexit
, und diese sind hier nicht solche Fälle nicht. Aber genau dasforking
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
quelle
Requires=
alle erforderlichen Instanzen enthält, und dannPartOf=ossec.target
in ossec @ .service festzulegen. Dies ermöglicht das Starten und Stoppen von ossec durch Starten und Stoppen von ossec.target.Behalten Sie Type = forking bei und geben Sie einen Speicherort für die PID-Datei an, wenn start service / app eine PID beibehält.
[Unit]
Description = "App beim Booten
ausführen " After = network.target syslog.target auditd.service
[Service]
Type = Forking
PIDFile = / var / run / apache2 / apache2.pid
ExecStart = / etc / init.d / apache2 Start
ExecStop = / etc / init.d / apache2 stoppen
StandardOutput = syslog
Standarderror = syslog
Restart = on-Ausfall
SyslogIdentifier = webappslog
[Install]
WantedBy = multi-user.target
Alias = webapps
quelle
Etwas verwandt, ich hatte einen systemd-Dienst, der den Anschein hatte, als würde systemd ihn nach 30s "töten".
systemctl status service-name
würdemain process exited, code=exited, status=1/FAILURE
nach Ablauf der 30er Jahre zeigen .Es würde gut "isoliert" laufen (wie manuell im Terminal mit der gleichen Umgebung ).
Es stellte sich heraus, dass es war
innerhalb
my_script_to_spawn_process.sh
es tat/bin/something > /dev/null 2>&1 &
Das funktioniert, verwirft aber die Ausgabeprotokollinformationen (normalerweise wird es in eine Datei verschoben, oder, wenn nicht, möglicherweise
journalctl
).Ändern Sie es, um sich an einen anderen Ort zu loggen
/bin/something > /tmp/my_file
dann verrät das
/tmp/my_file
tailing die eigentliche ursache. Was (tangential) war, dass Sie die Syntax nichtEnvironment=ABC="true"
wie in Bash verwenden können, müssen keine Anführungszeichen oder der Schlüsselwert in Anführungszeichen sein,Environment="ABC=true"
was dazu führte, dass mein Prozess nach ungefähr 30 Sekunden "in seiner Einrichtungsphase" beendet wurde.quelle
Beachten Sie, dass das Daemon-Modell von systemd simpel ist und nicht mit vielen vorhandenen Daemons kompatibel ist, die mehrfach forken, ausführen und einstellen. Am häufigsten sind die Daemons, die als root beginnen, um die Dinge einzurichten, und dann für den Routinebetrieb auf eine weniger privilegierte UID wechseln. zB Pid-Datei-Initialisierung ist eine Sache, die unter Systemd aufgrund von Berechtigungsproblemen fehlschlägt. Es gibt Workarounds (keine Fixes), aber es ist schlecht dokumentiert.
Die Erklärung von JdeBP ist willkommen, aber unvollständig, und seine Behauptung, es sei alles die Schuld von ossec-control, ist einfach nicht wahr. Sogar ganz einfache Dinge sind problematisch, z. B. nicht abgeschnittene Protokollzeilen zum Debuggen von Problemen oder sinnvolle Fehlermeldungen von systemd selbst, wenn Prozesse abgebrochen werden.
quelle