こんにちは!インフラやクラウドのセキュリティの世界へようこそ。
初めてKubernetes(クバネティス)やコンテナに触れる方にとって、次々と出てくる専門用語はちょっと難しく感じられますよね。でも、安心してください。一歩ずつ、身近な例えを交えながら分かりやすく紐解いていきましょう!
今回は、Kubernetesのセキュリティを守る上でとても大切な「特権コンテナの禁止」と、それを実現するPod Security Admission(PSA)という仕組みについてお話します。
—
1. 家の鍵に例える「特権コンテナ」の危険性
まず、コンテナ技術を「一軒の家(またはシェアハウスの個室)」に例えてみましょう。
通常のコンテナは、鍵の閉まった自分の部屋のようなものです。部屋の中では自由に家具を動かせますが、家全体の構造を変えたり、隣の部屋を勝手に覗き見たりすることはできません。この「部屋の中だけ動ける制限された状態」こそが、セキュリティを保つための基本です。
しかし、「特権コンテナ(Privileged Container)」はどうでしょう?
これは、いわば「家全体の合鍵どころか、建築会社のマスターキーを全部持っている状態」の部屋です。
この特権コンテナで動くアプリに、もし万が一、外から侵入(脆弱性の悪用など)されてしまったらどうなるでしょうか?
攻撃者はそのマスターキーを使って、コンテナの外側にある「Kubernetesの親(ホストOS)」に簡単に飛び出すことができます。結果として、同じサーバー上で動いている他のすべてのシステムが乗っ取られたり、クラウドの管理権限まで奪われたりという、最悪の事態に繋がってしまいます。
だからこそ、「最初からそんな強力なマスターキーを配らない(=特権コンテナを禁止する)」という対策が、インフラを守る第一歩になるのです。
—
2. Pod Security Admission(PSA)とは?
では、どうやって特権コンテナを禁止すればよいのでしょうか?
「開発者全員に、危ない設定を書かないでねとお願いする」のは、セキュリティの世界では一番やってはいけない失敗パターンです。人間はうっかりミスをしますし、忙しいとルールを忘れてしまうこともありますからね。
そこで登場するのが、Kubernetes標準の番人であるPod Security Admission(PSA)です。
PSAは、新しいアプリ(Pod)が家(クラスター)に入ろうとする時に、持ち物検査をしてくれる自動ゲートキーパーのようなものです。「おいおい、その荷物の中に入っている『特権モード(Privileged)』の道具は持ち込み禁止だよ!」と、玄関先でピシャリと跳ね返してくれます。
PSAには、セキュリティの厳しさに応じて、主に3つのレベルが用意されています。
- Privileged: 制限なし。何でも持ち込める(危険なので通常は使いません)
- Baseline: 一般的なベストプラクティス。危険な特権やホストの共有を禁止する
- Restricted: 最も厳しいレベル。アプリがroot権限で動くことすらも禁止する
今回は、この中のBaselineやRestrictedなルールを使って、安全な環境を作る方法を見ていきましょう。
—
3. 実際に設定を書いてみましょう
Kubernetesでは、名前空間(Namespace:家の中の部屋割りみたいなもの)単位で、PSAのルールを適用することができます。
例えば、production という本番用の名前空間に対して、「Baseline」レベルのチェックを義務付ける設定は、以下のようなマニフェスト(設定ファイル)で実現できます。
apiVersion: v1
kind: Namespace
metadata:
name: production
labels:
# Baselineレベルのセキュリティを適用する(危険な特権設定をブロック)
pod-security.kubernetes.io/enforce: "baseline"
# 違反があった場合に、警告(Warning)を出すだけでなく、実行を拒否(Enforce)する
pod-security.kubernetes.io/enforce-version: "v1.28"
# 開発者に「もっと厳しくできるよ」と警告を出すモード
pod-security.kubernetes.io/warn: "restricted"
この設定をした名前空間に対して、もしうっかり「特権コンテナ」を作ろうとすると、Kubernetesは以下のようなエラーを出して作成を拒否してくれます。
> Error from server (Forbidden): error when creating "pod.yaml": pods "risky-pod" is forbidden: violates PodSecurity "baseline:latest": privileged (container "app" must not set securityContext.privileged=true)
「ちゃんとゲートキーパーが仕事をして、危険な侵入を防いでくれた!」という瞬間ですね。
—
4. 安全なPodの書き方(デベロッパー向け)
それでは、PSAに怒られないためには、アプリの設定(Podの定義)をどう書けばよいのでしょうか?
ポイントは、securityContext という項目で、余計な権限を剥ぎ取ることです。
以下に、安全にコンテナを動かすための設定サンプルを載せます。実務の参考にしてみてください。
apiVersion: v1
kind: Pod
metadata:
name: secure-app-pod
namespace: production # 先ほどPSAを設定した名前空間
spec:
containers:
- name: web-app
image: nginx:alpine
securityContext:
# 【重要】特権コンテナの有効化を明示的に禁止(falseにする)
privileged: false
# ルート権限(root)での実行を禁止し、一般ユーザー権限で動かす
runAsNonRoot: true
runAsUser: 10001 # 固有のユーザーIDを指定
# 不要なLinuxケーパビリティ(特権機能)をすべて捨て去る
capabilities:
drop:
- ALL
# ファイルシステムを読み取り専用にして、不正な改ざんを防ぐ
readOnlyRootFilesystem: true
このように設定することで、アプリが必要最低限の権限だけで動き、万が一脆弱性を突かれても被害を最小限に食い止めることができます。
—
まとめ
今回は、KubernetesにおけるPod Security Admission(PSA)を用いた特権コンテナの禁止について解説しました。
- 特権コンテナは、家全体のマスターキーを渡すようなものなので絶対に避ける。
- 人間の注意力に頼らず、Pod Security Admission(PSA)という自動の門番にチェックを任せる。
- 設定ファイル(
securityContext)で、privileged: falseやrunAsNonRoot: trueを指定して、安全な状態を保つ。
セキュリティ対策は、最初は少し窮屈に感じるかもしれません。「ここまで縛る必要ある?」と思うこともあるでしょう。でも、それはあなたの大切なシステムとユーザーを守るための「頑丈な玄関の鍵」です。
一歩ずつ、安全で強いインフラを作っていきましょう!応援しています!
コメント