24時間365日フルマネージドホスティングサービスのデイーネット

[技術ブログvol.1] historyコマンドでお手軽操作ログを取る


Linuxを使っていて、操作ログを見たいときがよくあります。

しかし、historyコマンドをデフォルトのままで使うと、少し不便だったりするので、操作ログを簡単に取れるようにしたいと思います。

パッと思いつくのは、以下の数点ぐらいでしょうか。

・historyコマンドを使う
・scriptコマンドを使う
・psacctパッケージを使う
・teratermとかのターミナルアプリのロギング機能を使う

ちなみに、利用環境は「CentOS 6.4」で、利用シェルはbash (ver4.1.2)です。
それぞれの内容を下書きで書き出すと止まらなくなったので(笑)、今回は「お手軽に記録を残す」ことができそうな、

「historyコマンドを使う」

を、デフォルト設定から少し変更して、操作ログを取るようにしてみます。

※ちょっと前提条件
お手軽に実現したいので、「30日間は確実に詳細なログを取る」とか細かいことは考えず、「何か分かればラッキー程度」の気楽さで考えてみますhistoryコマンドは、アカウント毎に記録ファイルが作られ、そのアカウント毎にファイル操作ができてしまったり、ヒストリ機能自体を無効にすることもできるので、操作記録としての信用性が低いという問題があります。

しかし今回は、「各ユーザが勝手にそういうことをしない」という前提で、単純に「操作ログを取る」ことだけにスポットを当てることにします。

1.時間を記録する

それでは、早速historyコマンドで操作ログを取って行きたいので、おもむろにhistoryコマンドを実行してみます。

というような感じに出力されると思います。
これでは、各コマンドがいつ実行されたのかが分かりません。
1分前かもしれないし、1ヶ月前かもしれないので、このままでは情報としては不十分な感じです。

そこで、コマンドの実行時間も併せて記録するようにします。

これはシェル変数「HISTTIMEFORMAT」で設定が可能です。

記録する時間のフォーマット設定は「strftime 」形式で指定が可能です。
例えば、今年の西暦を4桁で表す場合は「%Y」と指定します。
 詳しくは、strftime のマニュアルを参照してください
 (オンラインマニュアルを見る場合は、「$ man strftime」と実行して参照できます)

今回は、「YYYY-MM-DD hh:mm:ss」という形式にしようと思うので、「%F %T」という指定にします。
この内容を以下のようにシェル変数に設定します。

これで、historyコマンドの結果が以下のように変わります。

※ただし、HISTTIMEFORMATの設定を変える前のコマンド実行時刻については、全て直前のログイン時刻で記録されます。

2.記録対象の詳細を設定する
また、試した環境では、直前と同じコマンドは記録されない設定でしたので、これも変更しておきます。

※lsコマンドといった、システム変更に影響がないようなコマンドなら、このままでも問題ありませんが、もしも何度もプロセスを連続して再起動するような場合は、こういった記録も細かく取得した方がいいと思います。

これらの履歴記録の設定はシェル変数「HISTCONTROL」で設定が可能です。
試した環境では、ignoredupsという内容になっており、これが「直前の同じコマンドは記録しない」という指定になります。

そこで、今回は「指定のコマンド以外は、すべての履歴を記録する」ことにします。

すべての履歴を記録するには、以下のようにシェル変数「HISTCONTROL」を削除します。


3.記録しないコマンドを指定する
指定のコマンドを記録しないようにするには、シェル変数「HISTIGNORE」で記録しないコマンドを指定します。

ls,pwd,historyあたりを指定しておきます。(ここは、ご利用の環境に合わせてください)

複数のコマンドを指定する場合は、コロンで区切って指定します。
また「*」「?」のようなワイルドカードも使えます。

上記で「ls*」というようにしているのは、「HISTIGNORE=ls」だけだと、「ls -l」のようにオプションを指定したコマンドの場合は、履歴として記録対象になってしまうからです。
また、ここで記録から外したコマンドは、履歴に残らないので、十字キーで過去のコマンドを呼びだせなくなるので、都度コマンドを打ち込む必要があります。

4.記録する数を変更する
こうして、履歴に残すコマンドを整理できたら、記録できる履歴数をシェル変数「HISTSIZE」や「HISTFILESIZE」で多めに拡張しておきましょう。
一日に1000回コマンドを打つとして(多いのかな...)、10日分程度保存するなら、10000あたりを設定しておけばいいかもしれません。

これで、最低限の操作ログを記録する環境にすることができました。

5.設定をいつでも使えるようにする
これまでの中で、ひと通り設定が完了しましたが、このままでは、ログアウトすると設定が初期化されてしまうので、再度ログインし直した時に、同じ設定をする必要があります。
これは手間なので、「/etc/profile」に設定しておくことで、すべてのアカウントで常に同じ設定が使えるようにしておきます。
※これでも、各アカウントの「~/.bash_profile」を編集されたら、各種の環境設定ファイルの読み込み順序の関係で、「~/.bash_profile」で上書きされてしまいますが...。

保存ができたら、ログインし直すか、以下のコマンドを実行してファイルを読み直します。

これで、次回ログイン時も同じ設定でhistoryコマンドが使えます。

6.historyコマンドの物足りない点をなんとかしたい
しかし、historyコマンドは、アカウント毎の記録になって、すべてのアカウント履歴を調べる場合などは、ちょっと面倒です。
また、何日分記録を残す、ということもはっきりとは指定できないので、historyコマンドだけでは心許ありません。

こういう場合は最初に挙げた「psacctパッケージ」を使えば、操作ログの世代管理や、全てのアカウントの操作ログの管理が一元的に可能です。
psacctパッケージについては、またいずれかの時に紹介しようと思います。

今回のまとめ

・historyコマンドに時間も記録する場合は、シェル変数「HISTTIMEFORMAT」を設定する。
(HISTTIMEFORMATは、strftime形式)
・履歴記録の設定は、シェル変数「HISTCONTROL」で設定する。
・すべての履歴を記録するには、シェル変数「HISTCONTROL」を削除する
・特定のコマンドを記録しないようにするには、シェル変数「HISTIGNORE」でコマンドを指定する。
・指定には、ワイルドカードが使える
・複数指定時は、「:」で区切る
・記録できる履歴数はシェル変数「HISTSIZE」と「HISTFILESIZE」を設定する。
・再度ログインした時も使えるように、設定は「~/.bashrc」に記載する。

オマケ1
HISTFILESIZEの設定値は、HISTSIZEの数と同じか、それ以上の指定にしておくといいです。

「HISTSIZE」は履歴の数で、「HISTFILESIZE」はファイルに保存する履歴の数なので、HISTFILESIZEの設定値がHISTSIZEの値よりも小さい場合は、ログアウトするとHISTFILESIZEの数しか記録できません。
これはログアウト時に記録している履歴がファイルに書き出される為ですが、それだと記録漏れが出てしまうと思うので、注意が必要かなと思います。
(履歴を記録するヒストリファイルは、デフォルトで「~/.bash_history」です)

オマケ2
履歴取得を設定できるシェル変数「HISTCONTROL」には、以下のものが指定できます。

ignorespace 半角スペースで始まるコマンドは記録しない
ignoredups 直前と同じコマンドは記録しない
ignoreboth 上記2つの両方を指定
erasedups 既にコマンド履歴にあるコマンドは記録しない

  • このページの先頭へ

  • 東京本社
    〒105-0001東京都港区虎ノ門2-3-22 第一秋山ビル5F
    TEL:03-3591-8887 FAX:03-3591-8886
  • 大阪本社
    〒541-0041 大阪市中央区北浜2-6-11北浜エクセルビル5F
    TEL:06-6231-8887 FAX:06-6231-8897

  • 認証範囲はこちらをご覧ください。

Denet logo

クラウドサービス・データセンタ・高機能専有サーバ・共有サーバホスティングサービス 株式会社ディーネット
dot_bar