Kubernetes API Serverは「城門」だ。そこを突破されたらおしまいだという話をしよう
現場のエンジニア諸君、お疲れ様。最近は「コンテナ化すればとりあえず安心」という幻想を抱いているチームによく出くわす。だが、Kubernetes(K8s)の心臓部である API Server が野放しになっていないか?
API Serverは、クラスター内のあらゆる操作を制御する「城門」だ。ここを突破されるということは、攻撃者に鍵を渡すに等しい。今日は、教科書に載っているような「RBACをやりましょう」という生ぬるい話ではない。なぜそれが破られるのか、そしてどうやって鉄壁の守りを固めるのか、その「現場の泥臭い戦術」を叩き込む。
—
1. 攻撃者が狙う「盲点」:匿名アクセスと過剰権限
攻撃者はまず、API Serverが匿名アクセスを許可していないか、あるいは認証がバイパスできるエンドポイントがないかを探る。
なぜRBACが有名無実化するのか
よくあるのが、system:serviceaccount に対して cluster-admin 権限を安易に付与するケースだ。「動かないから」という理由で、Pod内のアプリに広範な権限を与えていないか? もしそのアプリにRCE(リモートコード実行)脆弱性があれば、攻撃者はそのPodのトークンを使い、クラスター全体を乗っ取る。
PoCの視点:
攻撃者は、kubectl auth can-i --list を叩いて自分に何ができるかを確認し、secrets や pods/exec の権限を探す。ここを制限できていないと、彼らは「クラスターの管理者」に昇格する。
—
2. 実践:RBACによる「最小権限」の強制
「動けばいい」という甘えを捨て、必要な操作だけを許可する Role と RoleBinding を定義する。
セキュアな定義例: 特定の名前空間でPodの参照のみを許可する
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: production
name: pod-reader
rules:
- apiGroups: [“”]
resources: [“pods”]
verbs: [“get”, “watch”, “list”] # 実行(exec)や削除(delete)は許可しない
—
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods-binding
namespace: production
subjects:
- kind: ServiceAccount
name: my-app-service-account
namespace: production
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
—
3. 監査ログ(Audit Logs):事後検証ではなく「予兆検知」のために
「ログを取っています」と言うエンジニアは多いが、「何が起きたら通知するのか?」と聞くと黙り込む。ログはストレージの肥やしではない。攻撃の予兆を捉えるためのセンサーだ。
API Serverの監査ポリシー設定(audit-policy.yaml)
以下の設定は、重要なリソースへのアクセスを確実に記録し、ノイズを減らすためのバランスの取れた設定だ。
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
# 認証情報の漏洩を防ぐため、Secretのデータ部分は記録しない
- level: RequestResponse
resources:
- group: “”
resources: [“secrets”]
# ノードやPodの変更は全て記録(異常な操作の追跡用)
- level: Metadata
resources:
- group: “”
resources: [“pods”, “nodes”]
# 基本的な操作はRequestレベルで記録
- level: Request
users: [“admin”, “system:serviceaccount:default:my-app”]
—
4. 現場の知恵:SIEMとの連携と動的モニタリング
ログを保存するだけでは意味がない。私はいつも、Fluentd や Promtail を使い、ログを即座に外部のログ管理システム(Elasticsearch, Datadog, CloudWatch Logsなど)へ転送し、異常検知のクエリを走らせている。
現場で必ずアラートを出すべき条件:
system:anonymousによる API Server へのアクセス発生pods/execやpods/attachの実行(これが頻発するのは異常だ)- 権限変更(
RoleBindingやClusterRoleBindingの作成・更新)
Pythonによる簡易アラート監視のイメージ(ロジック)
SIEMのログから「権限変更」を抽出するロジックの概念
def check_audit_logs(log_entry):
# ロールバインディングの変更は極めて危険
if “RoleBinding” in log_entry[‘objectRef’][‘resource’] and log_entry[‘verb’] in [‘create’, ‘update’]:
trigger_security_alert(
f”危険: 権限昇格の予兆が検知されました: {log_entry[‘user’][‘username’]}”
)
実際の運用では、これをログストリームに対してリアルタイムで実行する
—
最後に:セキュリティは「設定」ではなく「文化」だ
Kubernetesの堅牢性は、ツールを入れた瞬間に完成するものではない。誰が、いつ、どの権限でクラスターを触ったか。この透明性を担保し続けることこそが、攻撃者を最も遠ざける防御策になる。
今日の記事を読んだら、まずは自分のクラスターで kubectl get clusterrolebindings を実行してみてくれ。身に覚えのない cluster-admin が付与されていないか? ログの保存先はどこか? 確認するなら、今すぐだ。
何かあれば、またいつでも質問してくれ。現場からは以上だ。
コメント