こんにちは!インフラやセキュリティの世界へようこそ。これからKubernetes(クーベネティクス)という、コンテナを管理するすごく便利なシステムを触っていくところですよね。
セキュリティの話を聞くと、「なんだか難しそうだな」「専門用語ばかりで頭が痛くなりそう…」と感じてしまうかもしれませんが、大丈夫です! 一歩ずつ、身近な例えから一緒に紐解いていきましょう。
今回は、Kubernetesの安全性をグッと高めるための仕組みである「Pod Security Admission(PSA)」と、その中でも絶対に押さえておきたい「特権コンテナの禁止」について、分かりやすく解説していきますね。
—
1. 家の鍵で例える「特権コンテナ」の危険性
まずは、私たちが普段暮らしている「おうちのセキュリティ」に例えて考えてみましょう。
コンテナというのは、言ってみれば「家の中にある個別の部屋(あるいはカプセル)」のようなものです。通常の部屋であれば、自分の部屋の掃除をしたり、中で勉強したりすることはできますが、家の外の構造を変えたり、隣の家を覗き見たりすることはできませんよね。これは、おうち全体の安全を守るために壁や鍵があるからです。
しかし、このコンテナの中に「特権(Privileged)」という名のマスターキーを持った状態の部屋を作ってしまうとどうなるでしょうか?
- 何が起きるのか:
特権コンテナは、その部屋(コンテナ)の中だけでなく、その家全体(つまり、コンテナを動かしている大元のホストサーバー)のすべてを自由に操作できるようになってしまいます。
- 泥棒が入ってきたらどうなる?:
もし、外部の悪い人(攻撃者)がその特権コンテナの隙をついて侵入に成功してしまったら……。マスターキーを奪われたのと同じなので、ホストサーバー自体が乗っ取られ、同じサーバー上で動いている他のすべてのシステムやデータがめちゃくちゃにされてしまいます。
だからこそ、「何でもできてしまう強力な鍵(特権)」を、不用意に普通のコンテナに持たせないことが、セキュリティの第一歩になるんです。
—
2. Kubernetesの「自動警備システム」:Pod Security Admissionとは?
開発者やインフラ担当者が毎回「このコンテナは特権を持たせてはいけないぞ」「ホストのフォルダを直接マウントさせてはいけないぞ」と手作業でチェックするのは、うっかりミスも起きるし大変ですよね。
そこで登場するのが、Kubernetesに標準で備わっているPod Security Admission(PSA)という仕組みです。
これは、いわば「マンションの厳格な管理人さん」のような存在です。
新しくお部屋(Pod)を作って入居しようとする人が現れたとき、管理人さんが「おいおい、その荷物の中身、危ない特権コマンドが入っていないかい?」「勝手に建物の裏口(ホストパス)の鍵を開けようとしていないかい?」と、チェックリスト片手に厳しく審査してくれます。
もし安全基準を満たしていない危ない設定であれば、「このお部屋への入居(デプロイ)は許可できません!」と、ビシッと門前払いしてくれる頼もしい機能なんです。
—
3. 実際にポリシーを設定してみよう
では、実際にこの「管理人さん」をKubernetesのネームスペース(お部屋の区画)に配置してみましょう。
Kubernetesでは、Pod Security Admissionのレベルとして主に以下の3つが用意されています。
1. privileged(特権): 制限なし。何でもありの状態(今回は使わないようにします)。
2. baseline(ベースライン): よくある危ない設定(特権コンテナやホストへの過剰なアクセスなど)を禁止する、一般的な安全レベル。
3. restricted(制限): さらに厳しく、コンテナがroot権限で動かないようにするなどの高度なセキュリティを強制するレベル。
今回は、実務の現場でも標準的に使われる baseline レベルを適用しつつ、万が一違反した場合には「お断り(Reject)」するように設定してみましょう。
ネームスペースの設定ファイル(YAML)のサンプルは以下のようになります。
apiVersion: v1
kind: Namespace
metadata:
name: secure-app-space # アプリケーションを配置するお部屋(ネームスペース)の名前
labels:
# Pod Security Admissionのモードを設定します
# 今回は「enforce(強制)」モードを使って、違反するPodの作成をブロックします
pod-security.kubernetes.io/enforce: "baseline"
# 警告を出すだけのモードもありますが、今回は厳しくブロックします
pod-security.kubernetes.io/enforce-version: "latest"
# 開発者に「注意喚起(Warning)」だけを表示する設定も組み合わせると親切です
pod-security.kubernetes.io/warn: "restricted"
pod-security.kubernetes.io/warn-version: "latest"
この設定を適用したネームスペース(secure-app-space)に対して、もし誰かがうっかり「特権コンテナ」を作ろうとすると、KubernetesのAPIサーバーが即座にエラーを返して止めてくれます。
—
4. 攻撃者が狙う「盲点」と現場の泥臭い対策
「よし、これでPSAを設定したから完璧だ!」……と言いたいところですが、現実のセキュリティの世界はもう少し泥臭いものです。
攻撃者は、私たちが「まさかここを見ないだろう」という盲点を巧みに突いてきます。例えば、以下のようなケースです。
- デフォルトのネームスペースへのうっかりデプロイ:
厳重なポリシーを設定したつもりが、開発用の default ネームスペースにうっかり重要度の高いPodをデプロイしてしまい、そこから突破される。
- ホストのボリュームマウントの悪用:
privileged: true にはしていなくても、ホストの /var/run/docker.sock などをコンテナ内にマウントしてしまうと、結局は裏技的にコンテナ外を操作できてしまいます(これも baseline ポリシーが防いでくれます)。
現場で役立つチェックの習慣
インフラ担当者や開発者の皆さんが日常の業務で意識してほしいのは、「動けばいいや」でマニフェスト(YAMLファイル)をコピー&ペーストしないことです。
特に、インターネット上で見つけたサンプルコードに securityContext: の設定がない場合や、安易に privileged: true が書かれている場合は要注意。「この設定、本当に今このコンテナに必要なんだっけ?」と立ち止まる勇気を持ちましょう。
安全なPodの書き方の例も見ておきましょう。
apiVersion: v1
kind: Pod
metadata:
name: safe-app-pod
namespace: secure-app-space
spec:
containers:
- name: web-app
image: nginx:alpine
# セキュリティコンテキストを明示的に指定して、安全性を高めます
securityContext:
allowPrivilegeEscalation: false # 特権昇格を明示的に禁止
runAsNonRoot: true # rootユーザー以外の権限で実行させる
capabilities:
drop:
- ALL # 不要なLinuxの特権機能をすべて剥ぎ取る
こうすることで、たとえアプリケーションの脆弱性を突かれてコードを実行されたとしても、システム全体の心臓部まで侵入されるリスクを劇的に低く抑えることができます。
—
おわりに
いかがでしたでしょうか?
「Pod Security Admission」や「特権コンテナの禁止」という言葉を聞くと難しく感じたかもしれませんが、要するに「おうちの中に危険な合鍵を持ち込ませないための、マンションの自動管理システム」なんだとイメージしていただければバッチリです。
セキュリティ対策は、一度にすべてを完璧にやろうとすると息切れしてしまいます。「まずはネームスペースにPSAのbaselineを設定してみよう」「マニフェストの securityContext を意識してみよう」といった形で、一歩ずつ確実にできることから取り入れていきましょう。
あなたの書いたコードとインフラストラクチャが、日々の開発を安全に支える強固な盾となりますように。これからも一緒に楽しく学んでいきましょう!
コメント