はじめに
表題のとおりなのだが、3rdパーティ製品を使わずに、OSの監査ログを取得する方法を考えてみる。
調べてみると、方法としては以下の3つみたい
- scriptコマンド
- psacctツール
- audit
検討
script vs psacct
scriptとpsacctの比較は、クラメソさんの記事を参考にしました。
scriptとpsacctの比較の場合、scriptコマンドの方がよさそう。
psacctは設定が楽なのはいいんだけど、調整可能項目が少ない。コマンド引数と実行結果がわからないのも、実用を考えるととても微妙。デーモンプロセスがスクリプトからコマンドたくさん実行していると、そのコマンドも大量に記録されるので、特定のインタラクティブ・セッションから、何のコマンドが実行されたかを見るのがつらい。
ただ、scriptは改竄が容易なのがネック。その点、psacctはrootでなければ改竄できない。
script vs audit
auditでの設定方法は、RHELのナレッジベース(1193303)を参考にしました。
auditのログは、rootでなければ改竄できないのと、いつ・誰が・何したをaureportで一覧表示できるのはよい。ただ、「何した」の部分がめちゃくちゃわかりずらいのだよね。やっぱり。Backspaceやら十字キーとかの操作が入ってくると最終的に実行した文字列の判別が非常にしんどい。
そういう意味では、scriptも見ずらいのだけど、scriptreplayコマンドを使うとめっちゃ見やすいのを知って、がぜんscript推しになってきた。 scriptreplayは、RHELのナレッジベース(2142441)を参考にしました。
scriptログの改ざん対策を考える
scriptの問題は、改ざんが容易なこと。rootになれたら改ざんできてしまうのは、他のツールも同じなので考えない。それを気にする必要がある場合は、おとなしく3rd Party製品の利用を検討する。
これを緩和するために、ログの作成と同時にchattr +a して追記しかできないようにすればいいんじゃない?と思いついて、調べてみた。
これも、RHELのナレッジベース(911493)からヒントをもらったのだが、inotifywaitコマンドを利用して、ファイルの作成をトリガーにコマンド実行できそう。
これを使って、ログイン→scriptコマンドの自動実行→ログファイルにchattr +aして追記しかできないようにしてみる
やってみる
inotify-toolsのインストール
デフォルトでは入ってなかったのでインストールする
# yum install inotify-tools
ディレクトリ作成
操作ログを出力するディレクトリを作成。すべてのユーザがファイルを作成できるが、他のユーザが作成したファイルを削除できないようにスティッキービットを立てる
# mkdir /var/log/ope_log
# chmod 1777 /var/log/ope_log
ログイン時にscriptコマンドが自動実行されるようにする
# cd /etc/profile.d/
# vi start_opelog.sh
以下のようなスクリプトを書く。
-
scriptコマンドの実行対象を、以下の通りにする。
-
親プロセスのPIDがsshdの場合 (そうしないと、start_opelog.shの実行がループしちゃう)
-
UIDが1000または5000以上 (OCIのOELつかってるので、1000はopcユーザ。その他ログイン用のユーザのuidを5000以上で作ってると仮定)
-
ログファイル名にユーザ名と日付、SSHクライアントIPを埋め込んで、いつ・誰が・どこからをファイル名で判別できるようにする。
-
scriptコマンドから抜けたら、exitしてセッションが終了するようにする。
# ---- start_opelog.sh ----
OPE_LOG_DIR=/var/log/ope_log
parent_process=$(ps -eo pid,comm |awk '$1=="'$PPID'" {print $2}')
time_prefix=$(date '+%Y%m%d%H%M%S')
# Get Client IP Address
if [[ -z ${SSH_CLIENT} ]]; then
client_ip='UNKNOWN'
else
client_ip=$(echo ${SSH_CLIENT} |grep -E -o -e "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+")
if [[ -z ${client_ip} ]]; then
client_ip='UNKNOWN'
fi
fi
log_name=${OPE_LOG_DIR}/$(whoami)_${time_prefix}_${client_ip}.log
timelog_name=${OPE_LOG_DIR}/$(whoami)_${time_prefix}_${client_ip}.time
# Check if parent process is sshd or not
is_parent_sshd() {
if [[ ${parent_process} =~ sshd ]]; then
return 0
else
return 1
fi
}
# Check user uid
is_target_uid() {
if [[ ${UID} -eq 1000 ]]; then
return 0
elif [[ ${UID} -ge 5000 ]]; then
return 0
else
return 1
fi
}
# If condition matches, start script and exit when script command ends
if is_parent_sshd && is_target_uid; then
LANG=en_US.UTF-8; script -f -q -t 2>${timelog_name} ${log_name}
exit
fi
ここまでで、ログイン用ユーザからログインした時にスクリプトログが取得できるようになっているはず
んで、このままだと改竄が容易なので、操作ログ出力先ディレクトリをinotifywaitで監視して、CREATE発生時にchattr +aするスクリプトをsystemdのサービスとして実装してみる。
ファイル属性変更用のスクリプト作成
スクリプトを作成する
# mkdir /usr/local/script
# vi /usr/local/script/chattr_ope_log.sh
こんな感じinotifywait でcreateイベントだけ拾ってファイルが存在したらchattr +aする。
#!/bin/bash
OPE_LOG_DIR=/var/log/ope_log
while read create_event
do
target_dir=$(echo ${create_event} |awk '{print $1}')
target_file=$(echo ${create_event} |awk '{print $NF}')
target_file_path=${target_dir}/${target_file}
if [[ -f ${target_file_path} ]]; then
chattr +a ${target_file_path}
fi
done < <(/usr/bin/inotifywait -e create -mq ${OPE_LOG_DIR})
これを、systemdにサービスとして登録する
# vi /etc/systemd/system/chattr_ope_log.service
とりあえず、こんな感じ
[Unit]
Description = harden operation log permission
[Service]
ExecStart = /usr/local/script/chattr_ope_log.sh
Restart = always
Type = simple
[Install]
WantedBy = multi-user.target
作ったファイルに実行権限付与して
# chmod 755 /usr/local/script/chattr_ope_log.sh
登録!
# systemctl enable chattr_ope_log --now
# systemctl status chattr_ope_log
● chattr_ope_log.service - harden operation log permission
Loaded: loaded (/etc/systemd/system/chattr_ope_log.service; enabled; vendor preset: disabled)
Active: active (running) since Sun 2021-11-07 14:39:29 JST; 3s ago
Main PID: 8056 (chattr_ope_log.)
Tasks: 3
CGroup: /system.slice/chattr_ope_log.service
├─8056 /bin/bash /usr/local/script/chattr_ope_log.sh
├─8057 /bin/bash /usr/local/script/chattr_ope_log.sh
└─8058 /usr/bin/inotifywait -e create -mq /var/log/ope_log
Nov 07 14:39:29 arm01 systemd[1]: Started harden operation log permission.
この状態で、ログインすると、scriptが自動実行されていて、
# w
14:41:05 up 71 days, 2:15, 2 users, load average: 0.00, 0.00, 0.00
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
opc pts/2 202.xxx.xxx.xxx 14:40 0.00s 0.01s 0.00s script -f -q -t /var/log/ope_log/opc_20211107144048_xx.xx.xx.log
opc pts/4 14:40 0.00s 0.02s 0.00s w
# > /var/log/ope_log/opc_20211107144048_202.xx.xx.xx.log
bash: /var/log/ope_log/opc_20211107144048_202.xx.xx.xx.log: Operation not permitted
$ rm /var/log/ope_log/opc_20211107144048_202.xx.xx.xx.log
rm: cannot remove ‘/var/log/ope_log/opc_20211107144048_202.xx.xx.xx.log’: Operation not permitted
→ 自分ではファイルを消せないし、viで修正しても修正できない!
うまくいっている感がある