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. 各ユーザーごとに設定してあげる必要がある
  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』というものを作ったので、便利そうだったら使ってみてほしいなと。
あと、上記のような複雑な記述をしなくても、こちらの内容のようにワンライナーで同様の処理が行えると思う。