hacktricks/linux-hardening/privilege-escalation/docker-security/cgroups.md

11 KiB
Raw Blame History

CGroups

AWSハッキングをゼロからヒーローまで学ぶには htARTE (HackTricks AWS Red Team Expert)をご覧ください!

HackTricksをサポートする他の方法:

基本情報

Linuxコントロールグループ、またはcgroupsは、プロセスの集合に対してシステムリソース制限、管理、優先順位付けすることを可能にするLinuxカーネルの機能です。Cgroupsは、システム内のプロセスグループのリソース使用量CPU、メモリ、ディスクI/O、ネットワークなど管理し分離する方法を提供します。これは、特定のプロセスグループに利用可能なリソースを制限したり、特定の種類のワークロードを他から分離したり、異なるプロセスグループ間でシステムリソースの使用を優先順位付けするなど、多くの目的に役立ちます。

cgroupsにはバージョン1と2があり、両方が現在使用されており、システム上で同時に設定することができます。cgroupsバージョン1とバージョン2の間の最も顕著な違いは、後者がcgroupsの新しい階層的な組織を導入したことであり、グループを親子関係を持つツリー構造で配置することができます。これにより、異なるプロセスグループ間でリソースの割り当てをより柔軟かつ細かく制御することが可能になります。

新しい階層的な組織に加えて、cgroupsバージョン2は新しいリソースコントローラーのサポート、レガシーアプリケーションのより良いサポート、パフォーマンスの向上など、いくつかの他の変更と改善も導入しました。

全体として、cgroupsのバージョン2はバージョン1よりも多くの機能と優れたパフォーマンスを提供しますが、古いシステムとの互換性が懸念される特定のシナリオでは、バージョン1が引き続き使用される場合があります。

/proc/<pid>のcgroupファイルを見ることで、任意のプロセスのv1とv2のcgroupsをリストすることができます。次のコマンドでシェルのcgroupsを見てみることから始めることができます

$ cat /proc/self/cgroup
12:rdma:/
11:net_cls,net_prio:/
10:perf_event:/
9:cpuset:/
8:cpu,cpuacct:/user.slice
7:blkio:/user.slice
6:memory:/user.slice 5:pids:/user.slice/user-1000.slice/session-2.scope 4:devices:/user.slice
3:freezer:/
2:hugetlb:/testcgroup
1:name=systemd:/user.slice/user-1000.slice/session-2.scope
0::/user.slice/user-1000.slice/session-2.scope

システムによっては出力がかなり短い場合がありますが、これはおそらくcgroups v2のみを持っていることを意味します。ここにある各行の出力は数字で始まり、異なるcgroupです。それを読むためのポインターは以下の通りです

  • 数字の212はcgroups v1用です。それらのコントローラーは数字の隣にリストされています。
  • 数字の1バージョン1用ですが、コントローラーはありません。このcgroupは管理目的のみのものですこの場合、systemdが設定しました
  • 最後の行、数字の0は、cgroups v2用です。ここにはコントローラーが表示されていません。cgroups v1を持たないシステムでは、これが唯一の出力行になります。
  • 名前は階層的で、ファイルパスの一部のように見えます。この例では、いくつかのcgroupsが/user.sliceと名付けられ、他は/user.slice/user-1000.slice/session-2.scopeと名付けられているのがわかります。
  • /testcgroupという名前は、cgroups v1では、プロセスのcgroupsが完全に独立していることを示すために作成されました。
  • user.sliceの下にある名前にsessionが含まれているものは、systemdによって割り当てられたログインセッションです。シェルのcgroupsを見ているときにそれらを見るでしょう。システムサービスcgroupssystem.sliceの下にあります

cgroupsの表示

Cgroupsは通常、ファイルシステムを通じてアクセスされます。これは、カーネルと対話するための従来のUnixシステムコールインターフェースとは対照的です。
シェルのcgroup設定を探るには、/proc/self/cgroupファイルを見てシェルのcgroupを見つけ、次に/sys/fs/cgroup(または/sys/fs/cgroup/unified)ディレクトリに移動し、cgroupと同じ名前のディレクトリを探します。このディレクトリに移動して周りを見ることで、cgroupのさまざまな設定とリソース使用情報を見ることができます。

ここにある多くのファイルの中で、主要なcgroupインターフェースファイルはcgroupで始まりますcgroup.procscatを使っても構いませんから始めてください。これはcgroup内のプロセスをリストします。同様のファイルであるcgroup.threadsにはスレッドも含まれています。

シェルに使用されるほとんどのcgroupsには、これらの二つのコントローラーがあり、使用されるメモリの量cgroup内のプロセスの総数を制御できます。コントローラーと対話するには、コントローラーのプレフィックスに一致するファイルを探します。例えば、cgroup内で実行中のスレッドの数を見たい場合は、pids.currentを参照してください

maxという値は、このcgroupに特定の制限がないことを意味しますが、cgroupsは階層的であるため、サブディレクトリチェーンを下ったcgroupがそれを制限する可能性があります。

cgroupsの操作と作成

プロセスをcgroupに入れるには、rootとしてそのcgroup.procsファイルにPIDを書き込みます

# echo pid > cgroup.procs
これがcgroupsの変更がどのように機能するかの一例です。例えば、**cgroupの最大PID数を制限したい**場合例えば、3,000 PIDsに、以下のように行います
# echo 3000 > pids.max

cgroupsの作成はもっと複雑です。技術的には、cgroupツリーのどこかにサブディレクトリを作成するのと同じくらい簡単です。そうすると、カーネルが自動的にインターフェースファイルを作成します。プロセスがないcgroupは、インターフェースファイルが存在してもrmdirでcgroupを削除できます。しかし、cgroupsを取り巻く規則には注意が必要です。これには以下のようなものがあります

  • プロセスは外側のレベル「葉」のcgroupsにのみ配置できます。例えば、/my-cgroupと/my-cgroup/my-subgroupというcgroupsがある場合、/my-cgroupにはプロセスを配置できませんが、/my-cgroup/my-subgroupは大丈夫です。例外は、cgroupsにコントローラーがない場合ですが、詳しくは触れません。
  • cgroupは、親cgroupにないコントローラーを持つことはできません
  • 子cgroupsには明示的にコントローラーを指定する必要があります。これはcgroup.subtree_controlファイルを通じて行います。例えば、子cgroupにcpuとpidsコントローラーを持たせたい場合、このファイルに+cpu +pidsと書き込みます。

これらの規則の例外は、階層の最下部にあるルートcgroupです。このcgroupにはプロセスを配置できます。これを行いたい理由の一つは、プロセスをsystemdの制御から切り離すことです。

コントローラーが有効になっていなくても、cgroupのcpu.statファイルを見ることでCPU使用状況を確認できます

これはcgroupの全生涯にわたる累積CPU使用量であるため、多くのサブプロセスを生成して最終的に終了するサービスがプロセッサ時間をどのように消費しているかを確認できます。

htARTE (HackTricks AWS Red Team Expert)でAWSハッキングをゼロからヒーローまで学ぶ!

HackTricksをサポートする他の方法