Kubernetesの境界線を無力化する:docker.sockマウントがもたらす絶望的な権限昇格
現代のKubernetes環境において、最も洗練された防御アーキテクチャでさえ、足元の些細な設定ミスで崩れ去る。その最たる例が、ホストの docker.sock をコンテナ内にマウントするという「死の呪文」だ。
これは単なる設定の不備ではない。コンテナの抽象化レイヤーを物理的に突き破り、ホストOSの管理者権限を掌中に収めるための「マスターキー」を自ら差し出す行為に等しい。
1. なぜ docker.sock はパンドラの箱なのか
KubernetesにおいてPodは隔離環境として振る舞うが、docker.sock を hostPath マウントした瞬間、その隔離は幻想と化す。
このソケットはDockerデーモンの制御インターフェースであり、ローカルのIPC(Unix Domain Socket)を介して通信を行う。攻撃者はこのソケットを通じて、Docker APIを叩き、ホスト側で任意のコンテナを立ち上げることが可能だ。
攻撃シナリオ:コンテナ脱出のメカニズム
攻撃者がPod内に侵入し、マウントされたソケット経由で新たなコンテナを作成する際のコード例を見てみよう。
# ホストのルートファイルシステムをマウントした特権コンテナを強制起動する
curl -X POST --unix-socket /var/run/docker.sock http://localhost/containers/create -d '{
"Image": "alpine",
"Cmd": ["/bin/sh", "-c", "chroot /mnt/host /bin/sh"],
"HostConfig": {
"Binds": ["/:/mnt/host"],
"Privileged": true
}
}'
このリクエストが成功すれば、攻撃者はホストOSのルートディレクトリを自由に操作できる。もはやKubernetesのRBACやNamespaceの制約は無意味だ。カーネルモジュールのロードから、全Podの機密情報の窃取まで、全てが攻撃者の意のままとなる。
2. 脆弱性の本質:抽象化の漏洩(Abstraction Leakage)
この問題の根本原因は、コンテナランタイムがホストのリソースを管理する仕組みと、Kubernetesというオーケストレーターが提供するセキュリティ境界の間に存在する「設計上の非対称性」にある。
Docker API自体は、認証をデフォルトで求めていない(ローカルソケット接続時)。これは「ソケットにアクセスできる=root権限がある」というUnixの伝統的な権限モデルに基づいているからだ。しかし、Kubernetes環境では、コンテナ内部のプロセスが「誰の権限で動いているか」と「ソケットに触れる権限があるか」が分離されていない。
3. 防御の最前線:PSP/Admission Controllerの限界と進化
かつての PodSecurityPolicy (PSP) は、今やDeprecatedであり、Kubernetes 1.25以降では完全に削除された。現在、我々が依存すべきは Pod Security Admission (PSA) と、より柔軟な Kyverno や OPA Gatekeeper を組み合わせたガードレイルだ。
実践的ガードレイル:Admission Controllerによる厳格な制限
Kyverno を使用し、docker.sock のマウントを物理的に禁止するポリシーの例を挙げる。
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: block-docker-sock-mount
spec:
validationFailureAction: Enforce
rules:
- name: restrict-docker-socket
match:
resources:
kinds:
- Pod
validate:
message: "ホストのDockerソケットのマウントは禁止されています。"
pattern:
spec:
volumes:
- operator: NotIn
hostPath:
path: "/var/run/docker.sock"
4. チーフホワイトハッカーの視点:監査の盲点
単にポリシーを適用するだけでは不十分だ。真のインシデントハンドリングでは、以下の点に注目する必要がある。
- Runtime Security Monitoring:
Falcoなどのツールを用い、/var/run/docker.sockに対するopenシステムコールをリアルタイムで監視すべきだ。カーネルレベルでのイベント監視こそが、設定漏れを見抜く最後の砦となる。 - eBPFによる可視化: プロセスがどのソケットを操作したか、どのプロセスツリーからAPIが叩かれたかを、eBPFのトレースデータとして保存・解析せよ。
- ゼロトラストへの移行: 将来的には、Dockerデーモンそのものを排除し、
containerdやCRI-Oへ完全移行すること。さらに、Pod内でDocker APIを必要とするワークロード(CI/CDパイプラインなど)は、kanikoやbuildahのような「デーモンレス」なビルドツールへとリプレイスすることが、リスクを根本から消し去る最適解だ。
結びに代えて
攻撃者は常に、インフラの「隙間」を突いてくる。docker.sock は、便利さと引き換えにセキュリティの根幹を腐食させる劇薬だ。「動くからいい」という開発現場の甘えを許容することは、セキュリティアーキテクトとしては怠慢に他ならない。
技術的な深淵を覗き込み、抽象化の裏側に潜むプロトコルの仕様を理解すること。それが、Kubernetesという複雑な要塞を守り抜くための唯一の道である。
コメント