Linux(xfs)がファイル作成日付を記録してくれないので

取れるんじゃねーのと、割と気軽に調べ始めたLinux上でのファイル作成日付はどうやら鬼門らしく、最近のRHEL7とかCENTOS7でデフォルトで使われているxfsではファイルシステムにそのようなレコードが記録されることすらないそうで、ファイルからは取得できない。ext4とか使えば方法はあるのだけども、まあ、xfsの方がきっと多勢ですよね、今どきは。

じゃあどうするんだと１時間考えた結果、auditで特定ディレクトリ下のファイル作成をウォッチして個別にログに記録しておくなりするのがよかろうという個人的結論に達したので、以下メモ。

# auditでディレクトリへのファイル作成を監視する
auditctlコマンドでディレクトリ変更を監視する設定を追加する。

```
# mkdir /test
# auditctl -w /test/ -p w
```

（動作確認）
ターミナルを２つ開き、一方はtail -fでaudit.logを出力し、他方でファイルを出力する。

```
# tail -f /var/log/audit/audit.log
```

```
# echo hello>>/test/hello
# echo hello>>/test/hello
# rm /test/hello
rm: remove regular file ‘/test/hello’? y
```

するとまあ、以下のようなログが出力される。
なので、ファイルの作成をフックしたいなら '^type=PATH .* name="/test/.* objtype=CREATE$' あたりを抽出すればいいかなという目途がつく。

```
type=SYSCALL msg=audit(1529248300.233:19145): arch=c000003e syscall=2 success=yes exit=3 a0=1ccea00 a1=441 a2=1b6 a3=0 items=2 ppid=28416 pid=28504 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=77 comm="bash" exe="/usr/bin/bash" key=(null)
type=CWD msg=audit(1529248300.233:19145):  cwd="/root"
type=PATH msg=audit(1529248300.233:19145): item=0 name="/test/" inode=33576278 dev=fd:00 mode=040755 ouid=0 ogid=0 rdev=00:00 objtype=PARENT
type=PATH msg=audit(1529248300.233:19145): item=1 name="/test/hello" inode=33576259 dev=fd:00 mode=0100644 ouid=0 ogid=0 rdev=00:00 objtype=CREATE
type=PROCTITLE msg=audit(1529248300.233:19145): proctitle="-bash"
type=SYSCALL msg=audit(1529248301.624:19146): arch=c000003e syscall=2 success=yes exit=3 a0=1cb1200 a1=441 a2=1b6 a3=0 items=2 ppid=28416 pid=28504 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=77 comm="bash" exe="/usr/bin/bash" key=(null)
type=CWD msg=audit(1529248301.624:19146):  cwd="/root"
type=PATH msg=audit(1529248301.624:19146): item=0 name="/test/" inode=33576278 dev=fd:00 mode=040755 ouid=0 ogid=0 rdev=00:00 objtype=PARENT
type=PATH msg=audit(1529248301.624:19146): item=1 name="/test/hello" inode=33576259 dev=fd:00 mode=0100644 ouid=0 ogid=0 rdev=00:00 objtype=NORMAL
type=PROCTITLE msg=audit(1529248301.624:19146): proctitle="-bash"
type=SYSCALL msg=audit(1529248304.865:19147): arch=c000003e syscall=263 success=yes exit=0 a0=ffffffffffffff9c a1=1ec00c0 a2=0 a3=7fff9b81d8e0 items=2 ppid=28504 pid=11389 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=77 comm="rm" exe="/usr/bin/rm" key=(null)
type=CWD msg=audit(1529248304.865:19147):  cwd="/root"
type=PATH msg=audit(1529248304.865:19147): item=0 name="/test/" inode=33576278 dev=fd:00 mode=040755 ouid=0 ogid=0 rdev=00:00 objtype=PARENT
type=PATH msg=audit(1529248304.865:19147): item=1 name="/test/hello" inode=33576259 dev=fd:00 mode=0100644 ouid=0 ogid=0 rdev=00:00 objtype=DELETE
type=PROCTITLE msg=audit(1529248304.865:19147): proctitle=726D002D69002F746573742F68656C6C6F
```

# ファイルが作成されたタイミングでアクションを実行
単にファイル作成ログを別ファイルに抽出するでも良いかもしれないが、ファイル作成されるたびに何らかのコマンドを実行するなら以下のような感じ。例ではsyslogに作成されたファイル名を出力。

```
# tail -f /var/log/audit/audit.log | awk 'match($0, /^type=PATH .* name=\"(\/test\/[^\"]*)\" .* objtype=CREATE$/, a){system("logger -t test " a[1]);}'
```

# それをsystemdに設定する
tail -fほにゃららをシステム起動時に実行するには以下。
一応rsyslogとauditdは開始を待つ。

```
# cat > /root/dirwatch.sh << 'EOF'
#! /usr/bin/bash
tail -f /var/log/audit/audit.log | awk 'match($0, /^type=PATH .* name=\"(\/test\/[^\"]*)\" .* objtype=CREATE$/, a){system("logger -t dirwatch " a[1]);}'
EOF
# chmod +x /root/dirwatch.sh
# cat > /root/dirwatch.service << 'EOF'
[Unit]
Description=Directory Watcher (/test)
After=syslog.target auditd.service

[Service]
ExecStart=/root/dirwatch.sh

[Install]
WantedBy=multi-user.target
EOF
# cp dirwatch.service /usr/lib/systemd/system/
# systemctl daemon-reload
# systemctl enable dirwatch
# systemctl start dirwatch
```