Fluentd + Kibana3 で FortiAnalyzer いらず (更新あり)

2013-10-15 ちょいと更新

いや、FortiAnalyzer 使ったこと無いんでホントに代わりになるかどうか知らないんですけど、お高いんですよ(ね?)今はクラウド版っつーのもあるみたいですね。

で、FortiAnalyzer が無いとログをマトモに見れないのかなぁなんて思ってたんですけど、どうやって Analyzer にログ送ってるんだろう?って試したら Syslog (UDP) だったんですね。TCP の 514 にも謎のパケットが飛んでるけどそっちは放置。

Syslog だったらファイルに書き出したものを Fluentd でなんとでもなるぞと。

ログのフォーマットは次のような感じで key=value がスペース区切りで並んでいます。value にスペースが含まれる可能性のある場合はクオートされます key="aaa bbb" のように。ただし、 service という項目だけはスペースを含む可能性があるのにクオートされません。でも幸い、この項目にスペースが入るのはカスタム設定で自分でスペースを入れて設定した場合のみなので回避可能です。

Oct 10 00:00:00 192.168.1.1 date=2013-10-09 time=23:59:59 devname=FG..... device_id=FG... \
  type=traffic subtype=other pri=warning status=deny vd="root" \
  src=192.168.1.2 srcname=192.168.1.2 src_port=1234 \
  dst=192.168.1.255 dstname=192.168.1.255 \
  dst_country="Reserved" src_country="Reserved" ....

これの parser を Fluentd の plugin として書きました。
https://gist.github.com/yteraoka/6911252

FortiGate のログはすごく項目が多くて、Kibana3 で見る必要の無い項目は ElasticSearch に入れたくなかったので必要な項目だけに絞るか、不要な項目を削るという機能を入れました。需要なさそうだから gem にしたりしない。/etc/td-agent/plugins/ に置けば使えるので。

※ 2013-10-15追記 (1)
書いてる時からヒドいなぁと思いながらいた Loop での gsub! はやっぱりとっても重いので書き直しました。Gist に Bench も載っけておきました。

ここまで来れば、後は fluent-plugin-elasticsearchElasticSearch に突っ込んで Kibana3 で自由自在です。Kibana3 については前回の 「Kibana3 を使ってみよう」 をどうぞ。

FortiGate のログには src_country, dst_country という項目に国名を出力してくれます。でも、2文字の国コードじゃないので http://dev.maxmind.com/geoip/legacy/geolite/ あたりからリストをダウンロードして置換してあげれば Kibana3 の World Map 機能が使えそうです。

Syslog は rsyslog の Template 機能で出力先を日別に変わるようにしているのですが、この場合、Fluentd 付属の in_tail ではそのままでは日をまたげません。でも fluent-plugin-tail-ex ってのがあるよって教えてもらいました。


これは便利そうだという事で試してみたものの、pos_file が効かないのと、停止時になんかエラーが出るのが気になったので見送りました。詳細は調べてない。またオレオレ plugin を書こうかとも思いましたが、 fluent-plugin-tail-asis ほど簡単にも書けなさそうだったから symlink を張り替えるスクリプトを書くことで対応しました。ところで、今回は parse 処理は out_fortigate_syslog_parser.rb で行うので tail で parse する必要がないため、使うなら fluent-plugin-tail-ex-asis の方がより合っていそうです。(tail-asis 相当の機能は none parser として本家に merge されたので asis の役割は終わりました)

rsyslog の Template を使った例

$template HostSeparatedDailyLogFile,"/some/where/%syslogfacility-text%/%$YEAR%%$MONTH%%$DAY%/%HOSTNAME%"
*.* ?HostSeparatedDailyLogFile

Kibana3 を使ってみよう」 の中で触れた ElasticSearch の Template 機能ですがちょうど良い例を見つけました。 https://gist.github.com/deverton/2970285 これを参考にすると良さげです。ElasticSearch には ip っていうタイプもあったので IP アドレスのところはこれを使ってみました。

FortiGate ユーザーのみなさん、FortiAnalyzer 買ってなかったら試してみてください。ではでは。

※ 2013-10-15追記 (2)
@ipv6labs さんから「区切り文字カンマでロギングすると楽ですよ」と助言をいただき、「え? CSV 出力って syslog の設定にしかないんじゃないの?そして syslog だと traffic ログって出せないんじゃ??」って思ってたん出すけどやり取りの中で config log syslogd filter で設定できそうなことがわかりました。ありがとうございます。
log : {disk | fortianalyzer | fortianalyzer2 | fortianalyzer3 | memory | syslogd | syslogd2 | syslogd3 | webtrends | fortiguard} filter
でもまぁ、カンマ区切りにしても

dns_name="www.googleadservices.com",dns_ip="173.194.38.90,173.194.38.89,173.194.38.77"

とか、値にもカンマが入るし、 CSV って言っても値が key="value" だし...
まぁ、書きなおさなくてもいっかな。

あ、そもそもの問題は key に空白が含まれる可能性があるってやつだからやっぱりカンマ区切りにしておこう。

Kibana3 を使ってみよう #kibana3

話題の kibana3 を使ってみたメモです。
fluentd-plugin-elasticsearchElasticSearch に突っ込めば簡単に Kibana3 を試せるよっていうブログはちょいちょい見るのですが、Kibana3 をどうやって使うのか書かれてるものが少ないようなので書いてみます。そういうことなので、ElasticSearch に取り込むところまでは省略。

でも一点だけ、ElasticSearch の template 機能を使ったほうが良いですよ(と会社の同僚に教えてもらいました)。
fluentd-plugin-elasticsearch はすべてのフィールドを文字列として送ってしまうので、ElasticSearch 側でこのフィールドは Integer だよとか、日付型だよって教えてあげないと行けませんが、Kibana では日毎のインデックスを使うのでインデックス毎に設定するのは厳しいです。template を設定しておくと、指定したルールにマッチするインデックスに自動でスキーマが適用されます。全部のフィールドを指定する必要がありません。文字列で良いフィールドは放置でOK。複数サービスでも使えるようにインデックスの名前と template のマッチ条件を合わせてあげるのが良いです。Integer 指定は重要で、Kibana3 で合計や平均値をグラフにするのに必要です。文字列よりもインデックスサイズが小さくなりますしね。

Kibana3 の初期ページこれが、Kibana3 の初期ページです。


右下の

  1. Sample Dashboard
  2. Unconfigured Dashboard
  3. Blank Dashboard

から始めても良いですし、左上の Introduction と書いてある右の歯車アイコンで、このページを直接いじっても良いです。

それでは、歯車から設定していきましょう。
Index 指定まずは、インデックス名の指定です。 Timestamping で none 以外を選択すると左のフォームが表示されるので、[logstash-]YYYY.MM.DD の logstash- 部分を自分で指定したものに変更しましょう。


次はパーツを配置するための行 (rows) を作成します。
Kibana3 row 設定行のタイトルと高さ(ピクセル)を指定して作成します。順番は後から変更できます。行を作成するとページの左端に行のタイトルが表示されます。それぞれの行にどのパーツを配置するかはタイトルの上にある小さな歯車アイコンから行います。


Kibana3 panelsTwieer Bootstrap なので(ですよね?)各パーツの幅を12段階から選択します。


パネルの種類には次のものがあります。

  • bettermap
  • column
  • dashcontrol
  • derivequeries
  • fields
  • filtering
  • histgram
  • hits
  • map
  • pie
  • query
  • table
  • terms
  • text
  • timepicker
  • trends

が、ここでは私の使ったものだけを簡単に紹介します。
全体像はこんな感じ全体像はこんな感じ。


timepicker panelまずは TImepicker から。これで対象範囲を期間で絞ります。Relative, Absolute, Since の3タイプがあります。ワンクリックで相互切り替えできます。


Timepicker relativeRelative: ワンクリックで過去5分とか過去6時間とか切り替えられます。並べるリストもカスタマイズ可能です。


Timepicker absoluteAbsolute: 開始、終了日時を直接指定します


Timepicker sinceSince: 指定の日時以降を対象にします


search期間が絞れたところで、次は query で対象を絞ります。複数の検索条件を保存でき、それぞれの条件を使ってグラフなどを表示することができます。検索クエリの Syntax は Lucene のページを確認しましょう。
LuceneTutorial.com とか?最後の欄にある「+」アイコンをクリックすることでクエリを追加できます。


Query Alias色のついて丸いところをクリックすると別の色を選択することができます、また、クエリが長いとわかりづらいので名前をつけることができます。日本語も可。グラフの方にはその名前で表示されます。左上のピンアイコンをクリックすると pinned 状態にできます。グラフのパネルで queries 選択で pinned, unpinned を選択することで pinned したものを対象にしたり、その逆にしたりをして簡単に表示対象を切り替えることができます。


Kibana3 Access Count Panel続いてヒストグラムを使って、アクセス数を表示します。この例では Lines を選択しています。線の太さも選べます。複数の線グラフを並べるので Stack のチェックを外してあります。


Kibana3 Access Countこんなグラフになります。Countだじゃなくて、Max, Mean, Min というのもあるのでレスポンスタイムの最大値や平均値のグラフも簡単にできます。


Kibana3 Response Timeこれもヒストグラムですが、今度はレスポンスタイム毎に Stack する棒グラフにしてみました。「< 200ms」などクエリのAliasが表示されていますね。このクエリは「usec:[0-199999]」てな感じです。

Pie Chartお次はステータスコードのパイチャート


あと、全体像の下につらつらと表示されているのは「table」というパネルで、検索条件にマッチしたログがリスト表示されます。ページングサイズも指定可能。クリックするとそのログについてインデックスされているすべての情報が確認できます。User-Agent とか Remote Host とか。


Kibana3 Save苦労して設定したパネルは右上のフロッピーディスクアイコン(若者にはわからない?)をクリックし、名前をつけて保存しておきましょう。次からフォルダアイコンから呼び出せます。デフォルトに指定することもできます。

はあ〜長かった(画像が多いだけか)。

どうでしょう?試してみたくなりました?

もっとこうやったら良いとか便利情報お待ちしてます。

あ、そうそう、日別に作られてるインデックスは貯めこまないで削除しましょう。APIを駆使すれば自動化可能です。Vagrant で 1GB heap の環境で試してたけど、このブログのアクセスログ(少ない)を数ヶ月分突っ込んでみたら、ちょいちょい応答がなくなって ElasticSearch を再起動すると復活するような感じでした。