ZabbixでpreforkなApacheをhttpsのmod_status経由で監視する2019/04/27ApacheZabbixZabbixで個別アプリケーションを監視しよう第3弾。ApacheはZabbixのビルトインのテンプレートに入ってますが、なんとシンプルチェックでHTTP、HTTPSそれぞれのサービスが稼働しているかどうかしか監視してくれない。細かく監視ができるテンプレートを導入します。導入にあたってHSTSなApacheを監視できなかったのでそれにも対応しました。Shareという監視テンプレートの共有サイトを見ます、https://www.zabbix.com/integrations/apacheRatingがRecommendedになっているもの以外、外部スクリプトを呼び出してApacheを監視する仕組みのテンプレートが多かったです。余計なスクリプトは動かしたくなかったため、Reccomendされていたgithub.com/v-zhuravlev/zbx_template_apache2のテンプレートをお借りすることにしました。https://github.com/v-zhuravlev/zbx_template_apache2README.mdを読むと、Apacheのモジュールであるmod_statusの出力結果をパースして監視するっぽいですね。他のテンプレートも見ましたが、スクリプトでやるやつも結局はmod_statusの出力を読んでいるみたいです。外部スクリプトは極力作りたくない(置きたくない、管理したくない)ので、このテンプレートを使うことにしました。Apache側でmod_statusを有効化しておきます。Apacheでmod_statusを有効化Loadmoduleされているか確認し、されていなければアンコメントして有効化しておく。modules/mod_status.so1234httpdの設定ファイルの適当なところでmod_statusの出力設定を行います。Locationコンテナに指定したパスへのアクセスがあったら、処理をserver-statusハンドラー(mod_status)に渡します。このパスは外部から見られないようアクセス制御をしておきます。</requireany></location>12345678mod_rewriteを使用している環境の場合、この/server-statusへのアクセスが書き換えられないように設定しておきます。</ifmodule></directory>123456789101112131415161718私のmod_statusは、一番最後で存在しないファイルやディレクトリへのアクセスを全てindex.phpに向ける設定にしています。「server-status」は実際に存在するファイル/ディレクトリではない(Apacheがこのパスにアクセスを受けたらハンドラーがレスポンスを生成して返す)ため、そのindex.phpに振り向ける規則の前に、server-statusへのアクセスはリダイレクトしない、という設定を追加します。構文チェックして問題なければリロード。httpd123念のため、server-statusが取得できるか確認します。Apacheが入っているサーバ上からcurlで確認します。監視テンプレートのインポート先ほどダウンロードしてきたテンプレートの中には、2つのxmlファイルがあります。Zabbixサーバが直接/server-statusにGETした結果をパースして監視する方式のテンプレートと、Zabbixエージェントに内部から/server-statusを監視してもらう方法。agent.xmlのほうを利用します。インポートしたテンプレートはhttpsなserver-status画面を確認できないことに気付くこのTemplateのItemを見てみます。他全てのItemが依存している旨が記載されています。statusの中身を見てみます。Keyの中身は以下のようになっています。web.page.get[{$STUB_STATUS_HOST},{$STUB_STATUS_PATH},{$STUB_STATUS_PORT}]1web.page.getはZabbixビルトインのKeyです。このKeyは、仕様としてhttp以外のプロトコルでのアクセスができません。httpsには対応してくれよとZabbixのユーザフォーラムにも意見が出ていますが、音沙汰なしです。https://support.zabbix.com/browse/ZBXNEXT-1816このテンプレートの監視方式は、mod_statusで生成された/server-status?autoのWebページの文字列をパースしてApacheの状態を確認する、という方式なので、/server-statusをhttpsで公開するしているサーバは監視することができません。監視ソフト(Zabbix)が対応してないからという理由で、せっかくのHSTSなサーバを、/server-statusのみhttpで公開するというのはあまり本質的な解決方法ではありません。httpsでも監視できるようこのKeyを修正します。statusに依存するVersionというアイテムのPreprocessiongを見てみます。statusで取得する/server-status?autoに「ServerVersion」という文字列は含まれていませんので監視できません。-vを打つ仕組みに変更して監視しようと思います。ここでなんかおかしいなと。Connections*以下の4つが当てはまります。statusの結果をPreprocesingにて正規表現でパースして値を取得する処理になっているのですが、これらも該当する文字列が/server-status?auto中にない......。MPMで稼働しているApacheのステータスなのね......。MPM向けだったっぽいですね。MPMなら上記のServerVersionも表示されるっぽい。私のApacheはpreforkなのでこれらのConnections*系は監視しなくていいです。アイテムを修正するここからいろいろテンプレートを直していきました。status以下のようにアイテムのKeyを修正します。$STUB_STATUS_PROTOとして、プロトコルを指定する変数を追加し、併せてKey名を独自定義のものに修正しました。-vを打たせてApacheのバージョンを取得させる想定で修正します。agentに変更しておきます。zabbixエージェントがコマンドが打つだけなので、他のアイテムに依存するわけではないからです。独自Keyを定義しておいて、あとでZabbixエージェント側の設定ファイルでこのKeyに紐づくコマンドを定義します。取得できるデータ型もCharacter(一文字)からText(複数文字)に変更しておきます。Preprocessingは不要ですので、項目ごと削除します。status」のトリガを修正するアイテムを変更した(監視の仕方を変えて取得するデータのフォーマットも変わった)ため、そのアイテムによって引かれるトリガも修正します。Triggersをクリックします。page」というトリガーを引く設定になっています。Apacheのserver-statusが取得できなかったよというトリガーです。orでつながれている後者の.nodata(30m)は、30秒間何もデータが得られなかったときに1を返し、そうでなければ0を返すZabbixの関数です。「.str()」は、実行結果のテキストからかっこの中身のテキストを検索し、ヒットすれば1を、しなければ0を返すZabbixの関数です(逆のほうがよくね?)。200"」という文字は含まれていませんでした。Apacheが稼働していることがわかって、/server-status?autoの結果を取得できているかどうかがわかればいいと考えたので、/server-status?autoに「Uptime」の文字が含まれているかどうかを判断する方式に変更します。変更したらUpdate。statusにて、変数$STUB_STATUS_PROTOを追加しました。この変数は、テンプレートにてデフォルト値を定義しておきます。このテンプレートを開き、Macrosを開きます。以下のように、変数定義を追加。このテンプレートで定義している値はホスト単位でオーバーライドできますので、デフォルト値はhttpにしておきます。ホスト変数の定義このテンプレートをホストにリンクさせます。HostsからApacheを監視したいホストをクリック。agentをSelectしてAddしてUpdate。つづいてTemlateの変数をオーバーライドします。HostsからApacheを監視したいホストをクリック。Macros画面に移動します。macros」にトグルすると、テンプレートから引き継いだ変数一覧が表示されます。$STUB_STATUS_PROTOでプロトコルを指定します。私はそれぞれ以下のように設定しました。終わったらUpdate。httpsこれでZabbix側での設定は終わり。Commandの対応付けをエージェントに設定する以下のようなZabbixエージェントの設定ファイルを作成します。mykey.curl[*]Keyはmykey.curl[*]。アスタリスクの意味は、Zabbixサーバから送られたmykey.curlのKeyの変数すべてを一旦受け取るということです。実際は、さきほどのItemのKeyの修正の際に定義した{$STUB_STATUS_PROTO},{$STUB_STATUS_HOST},{$STUB_STATUS_PATH},{$STUB_STATUS_PORT}の4つが送られてきます。この受け取った変数は、シェルと同様に$<数字>で呼び出すことができます。その変数を呼び出してcurlコマンドを組み立てます。status」の並びと合わせています。ZabbixエージェントがUnsafeなUserParameterを受け取れるようにする$STUB_STATUS_PATHには、「server-status?auto」という文字が格納されています。この?という文字はZabbixエージェントにとってのUnsafeな文字であるため、デフォルトではUserParameterで?を含む文字列を受け取った場合にコマンドの実行を拒否します。ワイルドカードだからですかね。そのため、?などUnsafeな文字をZabbixエージェントが受け取ってコマンドを実行することを許可してやる必要があります。/etc/zabbix/zabbix_agentd.confUnsafeUserParameters=112ちなみに、Unsafeだとされている文字の一覧は公式にあります。https://www.zabbix.com/documentation/3.4/manual/appendix/config/zabbix_agentd私はこれがわからんくて2時間くらい悩みました。値がとれていることが確認出来たら完了。MPMでしかとれないので表示されていません。/server-status?autoのScoreboardでリクエストに対して各Apacheの子プロセスがどういう処理を行っているか取れるので、余裕があるときに関しできるようにしてみたいです(Zabbixサーバ側で正規表現で改行を含むScoreboardの値をとってくるのがしんどすぎて諦めた。なんかうまいやり方無いかな)。おわりに監視できた項目をScreenに起こすとこんな感じ。かっこよくなってきた。Zabbixはそろそろもうよくて別な勉強をしないといけない。