Linuxで実行中のプロセスを監視することの複雑さ

Linuxシステムで実行中のプロセスを監視する方法は誰もが知っています。しかし、そのような観察で高精度を達成する人はほとんどいません。実際、この資料で説明するプロセスを監視するすべての方法には、何かが欠けています。 実験を開始する前に、プロセス監視システムの要件を定義しましょう。











  1. 短期間のプロセスであっても、すべてのプロセスに関する情報をログに記録する必要があります。
  2. 実行中のすべてのプロセスの実行可能ファイルへのフルパスに関する情報が必要です。
  3. 当然のことながら、カーネルのさまざまなバージョン用にコードを変更または再コンパイルする必要はありません。
  4. : - Kubernetes Docker, , / . cgroup ID . , , «» « ». , « », « », « », API, Docker . ID , . Docker .


このタスクに役立つ一般的なLinuxAPIについて説明しましょう。話を複雑にしないために、システム呼び出しを使用して作成されたプロセスに特別な注意を払いますexecve問題のより完全な解決策について話す場合、その実装中に、さらに、システム呼び出しfork/cloneとそのバリアントを使用して作成されたプロセス、および呼び出しの結果を監視する必要がありますexecveat



ユーザーモードで実装されたシンプルなソリューション



  1. 連絡してい/procます。この方法は、プロセスの寿命が短いという問題があるため、私たちには特に適していません。
  2. netlink. netlink , PID . . /proc, .
  3. Linux. — , . API . . . — , , , . , API , auditd osquery. , , auditd go-audit理論的には、この問題を軽減できます。しかし、エンタープライズクラスのソリューションの場合、顧客がそのようなツールを使用しているかどうか、使用している場合はどのツールを使用しているかを事前に知ることはできません。また、AuditingAPIと直接連携するセキュリティコントロールがクライアントによって使用されていることを事前に知ることもできません。2番目の欠点は、監査APIがコンテナについて何も知らないことです。そしてこれは、この問題が長年議論されてきたという事実にもかかわらずです。


シンプルなカーネルモードデバッグツール



これらのメカニズムの実装には、1つのコピーでさまざまなタイプの「プローブ」を使用することが含まれます。



▍トレースポイント



トレースポイントの使用(tracepoint)。トレースポイントは、コンパイル中にカーネルの特定の場所に静的に接続されるセンサーです。このような各センサーは、他のセンサーとは独立してオンにすることができます。その結果、カーネルコードが埋め込まれている場所に到達した場合に、通知が発行されます。カーネルには、私たちに適したいくつかのトレースポイントが含まれており、そのコードはシステム呼び出しのさまざまなポイントで実行されますexecve。この- 、sched_process_execopen_execこのリストを取得するために、コマンドを実行しましたsys_enter_execvesys_exit_execvecat /sys/kernel/tracing/available_events | grep execカーネルコードの読み取りから取得した情報を使用して、結果のリストをフィルタリングしました。これらのトレースポイントは、短期間のプロセスの観察を整理できるため、上記のメカニズムよりも適しています。ただし、パラメータexecがそのようなファイルへの相対パスである場合、それらのいずれもプロセスの実行可能ファイルへのフルパスに関する情報を提供しませんつまり、ユーザーがのようなコマンドを実行するとcd /bin && ./ls、パス情報はフォーム./lsではなく、フォーム取得され/bin/lsます。簡単な例を次に示します。



#    the sched_process_exec
sudo -s
cd /sys/kernel/debug/tracing
echo 1 > events/sched/sched_process_exec/enable

#  ls    
cd /bin && ./ls

#      sched_process_exec
#    ,        
cd -
cat trace | grep ls

#   
echo 0 > events/sched/sched_process_exec/enable


▍kprobe/ kretprobeセンサー



センサーをkprobe使用すると、カーネル内のほぼどこからでもデバッグ情報を抽出できます。これらは、コードの実行を停止せずに情報を提供するカーネルコードの特別なブレークポイントのようなものです。kprobeトラックポイントとは異なり、センサーはさまざまな機能に接続できます。このようなセンサーのコードは、システム呼び出しの実行中にトリガーされますexecve。しかしexecve、パラメータがPIDプロセスとその実行可能ファイルへのフルパスの両方である関数の呼び出しグラフには見つかりませんでした。その結果、トレースポイントを使用する場合と同じ「相対パスの問題」に直面します。ここでは、特定のカーネルの機能に依存して、何かを「微調整」することができます。結局のところ、センサーkprobeカーネル呼び出しスタックからデータを読み取ることができます。ただし、このようなソリューションは、異なるカーネルバージョンでは安定して機能しません。したがって、私はそれを考慮しません。



▍トレースポイント、kprobeおよびkretprobeプローブを使用したeBPFプログラムの使用



ここでは、一部のコードが実行されると、トレースポイントまたはセンサーがトリガーされますが、通常のイベントハンドラーのコードではなく、eBPFプログラムのコードが実行されるという事実について説明します。



このアプローチを使用すると、私たちにいくつかの新しい可能性が開かれます。これで、システム呼び出しを行うときに、カーネルで任意のコードを実行できますexecve。これにより、理論的には、カーネルから必要な情報を抽出してユーザースペースに送信できるようになります。この種のデータを取得する方法は2つありますが、いずれも上記の要件を満たしていません。



  1. , task_struct linux_binprm. , , . , sched_process_exec , eBPF- , dentry bprm->file->f_path.dentry, . eBPF- . . , eBPF- , , , .
  2. eBPF . , . — API. — . (, eBPF, cgroup ID, ).


«»



  1. LD_PRELOAD exec libc. , . , , , , .
  2. execve, fork/clone chdir , . , execve execve . — eBPF- eBPF- , .
  3. , ptrace. -. — ptrace seccomp SECCOMP_RET_TRACE. seccomp execve , execve seccomp execve.
  4. AppArmorを使用します。AppArmorプロファイルを記述して、プロセスが実行可能ファイルを呼び出さないようにすることができます。このプロファイルをトレーニングモードで使用する場合(文句を言う)、AppArmorはプロセスの実行を禁止せず、プロファイルで指定されたルールの違反に関する通知のみを発行します。プロファイルを実行中の各プロセスに接続すると、機能しますが、非常に魅力的でなく、「ハック」なソリューションが得られます。このアプローチを使用する価値はおそらくありません。


その他の解決策



これらのソリューションはいずれも私たちの要件を満たしていないことをすぐに言いますが、それでも、それらをリストします。



  1. ユーティリティの使用psこのツールは単に参照するだけで/procあり、その結果、への直接アクセスと同じ問題が発生します/proc
  2. execsnoop, eBPF. , , , kprobe/kretprobe, , , . , execsnoop , , , .
  3. execsnoop, eBPF. — kprobe, .




将来的には、まだ利用できない補助eBPF関数get_fd_pathを使用できるようになりますカーネルに追加すると、問題の解決に役立ちます。確かに、プロセスの実行可能ファイルへのフルパスは、カーネルデータ構造からの情報の読み取りを提供しない方法を使用して取得する必要があります。



結果



私たちがレビューしたAPIはどれも完璧ではありません。以下に、プロセスに関する情報を取得するために使用するアプローチと、それらをいつ使用するかについてのガイドラインを示します。



  1. auditd go-audit. , . , , , . , , , - API , , . — , .
  2. , , , , , execsnoop. — .
  3. , , , , , . , . , , eBPF- eBPF-, perf..。これらすべてについての話は、別の記事に値します。このプロセス監視方法を選択する際に覚えておくべき最も重要なことは次のとおりです。eBPFプログラムを使用する場合は、静的コンパイルの可能性を確認してください。これにより、カーネルヘッダーに依存しないようになります。しかし、私たちがこの方法の使用を避けようとしているのは、まさにこの依存関係です。この方法を使用すると、カーネルデータ構造を操作できなくなり、実行時にeBPFプログラムをコンパイルするBCCのようなフレームワークを使用できなくなります。
  4. 短期間のプロセスに関心がなく、以前の推奨事項が適切でない場合は、netlink機能をと一緒に使用してください/proc


Linuxで実行中のプロセスの監視をどのように整理しますか?










All Articles