【入門編】KubernetesにおけるNetworkPolicyを用いたPod間通信のマイクロセグメンテーション – アプリケーションセキュリティ & 安全な開発防御ガイド

Kubernetesの「壁」でサイバー攻撃者の侵入を防ぐ!NetworkPolicyで実現するPod間通信のマイクロセグメンテーション

皆さん、こんにちは!セキュリティの最前線で日々奮闘している、〇〇(あなたの名前)です。今回は、最近ますます存在感を増しているKubernetesの世界で、サイバー攻撃者の「横展開」を食い止めるための強力な武器、「NetworkPolicy」について、初心者の方にも分かりやすく解説していきますね。

泥棒はどこから入ってくる?攻撃者が狙う「隙間」とは

まず、サイバー攻撃って、どんなイメージをお持ちですか?「ハッカーが画面をバンバン叩いて、パスワードを破る!」…そんなイメージかもしれませんね。もちろん、そういう攻撃もありますが、もっと地道で、見落としがちな「隙間」を狙ってくる攻撃も多いんです。

例えば、あなたの家を想像してみてください。玄関の鍵をしっかりかけていても、窓が開けっ放しだったらどうでしょう?泥棒は、そこから忍び込んで、家の中を物色するかもしれません。そして、もし家の中の部屋のドアも開けっ放しだったら…?泥棒は、リビングから寝室、書斎へと、自由に移動できてしまいますよね。これが、ITの世界では「ラテラルムーブメント」、つまり「横展開」と呼ばれる攻撃です。

Kubernetesクラスターも、これと似ています。たくさんの「コンテナ(Pod)」が集まって、お互いに連携しながら動いています。もし、これらのPod間の通信が、誰でも自由にできる状態だったら…?攻撃者が、一つのPodに侵入できたとしても、そこから他の大切なPodへ簡単に移動できてしまう、というわけです。これは、とっても危険ですよね。

Kubernetesの「見えない壁」:NetworkPolicyの役割

そこで登場するのが、今回ご紹介する「NetworkPolicy」です。これは、Kubernetesが提供する、Pod間の通信を細かく制御できる機能なんです。例えるなら、家の中の各部屋に「ドア」と「鍵」を取り付けるようなもの。誰が、どの部屋(Pod)に入って、どの部屋(Pod)と通信できるのかを、細かくルールで決められるんです。

しかも、NetworkPolicyのすごいところは、「デフォルト拒否」という考え方を基本にしている点です。これは、「何も許可されていない通信は、すべて拒否する」という考え方。つまり、最初から「閉じた状態」にしておいて、必要な通信だけを「許可」していく、という、非常に安全なアプローチなんです。

これは、先ほどの家の例で言えば、「すべての部屋のドアは、原則として閉まっている。そして、家族(許可されたPod)だけが、必要な時に、必要な部屋のドアを開けて、中に入ったり、他の部屋とやり取りしたりできる」というイメージです。

ラベルは「表札」!通信を制御するカギ

では、具体的にどうやって通信を制御するのでしょうか?ここで活躍するのが、「ラベル」という仕組みです。

Kubernetesでは、Podに「ラベル」という「表札」のようなものを付けることができます。例えば、「app=frontend」というラベルを付ければ、それは「Webサイトの画面を担当するPod」だと分かります。「app=backend」なら「裏側でデータ処理をするPod」といった具合です。

NetworkPolicyは、このラベルを使って、「どのPodが、どのラベルのPodと通信できるか」を定義します。

例えば、こんなルールが考えられます。

  • 「Webサイトの画面(app=frontend)のPodは、データ処理(app=backend)のPodとだけ通信できる。」
  • 「データ処理(app=backend)のPodは、データベース(app=database)のPodとだけ通信できる。」
  • 「それ以外の通信は、すべて拒否する。」

こうすることで、もし万が一、攻撃者がWebサイトの画面のPodに侵入できたとしても、それ以上、データ処理のPodやデータベースのPodには移動できない、ということになるんです。攻撃者の「横展開」を、ここでストップさせることができるんですね!

実際にNetworkPolicyを使ってみよう!

言葉だけではイメージしにくいかもしれませんので、簡単な例を見てみましょう。

例1:frontend Pod から backend Pod への通信のみを許可する

まず、frontend Podとbackend Podに、それぞれラベルを付けます。

frontend-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: frontend-pod
labels:
app: frontend # frontend というラベルを付けます
spec:
containers:

  • name: nginx

image: nginx:latest

backend-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: backend-pod
labels:
app: backend # backend というラベルを付けます
spec:
containers:

  • name: app

image: your-backend-app-image # あなたのバックエンドアプリケーションのイメージを指定してください

次に、この2つのPod間の通信だけを許可するNetworkPolicyを作成します。

allow-frontend-to-backend.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-backend
namespace: default # このポリシーが適用されるNamespaceを指定します
spec:
podSelector:
matchLabels:
app: frontend # このポリシーが適用されるPod(frontend Pod)を指定します
policyTypes:

  • Egress # 送信(Egress)通信を制御します

egress:

  • to:
  • podSelector:

matchLabels:
app: backend # backend ラベルを持つPodへの通信を許可します
ports:

  • protocol: TCP

port: 8080 # backend Podが待ち受けているポート番号を指定します(例)

解説:

  • metadata.name: このNetworkPolicyの名前です。分かりやすい名前を付けましょう。
  • metadata.namespace: このポリシーが有効になるNamespaceを指定します。
  • spec.podSelector: このポリシーがどのPodに適用されるかを指定します。ここでは app: frontend というラベルを持つPodに適用されます。
  • spec.policyTypes: 制御する通信の種類を指定します。Egress はPodから外への通信(送信)、Ingress はPodへ入ってくる通信(受信)です。今回はfrontend Podからbackend Podへの「送信」を制御したいので Egress を指定します。
  • spec.egress: 送信通信のルールを定義します。
  • to: どこへの通信を許可するかを指定します。
  • podSelector: 特定のラベルを持つPodへの通信を許可します。ここでは app: backend を指定しています。
  • ports: どのポートへの通信を許可するかを指定します。protocol (TCP/UDP) と port 番号を指定します。

このポリシーを適用すると、frontend-pod は backend-pod の 8080 番ポートへのTCP通信のみが可能になります。それ以外のPodへの通信や、他のポートへの通信はすべてブロックされます。

例2:デフォルト拒否ポリシーを作成する

さらに安全性を高めるために、クラスター内のすべてのPodに対して「デフォルト拒否」のポリシーを適用することもできます。これは、明示的に許可されていない通信はすべてブロックするという強力な防御策です。

default-deny.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: default # このポリシーが適用されるNamespaceを指定します
spec:
podSelector: {} # すべてのPodに適用(空のpodSelectorはすべてを意味します)
policyTypes:

  • Ingress
  • Egress

解説:

  • spec.podSelector: {}: 空の podSelector は、そのNamespace内のすべてのPodにこのポリシーが適用されることを意味します。
  • spec.policyTypes: Ingress と Egress の両方を指定しているので、入ってくる通信も出ていく通信も、すべてデフォルトで拒否されます。

この default-deny-all ポリシーを適用した上で、先ほどの allow-frontend-to-backend のような、必要な通信だけを許可するポリシーを追加していくという運用が、非常に効果的です。

注意点:
この default-deny-all ポリシーを適用する際は、KubernetesのAPIサーバーやCoreDNSなど、クラスターの正常な動作に必要な通信もブロックされてしまう可能性があります。そのため、クラスターの運用に必要な通信を許可するポリシーも忘れずに作成・適用する必要があります。これは、最初は少し難しく感じるかもしれませんが、一つずつ確認しながら進めていきましょう!

まとめ:攻撃者の「隙間」をなくし、安全なKubernetes環境を築こう!

NetworkPolicyは、Kubernetesクラスター内のセキュリティを強化するための、非常に強力で柔軟なツールです。

  • 攻撃者の「横展開」を阻止する
  • デフォルト拒否ポリシーで、安全な通信基盤を構築する
  • ラベルを使った通信制御で、細やかなセキュリティ設定が可能になる

これらの機能を理解し、適切に活用することで、サイバー攻撃のリスクを大幅に減らすことができます。

最初は少し難しく感じるかもしれませんが、まずは簡単な例から試してみて、少しずつ理解を深めていくのがおすすめです。そして、もし分からないことがあれば、いつでも周りのエンジニアに質問したり、ドキュメントを読んだりしながら、一歩ずつ対策を学んでいきましょう!

皆さんのKubernetes環境が、より安全で安心なものになることを願っています!

コメント

タイトルとURLをコピーしました