しまねソフト研究開発センター(略称 ITOC)にいます、東です。
前回 は、Zabbix クライアントでコマンドを実行することで、標準では用意されていない項目の監視を行いました。
今回はサーバ側でコマンドを実行して監視する例として、SSLサーバ証明書の有効期限の監視を行ってみます。
目標
- SSLサーバ証明書が有効かを監視する
- 証明書有効期限30日前になったら通知する
手順
Zabbix サーバーには、外部チェック という機能があります。重要な点を抜粋すると、
- Zabbixサーバで任意のスクリプトを実行して監視を行うことができる
- 監視スクリプトは、設定ファイル (zabbix_server.conf) の ExternalScripts オプションによって指定されたディレクトリに置く
- スクリプトには、任意のパラメータが指定できる
- チェック結果(実行結果)は、標準出力に出力する
ということですので、該当ディレクトリに任意のスクリプトをおいて、Zabbixコンソールでそれを利用する設定を追加すれば良さそうです。
スクリプトの設置
SSLサーバ証明書は、たとえば HTTPS なら443番ポートにアクセスして確認することができます。これには openssl コマンドが利用できますが、openssl コマンドの出力結果は、かなりたくさんの情報が含まれます。Zabbixサーバには phpがインストールされているので、phpを使ってその出力を加工するとともに、パラメータ処理などを少しインテリジェントにしたいと思います。
FreeBSDの標準(ports/pkg)インストールでは、 /usr/local/etc/zabbix6/zabbix/externalscripts
がデフォルトのスクリプト設置ディレクトリです。
Zabbixサーバーへログインし、該当のディレクトリへ以下のスクリプトを設置します。
#!/usr/local/bin/php
<?php
#
# SSL/TLSサーバ証明書の有効期限取得
#
# Usage:
# get_certificate_expiration.php hostname [port num|https|submission]
# Return:
# Remaining validity days.
#
if( !isset($argv[1]) ) {
echo "Usage: " . $argv[0] . " hostname [service|port]\n";
exit( 1 );
}
$host_name = $argv[1];
$service = isset($argv[2]) ? $argv[2] : "https";
$starttls = "";
if( preg_match("/^[0-9]+$/", $service) ) {
$port = $service;
} elseif( $service == "https" || $service == "{\$PORT}" ) {
$port = 443;
} elseif( $service == "submission" ) {
$starttls = " -starttls smtp";
$port = 587;
} else {
echo "Error: service name is not supported.\n";
exit( 1 );
}
$cmd = ":| openssl s_client -connect " . $host_name . ":" . $port
. " -servername " . $host_name . $starttls . " 2>/dev/null"
. " | openssl x509 -noout -enddate";
$enddate = exec( $cmd );
if( $enddate === false ) {
echo "Error: openssl command.\n";
exit( 1 );
}
preg_match("/^notAfter=(.+)$/", $enddate, $matches );
if( !isset($matches[1]) ) {
echo "Error: openssl command gave unexpected response.\n";
exit( 1 );
}
$d = date_create_from_format("F d H:i:s Y e", $matches[1] );
echo $d->diff( new DateTime())->days, "\n";
exit( 0 );
このスクリプトは、
get_certificate_expiration.php www.example.com 443
として実行すると、有効期限までの日数を標準出力で返してくれます。第2パラメータのポート番号は、https
もしくは、submission
を指定することもできます。
監視対象サーバの登録
ウェブフロントエンドを使い、監視対象のサーバを追加します。
ここでは、新規にサーバを追加する方法を説明します。既に ZabbixAgentを使った監視登録がしてあるサーバがある場合は、この項をスキップしてください。
- 左ペインのメニューから
設定
>ホスト
とクリックします - 右ペイン上部の
[ホストの作成]
をクリックします - 新しいホストの作成画面が表示されるので、以下の項目を入力します
ホスト名: 任意
テンプレート: HTTPS Service
グループ: 任意
インターフェース: エージェント
DNS名: (FQDN)
接続方法:DNS
今回、対象のサーバーには ZabbixAgentはインストールしていませんが、DNS名が必要なため、インターフェースにはエージェントを指定し、DNS名欄への入力と接続方法を DNS
へ変更します。
また、テンプレートは入れなくても構いませんが、一応ここでは、HTTPS Service
を指定しておきました。
証明書有効期限の監視を追加
ホスト一覧に、先ほど追加したサーバが追加されているので、その アイテム
の箇所をクリックします。
- 右ペイン上部の
[アイテムの作成]
をクリックします - アイテム作成画面が表示されるので、以下の項目を入力します
名前: SSL expiration
タイプ: 外部チェック
キー: get_certificate_expiration.php["{HOST.CONN}","https"]
監視間隔: 6h
以上で監視設定は完了です。
トリガーの設定
ホスト一覧から、対象サーバの トリガー
の箇所をクリックします。
- 右ペイン上部の
[トリガーの作成]
をクリックします - トリガー作成画面が表示されるので、以下の項目を入力します
名前: Server SSL expiration {HOST.CONN}
深刻度: 軽度の障害
条件式: 右の [追加]
ボタンで以下のとおり追加します
アイテム: (ホスト名): SSL expiration
結果: <
30
以上でトリガーの設定は完了です。
これで、証明書有効期限が30日を切ったら、通知が送られます。
おわりに
今回は、サーバーでコマンドを実行することによる監視、例題としてサーバ証明書期限監視を行ってみました。例示では、ポート番号443の HTTPSの監視を行いましたが、同様の設定で pop3やsubmissionポートで使われる証明書の監視もできると思います。証明書の更新は、たいてい1年ごとなので忘れやすく、期限切れになると接続ができなくなってしまうため、積極的に監視したい項目です。
また、監視するサーバが多い場合は、監視アイテムの追加と通知トリガーの追加のセットをテンプレートにしておくと便利です。