2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Linuxで作業のlogをこっそりとる

Posted at

できること

linuxサーバーでの作業履歴を記録する。
履歴をとっていることがバレにくい。
ssh接続時はアクセス元の記録もできる。

前提条件

OS: Linux
シェル: bash

やり方

結論から。

.bashrc
if [ "$SHLVL" = "1" ] && [ ! -z "$PS1" ]
then
    [ -d ~/scripts/ ] || mkdir ~/scripts
    find ~/scripts/ -type f -mtime +60 -delete
    export Guest=`who am i`
    date=`date +script_%F_%T`
    LANG=C script -qft 2>~/scripts/$date.time ~/scripts/$date.log
    exit
elif [ `ps aux | grep $PPID | grep -v grep | awk '{ print $11 }'` = "script" ]
then
  echo $Guest
fi

scriptで履歴を取得

単体で .bashrc に書くと 無限ループ になります。

date=`date +script_%F_%T`
LANG=C script -qft 2>~/scripts/$date.time ~/scripts/$date.log
  • dateコマンドで、日付をフォーマットする。「script_2022-12-31_12:59:59」
  • scriptコマンドで履歴を取得
    • LANG=C: 日本語だと後に利用するscriptreplayがうまくいかないため。scriptreplayを使わないならなくてもいい。
    • -q: scriptコマンドを開始、終了した旨のメッセージを非表示にする。これがないと記録してるのがバレバレ。
    • -f: 記録をリアルタイムで参照できるようにする。なくても構わない。
    • -t: 文字を入力した時間を標準エラー出力に出力する。scriptreplayを使うなら必須。
    • 2>~/scripts/$date.time: -tで出力された時間をファイルにリダイレクトする。これがないと色々と大変なことになるので、-tをつけるなら絶対つけること。
    • ~/scripts/$date.log: ログ出力先のファイル。

scriptは子シェルを生成し、その中でコマンドを実行させる。そのため、これを単体で書くと生成されたシェルでさらにscriptがシェルを生成し、無限ループになる。

無限ループにならないようにする。

if [ "$SHLVL" = "1" ] && [ ! -z "$PS1" ]

$SHLVLはシェルの深度。scriptコマンド下ではこれが2になるため判別できる。
$PS1はプロンプト。空文字でないことを実行条件としている。

アクセス元を記録

アクセス元のIPは、アクセス直後のシェルでwho am iを実行すると取得できる。
ただ、script下で実行しても取得できない。
そこで、script実行前に取得して環境変数に入れておき、script下で出力することで記録させている。

if [ "$SHLVL" = "1" ] && [ ! -z "$PS1" ]
then
    export Guest=`who am i`
elif [ `ps aux | grep $PPID | grep -v grep | awk '{ print $11 }'` = "script" ]
then
  echo $Guest
fi

ps aux | grep $PPID | grep -v grep | awk '{ print $11 }'で親プロセスの名称を取得している。

  • ps aux: プロセス一覧を取得
  • grep $PPID: 親プロセスのPID($PPID)が含まれるもので絞り込み
  • grep -v grep: 上記にはこのコマンド自身も含まれてしまうので、grepが含まれていないものを抽出。これで親プロセスだけになった。
  • awk '{ print $11 }': スペース区切りで11個目であるプロセス名を取得。親プロセスがscriptコマンドであればscriptが入る。

諸々追加

保存先のフォルダがなければ作る (任意)

[ -d ~/scripts/ ] || mkdir ~/scripts

60日以上前のログを削除 (任意)

find ~/scripts/ -type f -mtime +60 -delete

exitコマンドを一回で済ませる

LANG=C script -qft 2>~/scripts/$date.time ~/scripts/$date.log
exit

通常、scriptコマンドを実行中にシェルを抜けるにはexitを二回入力する必要がある。
しかし、script終了時に自動的にexitを実行すれば、一回で済ませられる。
これにより、ログの取得がほぼバレなくなる。

結果の再掲

.bashrc
if [ "$SHLVL" = "1" ] && [ ! -z "$PS1" ]
then
    [ -d ~/scripts/ ] || mkdir ~/scripts
    find ~/scripts/ -type f -mtime +60 -delete
    export Guest=`who am i`
    date=`date +script_%F_%T`
    LANG=C script -qft 2>~/scripts/$date.time ~/scripts/$date.log
    exit
elif [ `ps aux | grep $PPID | grep -v grep | awk '{ print $11 }'` = "script" ]
then
  echo $Guest
fi
2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?