WindowsイベントログをZabbixで簡単に監視する

2019年10月24日Microsoft Windows, NXLog, Windows Event Log, Zabbix, まるごとおまかせZabbix

こんにちは。プラットフォーム技術部の大畑です。

ZabbixでWindowsのイベントログを監視するのは難しい

とある案件で初めてイベントログ監視を担当し、Google先生に泣きついていた時によく目にしたフレーズです。

確かに、Zabbix界隈ではよく言われていることのような気がします。イベントログ監視のために、 監視設計の段階からトリガー条件式や正規表現を複雑に作りこんでいるケースはあまり見たことがありません。さらに私自身、「イベントログの監視って難しいのかー…まぁWindowsはブラックボックスが多くて扱いにくいってよく聞くし…」と変な先入観を持っていて、それ以上深掘りすることがありませんでした。

しかし、よく考えてみれば、私は「なぜイベントログ監視が難しいのか」を知りません。

Zabbixと言えば、自由度が高く高性能なフリーの監視ソフトウェア。監視はもちろんのこと、様々なツールと組み合わせて監視情報を集約できる万能選手です。少なくとも私はそう思っています。

…弱点があるなんて非常に勿体ない気がする!!!

そこで今回は、Windowsイベントログ監視が難しいと言われている理由について学び、このZabbixの弱点を克服できないか、とあるツールを使って試した様子をご紹介したいと思います。

私と同じように「よく分からないけど難しいんでしょう?」と感じている方のヒントになれば幸いです。

Zabbixの弱点、Windowsイベントログ監視

Windowsイベントログが難しい

何度も言うようですが、Windowsは私にとって難しくて分かりにくいOSです。ログの形態も、Linuxとは全然違うように感じています。

まずは、私が思うWindowsイベントログの難しさについて、主観100%で簡単にまとめてみたいと思います。

※いまさら初歩的なことはいいから早く本題に、という方は読み飛ばしてください。

個人的な難ポイント①:テキストデータではない

LinuxではOSやアプリなどが出力するログはテキストデータです。

テキストベースのログファイルは例えば、日時やソース(出力元)、メッセージレベル、メッセージID、メッセージ本文などの各要素が、全て一つのレコードにプレーンテキストとして保持されています。

ログそのもののフォーマットはモノによりけりですが、それにしても非常にシンプルな作りですよね。“Simple” is “best”. シンプルこそ至高です。

一方で、WindowsのイベントログはEVT/EVTX形式のバイナリデータです。プレーンテキストではないので、当然ながらテキストログのように一つのレコードに各要素が並んでいるわけではありません。イベントビューアーを使ってイベント毎に内容を一つ一つ確認する必要があるので、Linuxに慣れている人にとっては若干面倒です。

ログデータから監視設計を考えるとなると、必要な情報だけフィルタしてドキュメント用に2次加工する上で、テキストデータの方が自由度高く扱いやすいですよね。

そんな時、特に私のように経験の浅いSEはバイナリデータというだけでビビる。あるあるではないでしょうか。

個人的な難ポイント②:イベントログそのものの構造が複雑

Windowsのログファイルは、イベントビューアーが管理している「Windowsログ」という一つの大きなフォルダの中に「System」「Application」「Security」のような種類ごとに分類された個別ファイルが内包されているようなイメージの造りになっています。

Zabbixにおいて、これら個別ファイルの考え方がとても複雑なので、私のようなWindows初心者の皆さんは要注意です。

Zabbixにおけるイベントログ監視では、

eventlog[name,<regexp>,<severity>,<source>,<eventid>,<maxlines>,<mode>] 

というアイテムキーを使用し、”name”部分に監視対象となるファイルを指定します。

この時点で監視対象が”name”に指定した個別ファイルに絞られ、以降の各パラメータに指定する条件は全てこの個別ファイルを対象としたものになります。

つまり、各個別ファイルを監視したい場合は、「System」「Application」「Security」それぞれを"name"に指定したアイテムキーを作成する必要があります(監視要件に応じてアイテムキーを複数作成する必要があるかもしれません)。

また、イベントログの場合、ログ日付やイベントIDなどのログ構成要素は、下図赤枠のようにそれぞれ専用のフィールドに保持されます。

イベントログでは、専用のフィールドに日付やソース等の情報を保持している

例えば上図では、「システム」というファイルに対し、「UserModePowerService」と「Kernel-Power」という2つのソースのイベントログが出力されています。これらのソースはそれぞれ異なるログの出力元を表し、それぞれが独立したイベントIDを有しています。

「UserModePowerService」ソースにイベントID:12のイベントログがあるからと言って、「Kernel-Power」ソースにイベントID:12のイベントログが存在しない、なんてことはありません。

つまり、1つのファイル内であっても、イベントIDの重複があり得るということなのです!

テキストログファイルでは、1つのファイル内で例えばメッセージIDが同じなのに内容が異なるというケースはあり得ないですよね。このちょっと複雑な構造こそがイベントログが難しいと考えられる所以ではないでしょうか。

Zabbixでの監視設計も必然的に難しくなる

上記のような構造を念頭に置いて、Zabbixにおけるイベントログ監視についてあらためて考えてみます。イメージしやすいように、図をベースに考えてみましょう。

監視要件

→イベントログ“System”のERRORログから、下記2条件に一致するログメッセージを除外する

  • 除外条件 A
    • ソース:aaa
    • イベントID:111
  • 除外条件 B
    • ソース: aaa
    • イベントID:123

まずは、下図①②のように取得対象となるイベントログの大枠を取得します。

Zabbixにおけるイベントログ監視では、初めに取得対象を決定する

この時点で、図の濃い青色部分が取得する範囲となっています。ここまでは特に問題ないと思います。


続いて、②で絞った範囲から、除外条件A、除外条件Bを除外します。

除外条件の対象範囲を求める

②で絞ったERRORログと除外対象範囲が全て重なった部分(下図赤枠)が、最終的な除外対象範囲です。これを監視設定対象範囲から除けば、今回想定した監視条件を満たすことができます。

取得対象範囲と除外条件との重なり部分が、最終的に監視したい範囲となる

図で考えてみるとイメージしやすいかもしれませんが、これをZabbixで設定する場合、どう設定すれば良いかパッと思い浮かぶでしょうか?

また、上記例は比較的単純な検知条件でしたが、実際の運用現場では検知条件をより細かく複雑に考えることになると思います。

複雑に膨らんだ検知条件を1つのアイテムキーに盛り込むことが出来ずに、やむを得ずアイテムキーを分割する必要性が生じる場面があるかもしれません。

このような場合には、意図しないアラート発報が起きないようにするため、アイテムキー間での検知条件の重複についても考慮しなければなりません。

アラートの多重発報については、それだけで記事が一本書けてしまうため本記事では割愛しますが、絶対に避けるべき重要な課題の一つです。

全ての要件を網羅し、設定した検知/除外条件のカバー範囲を正しく把握し、一単語の重複も漏らさずに考慮する。

…考えるだけで頭が痛いです。

どうすれば難しく考えずに済む?

ここまで長ったらしく説明してきましたが、要するに、イベントログはEVT/EVTX形式のバイナリデータであるから扱いにくく、そして難しいわけです。

このEVT/EVTX形式のバイナリデータをテキストデータに変換できれば、Zabbixでも簡単に監視できると思いませんか?

ここで紹介したいのが、NXLogというフリーツールです。

NXLogとは

NXLogは、様々な形式のログを収集、転送するのに非常に便利なログ管理ツールです。

日本のOSSプロジェクト向けのホスティングサイトである OSDNによると、

nxlog は、マルチプラット フォーム対応のモジュール、マルチ スレッド、高パフォーマンスのログ管理ソリューションです。概念の syslog-ng や rsyslog に似ていますが、unix/syslog に限定されていません。さまざまな形式のファイルからログを収集でき、UDP、TCP または TLS/SSL を介してネットワーク経由でログを受信できます。 …(以下略)

https://ja.osdn.net/projects/sfnet_nxlog-ce/

とのこと…なんだかよく分からないので、先人たちの活用方法をGoogle先生に聞いてみました。たくさんの活用例が出てきますが、どうやらメインの使い道はイベントログの転送のようです。

転送先はログサーバーやDB、ローカルのファイルであったり、fluentdやLogstash等のツールであったりと様々。イベントログを「どこに」「どのような形式で」転送するのかによって、いろいろな使い方ができそうです。

今回は、このNXLogを使ってイベントログを「適当に作成したディレクトリ下に」「テキストファイル形式で」転送して、Zabbixからテキストログとして監視してみようと思います。

Windowsイベントログをテキストファイルに出力する

準備

環境

今回の環境は下記の通りです。

  • Zabbixサーバー
    • OS:CentOS 7
    • Zabbix 4.0 LTS版 / DL元ページはこちら
  • イベントログ監視対象サーバー
    • OS:Windows10
    • zabbix-agent(4.0 LTS版) / DL元ページはこちら
    • NXLog Community Edition 2.10.2150 / DL元ページはこちら

肝心のNXLogのインストール方法ですが、ダウンロードしたインストーラーを実行するだけです!非常に簡単なので、本記事では割愛いたします。

confファイルの設定

NXLogをインストールすると、「nxlog.conf」というconfファイル(設定ファイル)が作成されます。このconfファイルに、実現したい動作設定について記述します。

基本的には、

  • <INPUT>
    • 収集対象のログをどう収集するか
  • <OUTPUT>
    • 収集したログをどこに吐き出すか
  • <ROUTE>
    • INPUTとOUTPUTの設定をつなぐ

という流れさえ押さえておけばとりあえずは大丈夫です。各ブロックに設定できるモジュールやパラメータがたくさん用意されていますので、要件次第で色々な設定が出来ると思います。詳しくは公式マニュアルを読んでみてください。

今回は、SystemログとApplicationログをCドライブ直下の「logs」というディレクトリ下に出力してみたいと思います。confファイルはこんな感じで書いてみました。

Panic Soft
define ROOT     C:\Program Files (x86)\nxlog
define CERTDIR  %ROOT%\cert
define CONFDIR  %ROOT%\conf
define LOGDIR   %ROOT%\data
define LOGFILE  %LOGDIR%\nxlog.log
LogFile %LOGFILE%
Moduledir %ROOT%\modules
CacheDir  %ROOT%\data
Pidfile   %ROOT%\data\nxlog.pid
SpoolDir  %ROOT%\data
<Extension _syslog>
    Module      xm_syslog
</Extension>
<Extension json>
    Module  xm_json
</Extension>
<Extension _charconv>
    Module      xm_charconv
    AutodetectCharsets iso8859-2, utf-8, utf-16, utf-32
</Extension>
<Extension _exec>
    Module      xm_exec
</Extension>
### Eventlog Application
<Input eventlog_app>
    Module im_msvistalog
    Channel Application
    ReadFromLast FALSE
    SavePos TRUE
    Exec $Message = replace($Message, "\r\n", " ");
    Exec $Message = replace($Message, "\n", " ");
    Exec $Message = replace($Message, "\t", " ");
</Input>
<Output eventlog_app_out>
    Module om_file
    File 'C:\logs\eventlog-app.log'
</Output>
<Route eventlog_app_route>
    Path eventlog_app => eventlog_app_out
</Route>
### Eventlog System
<Input eventlog_sys>
    Module im_msvistalog
    Channel System
    ReadFromLast FALSE
    SavePos TRUE
    Exec $raw_event = replace($raw_event, "\r\n", " ");
    Exec $raw_event = replace($raw_event, "\n", " ");
    Exec $raw_event = replace($raw_event, "\t", " ");
</Input>
<Output eventlog_sys_out>
    Module om_file
    File 'C:\logs\eventlog-sys.log'
</Output>
<Route eventlog_sys_route>
    Path eventlog_sys => eventlog_sys_out
</Route>

サービス起動、確認

confファイルを保存したら、さっそくNXLogサービスを起動します。Windowsの検索バーをクリック>「アプリ」>「サービス」を選択し、サービス管理ツールから「NXLog」を起動してください。

それでは、先ほどconfファイルで指定したイベントログの出力先である「logs」ディレクトリを確認してみます。

指定したイベントログが、「logs」ディレクトリ下にテキストファイルとして転送された

【以下 一部抜粋】

2019-09-26 15:19:02 DESKTOP-XXXXXXX INFO 15 Updated Windows Defender status successfully to SECURITY_PRODUCT_STATE_ON.
2019-09-26 15:33:21 DESKTOP-XXXXXXX INFO 101 The license period for this installation of Windows has expired. The operating system is shutting down.
2019-09-26 15:33:23 DESKTOP-XXXXXXX INFO 6000 The winlogon notification subscriber <WSearch> was unavailable to handle a notification event.
2019-09-26 15:33:25 DESKTOP-XXXXXXX INFO 8225 The VSS service is shutting down due to shutdown event from the Service Control Manager. 
2019-09-26 15:33:25 DESKTOP-XXXXXXX INFO 1532 NT AUTHORITY\SYSTEM The User Profile Service has stopped.    
2019-09-26 16:10:13 DESKTOP-XXXXXXX INFO 4625 The EventSystem sub system is suppressing duplicate event log entries for a duration of 86400 seconds.  The suppression timeout can be controlled by a REG_DWORD value named SuppressDuplicateDuration under the following registry key: HKLM\Software\Microsoft\EventSystem\EventLog.
2019-09-26 16:10:12 DESKTOP-XXXXXXX INFO 1531 NT AUTHORITY\SYSTEM The User Profile Service has started successfully.    

出力できています!ファイルの種類もちゃんと「テキストドキュメント」となっています。完璧です。

では、このテキストログをいつも通りにZabbixのテキストログ監視で監視してみます。

Zabbixのテキストログ監視でイベントログを監視する

Zabbixの設定

アイテム

Systemログを監視するアイテムを以下のように作成します。

  • 名前
    • [NXLog] System
  • タイプ
    • Zabbixエージェント(アクティブ)
  • キー
    • log[C:\logs\eventlog-sys.log,@test,,,skip]
  • データ型
    • ログ
  • 監視間隔
    • 1s

正規表現

  • 正規表現名
    • test
  • 設定内容(条件式の形式 / 条件式 / 大文字小文字を区別)
    • 結果が真 / ERROR / ☑
    • 結果が真 / aaa / ☑
    • 結果が偽 / “EventID":111 / ☑
    • 結果が偽 / “EventID":123 / ☑

なお、イベントIDの除外指定は、除外したいイベントIDのみを確実に拾うよう、ログ出力形式に合わせて指定してみました。これで、もしユーザーID等の中に「123」のような数列が含まれてしまっても安心です。

トリガー

先ほど作成したSystemログ監視アイテムに対し、以下のようなトリガーを設定します。

  • 名前
    • [NXLog : sys] Message test
  • 深刻度
    • 重度の障害
  • 条件式
    • {H-win:log[C:\logs\eventlog-sys.log,@test,,,skip].regexp(.*)}=1
  • 正常イベントの生成
    • 条件式
  • 障害イベント生成モード
    • 複数
  • 正常時のイベントクローズ
    • すべての障害

テスト用イベントログを出力

コマンドプロンプトを管理者権限で開き、以下のイベントログを出力します。

EVENTCREATE /ID 111 /L system /SO aaa /T ERROR /D "This is a test message."
EVENTCREATE /ID 123 /L system /SO aaa /T ERROR /D "This is a test message."
EVENTCREATE /ID 999 /L system /SO aaa /T ERROR /D "This is a test message."
EVENTCREATE /ID 111 /L system /SO bbb /T ERROR /D "This is a test message."
EVENTCREATE /ID 123 /L system /SO bbb /T ERROR /D "This is a test message."
EVENTCREATE /ID 999 /L system /SO bbb /T ERROR /D "This is a test message."

イベントソースが「aaa」のログのうち、イベントIDが「111」「123」以外のものを対象に検知できるように正規表現を設定しているため、3行目の

  • イベントID
    • 999
  • イベントソース
    • aaa

で出力されるログのみが検知されれば検証成功です。

同じイベントID「999」でも、イベントソースが「bbb」のイベントログは検知されないはずです。

では、Zabbixで検知できているか確認しましょう。

検知確認

NXLogを使用してイベントログをテキストファイルに出力すれば、Zabbixのテキストログ監視にてイベントログを簡単に監視できる
検知したイベントの詳細画面

期待通り、イベントID:999かつイベントソース:aaa のイベントログのみが検知されました!

検知条件が増えれば増えるだけ条件の漏れや重複が起こりやすくなるというリスクを考えると、NXLogを用いたイベントログ監視は非常にカジュアルで手軽な方法だと言えそうです。

ログの運用:ログローテート

ちなみに、実際の運用現場ではログローテートして世代管理をするのが一般的かと思います。

NXLogの凄いところは、アプリケーション単体でログローテーションまでしてくれるところ。

しかも、設定を書き込むのは先ほど編集していたものと同じ設定ファイルです。「ローテートするための設定ファイルはどこだっけ?」「こっちの設定ファイルの書き方はどうだっけ?」などと混乱せずに済むので、かなり助かります。

書き込む設定内容もとても簡単なものなので、さっそく試してみましょう。

ローテート設定

confファイルの <Output> ~ </Output> 部分を下記のように変更してみます。

<Output eventlog_sys_out>
    Module om_file
    File 'C:\logs\eventlog-sys.log'
    <Exec>
        if file_size() > 30K
        {
        $newfile = file_name() + "_" + strftime(now(), "%Y%m%d%H%M%S");
        rotate_to($newfile);
        }
    </Exec>
</Output>

変更後、NXLogを再起動すると…

ログファイルが条件に基づいてローテートされる

どどーんとローテーションしてくれます。か、簡単すぎる…!!

今回は手っ取り早く結果が見たくて「ログファイルのサイズが30KBよりも大きくなったら」という条件にしていますが、とんでもない勢いでローテートされていきます。この辺りの条件は、マニュアルを参考によしなに調整してください。

古くなったログの削除

ログローテートを考える場合、ある程度の保存期間が過ぎたログをどうするかも気になりますよね。多くの運用現場では、圧縮したり削除したりして対応していると思います。

ご安心ください。NXLogは、圧縮も削除もできるんです。

試しに、先ほどローテートしたファイルを削除してみましょう。

confファイルに、新しく以下のようなブロックを追加します。

<Extension _fileop>
    Module      xm_fileop
	<Schedule>
		Every	3 min
		Exec	file_remove('C:\logs\eventlog-app.log_*',now());
	</Schedule>
</Extension>

<Schedule> ~ </Schedule> 部分に記載したfile_removeという関数によって、指定したファイル名(正規表現による条件付けも可能)、およびファイル作成日時(指定した日時より古いファイルが対象になる)に合致するファイルが削除されます。

再びNXLogを再起動すると…。  

設定した条件に合致するファイルのみが削除される

条件に合致するファイルのみが削除されました!!!

こちらも例によって「3分ごとに該当するファイルがないかチェックする」 「now()関数で取得した現在時刻よりもファイル作成日時の方がが古い場合に削除する」というなかなか乱暴な条件にしていますが、この設定だとローテート後のログファイルはロクに残りません。当然ですね。ここも、よしなに調整してください。

おまけ

快適Z Windowsイベントログ監視拡張オプション

今回はNXLogを用いることでWindowイベントログを「テキストログ監視」と同様に実現する方法を紹介しましたが、NXLogを使わずともイベントログ監視をより簡単に実装・管理できるようにしたい、という方もいらっしゃるかと思います。

アークシステムが提供している「まるごとおまかせZabbix」には、そのような方におすすめなとても便利なオプションがあるんです。


アークシステムが提供しているまるごとおまかせZabbixの「快適Z」には、Zabbix 単体では設定が難しい複雑な検知要件の Windows イベントログ監視を、GUIから簡単に設定出来る機能を提供するWindows 監視拡張オプションがあります。このオプションでは、専用ツールを監視対象にインストールすることにより、画面上で簡単にイベントログの通知条件/除外条件を設定することが出来ます。

イベントログ監視の最大難所である除外対象設定も、画面上で除外対象をクリックするだけ。

設定内容を視覚的に把握することができるため、Zabbix画面で条件式や正規表現の羅列を眺めるよりも断然分かりやすく、設定ミスによる誤検知を防ぐこともできます。

フィルタリング条件の複雑さにお悩みの方。GUIで視覚的にも分かりやすい運用をしたい方。 等々。

本オプションに少しでもご興味をお持ちの方がいらっしゃいましたら、是非以下のサービス紹介ページをご覧ください。

まとめ

  • NXLogを使ってイベントログをテキストファイルに出力すれば、ログが見やすく柔軟に扱えて監視設計もやり易くなるので、Zabbixでも簡単に監視できる
  • NXLogはインストールが簡単
  • NXLogはconfファイルをちょっと編集するだけで簡単に使える
  • 出力したテキストファイルのローテートもできるので、とってもお手軽で便利
  • 株式会社アークシステムの来訪管理・会議室予約システム BRoomHubs
  • 低コスト・短納期で提供するまるごとおまかせZabbix