systemd
OSSEC HIDS用のユニットファイルを作成しています。問題は、systemd
サービスを開始するとすぐに停止することです。
次のコマンドを使用すると、ExecStart
すべてがうまく機能します。
ExecStart=/var/ossec/bin/ossec-control start
ただし、次のような小さな改善が適用されたときに、ブートSIG 15
後に受信したOSSECログにこれらの事実が見つかりました。
ExecStart=/bin/sh -c '${DIRECTORY}/bin/ossec-control start'
別の小さな変更を加えると、サービスはSIG 15
20秒後にそれを受け取ります。
ExecStart=/bin/sh -c '${DIRECTORY}/bin/ossec-control start && sleep 20'
だから私はサービスが開始した後、プロセスを終了しますsystemd
。/bin/sh
/bin/sh
OSSEC
この問題をどのように解決できますか?
ベストアンサー1
プロトコルミスマッチの準備
Wielandが示唆しているように、Type
この品質は重要です。この設定はどういう意味ですか?契約の準備systemdはサービスが会話できると期待しています。simple
サービスは即時準備とみなされます。forking
初期プロセスが子プロセスに分岐して終了すると、サービスは準備済みと見なされます。dbus
デスクトップバスにサーバーがある場合、サービスは準備ができていると見なされます。など。
サービス機能に一致するサービスユニットで準備プロトコルを宣言しないと、問題が発生する可能性があります。準備プロトコルの不一致により、サービスが正しく開始されないか(より一般的に)systemdでエラーと診断される可能性があります。サービスを開始できないと見なされると、systemdは次のことを保証します。サービスの各孤児追加プロセスエラーの一部として(該当する観点から)実行されていた可能性があるサービスは、サービスを非アクティブ状態に適切に戻すために終了します。
それがまさにあなたがすることです。
まず、単純なもの:sh -c
一致しType=simple
ないかType=forking
。
simple
プロトコルの初期プロセスは次のとおりです。はいサービスプロセスただし、実際にsh -c
ラッパーは実際のサービスプログラムを実行します。子プロセスとして。まず、問題が発生して動作が停止しますMAINPID
。ExecReload
を使用するときは、またはをType=simple
使用する必要があります。sh -c 'exec …'
使用しないでください sh -c
最初。後者は、一部の人が考えるよりも本当であることがよくあります。
sh -c
やはり一致しませんType=forking
。サービス準備プロトコルはforking
非常に具体的です。初期プロセスは子プロセスを分岐してから終了する必要があります。 systemdはこのプロトコルにタイムアウトを適用します。初期プロセスが割り当てられた時間内にフォークされない場合は、準備ができていません。指定された時間内に初期プロセスが終了しないと失敗します。
不要な恐怖ossec-control
これは私たちに複雑なもの、つまりスクリプトを紹介しますossec-control
。
それは明らかですrc
これは、4〜10個のプロセスを分岐し、独自に分岐して終了するSystem 5スクリプトです。これは、ループ、競合状態、これを回避する任意のs、およびシステムを半分のブート状態にすることができる障害モードをrc
使用して、1つのスクリプトでサーバープロセス全体を管理しようとするSystem 5スクリプトの1つです。他のすべての怖いものAIXシステム・リソース・コントローラーやdaemontoolsなどのものは20年前に発明されました。特別な機能と動詞を実装するために動的に書き換えられたバイナリディレクトリに隠されたシェルスクリプトを忘れないでください。for
sleep
enable
disable
次のよう/bin/sh -c '/var/ossec/bin/ossec-control start'
な場合はどうなりますか?
- systemd は期待するサービスプロセスをフォークします。
- それが知覚であり、二股に分かれています
ossec-control
。 - すると、4~10人の孫が誕生することになります。
- 孫はすべて順番にフォークして出かけた。
- すべての子孫は分岐して並列に終了します。
ossec-control
やめる。- 最初のシェルが終了します。
- サービスプロセスはいいね -孫ですが、これがうまくいく方法がよく似合います。どちらもありませんこれ
forking
...でもない準備プロトコルに従って、simple
systemd はサービス全体が失敗したとみなし、再び終了します。
systemdでは、これらの恐ろしいことは実際にはまったく必要ありません。何もない。
systemdテンプレートサービスユニット
代わりに非常に簡単に書いてください。テンプレートユニット:
[単位] 説明=OSSEC HIDS %i サーバー 以降 = network.target [提供する] タイプ=シンプル ExecStartPre=/usr/bin/env /var/ossec/bin/%p-%i -t ExecStart=/usr/bin/env /var/ossec/bin/%p-%i -f [インストールする] WantedBy =マルチユーザー。ターゲット
別の名前で保存してください。/etc/systemd/system/[email protected]
様々な実務サービスはインスタンス化テンプレート名は次のとおりです。
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
その後、機能を有効または無効にします。サービス管理システムから直接(そしてRed Hat エラー 752774修正)シェルスクリプトを隠すことなく。
systemctl を有効にする
さらに、systemdは各実サービスの直接的な可視性と追跡機能を備えています。これはログをフィルタリングするために使用できますjournalctl -u
。単一のサービスがいつ失敗するかがわかります。どのサービスを有効にして実行する必要があるかを知っています。
注:ここのType=simple
オプションは-f
他の多くの場合と同様に正確です。現場サービスがほとんどない実際に彼らは準備ができていることを示しています。おかげでexit
ここでもそうではありません。しかし、それはforking
タイプに関するものです。野生のサービスはほとんどフォークして終了することです。なぜなら、これがデーモンがしなければならないことであるという誤解があるからです。実際にはそうではありません。 1990年代以降はそうではありませんでした。今追いつく時間です。
追加読書
- ジョナサンデボインポラード(2015)。Unixデーモンの準備プロトコルの問題。よく与えられる答えです。