defending-kubernetes について
defending-kubernetesは、Kubernetesクラスターのセキュリティを評価・強化し、初期トリアージ後の侵害疑いを調査するスキルです。RBAC、Podセキュリティ、ネットワーク、認証情報、監査ログの対策を優先順位に沿って扱います。
主な機能
- 01RBACの最小権限を優先
- 02Pod Security Admissionを適用
- 03ネットワークポリシーのデフォルト拒否を推奨
- 04トークンとシークレットの露出を低減
- 05監査ログの検知シグナルを特定
活用シーン
- 01クラスターのRBACとアドミッション設定の確認
- 02ネットワークとPodのセキュリティ対策の強化
- 03攻撃に関する発見を防御策に反映
- 04侵害疑いの後に監査範囲を確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ trilwu/ secskills --skill defending-kubernetesインストール後、Claude Code で/defending-kubernetesを入力して読み込まれたか確認します。
詳細
Kubernetes の防御
Kubernetes の弱点は、奇抜なバグではなく、便利さを優先したデフォルト設定にあります。実際に成立する攻撃は、意図以上の権限を与える RBAC、何も制止しないために特権で実行される Pod、フラットな Pod ネットワーク、そしてクラスター全体にアクセスできるマウント済みのサービスアカウントトークンです。防御の大半は、優先順位に従ってこれらを塞ぎ、誰かが試みたときに検知できるようにすることです。
これは attacking-eks-gke-aks と exploiting-containers に対応する内容です。攻撃者の手口を知るにはそちらを読み、適用すべき制御と監視すべき項目を知るにはこちらを使ってください。
使用する場面
- クラスターのセキュリティ態勢や、Admission/RBAC の設定をレビューするとき
- クラスター侵害の疑いに対応するとき(初期トリアージ後)
- 適用する制御(Pod Security、ネットワークポリシー)と検知項目を決めるとき
- 攻撃側から見つかったクラスターの問題を、具体的な制御に落とし込むとき
- コントロールプレーン、kubelet、etcd の露出を強化するとき
使用しない場面
- クラスターを攻撃するとき —
attacking-eks-gke-aksを使ってください - 特にコンテナーエスケープやランタイムの内部を扱うとき — 手法については
exploiting-containers/escaping-hardened-containersを使い、 制御についてはここに戻ってください - クラスターを取り巻くクラウド IAM プレーン(IRSA、ワークロード ID、ノードロール) — こちらは
investigating-*-incidents/hardening-cloud-postureが対象です。GKE/EKS/AKS のインシデントでは通常、両方のプレーンへの対応が必要です - アラートがインシデントかどうかを判断するとき —
triaging-security-alertsを使ってください
優先順位に従った適用
順序が重要です。実際の侵入経路となっている頻度が高い順に並べています。
1. RBAC の最小権限
実際によく見られる弱点です。一見無害に見えても、権限昇格の手段となるバインディングを探してください。
# Who can create pods anywhere? (→ mount any secret, run as any SA)
kubectl auth can-i create pods --all-namespaces --as=system:serviceaccount:ns:sa
# Subjects bound to cluster-admin
kubectl get clusterrolebindings -o json | \
jq '.items[] | select(.roleRef.name=="cluster-admin") | .subjects'
危険な動詞は * だけではありません。create pods があれば、サブジェクトはその名前空間内の任意のサービスアカウントとして Pod を実行し、任意のシークレットをマウントできます。実質的に名前空間の管理者権限を与えることになります。ロールに対する escalate と bind があれば、サブジェクトは自分が持つ以上の権限を自らに付与できます。pods/exec に対する create、および secrets、serviceaccounts/token、nodes/proxy へのアクセスは、それぞれが権限昇格の経路です。ロールの名前ではなく、各サブジェクトが 実際にできること を列挙してください。
2. Pod Security Admission
PodSecurityPolicy は Kubernetes 1.25 で削除されました。組み込みの後継機能である Pod Security Admission は、Pod Security Standards の 3 つのレベル(privileged、baseline、restricted)を、名前空間ごとにラベルを使って適用します。
# Namespace label: enforce the restricted profile, and warn/audit on violations
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/warn: restricted
pod-security.kubernetes.io/audit: restricted
restricted は、エスケープや権限昇格を容易にする Pod の設定をブロックします。対象には、特権コンテナー、ホスト名前空間(hostPID、hostNetwork、hostIPC)、host-path マウント、root としての実行、追加のケイパビリティが含まれます。プロファイルが適用されていないクラスターは、securityContext.privileged: true ひとつでノードが乗っ取られる状態です。3 つのレベルを超えるポリシー(イメージの来歴、レジストリの許可リストなど)が必要な場合は、外部の Admission コントローラー(Kyverno、OPA Gatekeeper)が必要です。これを記録し、PSA が対応しているかのように扱わないでください。
3. ネットワークポリシーのデフォルト拒否
デフォルトでは、すべての Pod が他のすべての Pod に到達できます。名前空間ごとにデフォルト拒否の ingress ポリシーを設定し、明示的に許可することで、侵害された Pod ひとつが横方向の移動に使われるのを防ぎます。CNI が NetworkPolicy を実際に適用していることを確認してください。設定によってはオブジェクトを受け付けるだけで何も適用しないものがあります。適用されていないことが分かりにくいため、何も設定しないより悪い状態です。
4. サービスアカウントトークンとシークレット
- API を呼び出さない Pod では、
automountServiceAccountToken: falseを設定してください。 マウントされたトークンと、過剰に許可された RBAC バインディングの組み合わせは、クラスター内での横移動に使われる典型例です。 - Kubernetes のシークレットは、保存時の暗号化が設定されていないかぎり、etcd 内では暗号化されず、Base64 エンコードされるだけです。設定を確認してください。
- 環境変数として渡されているトークンやクラウド認証情報を探してください。ログやクラッシュダンプに漏れるおそれがあります。
5. コントロールプレーンと kubelet の公開
- API サーバーは、認証・認可なしにインターネットへ公開すべきではありません。可能であれば、ネットワーク制限も設けてください。匿名認証は無効にする必要があります。
- kubelet の読み取り専用ポート(10255)と認証済みポート(10250)は、ワークロードから到達できないようにする必要があります。
nodes/proxyRBAC と公開された 10250 は、ノード上でコマンドを実行する直接的な経路です。 - etcd では相互 TLS を必須にする必要があります。etcd へのアクセスはすべてを失うことを意味します。すべてのシークレットがそこに保存されています。
検知:監査ログを有効にする
ほとんどのクラスターでは有効な監査ポリシーが設定されていないため、事後に調査するための情報が残りません。監査ポリシーが設定されていないクラスターは、GCP Data Access ロギングが無効になっているのと同じ Kubernetes 版です。アクティビティが記録されていないのです。
価値の高い監査シグナル:
- ポッドへの
exec、attach、port-forward— 対話型アクセス - 大量のシークレットに対する
get/list。特にクラスター全体を対象とするもの clusterrolebindingsおよびrolebindingsに対するcreate/updateprivileged、ホスト名前空間、またはホストパスマウントを使用して作成されたポッド- 成功した匿名または
system:unauthenticatedリクエスト TokenRequestAPI によるサービスアカウントトークンの作成
マネージドクラスターでは、監査ログはクラウドのロギングプレーン(GKE → Cloud Audit Logs、EKS → CloudWatch、AKS → Azure Monitor)に送信されます。調査では、そこで investigating-*-incidents スキルとの情報を突き合わせます。
拒否すべきもっともらしい言い訳
- 「ロール名に admin と付いていないから問題ありません。」 名前は関係ありません。名前空間内で
create podsやsecrets getができれば、実質的に名前空間管理者です。肩書きではなく、権限を列挙してください。 - 「Pod Security を適用しているので、コンテナは隔離されています。」 プロファイルが
restrictedで、実際に強制されている場合に限ります。warnにしているだけでは不十分です。baselineラベルや監査のみのラベルでは、脱出経路をほとんど防げません。 - 「NetworkPolicies を定義しているので、ネットワークはセグメント化されています。」 CNI がそれらを強制している場合に限ります。オブジェクトの存在ではなく、強制されていることを確認してください。
- 「シークレットは etcd にあるので保護されています。」 保存時の暗号化が有効でなければ、シークレットは Base64 でエンコードされているだけです。etcd を読み取れる者、または
get secretsを実行できる者は、シークレットを取得できます。 - 「マネージドクラスターなので、プロバイダーがセキュリティを確保しています。」 プロバイダーが保護するのは、自ら運用するコントロールプレーンです。RBAC、Pod Security、ネットワークポリシー、ワークロード ID はお客様の責任です。責任共有モデルに、お客様のバインディングは含まれません。
- 「アラートは発生していません。」 沈黙を安全の証拠とみなす前に、そもそも監査ポリシーが存在するか確認してください。
外部ソースを読む
公開されているアドバイザリ、仕様、ベンダーレポートを Markdown として取得します:
curl -sL "https://defuddle.md/<url>" # scheme in the path is optional
これにより、ページの定型部分が取り除かれ、文章主体のページではトークン数がおよそ 78% 減少します。また、要約ではなく全文が返されるため、grep で検索し、該当なしという結果を信頼できます。
この用途に適さないケースが 3 つあります。構造化データは可読性抽出によって壊されるため、JSON と API レスポンスはそのまま取得してください。認証が必要なページや JavaScript でレンダリングされるページは、匿名で取得されるため、直接取得してください。また、攻撃者のインフラストラクチャ(フィッシングリンク、C2、マルウェアホスティング)、クライアント所有のホスト、またはエンゲージメント URLを経由させてはいけません。リクエストはマシンから第三者へ送られ、稼働中の攻撃者インフラストラクチャの場合は、運用者に気付かれることにもなります。
抽出ツールをブロックし、ページではなくエラーの内容を返すサイトもあります。たとえば freedesktop.org から返される {"error":"Failed to fetch: 418 I'm a teapot"} などです。これは取得が拒否されたことを示しており、ソースが対象の情報は存在しないと述べているわけではありません。そこから結論を導く前に、URL を直接再取得してください。
参考資料
attacking-eks-gke-aks— これらの制御で防止する攻撃経路exploiting-containers、escaping-hardened-containers— Pod Security が防止を目指す脱出手法hardening-cloud-posture— クラスターを取り巻くクラウド IAM プレーンengineering-detections— 上記の監査シグナルをルールにする方法investigating-aws-incidents/investigating-gcp-incidents— マネージドクラスターの監査証跡が導く調査先