こんにちは!セキュリティバイブルの執筆を担当している、最高セキュリティ責任者の「白(ハク)」です。
普段は、目に見えないサイバー攻撃者たちの巧妙な手口を分析し、企業のデジタルな城を守る仕事をしています。こう聞くと「なんだか怖そう……」と思うかもしれませんが、安心してください。今日は、皆さんが大切に育てている「Kubernetes(クバネティス)」という庭を、泥棒から守るための「優しい防犯術」を一緒に学んでいきたいと思います。
今回のテーマは、「NetworkPolicy(ネットワークポリシー)によるPod間通信のマイクロセグメンテーション」です。
難しい言葉が並んでいますが、大丈夫。一歩ずつ、噛み砕いて解説していきますね!
—
1. Kubernetesの「初期設定」は、実は「鍵のないシェアハウス」?
まず、皆さんに知っておいてほしい衝撃的な事実があります。
Kubernetesという仕組みは、デフォルトの状態だと「同じ家(クラスター)の中にいるPod同士なら、誰でも自由に会話ができる」という設定になっているんです。
これを「家の防犯」に例えてみましょう。
あなたは大きなシェアハウスに住んでいるとします。
- Webサーバー君:玄関(インターネット)に一番近い部屋。
- DB(データベース)君:家の奥深くにある、金庫が置かれた部屋。
本来なら、金庫の部屋(DB)に入れるのは、管理者のあなたか、信頼できるWebサーバー君だけのはずですよね?
しかし、Kubernetesのデフォルト設定は、「家の中のドアに一切鍵がかかっていない状態」なのです。
もし、悪意のある泥棒がWebサーバー君の部屋に窓から忍び込んだらどうなるでしょうか。泥棒はそのまま廊下を歩いて、金庫の部屋(DB)までスルスルと入っていけてしまいます。これを専門用語で「ラテラルムーブメント(側方移動)」と呼びます。
この「誰でもどこへでも行ける」状態を解消し、「必要な人だけが、必要な部屋に入れるように鍵をかける」のが、今回ご紹介するマイクロセグメンテーション(ネットワーク分離)の役割です。
—
2. 「最小権限」という、セキュリティの魔法の言葉
セキュリティの世界には、「最小権限の原則」という鉄則があります。
これは、「仕事に必要な、最低限の権限だけを渡そうね」という考え方です。
これをネットワークに当てはめるとこうなります。
1. まずは全部のドアを閉める(Default Deny)
2. 許可された通信だけ、個別に鍵(ホワイトリスト)を渡す
最初から「全部OK」にしておいて、後から「ここはダメ、あそこもダメ」と禁止していく(ブラックリスト方式)のは、実はとても危険なんです。なぜなら、禁止し忘れた「抜け道」を、攻撃者は絶対に見逃さないからです。
—
3. 実践!NetworkPolicyで「鍵」を作ってみよう
それでは、実際にKubernetesでどのように「鍵」をかけていくのか、具体的なコード(YAML)を見ていきましょう。
手順①:まずは「すべて禁止」の壁を作る
まずは、基本となる「全ての通信を一旦ストップする」設定です。これが「全部のドアを閉める」作業になります。
# default-deny-all.yaml
# この設定を適用すると、同じ名前空間(Namespace)内の通信がすべて遮断されます。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: my-app-space # 適用する名前空間を指定します
spec:
podSelector: {} # 空っぽのブラケット {} は「この名前空間のすべてのPod」を指します
policyTypes:
- Ingress # 入ってくる通信を制限します
- Egress # 出ていく通信を制限します
この設定を適用した瞬間、あなたのシェアハウスの全ドアに鍵がかかりました。これで泥棒も動けませんが、Webサーバー君も仕事ができなくなります。そこで、次のステップです。
手順②:WebからDBへの通信だけを「許可」する
次に、「Webサーバー君が、DB君にデータを保存しに行くときだけ」の通信を許可します。
# allow-web-to-db.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-web-to-db
namespace: my-app-space
spec:
# 通信を「受け取る側(DB)」を指定します
podSelector:
matchLabels:
app: database # 「app: database」というラベルがついたPodが対象
policyTypes:
- Ingress # 「入ってくる通信」のルールを決めます
ingress:
- from:
- podSelector:
matchLabels:
app: web-server # 「app: web-server」というラベルのPodからの通信だけを許可
ports:
- protocol: TCP
port: 5432 # データベース(例:PostgreSQL)が使うポート番号だけを開けます
見てください、とてもシンプルですよね!
この設定により、「web-serverという名札をつけた人だけが、databaseという部屋の5432番の窓口から話しかけられる」というルールが出来上がりました。
—
4. 現場のプロが教える「陥りやすい罠」
ここで、私が現場で見てきたインシデントから得た、大切な教訓を共有しますね。
ラベル(Labels)の管理は命!
NetworkPolicyは、Podにつけられた「ラベル」を見て、誰が誰かを判断します。
もし、開発者が間違えて別のPodに app: web-server というラベルをつけてしまったら、そのPodも金庫(DB)にアクセスできてしまいます。
「ラベルは単なるメモではなく、鍵そのものである」という意識をチーム全員で持つことが大切です。
DNSの通信を忘れずに
全部を禁止(Deny All)にすると、実は「名前解決(DNS)」という、宛先を探すための通信も止まってしまいます。
Webサーバーが database-service という名前でDBを探そうとしても、DNSに聞きに行けなくなるのです。実務では、DNS(通常は kube-system 名前空間にあるPod)への通信を許可するルールも忘れずに設定しましょう。
—
5. まとめ:一歩ずつ、安全な庭を作っていきましょう
いかがでしたでしょうか?
「マイクロセグメンテーション」と聞くと難しそうですが、要は「大事な部屋には鍵をかけ、信頼できる人にだけ合鍵を渡す」という、私たちの日常で行っている防犯と同じなのです。
セキュリティ対策に「完璧」はありませんが、「最小権限の原則」に基づいて一歩ずつ設定を積み重ねていくことで、あなたのシステムは格段に強くなります。
1. まずは現状を知る(どのPodがどこに通信しているか?)
2. 「すべて禁止」を試してみる(開発環境で!)
3. 必要な通信だけを一つずつ許可する
このステップで、ぜひあなたのKubernetesクラスターを要塞化(ハーデニング)してみてください。
もし設定で迷ったり、「こんな場合はどうすればいいの?」という疑問が湧いたりしたら、いつでも相談してくださいね。セキュリティは、怖がるものではなく、正しく理解して味方につけるものです。
皆さんの開発が、より安全で楽しいものになるよう、心から応援しています!
—
執筆:白(ハク)
*最高セキュリティ責任者(CSO)。現場での泥臭いインシデント対応を愛し、攻撃者の心理を読み解くのが趣味。難しい技術を「お隣さんへの挨拶」くらい身近に伝えることをミッションとしている。*
コメント