📽️

Linux で script コマンドを使用してコマンド実行ログを記録する

2021/08/17に公開
2

複数人で同一のサーバを管理していると、何かの問題が起きたときに「それが誰がなにをしたために起こったのか」がわからなくなりがちなので、ログを記録しておくことが重要。
とはいえ、毎回操作時にスクリーンショットを取ったり手動でログを記録したりするのは面倒なので、自動化しておくと便利。

この記事では、script コマンドを用いたログ記録と、SSH 接続時に自動で script によるログ記録を開始するようにする設定、そのほか script コマンドの活用方法についてまとめておく。

環境

  • CentOS 7.8
  • GNU bash 4.2.46(2)-release

script コマンドとは

参考: SCRIPT - JM プロジェクト (linuxjm.osdn.jp)

script ファイル名 でファイルに作業ログを記録してくれる。-a オプションをつければ、既存のファイルに追記してくれる。
記録したファイルのことは「タイプスクリプト」と呼ばれる。プログラミング言語とは違う。

ターミナルに表示された Raw テキストデータがそのままログに書き込まれるので、文字色変更やカーソル移動などのエスケープシーケンスも全部まとめて書き込まれている。タイプしたテキストもすべて記録されているので、下手にミスタイプするとそれまで記録されてしまう。

これを人間の目で読むのはさすがに厳しいので、more コマンドや scriptreplay コマンドを用いて読むことが多い。しかし、scriptreplay の場合は記録時に script --log-timing=タイミングファイル名 ファイル名 でタイミングファイルを書き出す必要がある。
ここでは scriptreplay での閲覧(再生)について解説しないので、 scriptreplay --helpman scriptreplay などのヘルプやマニュアルを読んでほしい。

SSH 接続時、自動で script 記録を実施させる

さて本題。

作業時にいちいち script xxxxxx.log と実行してから作業するのは面倒だし、script コマンドの実行を忘れてしまうかもしれない。ならば、普段から script コマンドのログを取ってしまえばよい。
というわけで、SSH 接続時に自動的に script によるログ記録を開始するように設定する。

保存先ファイルは /var/log/scripts/<ログインユーザー名>/<IPアドレス>_<ログ記録開始日時>.log になるようにする。

結論としては、以下を /etc/profile の末尾に追記すればよい。

$PPID には、自身の親プロセス名を返す。ps aux コマンドを実行したとき、ps コマンドプロセスの親は SSH のホストプロセスである sshd であれば SSH 経由で実行されたと判断できる。

ログイン元の IP アドレスを取得するために、 w -i の出力を加工して取得する必要があった。w -i の出力では端末デバイスの表示に pts/1 というような形式で表示される。

[#1 tomachi@Comet2 12:50:57 ~]$ w -i
 12:51:00 up 2 days,  6:49,  4 users,  load average: 0.39, 0.34, 0.32
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
tomachi  pts/2    xxx.xxx.xx.xxx   10:32    4.00s  0.13s  0.00s w -i

現在の端末デバイスファイルを取得するには tty コマンドで実行できるが、出力は /dev/pts/1 というような形式(実体ファイルの完全パス)である。
なので、/dev/ 部分を sed コマンドで取り除いて、w -i の結果を grep することで、接続元の IP アドレスを取得している。

もし、IP アドレスやログインユーザー名以外の情報をファイル名やディレクトリ名に設定したいなら、grep やら sed やら awk やらで加工して設定してしまえば可能。

Gist に置いたので、curl https://gist.githubusercontent.com/book000/2bf133fc79a7f2326d2466c3f8fb84cb/raw/417621b4f1391a13d83c83d6677d82e587549d05/script-logging.sh >> /etc/profile とかすれば適当に導入できる。

script コマンドの活用方法

nwtgck さんの piping-serverQiitaの解説記事)を使えば、操作中のターミナルを他者と共有できる。この用途で使ったことはないが、非常におもしろい発想だと思っている。

参考文献

記事を書いている途中に見つけた ログインしたユーザーの操作ログを自動的に取る - TechRacho では、親プロセス名ではなく $SHLVL$PS1 の存在有無などで判断している様子。どっちが良いのやら…?

GitHubで編集を提案

Discussion

坦々狸坦々狸

自動で記録が出来るかどうかわかりませんが
asciinema便利ですよ

https://gihyo.jp/admin/serial/01/ubuntu-recipe/0551

再生速度簡単に変えられるのが便利なのと簡単に公開出来るので人に操作ログ見せる時とかにも便利です
プレイヤー上の文字列もそのままコピペ出来るから真似してもらうのも楽ですし

TomachiTomachi

コメントいただきありがとうございます!asciinema、初めて知りました。試してみようと思います。