SUSE Linux 15 inotify-tools でファイルアクセス監査

一般的に Linux のファイルアクセス監査ってどうするのか、ふと疑問が出てきました。そこで、SUSE Linux 15(openSUSE/SLE) でファイルアクセス監査ツール inotify-tools を使ったファイルアクセスのチェック方法を調べてみました。

inotify - get your file system supervised

inotify自体は、カーネルに組み込まれた API でそのAPIから、ファイルアクセス監視をするためのツールが inotofiwait と inotifywatch コマンドです。



- openSUSE 15 での inotify-tools インストール -

openSUSE 15.1 では標準リポジトリに inotify-tools パッケージが含まれているので、zypper か YaST の Software Management からインストールできます。

SUSE Linux でパッケージインストールの色々な方法
https://islandcnt.exblog.jp/240051518/

YaST (yast2) による SUSE Linux のパッケージ管理, インストールと削除
https://islandcnt.exblog.jp/23923745/

SUSE Linux 15 YaSTの基本 (openSUSE Leap, SLE)
https://islandcnt.exblog.jp/238758768/

SUSE Linux 15 inotify-tools でファイルアクセス監査_a0056607_12173895.png



- SLE15 の場合 inotify-tools のインストール -

SLE15 の標準パッケージや、リポジトリに含まれていません。2020の現時点では1 Click Install はできないようです。

そこで openSUSE の 1  Click インストールから、"Expart Download"を開いて、指示通り zypper install しました。SLE のユーザ登録したレポジトリではないので、エラーが出まくりました。エクスパートインストールでは、次のコマンドラインが提示されたので、そのまま実行してインストールできました。


# zpper addrepo https://download.opensuse.org/repositories/filesystems/SLE_15/filesystems.repo
# zypper refresh
# zypper install inotify-tools

インストールができたら、inotifywait, inotifywatch というコマンドがインストールされます。
opensuse151:~ # find / -name "inotify*"
/usr/share/man/man1/inotifywait.1.gz
/usr/share/man/man1/inotifywatch.1.gz
/usr/share/man/man7/inotify.7.gz
/usr/share/man/man2/inotify_add_watch.2.gz
/usr/share/man/man2/inotify_init.2.gz
/usr/share/man/man2/inotify_init1.2.gz
/usr/share/man/man2/inotify_rm_watch.2.gz
/usr/lib/perl5/vendor_perl/5.26.1/x86_64-linux-thread-multi/bits/inotify.ph
/usr/lib/perl5/vendor_perl/5.26.1/x86_64-linux-thread-multi/linux/inotify.ph
/usr/lib/perl5/vendor_perl/5.26.1/x86_64-linux-thread-multi/sys/inotify.ph
/usr/bin/inotifywait
/usr/bin/inotifywatch
/proc/sys/fs/inotify


- inotifywait のヘルプを見てみた -

opensuse151:~ # inotifywait --help
inotifywait 3.14
Wait for a particular event on a file or set of files.
Usage: inotifywait [ options ] file1 [ file2 ] [ file3 ] [ ... ]
Options:
        -h|--help       Show this help text.
        @<file>         Exclude the specified file from being watched.
        --exclude <pattern>
                        Exclude all events on files matching the
                        extended regular expression <pattern>.
        --excludei <pattern>
                        Like --exclude but case insensitive.
        -m|--monitor    Keep listening for events forever.  Without
                        this option, inotifywait will exit after one
                        event is received.
        -d|--daemon     Same as --monitor, except run in the background
                        logging events to a file specified by --outfile.
                        Implies --syslog.
        -r|--recursive  Watch directories recursively.
        --fromfile <file>
                        Read files to watch from <file> or `-' for stdin.
        -o|--outfile <file>
                        Print events to <file> rather than stdout.
        -s|--syslog     Send errors to syslog rather than stderr.
        -q|--quiet      Print less (only print events).
        -qq             Print nothing (not even events).
        --format <fmt>  Print using a specified printf-like format
                        string; read the man page for more details.
        --timefmt <fmt> strftime-compatible format string for use with
                        %T in --format string.
        -c|--csv        Print events in CSV format.
        -t|--timeout <seconds>
                        When listening for a single event, time out after
                        waiting for an event for <seconds> seconds.
                        If <seconds> is 0, inotifywait will never time out.
        -e|--event <event1> [ -e|--event <event2> ... ]
                Listen for specific event(s).  If omitted, all events are
                listened for.

Exit status:
        0  -  An event you asked to watch for was received.
        1  -  An event you did not ask to watch for was received
              (usually delete_self or unmount), or some error occurred.
        2  -  The --timeout option was given and no events occurred
              in the specified interval of time.

Events:
        access          file or directory contents were read
        modify          file or directory contents were written
        attrib          file or directory attributes changed
        close_write     file or directory closed, after being opened in
                        writeable mode
        close_nowrite   file or directory closed, after being opened in
                        read-only mode
        close           file or directory closed, regardless of read/write mode
        open            file or directory opened
        moved_to        file or directory moved to watched directory
        moved_from      file or directory moved from watched directory
        move            file or directory moved to or from watched directory
        create          file or directory created within watched directory
        delete          file or directory deleted within watched directory
        delete_self     file or directory was deleted
        unmount         file system containing file or directory unmounted
opensuse151:~ #


- inotifywait の使用例 -

1. 一番単純な使い方

opensuse151:~ # inotifywait   /etc/hosts
Setting up watches.
Watches established.
/etc/hosts OPEN
opensuse151:~ #

ファイルオープンの後 access がありますが、一発目のイベント、”open” のみ記録されます。
今度は -e イベント access を付けて、「ファイルが読みだされた」イベントを監視します。

opensuse151:~ # inotifywait   -e access  /etc/hosts
Setting up watches.
Watches established.
/etc/hosts ACCESS
opensuse151:~ #

2. 指定した /etc/passwd ファイルに -e vent に access 一発アクセスがあれば log.txt に時刻を記録してそのまま終了する。

常駐したら /etc/passwd ファイルを読み込んでみます。

opensuse151:~ # inotifywait  -e access  --outfile=log.txt -q  --format \
'%T %w%f (%e)' --timefmt '%F %T'  /etc/passwd 
opensuse151:~ # cat log.txt
2020-02-08 13:42:55 /etc/passwd (ACCESS)
opensuse151:~ # ps ax | grep inotify
18129 pts/0    S+     0:00 grep --color=auto inotify
opensuse151:~ #


一発アクセスで終了した。

3. -r オプションで /etc/ の下の何かのファイルに -e イベント Access があれば記録する。-m は常駐モニタモード、 -r で指定したディレクトリ以下を全部再帰的に監査。
コマンドの末尾に "&" を付けてデーモン化させる。 --outputfile でログファイルに記録する。


opensuse151:~ # inotifywait -m -r -e access  \
--outfile=log.txt -q /etc/ &
[2] 17390
opensuse151:~ # cat log.txt
/etc/ ACCESS passwd
/etc/ ACCESS passwd
/etc/ ACCESS hosts
opensuse151:~ # ps ax | grep inoti
17390 pts/0    S      0:00 inotifywait -m -r -e access --outfile=log.txt -q /etc/
17410 pts/0    S+     0:00 grep --color=auto inoti

opensuse151:~ # kill 17390 ログがあふれるのでkillする


常駐しているので kill しました。
常駐しているので複数のイベントが記録されます。

4. 3.にもう少し色を付けてアクセス時刻をログに書きます。& を付けてデーモン化させます。
opensuse151:~ # inotifywait -m -r -e access  --outfile=log.txt \
q --format '%T %w%f (%e)' --timefmt '%F %T' /etc/ &
[2] 17743
opensuse151:~ # ps ax | grep inoti
17743 pts/0    S      0:00 inotifywait -m -r -e access --outfile=log.txt -q --format %T %w%f (%e) --timefmt %F %T /etc/
17753 pts/0    R+     0:00 grep --color=auto inoti
opensuse151:~ # kill 17743
opensuse151:~ # cat log.txt
2020-02-08 13:37:40 /etc/passwd (ACCESS)
2020-02-08 13:37:50 /etc/hosts (ACCESS)
opensuse151:~ #


ファイルアクセスのイベントが記録できますが、低水準ファイルシステムの API なので、誰がアクセスしたのかの監視はできないようです。

- inotifywatch も見てみる -

こちらは、ファイルアクセスのイベントの統計を取るために利用します。
まず inotifywatch のヘルプから

opensuse151:~ # inotifywatch --help
inotifywatch 3.14
Gather filesystem usage statistics using inotify.
Usage: inotifywatch [ options ] file1 [ file2 ] [ ... ]
Options:
        -h|--help       Show this help text.
        -v|--verbose    Be verbose.
        @<file>         Exclude the specified file from being watched.
        --fromfile <file>
                Read files to watch from <file> or `-' for stdin.
        --exclude <pattern>
                Exclude all events on files matching the extended regular
                expression <pattern>.
        --excludei <pattern>
                Like --exclude but case insensitive.
        -z|--zero
                In the final table of results, output rows and columns even
                if they consist only of zeros (the default is to not output
                these rows and columns).
        -r|--recursive  Watch directories recursively.
        -t|--timeout <seconds>
                Listen only for specified amount of time in seconds; if
                omitted or 0, inotifywatch will execute until receiving an
                interrupt signal.
        -e|--event <event1> [ -e|--event <event2> ... ]
                Listen for specific event(s).  If omitted, all events are
                listened for.
        -a|--ascending <event>
                Sort ascending by a particular event, or `total'.
        -d|--descending <event>
                Sort descending by a particular event, or `total'.

Exit status:
        0  -  Exited normally.
        1  -  Some error occurred.

Events:
        access          file or directory contents were read
        modify          file or directory contents were written
        attrib          file or directory attributes changed
        close_write     file or directory closed, after being opened in
                        writeable mode
        close_nowrite   file or directory closed, after being opened in
                        read-only mode
        close           file or directory closed, regardless of read/write mode
        open            file or directory opened
        moved_to        file or directory moved to watched directory
        moved_from      file or directory moved from watched directory
        move            file or directory moved to or from watched directory
        create          file or directory created within watched directory
        delete          file or directory deleted within watched directory
        delete_self     file or directory was deleted
        unmount         file system containing file or directory unmounted
opensuse151:~ #


-e でイベント access, open を -r で /etc の下全部 -t 20 秒間、 -v verbose モードで統計を取ってみる。 
opensuse151:~ # inotifywatch -r -e access -e open -t 20 -v /etc
Establishing watches...
Setting up watch(es) on /etc
OK, /etc is now being watched.
Total of 394 watches.
Finished establishing watches, now collecting statistics.
Will listen for events for 20 seconds.
total  access  open  filename
6      0       6     /etc/zabbix/web/
6      2       4     /etc/
opensuse151:~ #




- まとめ -

実際には、スクリプトを書いて、特定のファイルにイベントが発生したらログに残すとかメールするとかに使えるようです。

また、incron と言う cron の様なツールで、イベントが発生したら処理を実行するという地味に資料が少ないツールも別にありました。試してみるのもいいでしょう。

inotify - get your file system supervised

inotify

また audit コマンドが openSUSE 15 には標準で入っているようなので、これもまた方法。それに AppArmor もあったなぁ。それぞれ目的も用途も違います。
と、あまり突っ込むとハマりそうで深いのがファイルアクセス監査のツールなのだな、と感じました。





by islandcenter | 2020-02-10 13:21 | SUSE | Comments(0)