さくらのVPSからZABBIXで外部死活監視を行う
自宅サーバに限らず、インターネットでサーバを立てる場合、その死活監視が問題になる。要件としては、
- 24 時間 365 日自動で監視すること。
- 問題が発生した場合は、メールや IRC などで迅速に通知できること。
- L2・L3 レベルに加えて、Web死活監視など L7 レベルの監視もできると望ましい。
あたりだろうか。さらに死活監視内容は 2 パターンあって、
- ネットワーク内の全てのサーバ機器が正常に動作しているか監視。
- ネットワーク外からサービスが正常に見えているか監視。
となる。ネットワーク外からネットワーク内のサーバ機器全てが見える状況はセキュリティの観点から全くあり得ないので、前者と後者は常にセットで実施する必要がある。そして後者は監視対象とは別のネットワークに置く必要がある。理由は簡単で、
- 監視対象のネットワークが存在する回線に問題がある場合、ネットワーク内にある死活監視からはアラートを送信できない。
- 参照する DNS の場所やファイアウォールのルールなどの関係で、ネットワーク内から見えるステータスとネットワーク外から見えるステータスが同じとは限らない。
が挙げられる。
長らく我が家の自宅サーバは外部死活監視が存在しない状況だったが、ISP の仕様上、10,800 秒 (= 7 日) ごとに接続が切れること、そのタイミングで外側のネットワークインターフェイスを named が listen しなくなることがあることから、さくらの VPS で外部死活監視を行うことにした。
死活監視などのモニタリングを行うソフトウェアとしては、定番の Nagios の他に ZABBIX などがある。何を採用するかは個々人の嗜好もあるとは思うが、今回は死活監視の他にメトリクス収集も行う統合監視ソフトウェアである ZABBIX を使うことにした。何よりも、これまで 2 年ほど自宅ネットワーク内の死活監視やメトリクス収集で使っていて慣れているということがある。
インストールそのものは割愛する。うちの場合はさくら側も Gentoo Linux なので、
USE="server agent frontend mysql" emerge -av zabbix
で問題なくインストールされた。ZABBIX の実行には SQLite や MySQL といったデータベースに加え、フロントエンドは PHP で動作するので PHP 環境も必要になる。
ただ、さくらの VPS の 980 円コースは実メモリが 512 MB しか割り当てられないので、極力メモリを節約するために nginx + PHP-FPM 構成にした。さくらの VPS でホストするWeb サービスは ZABBIX のみ、ZABBIX ユーザも 1 人しかいない上に自宅ネットワークからのアクセス以外は iptables で DROP しているためにアクセスはほとんどないことから、pm.min_spare_servers
は 10 にしている。
ZABBIX のインストールが終わったら、監視対象の設定を行う。ZABBIX は基本的に監視対象のサーバに ZABBIX エージェントをインストールしてメトリクス収集を代行させるか、または SNMP でメトリクスを収集する。だが、今回のように外部から監視したい場合、IP を制限するとはいえ極力ファイアウォールに穴を開けたくない。そういった要求に備えて、ZABBIX はサーバ単体で ping やポート別の tcp 死活監視といった基本的な監視を行う、シンプルチェック機能が使える。これを使って死活監視を行う。
まず、死活監視対象のホストを追加する。[Configuration] → [Hosts] をクリックし、右上の [Create Host] を押す。IP アドレスは対象の IP アドレスを、Connect to は「IP Address」、Zabbix agent port はエージェントを使わない監視なので 0 にして [Save] する。
次に、死活監視のアイテムを追加する。[Configuration] → [Hosts] に追加した死活監視対象が表示されているはずなので、「Items」のリンクをクリックし、右上の [Create Item] を押す。Type で「Simple check」を選択すると、Key の横にある [Select] で監視対象を選択できるようになる。ping 監視の場合は、
icmpping[ip,count,interval,size,timeout]
とする。interval は最低 20 秒なので、うちの場合は
icmpping[xxx.xxx.xxx.xxx,5,20]
にしている。
DNS 死活監視の場合は、ポート 53 がオープンしているかをチェックすればいいので、
tcp,53
とすればよい。ただ、シンプルチェックの場合はポートが開いているかのチェックしかできないので、DNS を実際に引いて確認するには net.tcp.dns.query
などで行う必要がある。なお、第一引数は無視されるので、/etc/resolv.conf
で監視対象の DNS を指定しておく必要がある。
監視アイテムが設定できたら、次はトリガーの設定を行う。ホスト一覧の「Triggers」をクリックし、同じように [Create Trigger] を押す。Expression の記述だが、icmpping
キーも tcp
キーはポートに接続できれば 1 を、そうでない場合は 0 を返すので、
{ホスト名:icmpping[xxx.xxx.xxx.xxx,5,20].last(0)}<1
などとしておけばよい。
トリガーが設定できれば、発報時のアクションを設定しておく。[Configuration] → [Actions] からアクションを追加できるので、うちの場合は深刻度が High 以上の場合にメールを送信するようにしている。ZABBIX の場合、メールの送信先はユーザまたはユーザグループのみになる。なので、各ユーザにメールアドレスを設定させるか、またはメーリングリスト用のユーザを作っておいて、そのユーザのメールアドレスをメーリングリストアドレスにするなどの対応が必要になる。
こんな感じで外部死活監視設定をしていけばよい。設定が完了したら、(支障のない)サービスを止めてみて正しくアラートが発報されるかを確認しておく。
さらに、この外部監視用の ZABBIX を監視する必要がある。ネットワーク内にネットワーク内向け ZABBIX が稼動しているうちの場合は、ネットワーク内の ZABBIX で外部の ZABBIX を監視している。このように監視対象をクロスさせることで、知らない間に外部死活監視が死んでいて肝心なときに役に立たなかったという事態を防ぐことができる。また、ZABBIX が動作しているさくらの VPS でセカンダリ DNS を稼働させている関係で、
- ネットワーク内 ZABBIX からセカンダリ DNS のポートが開いているかの監視。
- セカンダリ DNS をホストしているさくらの VPS の
/etc/resolv.conf
は 8.8.8.8 と 8.8.4.4 を向けておき、自前でホストしているドメインの名前解決が常に Non-authoritative answer になるように設定。
としている。後者も重要で、セカンダリ DNS である 127.0.0.1 にしていたりすると、自分所有のドメインの移譲先が自前 DNS の場合にせっかくの監視システムでは検知できないケースが発生する。
本来、名前解決の際にはルートネームサーバからネームサーバをたどっていくが、自分所有のドメインを自前 DNS でホストしている場合、ルートからたどらなくても自前 DNS だけで名前解決が可能になる。そのため、例えばレジストラに間違ったネームサーバを登録した場合や iptables の設定をミスった場合などで自前 DNS 以外からのみ (= ほぼグローバル) 名前解決できないという事態が発生する。これを防ぐためにも、ZABBIX が参照する DNS を第三者の DNS にするこの設定は重要になる。