ZabbixのWeb監視部分のソースコードを読んでみた

ZabbixにはWeb監視の機能があり、
シナリオに沿って、各ページのレスポンスコードや応答時間などの監視を行うことが可能です。

シナリオは例えば以下のような形で設定します。

ステップ1
 URL: http://hostname/login
 想定レスポンスコード: 200
 レスポンスに含まれるべき要求文字列: login page
 
ステップ2
 URL: http://hostname/auth
 想定レスポンスコード: 200
 レスポンスに含まれるべき要求文字列: ok

といった具合に設定していきます。
また、Basic認証が要求されるようなサイトの場合は、
シナリオに対して、User、Passwordを設定しておくことで認証後のページのチェックを行うことも可能です。

Web監視の機能で設定したURLをチェックした場合に、
もしリダイレクトされるとどういう挙動をするのかをソースコードから追ってみました。

Zabbixのソースコードのsrc/zabbix_server/httppoller/httptest.cにWeb監視処理が記述されています。

この中を見ると、Web監視にはlibcurl(http://curl.haxx.se/libcurl/)というライブラリを利用しているのがわかります。

libcurlについてはこちらのページに詳しく書かれているので参考にさせていただきました。
http://d.hatena.ne.jp/irasya/20090726/1248610519

・・・・略
if (NULL == (easyhandle = curl_easy_init()))
{
     err_str = zbx_strdup(err_str, "could not init cURL library");
     zabbix_log(LOG_LEVEL_ERR, "web scenario \"%s\" error: %s", httptest->name, err_str);
     goto clean;
}

if (CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_COOKIEFILE, "")) ||
     CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_USERAGENT, httptest->agent)) ||
     CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_FOLLOWLOCATION, 1L)) ||
     CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_WRITEFUNCTION, WRITEFUNCTION2)) ||
     CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_HEADERFUNCTION, HEADERFUNCTION2)) ||
     CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_SSL_VERIFYPEER, 0L)) ||
     CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_SSL_VERIFYHOST, 0L)))

・・・・略

     if (CURLE_OK != (err = curl_easy_getinfo(easyhandle, CURLINFO_RESPONSE_CODE, &stat.rspcode)))
     {

・・・・略

この辺りがlibcurlを利用している部分になります。

curl_easy_init()で初期化をし、
curl_easy_setopt()でcurlを実行する際のオプション設定を行なっています。
curl_easy_setopt()については上記部分だけではなく、シナリオのステップ設定に応じて追加設定するよう書かれています。

オプション設定が終了後、curl_easy_getinfoでレスポンスコードや処理時間などの値を取得しています。

この中でWeb監視の挙動を決めているcurl_easy_setoptについて詳しく見てます。

上記設定を見ると、まずデフォルトで以下のオプションを指定しているのがわかります。

  • CURLOPT_COOKIEFILE
  • CURLOPT_USERAGENT
  • CURLOPT_FOLLOWLOCATION
  • CURLOPT_WRITEFUNCTION
  • CURLOPT_HEADERFUNCTION
  • CURLOPT_SSL_VERIFYPEER
  • CURLOPT_SSL_VERIFYHOST

それぞれが何を意味しているのかはこちらのサイトが参考になりました。
http://curl.haxx.se/libcurl/c/curl_easy_setopt.html

リダイレクト先を見に行くかどうかに関係している設定は"CURLOPT_FOLLOWLOCATION"になります。
この設定をTrueにすることでレスポンスヘッダのLocation:部分をチェックして、その先まで見に行くようになります。

上で示したコード中では、

CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_FOLLOWLOCATION, 1L)) ||

このように設定され、有効に設定されています。
そのため、リダイレクト先の情報を見に行くようになっていることがわかります。

次に気になる点としては、何個先まで見に行くようになっているのかについてです。

この設定は、curl_easy_setoptで"CURLOPT_MAXREDIRS"で指定を行うようです。
Zabbixのソースコード中にはこの指定が存在していないため、
Locationを最後まで辿っていくようです。

実際に以下のような環境を作って試してみました。

http://hostname/top レスポンスコード:301
↓Redirect
http://hostname/next レスポンスコード:301
↓Redirect
http://otherhost/final レスポンスコード:403

このようなリダイレクトするサイトを用意し、
ZabbixのWeb監視でhttp://hostname/topを監視してみると、
取得できたレスポンスコードは最終的な403でした。

Web監視の挙動が気になる方はこういったポイントをチェックしてみてはいかがでしょうか?