Kubernetesオーケストレーション層のセキュリティ
コンテナイメージが安全でも、Kubernetesクラスタの設定が緩ければ攻撃者はそこを突破口にします。このページでは EKS・AKS・GKE を横断して、RBAC、Pod Security Standards、NetworkPolicy、Admission Controlという「オーケストレーション層」の制御を扱います。コンテナイメージやビルド時のセキュリティは Container Security のページで別途扱います。
なぜオーケストレーション層の制御が重要なのか
Kubernetesはデフォルトで「性善説」に近い設計になっています。NetworkPolicyを何も定義しなければ全Podが全Podと通信でき、ServiceAccountトークンはデフォルトで各Podに自動マウントされ、Pod Security Admissionを明示的に強制しなければ特権コンテナの起動を止める仕組みは働きません。つまりクラスタは「何も設定しなければ最も緩い状態」で動き続けます。
1つのPodの侵害が、クラスタ全体の侵害につながる
脆弱なアプリケーションが動くPodが1つ侵害されただけでも、そのPodが特権コンテナで動いていたり、過剰な権限を持つServiceAccountを使っていれば、攻撃者はノードへのエスケープやクラスタ全体のリソース列挙まで到達できます。
典型的なクラスタ制御アーキテクチャ
クラスタへのすべての変更はkube-apiserverを経由します。Admission Controlはこの経路上に位置する「最後の砦」であり、ここでPodの起動を許可するかどうかが決まります。
Admission Controlの段階が「Security Gate」です。ここでPod Security Admissionやポリシーエンジンが特権コンテナ・hostPath・hostNetworkの利用を拒否できなければ、etcdに書き込まれた設定はそのままノード上で実行されてしまいます。
主要概念とEKS/AKS/GKEの対応
| 概念 | EKS (AWS) | AKS (Azure) | GKE (Google Cloud) |
|---|---|---|---|
| クラウドIAMとのRBAC連携 | IRSA (IAM Roles for Service Accounts) | Azure AD Workload Identity | Workload Identity Federation |
| デフォルトのPod Security強制 | 強制なし(手動でPSAラベル付与が必要) | 強制なし(Azure Policyアドオンで補完) | Autopilotはrestricted相当を既定で強制 |
| NetworkPolicyエンジン | Amazon VPC CNI + Calico(要有効化) | Azure Network Policy / Calico(要有効化) | Calico(GKEに組み込み、有効化が必要) |
| コントロールプレーンの監査ログ | EKS control plane logging (CloudWatch Logs) | AKS Diagnostic settings | GKE Audit Logs (Cloud Audit Logs) |
よくある設定ミス
-
特権コンテナの起動 High Risk
privileged: trueやhostNetwork: true/hostPID: trueを持つコンテナは、ホストとほぼ同等の権限で動作し、Pod境界を無意味にする。 -
過剰なClusterRoleBinding High Risk
cluster-adminがdefault ServiceAccountや特定Namespace全体に紐づけられ、検証用の設定がそのまま本番に残るケース。 -
NetworkPolicy未設定 Medium Risk
NetworkPolicyが1つも定義されておらず、クラスタ内の全Podが全Podへ自由に到達できる状態になっている。
-
Pod Security Admissionの未強制 High Risk
Namespaceに
pod-security.kubernetes.io/enforceラベルが設定されておらず、実質的にprivilegedレベルのまま運用されている。 -
シークレットの平文環境変数マウント Medium Risk
APIキーやDB認証情報がSecretsマネージャーやCSIドライバ経由ではなく、Podの環境変数に平文で渡され、
kubectl describeやログから漏洩しやすくなる。
攻撃シナリオ: 特権Podからのクラスタ侵害
攻撃者が脆弱なWebアプリケーションのコンテナ実行権限(RCE)を獲得した、という想定です。
- 侵害したPod内から、マウントされているdefault ServiceAccountの権限を確認する。
- そのPodがprivilegedで動作しているかをクラスタ全体で調査する。
- hostPath/hostNetworkの利用有無から、ノードへのエスケープ経路を探す。
- 特権コンテナのホストファイルシステムアクセスを悪用し、ノード上で任意コマンドを実行する。
# 1. マウントされたdefault ServiceAccountの権限を確認
$ kubectl auth can-i --list --as=system:serviceaccount:default:default
# 2. クラスタ全体で特権コンテナを検索
$ kubectl get pods -A -o json | jq '.items[] | select(.spec.containers[].securityContext.privileged==true) | .metadata.name'
# 3. 発見した特権Podのspecを確認(hostPath/hostNetworkの有無)
$ kubectl get pod vulnerable-app-7d9f8 -n default -o yaml | grep -E 'privileged|hostNetwork|hostPath'
# 4. 特権コンテナ内からホストのファイルシステムへアクセス
$ kubectl exec -it vulnerable-app-7d9f8 -n default -- chroot /host /bin/bash
検知
Kubernetes監査ログとクラウドネイティブな脅威検知サービスを組み合わせ、以下のようなシグナルにアラートを設定します。
- Podの
create/updateイベントでsecurityContext.privileged: trueを含むもの。 - Kyvernoのポリシーレポート(
PolicyReport/ClusterPolicyReport)でfail判定が急増している。 - kube-benchによるCIS Kubernetes Benchmark定期スキャンの失敗項目。
- GuardDuty for EKS / Microsoft Defender for Containers / GKE Security Postureが検出する異常な特権昇格・不審なプロセス実行。
SELECT stageTimestamp, user.username, verb, objectRef.namespace, objectRef.name
FROM kubernetes_audit_logs
WHERE verb IN ('create', 'update')
AND objectRef.resource = 'pods'
AND requestObject.spec.containers[*].securityContext.privileged = true
ORDER BY stageTimestamp DESC;
是正
該当Namespaceに対してPod Security Admissionを強制し、PodのsecurityContextを最小権限の設定へ書き換えます。
# Namespaceに restricted レベルのPod Security Admissionを強制
$ kubectl label namespace default pod-security.kubernetes.io/enforce=restricted --overwrite
# default ServiceAccountの自動マウントを無効化
$ kubectl patch serviceaccount default -n default -p '{"automountServiceAccountToken": false}'
# 過剰なClusterRoleBindingを削除
$ kubectl delete clusterrolebinding default-cluster-admin-binding
PodのsecurityContextは以下のように変更します。
# Before (危険な設定)
securityContext:
privileged: true
runAsUser: 0
# After (最小権限)
securityContext:
privileged: false
allowPrivilegeEscalation: false
runAsNonRoot: true
runAsUser: 1000
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
実際に手を動かす
このページで扱った「特権コンテナによるクラスタ侵害」の再現と是正を、実際のシナリオ形式で体験できます。Scenario → Architecture → CLI Commands → Misconfiguration → Detection → Remediation → Verification の流れで進めます。
Lab: Kubernetes Privileged Container を始める →