audit.logのパーサを書いた

先日、Kyoto.rbがあったので、参加してもくもくとLinuxauidt.logのパーサを書いてきた。

github.com

audit.logは構造化されているようでいて、微妙に例外のあるフォーマットで*1Red 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プラグインも書いた。

github.com

audit.logはrsyslogに対応しているので、集約のためにfluentdを使う必要はないんだけれど、集約先でいろいろ加工してほかのサービスに送ったりするには、やはりfluentdが便利。

(追記)

ausearchで絞り込めているのを見ると、内部的に何らかのパース処理をやっていると思うんだけど。 ソースコード読まねば。

(追記2)

既存のあった

github.com

*1:postfixのログもそんな感じだった