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

KubernetesにおけるNetworkPolicyを用いたPod間通信のマイクロセグメンテーション:攻撃者の横展開を断ち切る最終防衛線

サイバー攻撃は、もはや単一の脆弱性を突くだけでなく、巧妙なサプライチェーン攻撃や、クラウドネイティブ環境の複雑性を悪用した多段階攻撃へと進化しています。特にKubernetesのようなコンテナオーケストレーションプラットフォームは、その柔軟性とスケーラビリティの裏側で、攻撃者にとって魅力的な「攻撃対象領域(Attack Surface)」を内包しています。本稿では、Kubernetesクラスター内における攻撃者の「横展開(Lateral Movement)」を阻止するための、最も効果的かつ根本的な防御策の一つであるNetworkPolicyを用いたマイクロセグメンテーションについて、その核心に迫ります。

攻撃者の視点:Kubernetesクラスター内の「開かれた窓」

攻撃者がKubernetesクラスターに侵入したと仮定しましょう。彼らの次の目的は、単一のPodを侵害しただけでは満足しません。真の目的は、クラスター内の他のサービス、機密データ、あるいはより権限の高いシステムへと「横展開」し、最終的な目標を達成することです。

攻撃者の視点から見れば、Kubernetesクラスターは、デフォルトでは「すべてがすべてに通信可能」な、広大なオープンワールドのようなものです。標準的なKubernetesのネットワークモデルでは、PodはクラスターIPアドレスを持ち、他のPodと通信できます。これは開発者にとっては非常に便利ですが、セキュリティの観点からは、攻撃者にとって「開かれた窓」が数多く存在することを意味します。

例えば、あるWebアプリケーションのPodが侵害されたとします。もしネットワークポリシーが適切に設定されていなければ、攻撃者はそのPodから、データベースPod、認証サービスPod、あるいは管理用API Podへと、何のリスクもなく容易に通信を試みることができます。これは、まるで一つの部屋のドアを開けられただけで、家中のすべての部屋へのアクセスが許されているようなものです。

マイクロセグメンテーションの必要性:攻撃の連鎖を断ち切る

ここで登場するのが「マイクロセグメンテーション」の概念です。これは、ネットワークをより小さなセグメントに分割し、各セグメント間の通信を厳格に制御することで、万が一あるセグメントが侵害されても、その影響を最小限に抑えるためのセキュリティ戦略です。Kubernetes環境において、このマイクロセグメンテーションを実現する最も強力なツールが「NetworkPolicy」です。

NetworkPolicyは、Pod間のネットワーク通信を定義するためのKubernetesネイティブなリソースです。これは、IPアドレスベースのファイアウォールのように機能し、どのPodがどのPodと(あるいはどのIPアドレス範囲と)通信できるかを、ラベルセレクターを用いて柔軟に定義できます。

デフォルト拒否(Default Deny)ポリシーの重要性

マイクロセグメンテーションの基本原則は、「デフォルト拒否(Default Deny)」です。これは、明示的に許可されていない通信はすべて拒否するという考え方です。KubernetesのNetworkPolicyも、この原則に基づいて設計されています。

クラスター全体、あるいは特定のNamespaceに対して、どのNetworkPolicyも適用されていない場合、Pod間の通信は制限されません。しかし、一つでもNetworkPolicyが適用されると、そのNamespace内のPodは、そのNetworkPolicyによって明示的に許可された通信のみが可能になります。

つまり、「何も許可しない」ポリシーをデフォルトで適用し、必要な通信だけを明示的に許可していくというアプローチが、攻撃者の横展開を阻止するための最も堅牢な基盤となります。

NetworkPolicyの仕組み:ラベルとセレクターの魔法

NetworkPolicyは、Podを識別するために「ラベル」と「セレクター」を巧みに利用します。

  • Podのラベル: 各Podには、その役割や所属を示すためのラベルを付与できます。例えば、app: web、tier: frontend、env: production のようなラベルです。
  • NetworkPolicyのセレクター: NetworkPolicyリソースは、podSelector を用いて、どのPodにそのポリシーを適用するかを指定します。また、policyTypes (Ingress/Egress)、ingress、egress の各セクションで、通信元/通信先を podSelector や namespaceSelector、あるいはIPブロックで指定します。

実践的なNetworkPolicyの例:Webアプリケーションとデータベースの分離

ここでは、典型的なWebアプリケーションとデータベースの構成を例に、NetworkPolicyを用いたマイクロセグメンテーションを解説します。

シナリオ:

  • frontend というラベルを持つPod群 (Webサーバー) は、backend というラベルを持つPod群 (APIサーバー) とのみ通信を許可する。
  • backend というラベルを持つPod群は、database というラベルを持つPod群 (データベース) とのみ通信を許可する。
  • 外部からのHTTP/HTTPS通信は frontend Pod群にのみ許可する。

まず、各Podに適切なラベルを付与します。

frontend-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend-app
spec:
selector:
matchLabels:
app: frontend
template:
metadata:
labels:
app: frontend # ここでラベルを付与
tier: web # 役割を明確にするための追加ラベル
spec:
containers:

  • name: web

image: nginx:latest
ports:

  • containerPort: 80

backend-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend-api
spec:
selector:
matchLabels:
app: backend
template:
metadata:
labels:
app: backend # ここでラベルを付与
tier: api
spec:
containers:

  • name: api

image: your-backend-image:latest
ports:

  • containerPort: 8080

database-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: database
spec:
selector:
matchLabels:
app: database
template:
metadata:
labels:
app: database # ここでラベルを付与
tier: db
spec:
containers:

  • name: db

image: postgres:latest
ports:

  • containerPort: 5432

次に、これらのPod間の通信を制御するNetworkPolicyを定義します。

1. デフォルト拒否ポリシー (Namespace全体に適用)

まず、Namespace全体に対して、デフォルトで全てのIngress/Egress通信を拒否するポリシーを適用します。これにより、明示的に許可されていない通信はすべてブロックされます。

default-deny-all.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: default # 対象のNamespaceを指定
spec:
podSelector: {} # 空のセレクターはNamespace内のすべてのPodに適用
policyTypes:

  • Ingress
  • Egress

# Ingress/Egressのルールが空なので、すべての通信が拒否される

このポリシーを適用したNamespaceでは、追加の許可ポリシーがない限り、Pod間の通信は一切行えなくなります。

2. Frontend PodへのIngressポリシー (外部からのアクセス許可)

外部(クラスター外)からのHTTP/HTTPS通信を frontend Podにのみ許可します。ここでは、LoadBalancer タイプなどのIngress Controllerや、CNIプラグインが提供するNodePortなどを想定した ipBlock を使用します。CNIによっては、より高度な制御が可能です。

frontend-allow-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: frontend-allow-ingress
namespace: default
spec:
podSelector:
matchLabels:
app: frontend # frontend Podに適用
policyTypes:

  • Ingress

ingress:

  • from:

# ここでは例として、Ingress ControllerのIP範囲を想定
# 実際の環境ではIngress Controllerの設定やCNIによって異なります。
# 例: Ingress ControllerのIPアドレス範囲 (CIDR)

  • ipBlock:

cidr: 192.168.1.0/24 # 実際のIngress ControllerのIP範囲に置き換えてください
ports:

  • protocol: TCP

port: 80 # HTTP

  • protocol: TCP

port: 443 # HTTPS

3. Frontend PodからBackend PodへのEgressポリシー

frontend Podが backend Podに対してのみ、特定のポートで通信できるようにEgressポリシーを設定します。

frontend-egress-to-backend.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: frontend-egress-to-backend
namespace: default
spec:
podSelector:
matchLabels:
app: frontend # frontend Podに適用
policyTypes:

  • Egress

egress:

  • to:
  • podSelector:

matchLabels:
app: backend # backend Podのみに通信を許可
ports:

  • protocol: TCP

port: 8080 # backend Podがリッスンしているポート

4. Backend PodへのIngressポリシー (Frontendからのアクセス許可)

backend Podは、frontend Podからの通信のみを受け入れます。

backend-allow-ingress-from-frontend.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: backend-allow-ingress-from-frontend
namespace: default
spec:
podSelector:
matchLabels:
app: backend # backend Podに適用
policyTypes:

  • Ingress

ingress:

  • from:
  • podSelector:

matchLabels:
app: frontend # frontend Podからのみ通信を許可
ports:

  • protocol: TCP

port: 8080 # backend Podがリッスンしているポート

5. Backend PodからDatabase PodへのEgressポリシー

backend Podは、database Podに対してのみ、特定のポートで通信できるようにEgressポリシーを設定します。

backend-egress-to-database.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: backend-egress-to-database
namespace: default
spec:
podSelector:
matchLabels:
app: backend # backend Podに適用
policyTypes:

  • Egress

egress:

  • to:
  • podSelector:

matchLabels:
app: database # database Podのみに通信を許可
ports:

  • protocol: TCP

port: 5432 # database Podがリッスンしているポート

6. Database PodへのIngressポリシー (Backendからのアクセス許可)

database Podは、backend Podからの通信のみを受け入れます。

database-allow-ingress-from-backend.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: database-allow-ingress-from-backend
namespace: default
spec:
podSelector:
matchLabels:
app: database # database Podに適用
policyTypes:

  • Ingress

ingress:

  • from:
  • podSelector:

matchLabels:
app: backend # backend Podからのみ通信を許可
ports:

  • protocol: TCP

port: 5432 # database Podがリッスンしているポート

これらのNetworkPolicyを適用することで、frontend -> backend -> database という通信フローのみが許可され、例えば frontend から直接 database への通信や、backend から frontend への通信はデフォルトでブロックされるようになります。これにより、仮に frontend Podが侵害されても、攻撃者は backend Podへしかアクセスできず、さらに backend Podが侵害されたとしても、攻撃者は database Podへしかアクセスできなくなります。攻撃者の横展開の可能性は著しく狭められます。

低レイヤの視点:CNIプラグインとiptables/eBPF

NetworkPolicyの定義は抽象的ですが、その背後ではKubernetesのCNI (Container Network Interface) プラグインが、実際のネットワークパケットを制御しています。多くのCNIプラグイン(Calico, Cilium, Weave Netなど)は、Linuxカーネルの iptables や、より進化した eBPF (extended Berkeley Packet Filter) を利用して、NetworkPolicyのルールを実装します。

  • iptables: 古くから使われているLinuxのパケットフィルタリング機構です。NetworkPolicyのルールは、iptablesのルールセットとしてクラスターノード上に生成されます。大量のルールが生成されると、パフォーマンスに影響が出る可能性があります。
  • eBPF: Linuxカーネルの実行パスにカスタムコードを挿入できる強力な技術です。eBPFベースのCNIプラグイン(Ciliumなど)は、より効率的かつ柔軟にネットワークトラフィックを制御できます。NetworkPolicyの評価をカーネル空間で行うため、ユーザー空間へのコンテキストスイッチが減り、パフォーマンスが向上します。また、eBPFはパケットのディープインスペクションや、より高度なL7レベルのポリシー適用も可能にします。

攻撃者は、これらの低レイヤの挙動を理解することで、NetworkPolicyの回避策を探る可能性があります。例えば、CNIプラグインのバグを突いたり、iptables/eBPFのルーティングやフィルタリングの穴を見つけたりする試みです。そのため、使用しているCNIプラグインのセキュリティアップデートを常に適用し、その動作原理を理解しておくことは、高度なセキュリティ対策において不可欠です。

脆弱性(CVE)との関連性:メモリダンプとプロトコル解析

NetworkPolicyは、Pod間の通信を「許可/拒否」するレイヤーセキュリティを提供しますが、アプリケーション自体の脆弱性(例: CVE)や、通信プロトコルの仕様上の欠陥による攻撃を防ぐものではありません。

  • メモリ挙動の悪用: 攻撃者は、脆弱なアプリケーションのメモリ領域に不正なデータを送り込み、バッファオーバーフローやUse-After-Freeなどの脆弱性を悪用して、任意のコードを実行しようとします。NetworkPolicyで通信を制限していても、許可された通信経路から脆弱なサービスに到達されれば、攻撃は実行される可能性があります。
  • 通信プロトコルの欠陥: 例えば、HTTP/2のヘッダーフラッシュ攻撃や、TLSの脆弱性(Heartbleedなど)は、プロトコルレベルでの欠陥を突くものです。NetworkPolicyはこれらのプロトコルの詳細な内容を理解しないため、プロトコルの脆弱性自体を防ぐことはできません。

これらの低レイヤの脆弱性に対する防御層としては、以下のような対策が重要になります。

  • WAF (Web Application Firewall) / API Gateway: L7レベルでHTTPリクエストを解析し、不正なパターンや既知の脆弱性を突く攻撃をブロックします。Kubernetes環境では、Ingress Controllerと統合されたWAFや、API Gatewayソリューションが有効です。
  • TLS暗号化と証明書管理: 通信経路の暗号化は、中間者攻撃を防ぐだけでなく、パケット内容の盗聴を防ぎます。耐量子暗号への移行も、将来的な量子コンピュータによる暗号解読リスクに備える上で、長期的な視点で検討すべき事項です。
  • 静的・動的コード解析 (SAST/DAST): 開発段階やデプロイ前にコードの脆弱性を検出し、メモリリークやバッファオーバーフローなどの根本原因を排除します。
  • サービスメッシュ (Istio, Linkerd): Istioなどのサービスメッシュは、NetworkPolicyの機能に加え、mTLS (mutual TLS) によるPod間通信の相互認証と暗号化、高度なトラフィック管理、詳細なオブザーバビリティを提供します。これにより、通信の信頼性を高め、攻撃者の横展開をさらに困難にします。

生成AIに対する防御層(ガードレイル)のアーキテクチャ設計

近年、生成AIの活用が急速に進んでいますが、それに伴い「プロンプトインジェクション」という新たな攻撃ベクトルが出現しています。これは、AIモデルに意図しない指示を注入し、本来実行されるべきでない操作(情報漏洩、不正なコード生成など)を実行させる攻撃です。

Kubernetes環境でAIサービスを運用する場合、NetworkPolicyはプロンプトインジェクションを防ぐ直接的な手段ではありません。しかし、AIサービスへのアクセスを厳格に制御することで、攻撃の起点となる可能性を減らすことはできます。

  • アクセス制御の最小化: AIモデルへのアクセスは、必要最低限のPodやユーザーのみに許可します。例えば、AIモデルへのリクエストは、特定のAPIゲートウェイや、認証されたバックエンドサービスからのみ受け付けるようにNetworkPolicyを設定します。
  • L7レベルでの入力検証: プロンプトインジェクション対策の核心は、AIモデルへの入力(プロンプト)を厳格に検証することです。これは、NetworkPolicyではなく、アプリケーションレベル、あるいはAIゲートウェイレベルでの実装が必要です。
  • 入力サニタイズ: 悪意のある可能性のある文字列(例: Ignore the above instructions.のような指示)を検出し、除去または無害化します。
  • 指示とデータの分離: AIモデルに与える指示と、処理対象のデータを明確に分離し、指示部分がデータとして解釈されないように設計します。
  • 外部ツールの利用: LLMGuardのようなライブラリや、カスタムのプロンプトガードレイルを構築し、AIモデルの入出力を監視・フィルタリングします。

NetworkPolicyは、あくまでネットワークレイヤーでの「壁」です。AIのプロンプトインジェクションのようなアプリケーションロジックの脆弱性に対しては、多層防御の考え方に基づき、アプリケーションレベルでのガードレイル設計が不可欠となります。

まとめ:Kubernetesネットワークセキュリティの未来

KubernetesにおけるNetworkPolicyを用いたマイクロセグメンテーションは、攻撃者の横展開という、クラウドネイティブ環境における最も深刻な脅威の一つに対抗するための、強力かつ基礎的な防御策です。デフォルト拒否の原則に基づき、ラベルセレクターを巧みに利用することで、Pod間の不要な通信を徹底的に排除し、攻撃対象領域を最小化できます。

しかし、これはセキュリティ対策の「すべて」ではありません。低レイヤの脆弱性、通信プロトコルの欠陥、そして生成AIのような新しい脅威に対しては、WAF、TLS、SAST/DAST、サービスメッシュ、そしてアプリケーションレベルでのガードレイル設計といった、より深い層での対策が複合的に必要となります。

サイバー攻撃者は常に進化し、新たな攻撃手法を生み出しています。我々セキュリティエンジニアもまた、教科書的な知識に留まらず、攻撃者の視点を持ち、低レイヤの挙動から最新のAI技術まで、あらゆる側面から防御策を講じ続けなければなりません。NetworkPolicyは、そのための堅牢な基盤を提供する強力なツールであり、その理解と実践は、現代のKubernetesセキュリティアーキテクトにとって必須のスキルと言えるでしょう。

コメント

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