Linux capabilities

Linux 2.2以降、伝統的な「rootは全権限・非rootは権限チェックあり」という2値のモデルを、CAP_NET_BIND_SERVICE(1024番未満のポートbind)・CAP_SYS_PTRACEなど約40個の独立したcapabilityに分割した仕組み。プロセスごとに必要なcapabilityだけを個別に有効化/無効化できる。 #linux #security

setuidとの違い

setuidは「昇格したらそのユーザー(多くはroot)の全権限」という粗い粒度なのに対し、capabilitiesは権限を単位ごとに切り出せる。例えば「1024番未満のポートをbindしたいだけ」のプログラムに、root権限そのものではなくCAP_NET_BIND_SERVICEだけを持たせれば、脆弱性があってもroot全権限を奪われるリスクを避けられる。

ファイルcapability

Linux 2.6.24以降、setcap(8)で実行ファイルの拡張属性(security.capability)にcapability集合を埋め込める。これによりsetuid-rootにせず、実行ファイル単位で細粒度な特権を付与できる。ファイルcapabilityには3つの集合があり、スレッド側の集合との組み合わせでexecve(2)後の最終的なcapabilityが決まる。

  • Permitted: 無条件でスレッドに許可される
  • Inheritable: スレッド側のInheritable集合とANDされ、execve(2)後のPermitted集合に反映される
  • Effective: 実際に権限チェックに使われる集合

Ambient capabilities

Linux 4.3以降、prctl(2)で直接操作できる「Ambient」集合も追加された。setuid/setgidによるID変更やファイルcapability付きプログラムの実行はAmbient集合をクリアする。

no_new_privsとの関係

no_new_privs属性(prctl(2))が立っているスレッドでは、setuid/setgidビットによる昇格と同様に、ファイルcapabilityによる権限付与も無視される。systemdのNoNewPrivileges=はこの属性を立てる形で「このプロセスとその子孫は二度とexecve()経由で特権を得られない」ことを保証する。seccompフィルタを非特権ユーザーが取り付ける前提条件(CAP_SYS_ADMINno_new_privsのどちらかが必要)にもなっている。

systemdでの宣言的な管理

systemd.execのunit定義には、実行ファイル側にcapabilityを埋め込まずとも権限を宣言できるディレクティブがある。

  • CapabilityBoundingSet= — プロセスが持てるcapabilityの上限集合を絞る
  • AmbientCapabilities= — 実際に有効化するcapabilityを指定
  • DynamicUser= — 起動のたびに使い捨てのUID/GIDを動的割り当て

実行ファイルのメタデータ(setuidビットやファイルcapability)に権限を埋め込むモデルから、起動する側(systemd)がポリシーを一元管理するモデルへの移行と言える。

Linuxの権限分離・権限昇格の仕組みの中での位置づけ

setuidの「昇格したら丸ごと全権限」という粗さを補う、細粒度化の方向の代替。seccompLandlockとはレイヤが異なり(こちらは「誰の権限か」、あちらは「何ができるか」)、組み合わせて使われることが多い。

出典

  • man 7 capabilities
  • man systemd.exec
作成日時: 2026-08-16 07:44 / 更新日時: 2026-08-16 07:44