見出し画像

KubernetesのNetworkPolicy default拒否を安全に導入する手順

Kubernetesクラスター内の意図しない通信をすべて遮断する「default拒否」は、セキュリティの最終防衛ラインです。しかし、一歩間違えればアプリケーション全体が通信不能に陥る諸刃の剣でもあります。

この記事を読めば、本番環境のサービスを止めることなく、安全にdefault拒否ポリシーを導入するための段階的な手順と、最初に設定すべき必須の許可ルールが分かります。

なぜdefault拒否?ゼロトラストセキュリティの基本

デフォルトのKubernetesは、同じクラスター内であればどのPodからどのPodへも自由に通信できる、非常にオープンなネットワーク設定になっています。これは利便性が高い反面、一度内部に侵入されると、攻撃者が他のサービスへ容易に攻撃を広げられる(ラテラルムーブメント)リスクを抱えています。

default拒否は、「許可したもの以外は、すべて拒否する」というゼロトラストの原則に基づき、Podが通信できる相手を必要最小限に絞るための設定です。これにより、たとえ一つのPodが乗っ取られても、被害をそのPodが所属するサービス内に封じ込めることができます。

公式情報源:
・ 
Network Policies - Kubernetes Documentation

NetworkPolicyが特に重要なシーン:

  • マルチテナント環境: 複数のプロジェクトやチームが同じクラスターを共有している場合

  • セキュリティ要件: PCI-DSSなど、厳格なセキュリティ基準への準拠が求められる場合

  • 本番環境: 重要な顧客データや機密情報を扱うアプリケーションを保護する場合

安全第一!default拒否の段階的導入 3ステップ

いきなり本番環境に適用するのは絶対にやめましょう。必ずテスト用のNamespaceで予行演習を行います。

  • 所要時間: 約30分

  • 前提条件:

    • Kubernetesクラスターが稼働していること

    • CalicoやCiliumなど、NetworkPolicyに対応したCNIプラグインが導入されていること

Step 1: テスト用Namespaceを作成し、default拒否を適用する

まず、実験用の隔離された空間を作ります。

Plaintext

kubectl create namespace network-policy-test

次に、このNamespace内のすべてのIngress(内向き)とEgress(外向き)通信を拒否するポリシーを適用します。

YAML

# deny-all.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
  namespace: network-policy-test
spec:
  podSelector: {} # 空のセレクタはNamespace内の全てのPodにマッチ
  policyTypes:
  - Ingress
  - Egress

kubectl apply -f deny-all.yaml を実行した瞬間から、このNamespace内のPodは内外との一切の通信ができなくなります。

Step 2: 【必須】DNS通信を許可する

Podが他のサービスの名前解決をするためには、DNSサーバー(通常はkube-dns)との通信が不可欠です。これを許可しないと、ほとんどのアプリケーションは機能しません。

YAML

# allow-dns.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-dns
  namespace: network-policy-test
spec:
  podSelector: {}
  policyTypes:
  - Egress
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: kube-system
      podSelector:
        matchLabels:
          k8s-app: kube-dns
    ports:
    - protocol: UDP
      port: 53
    - protocol: TCP
      port: 53

kubectl apply -f allow-dns.yaml でDNSへの出口だけを許可します。

Step 3: アプリケーションに必要な通信を許可する

最後に、アプリケーション固有の通信ルールを追加します。例えば、「app=frontend」ラベルを持つPodから「app=backend」ラベルを持つPodへのTCP 8080番ポートでの通信を許可する場合は、以下のようになります。

YAML

# allow-frontend-to-backend.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-frontend-to-backend
  namespace: network-policy-test
spec:
  podSelector:
    matchLabels:
      app: backend # このポリシーの対象はbackend
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: frontend # frontendからの通信を許可
    ports:
    - protocol: TCP
      port: 8080

このように、必要な通信を一つずつ許可していき、テスト用Namespace内でアプリケーションが正常に動作することを確認できれば、同じ手順で本番環境のNamespaceへも展開していきます。

応用編:Ingress Controllerからの通信を許可する

クラスター外部からのトラフィックを受け付けるIngress Controllerからの通信は、別途許可する必要があります。Ingress Controllerが所属するNamespace(例: ingress-nginx)を指定して、通信を許可するルールを追加しましょう。

YAML

# allow-from-ingress-controller.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-from-ingress-controller
  namespace: your-app-namespace
spec:
  podSelector:
    matchLabels:
      app: your-app # Ingressの通信先Pod
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          name: ingress-nginx # Ingress ControllerのNamespace

まとめ

  • 要点: default拒否ポリシーの導入は、テスト用Namespaceで影響を限定し、DNS通信アプリ間通信の順に必要な許可ルールだけを追加していくのが安全な手順です。

  • 注意点: DNS (UDP/53) と Ingress Controllerからの通信は、見落としがちな最重要許可ルールです。最初にこれらを許可する癖をつけましょう。

  • 今後の予測: 将来的には、サービスメッシュの監視データなどを基に、AIが必要最小限のNetworkPolicyを自動で生成し、適用を提案してくれるようになるでしょう。

おまけ:Kubernetes基盤の安定性がセキュリティの土台

NetworkPolicyで守るべきアプリケーションが稼働するKubernetesクラスターそのものが不安定では元も子もありません。安定したクラスターは、信頼性の高いサーバーノードによって支えられています。

中古PC・OA機器の専門店 ナベキンファトリー では、Kubernetesのマスターノードやワーカーノードに最適な、ECCメモリを搭載した中古サーバーや、高速なネットワークを構築するためのスイッチなどを取り揃えています。堅牢なKubernetes基盤の構築に、ぜひご検討ください。

#OA機器
#Kubernetes
#etworkPolicy_default
#ナベキンファクトリー
#ゼロトラストセキュリティ
#Zero_Trust_Security

いいなと思ったら応援しよう!