【テクニカル・上級編】KubernetesにおけるPod Security Admissionの適用とPod Security Standards – アプリケーションセキュリティ & 安全な開発防御ガイド

コンテナの「特権」という名の劇薬:Pod Security Admissionが守るべき最後の防衛線

Kubernetesのセキュリティを語る時、多くの現場が「ネットワークポリシー」や「OIDCによる認証」といった華やかな部分に目を奪われがちだ。しかし、真のインシデントレスポンダーにとって、最も悪夢を見るのは「Podがコンテナランタイムを突き抜けてホストOSを掌握する瞬間」である。

かつて、Pod Security Policy(PSP)が廃止された際、多くのエンジニアが迷子になった。しかし、後継であるPod Security Admission(PSA)は、単なる代替品ではない。これはKubernetesのコントロールプレーンにおける「最後の審判」だ。今回は、このPSAを単なるチェックリストではなく、攻撃者の侵入経路を物理的に遮断するための「防御アーキテクチャ」としてどう実装すべきか、深層から解説する。

—

1. なぜ「ルート権限」が攻撃者のゴールになるのか

CVE-2024-21626のようなRunCの脆弱性や、過去のDirty Pipe(CVE-2022-0847)を思い出してほしい。これらに共通するのは、コンテナ内でのプロセス権限がホストのカーネル空間へアクセスできるか、あるいは名前空間(Namespace)の境界が曖昧な場合に発生するという点だ。

もし、Podが privileged: true で起動されていれば、攻撃者は cgroups を利用してホストのプロセスを再定義し、特権昇格を成し遂げる。PSAを適用することは、「脆弱なアプリケーションが、脆弱なままホストを汚染するのを防ぐ」ための物理的なガードレールである。

—

2. PSAの実装:強制力のあるガバナンス設計

PSAは Namespace レベルで適用する。ここで重要なのは「Audit(監査)」から始めて「Enforce(強制)」へ移行するフェーズをどう設計するかだ。現場のエンジニアを疲弊させないためには、以下のような段階的な構成が推奨される。

名前空間レベルでのラベル付け戦略

まず、特定Namespaceに対して restricted プロファイルを適用する。これにより、Rootユーザーでの実行や、ホストパスの不適切なマウントをAPIサーバー側で拒絶できる。

名前空間にラベルを付与し、Podの実行権限を厳格化する
apiVersion: v1
kind: Namespace
metadata:
name: production-app
labels:
# 違反があった場合にログに記録する(まずはここから始める)
pod-security.kubernetes.io/audit: restricted
# 違反を即座にブロックする(最終的な防御ライン)
pod-security.kubernetes.io/enforce: restricted
# 違反のレベル(v1.28以降なら最新のバージョンを指定)
pod-security.kubernetes.io/enforce-version: v1.30

—

3. 回避不可能な「特権」に対するアーキテクチャの妥協と防衛

しかし、現実にはログ収集ツール(Fluentd等)やセキュリティエージェントが、どうしてもホストのディレクトリをマウントしなければならないケースが存在する。ここで安易に「Privilegedを許可」してはならない。

ここで私が推奨するのは、「最小権限の切り出し」だ。PSAで一律に禁止しつつ、特定の例外が必要なPodには pod-security.kubernetes.io/enforce-version の例外設定を活用するのではなく、Admission ControllerによるMutating Webhookを併用し、特定の機能(Capabilities)のみをピンポイントで追加することだ。

特定の例外が必要なPodの例:能力(Capability)の制限
apiVersion: v1
kind: Pod
metadata:
name: restricted-privileged-pod
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
containers:

  • name: app

securityContext:
allowPrivilegeEscalation: false # 特権昇格を物理的に防ぐ
capabilities:
drop: [“ALL”] # まず全ての能力を剥奪し、必要なものだけ追加する
add: [“NET_BIND_SERVICE”] # 必要な最小権限のみを付与

—

4. チーフホワイトハッカーとしての提言:監査とAIガードレイル

PSAは強力だが、これはあくまで「設定の誤り」を防ぐためのものだ。生成AIが書いたコードが、暗黙的に特権的な設定を要求するケースが増えている。プロンプトインジェクションにより、悪意あるYAMLが生成されるリスクを考慮すれば、CI/CDパイプライン内での OPA (Open Policy Agent) や Kyverno によるポリシー強制は必須となる。

私が現場で実施している監査の視点

1. ホストパスの禁止: hostPath を許容するPodは、PSA以前に論理的に排除せよ。
2. ReadOnlyRootFilesystemの徹底: コンテナのルートファイルシステムを読み取り専用にすれば、攻撃者が実行ファイルを配置・実行する「ファイルレス攻撃」の第一歩を挫ける。
3. Seccompプロファイルの強制: RuntimeDefault だけでなく、特定アプリケーションに最適化したカスタムSeccompプロファイルをプロファイリングせよ。

—

結論:防御は「境界」ではなく「振る舞い」にある

Pod Security Admissionは、Kubernetesの堅牢性を担保するための最低限の「礼儀」だ。しかし、真に強固なセキュリティは、コードがデプロイされた瞬間の構成だけでなく、実行時に何が起きているかをパケットレベルで監視し、異常なSyscallを検知する eBPF ベースのセキュリティツール(Falco等)との組み合わせで完成する。

セキュリティとは、終わりのない泥臭い作業の積み重ねだ。設定ファイルを一行書くたびに、「この権限が攻撃者に渡った場合、どこまで踏み込まれるか」を想像してほしい。その想像力こそが、世界最高峰のエンジニアと、その他大勢を分かつ唯一の境界線である。

さあ、次はあなたのクラスタの Namespace を確認するところから始めよう。デフォルト設定のまま放置されているものは、すでに脆弱な扉を開いているのと同じなのだから。

コメント

タイトルとURLをコピーしました