コマンド履歴をCloudWatch Logsで保存する

2016.11.15

渡辺です。

AmazonLinuxでコマンドの実行履歴を残したい(とはいっても専用の証跡アプリを入れるほどでもない)といった要件はしばしばあります。 幾つかの解決方法が考えられると思いますが、本日紹介するのはCloudWatch Logsへのコマンド実行履歴も転送する方法です。

.bash_historyによるコマンド実行履歴

簡易的にコマンド実行履歴を取得する方法としてお手軽なのは.bash_historyです。 改竄可能であったりと完璧ではありませんが、実コマンド実行履歴を簡単に取得することができます。

.bash_historyで履歴を書き込むのはセッション終了時

.bash_historyでは、コマンド実行直後に履歴を書き込むわけではありません。 コマンドを実行すると、履歴はバッファに溜まり、端末のセッションが閉じたタイミング.bash_historyへの書き出されます。

また、.bash_historyにはタイムスタンプが出力されません。 ログとして利用するには不十分です。

タイムスタンプオプションでは解決しない実行時間

historyコマンドには、タイムスタンプを記録して表示するオプションがあります。 しかし、.bash_historyの各コマンドの間にUnix Timeを記録する形式であるため、CloudWatch Logsへ転送したとき、コマンド/Unix Time/コマンド/Unix Timeといったログとなってしまいます。 また、これではCloudWatch Logsで実行時間から検索できません。

#1479193842
export HISTTIMEFORMAT='%F %T '
#1479193847
touch cloudwatch2
#1479193851
rm cloudwatch2
#1479193854
ls

一方、CloudWatch Logsは転送したタイミングの日時を転送日時として記録します。 若干のタイムラグはありますが、コマンド実行時にコマンドが書き出されれば、コマンドの実行日時はおおよそ記録できることになります。

.bash_historyのCloudWatch Logs転送

コマンド実行時に.bash_historyに実行履歴を書き出すことができれば、CloudWatch Logsでコマンド実行履歴を管理できそうです。 .bachrcに以下の1行を追加し、コマンドの実行直後にhistoryコマンドでバッファを追加します。

PROMPT_COMMAND="$PROMPT_COMMAND;history -a"

続けて、CloudWatch Logsの設定に、.bash_historyを追加し、CloudWatch Logs Agentを再起動します。

[/home/ec2-user/.bash_history]
log_group_name = .bash_history
log_stream_name = ec2-user@{{ inventory_hostname }}({instance_id})
file = /home/ec2-user/.bash_history

これで.bash_historyのCloudWatch Logs転送設定の完了です。

CloudWatch_Management_Console

まとめ

.bash_historyは簡易的にコマンド実行履歴を取得するには便利です。 CloudWatch Logsと組み合わせエコな運用をしてはどうでしょうか?