先日、Kyoto.rbがあったので、参加してもくもくとLinuxのauidt.logのパーサを書いてきた。
audit.logは構造化されているようでいて、微妙に例外のあるフォーマットで*1、Red Hatのドキュメントを見ても、以下のような感じで
type=SYSCALL msg=audit(1364481363.243:24287): arch=c000003e syscall=2 success=no exit=-13 a0=7fffd19c5592 a1=0 a2=7fffd19c4b50 a3=a items=1 ppid=2686 pid=3538 auid=500 uid=500 gid=500 euid=500 suid=500 fsuid=500 egid=500 sgid=500 fsgid=500 tty=pts0 ses=1 comm="cat" exe="/bin/cat" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key="sshd_config" type=CWD msg=audit(1364481363.243:24287): cwd="/home/shadowman" type=PATH msg=audit(1364481363.243:24287): item=0 name="/etc/ssh/sshd_config" inode=409248 dev=fd:00 mode=0100600 ouid=0 ogid=0 rdev=00:00 obj=system_u:object_r:etc_t:s0 type=DAEMON_START msg=audit(1363713609.192:5426): auditd start, ver=2.2 format=raw kernel=2.6.32-358.2.1.el6.x86_64 auid=500 pid=4979 subj=unconfined_u:system_r:auditd_t:s0 res=success type=USER_AUTH msg=audit(1364475353.159:24270): user pid=3280 uid=500 auid=500 ses=1 subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 msg='op=PAM:authentication acct="root" exe="/bin/su" hostname=? addr=? terminal=pts/0 res=failed'
- ヘッダ部?は固定のように見えるが、rsyslogを通すと
node=...
がつく - ボディ部?は
key=value
の空白区切りのように見えるがauditd start,
というメッセージが現れたりするuser pid=
のように、キー部分に空白を許容しているmsg='op=PAM:authentication acct="root"
のように、入れ子になっていたりする
また、エスケープについては \"
みたいなエスケープではなくて、空白・"
・'
が入ると16進数文字列にエスケープされる(ほかにもエスケープされる文字はあるかも)
Nov 4 03:15:09 localhost audispd: node=ldap-client-001 type=USER_CMD msg=audit(1541301309.434:92): pid=1757 uid=10000 auid=10000 ses=1 msg='cwd="/home/sugawara" cmd=636174202F7661722F6C6F672F666F6F332E6C6F67 terminal=pts/0 res=success'
["636174202F7661722F6C6F672F666F6F332E6C6F67"].pack('H*') #=> "cat /var/log/foo3.log"
フォーマットについては、公式のWikiがやや詳しいような気がする。
パーサぐらいその辺にありそうだと思って、いろいろ探してみたけれど、結局見つからなかったのでRubyで書いた。
パーサを書いたついで…というかこっちが本命だけれど、fluentdのfilterプラグインも書いた。
audit.logはrsyslogに対応しているので、集約のためにfluentdを使う必要はないんだけれど、集約先でいろいろ加工してほかのサービスに送ったりするには、やはりfluentdが便利。
(追記)
ausearch
で絞り込めているのを見ると、内部的に何らかのパース処理をやっていると思うんだけど。
ソースコード読まねば。
(追記2)
既存のあった