Linuxサーバで、sshログインされた際の操作ログを残したい、という希望は当然あるもの。
という訳で、今回はsshで操作された内容を、ログとして記録する設定について記述する。
設定は簡単。各ユーザの.bash_profileに、以下の内容を追記するだけだ。
# Operation Log.
P_PROC=`ps aux | grep $PPID | grep sshd | awk '{ print $11 }'`
if [ "$P_PROC" = sshd: ]; then
script -fq /取得するログのPATH
exit
fi
行っている内容は単純で、プロセスがsshdの場合のみ、scriptコマンドで指定したファイルにログを記述するというもの。
-fオプションでリアルタイムでの書き込み、-qオプションでログ取得時のメッセージを抑制している。
参考までに、私が実際に設定している内容は以下。
# Operation Log.
P_PROC=`ps aux | grep $PPID | grep sshd | awk '{ print $11 }'`
if [ "$P_PROC" = sshd: ]; then
script -fq /var/log/ssh_operation/`date +%Y%m%d_%H%M%S`_$USER.log
exit
fi
で、この設定、確かに便利なんだけど3つほど注意点がある。
- ログの取得先パスが存在しない場合、接続直後に落ちる
- 各ユーザーごとに設定してあげる必要がある
- ログローテーションの設定が必要
1.については、まぁ、当然というもの。存在しないディレクトリを指定しないよう、注意してもらいたい。
2.については、「/etc/profile」に設定すればいいのではないか?と考えると思うが、「/etc/profile」に記述すると、今度は.bash_profileが読み込まれなくなってしまう。
これはbashのファイル読込み順の仕様となる。このため、全員にこの設定を適用する場合、現在作成済のユーザについてはそれぞれに追記をおこない、、未作成のユーザの場合は、「/etc/skel/.bash_profile(Debian系の場合は.profile)」に追記しておけば良い。
3.については、ログが1アクションごとにたまってしまうので、運用時には必須だ。
別途スクリプトを作成するなどして対応してもらいたい。
2015/03/10 追記
なお、ターミナル終了時にexitコマンドを2度実行する必要が有ることから、一度exitした後に操作したログは記録されない。
exitコード1度でターミナルを終了する場合、以下のように「.bash_profile」に記述する。
# Operation Log.
P_PROC=`ps aux | grep $PPID | grep sshd | awk '{ print $11 }'`
if [ "$P_PROC" = sshd: ]; then
[[ $(ps -ocommand= -p $PPID | awk '{print $1}') = script ]] || { script -fq /var/log/ssh_operation/`date +%Y%m%d_%H%M%S`_$USER.log && exit ;}
exit
fi
exitコード1回でターミナルも終了するようになる。
2017/02/09 追記
ログイン時に実行するコマンドとして指定することで、ログを記録できるsshのラッパー『lssh』というものを作ったので、便利そうだったら使ってみてほしいなと。
あと、上記のような複雑な記述をしなくても、こちらの内容のようにワンライナーで同様の処理が行えると思う。