Edited at

レアなログを再受信してSplunkのSPLがちゃんと動いているかどうか確かめたい(ログを再送する)


SplunkへのSyslog取り込み

Splunkへスイッチやルータ、サーバなどのログを取り込むときには、SyslogサーバにSplunkのuniversal forwarderをインストールしてSplunkにログを送り込むのが一般的だと思っている。

Syslogサーバに届いたログは、「スイッチのログ、ルータのログ、サーバのログ」とか、「ログインのログ、Webサーバのログ、Firewalldのログ」なんて具合に要件ごとにログ保存先を分けて保存すると、SplunkでIndexとsourcetypeを分けることができるようになり、後々扱いやすくなる。

分類したいログごとにファイルを分け、universal forwarderで個々のログファイル毎にIndexとSorucetypeを設定すると、Splunkで検索させるときに、検索範囲が狭くなるため検索が早くなる(はずだ)。


人生、思うようにはいかない

新たな機器のログをSplunkに取り込みたい場合、Syslogサーバに取り込むログが予めわかっていればSyslogサーバの設定をログが到達する前に事前に実施しておき、然るべきファイルに保存できるようになる。

だが、そんなうまい話は世の中に転がっていない。

大抵の場合、「肝心のモノが無いのに事前にログを取得できるわけないだろ」とか「繋いでみないとどんなログがでるかわかりません」とか「あー、ログね。わかってるんだけどね、繋げば送られるから、つながるまで待ってね」などと言われて、事前に手に入れられることはまずない。

あったとしても、Syslogサーバで適切に分類するように設定しても、うまく分類できるかどうかはログを受信してみないとわからない。


大抵の場合

とりあえずログを受信する前にSyslogの設定をきっちり終わらせることは諦めて、新しい機器のログを受信してもなくさないように、未分類のログをためるためのファイルを用意しておくことになる。言うなれば、なんだかわからない物は「タコ部屋」もしくは「掃き溜め」に行ってもらって、あとからゆっくりsyslogサーバの設定をして、適切に分類するということになる。

大抵の場合、ログはバンバン流れてきているので、この方法で、Splunkにindexやsourcetypeをつけて送付できるようになるし、うまく分類できたあとは、Splunkでうまいことサーチして解析できるようになる。


レアなログがあるんだよ

そんなログの中には、しょっちゅう出ているログもあれば、ユーザが何か特別なことをやったときのみにしか出てこないレア度が高いログがある。こうしたログはログ送信元の機器を管理している人などに何度もお願いしてレアなログを出してもらうことになるのだが、大抵の場合そんなログを出すためだけに時間を割いてくれるいい人はなかなかいない

レアなログが未分類のログファイルに保存されていても、Splunkではindexやsourcetypeが本来解析しようとしているものとは異なっているためサーチ文でうまく引っかかるかどうか検証のしようがない。

嘆いていてもしかたない。レアなログが未分類ファイル、もしくは、未分類sourcetypeとしてSplunkにデータとして保存されているなら、それを取り出して再送できないか?と考えた。


loggerだよ、logger!

そこで、loggerを使ってログを再送してみることにした。

まずはじめに、loggerコマンドの使い方を再確認する。

# logger -i local0.info test

これで確かに/var/log/message に

Mar 3 03:03:03 from_host_ip hoge[31275]: local0.info test

と出力された。

これで、testのところに、実際のログを貼り付ければログが再送できる。

(from_host_ipのところは、hostnameか送信元IPアドレスが入っている。)

と、甘い夢を見ていたのだが、loggerは1024byteまでしか送信できないらしい。

ログの中にはかなり長いものもある。というか、1024byteまでに収まるログなんてほとんど無い。

Windowsのeventログなんて、そりゃー長いの長くないのってくらい長い。

結局、この方法ではダメだということがわかった。


syslogサーバに頑張ってもらえないか?

CentOSやUbuntuにはじめから入っているsyslogサーバはrsyslogだ。rsyslogはファイルの最終行が書き足されたら、その行を他のsyslogサーバに送信することができるらしい。この機能を使って再送できないか考えた。

再送するファイル名を/var/log/resend_log.txtとした場合、この機能は、/etc/rsyslog.confの最後の方に

module(load="imfile")

# File 1
input(type="imfile"
File="/var/log/resend_log.txt"
Tag="test"
Facility="local0"
Severity="info")

local0.info @xxx.xxx.xxx.xxx:514

と書き加えてあげる。ここで、xxx.xxx.xxx.xxxはsyslogサーバのIPアドレスだ。

この/var/log/resend_log.txtに何か更新があるとrsyslogdが検知してsyslogサーバに送信してくれる。

(もちろん、/var/log/resend_log.txtは、試験するユーザが書き込めるよう権限を変えてあげるし、

 rsyslog.confの設定を変えたらプロセスをリスタートする必要がある)

なので、コマンドで

echo 'test test test' >> /var/log/resend_log.txt

なんてことをしてあげると、syslogサーバに、test test testというログが送信される。

やったじゃん。できるじゃん、と思ってsyslogサーバのログを確認したら「これじゃダメだ」ということに気がついた。


IPアドレスがーー!

受信側のSylogサーバは、ログを受信した際に送信元のIPアドレスをきちんと認識している。

ログデータのフォーマットとしては、

Mar 15 21:42:50 aaa.aaa.aaa.aaa kernel: Rejected LOG IPv4 (INPUT) :IN=eth0 OUT= MAC=01:02:03:04:05:06:07:09:0a:0b:0c:0d:0e:0f SRC=bbb.bbb.bbb.bbb DST=224.0.0.1 LEN=32 TOS=0x00 PREC=0xA0 TTL=1 ID=22991 PROTO=2 

※ aaa.aaa.aaa.aaaは送信元IPアドレス

「日時 送信元IPアドレス 内容」という感じのログになることが多い。

「内容」については、先程の例ではtest test testとなっていたが、送信元IPアドレスは、ログを再送しようとしたサーバのIPアドレスになってしまっている。

syslogを振り分ける際には、「内容」の部分にある、「ユニークな文字列」で分類するのだが、そういう文字列が必ずあるとは限らないため、送信元IPアドレスを元にrsyslogで振り分けることもよくある。というかそのほうが多いかもしれない。rsyslogはログのフォーマットを制御することもできるのだが、送信元IPアドレスは受信したログのIPヘッダを見てつけているので、IPアドレス自体をいじくることはできない。

このままでは「ログを再送する」という状態にはなっていない。どうしよう……


そこで……

IPアドレスはOSがつけているのでどうしてもOSに元からついているIPアドレスでログは送信されてしまう。僕はプログラムがかけないので、ローレベルでOSを騙してパケットを送信させるようなプログラムはかけない。

「OSにつけてあるIPアドレスとは異なるIPアドレスでパケットを送信させるんだよなー」と漠然と考えていたら、「それって、IP Spoofingってやつじゃね?」とひらめいた。

いやー、セキュリティって諸刃の剣。

IP SpoofingをLinuxサーバでやる方法が見つかれば、syslogサーバで受信するログに記載されるIPアドレスを、元のログに記載されたIPアドレスにすることができる。ということで、検索してみると…

iptables -t nat -A POSTROUTING -j SNAT --to-source aaa.aaa.aaa.aaa

この方法で元のログの中にあった送信元IPをaaa.aaa.aaa.aaaとしてあげるとできることがわかった。

戻す方法は

iptables -t nat -D POSTROUTING -j SNAT --to-source aaa.aaa.aaa.aaa

とすればよい。

ということで、手順としては

1. syslogサーバから再送したいログを抜き出す

2. 時間の部分を削除する

3. 送信元IPアドレス(ここではaaa.aaa.aaa.aaaとする)を記録して削除する

4. iptablesを使って送信元IPアドレスをaaa.aaa.aaa.aaaに設定する

5. 残った「内容の部分のログ」を/var/log/resend_log.txtに書き足してあげる

6. syslogサーバにログが送出される

7. iptablesを使ってIP Spoofingの状態を元に戻す

という順番でコマンドを打てば良い。

自動化するなら、シェルスクリプトを書いて、syslogサーバから取ってきたログを貼り付けるだけで良いようにしたりphpなんかを使ってWebアプリを作っても良いだろう。

これで、レアなログの試験を、自分の好きなときに好きなだけやることができるようになった。