こんにちは!インフラやセキュリティの世界へようこそ。
Kubernetesやコンテナを使った開発、とてもワクワクしますよね。「アプリをサクッと動かせる!」という便利さに感動した方も多いのではないでしょうか。
でも、ちょっと待ってください。便利さの裏側で、「セキュリティの甘さ」が思わぬ大事故につながることがあるんです。今回は、新人のエンジニアや開発者の皆さんに向けて、コンテナ同士の通信を守る「ネットワークポリシー(Network Policies)」について、身近な防犯にたとえて優しく紐解いていきたいと思います。
一歩ずつ、安心して学んでいきましょう!
—
1. なぜコンテナの「ネットワーク分離」が必要なの?
皆さんは、自分の家やアパートの鍵をしっかり閉めて出かけていますよね。では、もし「玄関の鍵は開けっ放し、家の中の部屋のドアも全開、誰がどこに入っても自由」というシェアハウスがあったらどうでしょう?
リビングに泥棒が1人入り込んだ瞬間、すべての個室のプライベートな空間にフリーパスで侵入されてしまいますよね。
実は、初期状態のKubernetesクラスターは、まさにこの「部屋のドアが全開のシェアハウス」状態になっています。
ラテラルムーブメント(水平展開)の恐怖
セキュリティの世界では、攻撃者がシステムの一部分(たとえば、外からアクセスできるWebサーバーなど)を最初に突破した後、そこを踏み台にして内部のデータベースや機密情報を持つ別のサーバーへ次々と侵入していく手口を「ラテラルムーブメント(水平展開)」と呼びます。
もし、コンテナ同士のネットワークが無制限(デフォルトで全許可)だと、ひとつの脆弱なアプリが破られただけで、クラスター内のすべてのシステムが芋づる式に危険に晒されてしまいます。これを防ぐのが、今回学ぶ「ネットワークポリシー」という名の「家の中の頑丈な内鍵」です。
—
2. ネットワークポリシーの基本は「ホワイトリスト形式」
防犯の基本は、「怪しい人を追い出す」のではなく、「信頼できる人だけを通す(ホワイトリスト方式)」ことです。
ネットワークポリシーも全く同じ考え方をします。
初期状態では「すべての通信を禁止(全遮断)」しておき、「このコンテナからこのコンテナへの通信だけは特別に許可する」というルールを1つずつ丁寧に書き込んでいくことで、安全な城壁を築き上げるのです。
それでは、実際に動かせる設定ファイル(マニフェスト)のサンプルを見てみましょう。小難しい用語が出てきても安心してくださいね。一つずつコードの中身を日本語のコメントで解説していきます。
—
3. 実践!ネットワークポリシーを書いてみよう
ここでは、「バックエンド(Backend)のデータベース用コンテナ」に対して、「特定のフロントエンド(Frontend)からの通信だけを許可し、それ以外の不要な通信はすべて遮断する」という実用的なポリシーを作ってみましょう。
以下のYAMLファイルがその設定になります。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-backend # このポリシーの名前(分かりやすい名前をつけましょう)
namespace: production # 適用するネームスペース(部屋の名前のようなものです)
spec:
# どのコンテナ(ポッド)に対してこのルールを適用するかを指定します
podSelector:
matchLabels:
app: backend-database # 「app=backend-database」というラベルがついたコンテナが対象です
# このコンテナへの「入ってくる通信(Ingress)」に関するルールを定義します
policyTypes:
- Ingress
# 許可する通信のルール(ホワイトリスト)のリスト
ingress:
- from:
# 同じネームスペース内にある、特定のコンテナからの通信だけを許可します
- podSelector:
matchLabels:
app: web-frontend # 「app=web-frontend」というラベルがついたコンテナからのアクセスのみOK!
# 通信を許可するポート番号の指定
ports:
- protocol: TCP
port: 5432 # データベース(例: PostgreSQL)が使用するポート番号だけを開放
この設定のポイント
1. podSelector: 誰を守るのか?(今回は backend-database というラベルのついたコンテナを保護対象に指定しています)
2. policyTypes: [Ingress]: 外から入ってくる通信をコントロールするという宣言です。
3. from と podSelector: 「誰からの通信なら通していいよ」という許可証です。ここでは web-frontend 以外のコンテナからの通信は容赦なくシャットアウトされます。
4. ports: 通信を許可する扉(ポート)をピンポイントで指定しています(例では 5432 番ポートのみ)。不要な穴は一切あけません。
このように、誰が・どこから・どのポートにアクセスしていいかを明確に定義することで、万が一フロントエンド以外の場所から不正なアクセスがあっても、鉄壁のガードで防ぐことができるのです。
—
4. 現場でありがちな落とし穴とアドバイス
最後に、インフラの現場や開発現場で新人さんがよくハマりがちなポイントをいくつかアドバイスしておきますね。
- 「とりあえず動かないからポリシーを消そう」は禁物
ネットワークポリシーを導入した後にアプリが動かなくなると、「面倒だから全許可に戻そう」となりがちです。しかし、それではセキュリティの目的が失われてしまいます。動かないときは、kubectl logs やログ監視ツールを使って、「どの通信がブロックされているのか」を焦らず確認しましょう。
- CSI/CNIプラグインの確認を忘れずに
Kubernetesでネットワークポリシーを有効にするには、クラスターのネットワーク基盤(CNIプラグイン)がネットワークポリシーの制御をサポートしている必要があります(Calico、Cilium、Kube-routerなど)。「設定したのに効かないな?」と思ったら、まずはインフラの先輩に「このクラスター、ネットワークポリシーに対応してる?」と聞いてみるのが確実です。
—
まとめ
いかがでしたでしょうか?
コンテナのネットワーク分離(Network Policies)は、難しそうな名前をしていますが、やっていることは「家の中の部屋ごとにしっかり鍵をかけ、関係者以外立ち入り禁止にする」という非常にシンプルで理にかなった防犯対策です。
最初から完璧を目指す必要はありません。「まずは一番守りたいデータベースへの通信だけを制限してみよう」といった小さな一歩から、安全なインフラ作りを一緒に楽しんでいきましょう!
それでは、また次回のセキュリティ解説でお会いしましょう。安全で快適な開発ライフを!
コメント