新しいルートプロセスが起動したときにスクリプトを実行したい。 (Linuxの場合)どうすれば簡単にそれを行うことができますか?
ありがとう
これは、auditdにとって完璧な仕事のように思えます。最新のRedHatベースのシステムのデフォルトサービスである実行を監査したら、実行することで、希望どおりの動作をするルールを作成できます。
auditctl -a task,always -F uid=0
このコマンドルールを分解し、マニュアルページを過度に使用すると、次のことがわかります。
-a list,action task Add a rule to the per task list. This rule list is used only at the time a task is created -- when fork() or clone() are called by the parent task. When using this list, you should only use fields that are known at task creation time, such as the uid, gid, etc. always Allocate an audit context, always fill it in at syscall entry time, and always write out a record at syscall exit time.
したがって、フォークまたはクローンシステムコールが終了するたびに、常にこのアクションのレコードを書き出してください。
最後のオプションはフィルター文字列と考えることができます。ここでの使用では、-F uid=0
は単にプロセス所有者のuidが0である場合に制限します。
このルールは、auditdが適切に構成されていることを確認し、ルールを追加することで、実行時に実行できることに注意してください。-a task,always -F uid=0
あなたのディストリビューションに関連するファイル、おそらく/etc/audit/audit.rules
これはかなりうるさくなり、ログレビューを行う人は誰でもそれに備える必要があることを覚えておいてください。
カーネルをCONFIG_PROC_EVENTSやCONFIG_KPROBESで再コンパイルせずにこれを行うクリーンな方法はないと思います(ただし、それを行う方法があるかどうかを知りたいので、あなたの質問に賛成しました)。
私は/ proc内のディレクトリ作成にiWatch/inotifyを使用するという考えを持っていましたが、それは機能していないようで、auditctlも機能していません。ダーティではありますが、スクリプトからの変更についてpsを継続的に解析することが最良の選択のようです。次のPerlコードはそれを行いますが、一部を見逃しがちで、ps
を無視します(そうでなければそれ自体がトリガーされるため):
Perl -e 'my %pids; while(1) { my @pids = `ps -U root -u root`; foreach (@pids) { next if /ps$/; ($pid) = /^\s*(\d+)\D/; if (!$pids{$pid}) { $pids{$pid}++; print "Process $pid created (" . `cat /proc/$pid/cmdline` . ")\n"; } } }
私が考えることができる最善の方法は、 snoopy ライブラリを構築することです。スヌーピーは非常に小さな共有ライブラリであり、_/etc/ld.so.preload
_にフックされ、execve()
システムコールをラップします。すべてのexec()
、またはルートからのものだけをログに記録するように構成できます。現在のインカネーションでは、一致するイベント(execve()
へのsyscall)が発生するたびに、snoopyがsyslogにログを記録します。ただし、これは大きなプログラムではなく(せいぜい数百行のコード)、アクティビティをログに記録する代わりに(またはそれに加えて)スクリプトを実行することはそれほど難しくなく変更できます。スヌーピーはCで書かれています。
注意すべきいくつかの点: