fluentd でログを集めたい
なにも Elasticsearch で Kibana でふがほげとかは考えていなくて、何か所か借りている VPS への ssh とか http な攻撃のログをまとめて、共通した blacklist を作って、それぞれのインスタンスに配布したい。 攻撃側が分散処理をやっているのだから、しょぼいけど守る側も分散データを集めて処理したっていいじゃないか。
そんなことを考えている時に、ちょっと古い記事だけど Fluentdとはどのようなソフトウェアなのか - たごもりすメモ を読んだので、ログデータを集めるのは fluentd でやってみようと思ったのだった。
FreeBSD の syslog からローカルの fluentd に送る
httpd のログは file を tail するプラグインを使ってあっさり行った。問題は、sshd の認証関連のログが syslog に吐かれていることだけど、以下の設定でいけそうである。
fluent.conf
<source> @type syslog bind 127.0.0.1 port 5020 </source>
/usr/local/etc/syslog.d/fluent.conf
auth.info;authpriv.info @127.0.0.1:5020
/etc/rc.conf で syslog_flags="-ss" とかになっててはまったけど、まあそれはおいておく。
問題
この設定で動かすと、syslog からのメッセージを処理した結果の "host" の値が "sshd[12345]:" のように "ident" に入るべき内容になり、"ident" にはメッセージの最初の語が入ってしまう。でも /var/log/auth.log に記録されるログは次のように RFC3164 フォーマットになっている。
May 11 07:56:07 example sshd[6804]: Accepted keyboard-interactive/pam for cugel from 192.168.0.10 port 54764 ssh2
さんざん悩んだ挙句 tcpdump してみたら以下のようになっていて、RFC3164フォーマットにあるべき host のカラムが抜けていた。 /var/log/auth.log の方はちゃんと RFC3164 フォーマットなのに。
Facility auth (4), Severity info (6) Msg: May 10 01:45:33 sshd[20808]: Received disconnect from 115.69.232.33 port 12935:11: disconnected by user 01:45:33.844456 IP6 (hlim 64, next-header UDP (17) payload length: 94) localhost.syslog > localhost.5020: [bad udp cksum 0x0071 -> 0x0ea1!] SYSLOG, length: 86
解決方法
syslogd のオプションをごにょごにょしたら RFC3164フォーマットでなんとかならないかと思ったが無理だった。 それならというわけで、RFC5424フォーマットに なるように /etc/rc.conf で指定してみた。
syslogd_flags="-s -O rfc5424"
fluent.conf の方にも RFC5424フォーマットを指定した。
<source> @type syslog bind 127.0.0.1 port 5020 <parse> message_format rfc5424 </parse> </source>
tcpdump で見ても host がちゃんと含まれていて、それを受ける fluentd の方も、データを out_file フォーマットで保存してみたら次のようにきちんと処理されている。
2019-05-11T02:17:37+09:00 system.auth.info {"host":"example.ne.jp","ident":"sshd","pid":"24374","msgid":"-","extradata":"-","message":"reverse mapping checking getaddrinfo for 106.xxx.xxx.xxx.isp.timbrasil.com.br [xxx.xsx.xxx.106] failed."}
この先
それぞれのメッセージから IP アドレスと認証の成功/失敗/ワン切りを判別して、時刻付きで DB に入れてカウントするということをしたい。まあそのうち。