プロトコルミスマッチの準備

プロトコルミスマッチの準備

systemdOSSEC HIDS用のユニットファイルを作成しています。問題は、systemdサービスを開始するとすぐに停止することです。

次のコマンドを使用すると、ExecStartすべてがうまく機能します。

ExecStart=/var/ossec/bin/ossec-control start

ただし、次のような小さな改善が適用されたときに、ブートSIG 15後に受信したOSSECログにこれらの事実が見つかりました。

ExecStart=/bin/sh -c '${DIRECTORY}/bin/ossec-control start'

別の小さな変更を加えると、サービスはSIG 1520秒後にそれを受け取ります。

ExecStart=/bin/sh -c '${DIRECTORY}/bin/ossec-control start && sleep 20'

だから私はサービスが開始した後、プロセスを終了しますsystemd/bin/sh/bin/shOSSEC

この問題をどのように解決できますか?

ベストアンサー1

プロトコルミスマッチの準備

Wielandが示唆しているように、Typeこの品質は重要です。この設定はどういう意味ですか?契約の準備systemdはサービスが会話できると期待しています。simpleサービスは即時準備とみなされます。forking初期プロセスが子プロセスに分岐して終了すると、サービスは準備済みと見なされます。dbusデスクトップバスにサーバーがある場合、サービスは準備ができていると見なされます。など。

サービス機能に一致するサービスユニットで準備プロトコルを宣言しないと、問題が発生する可能性があります。準備プロトコルの不一致により、サービスが正しく開始されないか(より一般的に)systemdでエラーと診断される可能性があります。サービスを開始できないと見なされると、systemdは次のことを保証します。サービスの各孤児追加プロセスエラーの一部として(該当する観点から)実行されていた可能性があるサービスは、サービスを非アクティブ状態に適切に戻すために終了します。

それがまさにあなたがすることです。

まず、単純なもの:sh -c一致しType=simpleないかType=forking

simpleプロトコルの初期プロセスは次のとおりです。はいサービスプロセスただし、実際にsh -cラッパーは実際のサービスプログラムを実行します。子プロセスとして。まず、問題が発生して動作が停止しますMAINPIDExecReloadを使用するときは、またはを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年前に発明されました。特別な機能と動詞を実装するために動的に書き換えられたバイナリディレクトリに隠されたシェルスクリプトを忘れないでください。forsleepenabledisable

次のよう/bin/sh -c '/var/ossec/bin/ossec-control start'な場合はどうなりますか?

  1. systemd は期待するサービスプロセスをフォークします。
  2. それが知覚であり、二股に分かれていますossec-control
  3. すると、4~10人の孫が誕生することになります。
  4. 孫はすべて順番にフォークして出かけた。
  5. すべての子孫は分岐して並列に終了します。
  6. ossec-controlやめる。
  7. 最初のシェルが終了します。
  8. サービスプロセスはいいね -孫ですが、これがうまくいく方法がよく似合います。どちらもありませんこれforking ...でもない準備プロトコルに従って、simplesystemd はサービス全体が失敗したとみなし、再び終了します。

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]

様々な実務サービスはインスタンス化テンプレート名は次のとおりです。

その後、機能を有効または無効にします。サービス管理システムから直接(そしてRed Hat エラー 752774修正)シェルスクリプトを隠すことなく。

systemctl を有効にする

さらに、systemdは各実サービスの直接的な可視性と追跡機能を備えています。これはログをフィルタリングするために使用できますjournalctl -u。単一のサービスがいつ失敗するかがわかります。どのサービスを有効にして実行する必要があるかを知っています。

注:ここのType=simpleオプションは-f他の多くの場合と同様に正確です。現場サービスがほとんどない実際に彼らは準備ができていることを示しています。おかげでexitここでもそうではありません。しかし、それはforkingタイプに関するものです。野生のサービスはほとんどフォークして終了することです。なぜなら、これがデーモンがしなければならないことであるという誤解があるからです。実際にはそうではありません。 1990年代以降はそうではありませんでした。今追いつく時間です。

追加読書

おすすめ記事