権限を細かく絞る - capabilities
Linux の root 権限を約 40 の細かい能力に分割した仕組み。コンテナランタイムはデフォルトで一部だけを付与し、`--cap-drop` / `--cap-add` で絞り込む。最小権限の原則を徹底するための最重要機能。
概念図
構文
bash
docker run --cap-drop ALL --cap-add NET_BIND_SERVICE nginx実例
すべての capability を落として起動
bash
docker run --rm --cap-drop ALL alpine id80 番ポート bind だけ許可
bash
docker run --rm --cap-drop ALL --cap-add NET_BIND_SERVICE nginxデバッグ用に ptrace を追加
bash
docker run --rm --cap-add SYS_PTRACE ubuntu strace ls概要
Linux では「root = すべて可能」ではなく、機能ごとに capability と呼ばれる単位に分けられています。
CAP_NET_ADMIN(NIC 設定)、CAP_SYS_TIME(システム時刻変更)、CAP_SYS_ADMIN(広範な管理操作)など、合計約 40 種類が存在します。
Docker / Podman は起動時に「コンテナ用のデフォルト capability セット」を付与します。
このデフォルトはすでに最小化されており、SYS_ADMIN や SYS_TIME のような強力なものは含まれません。
さらに --cap-drop ALL --cap-add <必要なもの> と明示するのが推奨スタイルです。
典型的な用途
- Web サーバーに NET_BIND_SERVICE のみ付与して 80/443 を bind する
- 実運用コンテナで
--cap-drop ALLを既定にし、必要な能力だけ明示的に戻す - デバッグコンテナに一時的に SYS_PTRACE を付けて strace する
- ネットワーク系ツール(tcpdump 等)に NET_ADMIN / NET_RAW を許可する
- マルチテナント環境で
SYS_ADMINが必要な処理を専用コンテナに隔離する
コマンド例
# コンテナ内の capability を確認
docker run --rm alpine sh -c 'apk add -q libcap && capsh --print'
# すべて落としてから必要分だけ足す
docker run --rm \
--cap-drop ALL \
--cap-add NET_BIND_SERVICE \
--cap-add CHOWN \
nginx:alpine
# Compose で指定
# services:
# app:
# image: myapp:1.0
# cap_drop: [ALL]
# cap_add:
# - NET_BIND_SERVICE
ベストプラクティス
- 本番コンテナは常に
--cap-drop ALLから始め、足りないときだけ最小限を足す - Dockerfile で
USERを非 root に設定して capability を落ちやすくする --privilegedは最終手段。どうしても必要な場面(DinD、ハードウェア直結、FUSE 等)以外では避ける- Kubernetes では PodSecurity Standard の
restrictedプロファイルを使い、ALLを落としたポリシーを強制する - 必要な capability がわからないときは、まず全付与で動かし、段階的に削りながらテストする
注意点
--privilegedは capability を全付与するだけでなく、seccomp・AppArmor・デバイスアクセス制限まで解除する。セットで理解するSYS_ADMINは約 40 個ある capability の中でも突出して強く、ほぼ root 相当と考えるべき- カーネルバージョンによって追加 capability(例: CAP_PERFMON, CAP_BPF)の対応状況が異なる
- コンテナ内で capability を追加しても、実際のカーネル権限を超えては使えない(bounding set 制限)
- イメージのバイナリに file capabilities が付いている場合、コンテナ側と合わせて考慮する必要がある
関連トピック
rootless- コンテナランタイムとコンテナ内プロセスを非特権ユーザーで動かす方式。万一コンテナから脱出されてもホスト側で root を奪われない構成にできる。Podman はデフォルト、Docker もオプションで対応。 --read-only- コンテナのルートファイルシステムを読み取り専用で起動し、書き込みが必要な部分だけ tmpfs や volume に分離する構成。マルウェアの書き込みや改ざんを防ぎ、Immutable Infrastructure を強化する。 user namespace- コンテナ内の UID/GID をホスト側の別 UID/GID にマッピングする Linux の機能。これにより「コンテナ内では root、ホストから見ると非 root」を実現し、bind mount のパーミッション問題の根本原因にもなる。 