【入門編】 Kubernetes NetworkPolicyによるマイクロセグメンテーション – インフラ・ネットワーク & クラウドセキュリティ防御ガイド

こんにちは!インフラやクラウドの世界へようこそ。
システム開発をしていると、「Kubernetes(K8s)」という言葉を耳にする機会がぐっと増えたのではないでしょうか。たくさんのコンテナを上手に管理してくれる便利な仕組みですが、セキュリティを語る上では避けて通れない重要なテーマがあります。それが今回お話しする「Kubernetes NetworkPolicy(ネットワークポリシー)」です。

小難しいセキュリティ用語が出てくると、どうしても身構えてしまいますよね。「なんだか設定が難しそう…」と不安になるかもしれませんが、安心してください!今回は、身近な「家の防犯」に例えながら、一歩ずつ優しく紐解いていきましょう。

—

1. 家の鍵に例える「コンテナの世界」の危うさ

皆さんが住んでいるお家を想像してみてください。
頑丈な玄関のドアには鍵がついていて、見知らぬ他人が勝手に入ってくることはありませんよね。さらに、リビングと子供部屋、寝室のあいだにもドアがあり、家族であっても「今はプライベートな時間だから入らないでね」と区切ることもできます。

ところが、もし「家全体の玄関の鍵が常に開きっぱなしで、家の中に入りさえすれば、どの部屋のドアもノックなしで自由に出入りし放題」だったらどうでしょう?
……考えただけでもゾッとしますよね。泥棒が玄関から入ってきた瞬間、すべての部屋の貴重品がノーガードで狙われてしまいます。

実は、初期状態のKubernetesはこの「ドアノックし放題」の状態に近いのです。
Kubernetesクラスターの中には、ウェブサーバー、データベース、管理画面といった様々な「Pod(コンテナが動く最小単位の部屋)」が同居しています。デフォルトのままだと、どのPodからも、他のすべてのPodへ自由に通信が届いてしまいます。

もし、インターネットに面したウェブサーバーがサイバー攻撃者に乗っ取られてしまったらどうなるでしょうか?
攻撃者はそのウェブサーバーを踏み台にして、社内の機密データが入ったデータベースの部屋へ、まるで自分の家のようにすんなり歩いて侵入してしまいます。これが、セキュリティの世界で恐れられている「ラテラルムーブメント(横方向の移動・侵入拡大)」という攻撃シナリオです。

—

2. デフォルト拒否(Default Deny)という「最強の鉄格子」

このラテラルムーブメントを防ぐために私たちが最初にやるべきこと、それが「デフォルト拒否(Default Deny)」の適用です。

防犯の基本は、「許可された人以外、すべてお断り!」という原則から始まります。これと同じで、NetworkPolicyを使って「基本はすべての通信を遮断する。ただし、あらかじめ許可リストに入った通信だけを通す」という状態を作るのです。

言葉だけ聞くと「なんだか厳しすぎて、アプリが動かなくなりそう…」と心配になりますよね。でも大丈夫です。必要な通信だけをピンポイントで許可する「最小限のルール(最小特権の原則)」を丁寧に組み立てていけば、システムを安全に、かつ健やかに動かすことができます。

—

3. ラベルセレクタで「名札」を使った通信制限をしよう

Kubernetesでは、Podに「ラベル」という名札を貼ることができます。
例えば、ウェブサーバーのPodには app: web という名札を貼り、データベースのPodには app: db という名札を貼るイメージです。

NetworkPolicyでは、この名札を使って「どの部屋から、どの部屋への通信を許可するか」を細かく指定します。

それでは、実際のYAML設定ファイルを見てみましょう。「ウェブサーバーからデータベースへの通信だけは許可し、それ以外からのデータベースへのアクセスはすべてシャットアウトする」という設定のサンプルです。

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-web-to-db # このルールの分かりやすい名前です
  namespace: default # 対象となる名前空間を指定します
spec:
  # どのPodに対してこのルールを適用するか(今回はデータベースのPodを指定)
  podSelector:
    matchLabels:
      app: db

  # 適用するルールの種類(今回は「入ってくる通信(Ingress)」を制限します)
  policyTypes:
    - Ingress

  # 許可する通信のルールリスト
  ingress:
    - from:
        # 「app: web」という名札がついたPodからだけの通信を許可します
        - podSelector:
            matchLabels:
              app: web
      # データベースが待ち受けているポート番号(例: MySQLなら3306)を指定します
      ports:
        - protocol: TCP
          port: 3306

この設定ファイルをKubernetesに適用すると、何が起きるでしょうか?
たとえ他の怪しいPodや、関係のない別のアプリケーションからデータベースにアクセスしようとしても、Kubernetesのネットワーク層が「おっと、あなたには app: web の名札がないので通せません!」と、入り口でガッチリブロックしてくれます。これがマイクロセグメンテーション(細かい区画整理)の強力な効果です。

—

4. 実務で失敗しないための泥臭いアドバイス

ここまで読むと「なんだ簡単じゃん、さっそく本番環境にデプロイしよう!」と思われるかもしれませんが、現場のインフラエンジニアとして、ひとつだけ強くお伝えしたい泥臭い教訓があります。

それは、いきなり本番環境で「デフォルト拒否」を適用してはいけないということです。

何も考えずにいきなりすべてを遮断するポリシーを適用すると、これまで裏でこっそり連携していた監視ツールや、ログ収集の仕組み、思わぬマイクロサービス同士の通信までストップしてしまい、アプリケーションが盛大にエラーを吐いて沈黙します(現場がパニックになり、冷や汗をかく瞬間です)。

実務で安全に導入するためのステップは以下の通りです。

1. 開発・ステージング環境で試す: まずは本番に近い環境でデフォルト拒否を適用し、アプリが壊れないかテストします。
2. ログをよく観察する: どの通信が遮断されているのか、ネットワークプラグイン(CiliumやCalicoなど)のログや監査ログをじっくり観察します。
3. 必要な通信を少しずつ許可する: アプリの動作に必要な通信を洗い出し、先ほどのコード例のようにピンポイントで許可ルールを追加していきます。

焦る必要はありません。一歩ずつ、確実に対策を積み重ねていきましょう。

—

まとめ

今回は、Kubernetes NetworkPolicyを使ったマイクロセグメンテーションについて、家の防犯や身の回りの例えを交えながら解説しました。

  • デフォルト拒否で、まずはすべての不正な横移動をシャットアウトする。
  • ラベルセレクタを使って、本当に必要な最小限の通信だけを許可する。
  • 本番環境に適用する前には、必ず事前の検証とテストを行う。

セキュリティは、一度設定して終わりではなく、日々の運用の中でメンテナンスしていく大切な土台です。このブログ記事が、あなたのインフラストラクチャをより安全で堅牢なものにするための、確かな第一歩となれば嬉しいです。

それでは、また次回のセキュリティ解説でお会いしましょう!

コメント

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