[Istio] 自宅の戸締まりを厳重に 🚪: 外部トラフィックの全面遮断と許可 (ALLOW_ANY vs REGISTRY_ONLY)

こんにちは!今日は、Istioを導入する際にセキュリティ面で最初に検討すべき「Egress(アウトバウンド)トラフィック制御」について深く掘り下げていきたいと思います。

Kubernetes Pod内に密かに潜り込んだマルウェアが、外部のハッカーサーバーにデータを送信したらどうなるでしょうか?😱 想像するだけでも恐ろしいですよね。Istioは、非常に簡単な設定変更だけで、このような「データ漏洩」の試みを根本から阻止することができます。

デフォルト設定(ALLOW_ANY)とセキュリティ設定(REGISTRY_ONLY)の違い、そして実践的な設定方法まで一緒に見ていきましょう!🚀


1. Istioのデフォルト動作:「ドアは開けっ放し?」 🔓

IstioがインストールされたPodから外部インターネット(例:google.com、api.slack.com)へリクエストを送信するとどうなるでしょうか?

特別な設定をしていない場合、デフォルトで通信は成功します。

  • 設定値: outboundTrafficPolicy.mode = ALLOW_ANY
  • 動作: サイドカープロキシ(Envoy)は、自身が知らない宛先(サービスレジストリにないアドレス)へのリクエストが来た場合、「ひとまず通過(Passthrough)」させます。
  • 利点: 開発時に便利です。外部APIを自由に呼び出せるからです。
  • 欠点: セキュリティに脆弱です。ハッキングされたPodが外部のC&Cサーバー(攻撃者サーバー)と通信するのを防ぐことができません。

2. セキュリティ強化:「登録された場所しか行けない!」 🛡️

セキュリティが重要なプロダクション環境では、ホワイトリスト(Whitelist)方式を使用する必要があります。つまり、「私が許可した場所以外はどこにも行けない!」と宣言するのです。

  • 設定値: outboundTrafficPolicy.mode = REGISTRY_ONLY
  • 動作: サイドカープロキシはリクエストの宛先を確認します。Istioの内部サービスレジストリ(Service Registry)に登録されている場所であれば送信を許可し、そうでなければ容赦なく遮断します。
  • 利点: データ漏洩防止および強力なEgressセキュリティ。
  • 欠点: 外部通信が必要になるたびにServiceEntryを一つ一つ登録しなければならない手間があります。

3. 実践:セキュリティポリシーを適用してみよう 👨‍💻

istioctlを直接使用して、クラスター全体のアウトバウンドポリシーを変更してみましょう。

Step 1: 現在の状態を確認 (ALLOW_ANY)

現在はデフォルト設定の状態です。テスト用Pod(tester)から外部サービスであるhttpbin.orgに接続してみます。

kubectl exec tester -- 
    curl -sS -o /dev/null -D - http://httpbin.org/status/200 | 
    grep "HTTP/"

# 結果: HTTP/1.1 200 OK (成功!)

何の制約もなく外部通信がうまくいきます。

Step 2: ポリシー変更 (REGISTRY_ONLYへ切り替え) 🔥

istioctl installコマンドを使用してグローバル設定を変更します。meshConfigを修正して、未知のトラフィックを遮断するように設定します。

istioctl install --set profile=demo 
    -y --manifests=/root/istio-${ISTIO_VERSION}/manifests 
    --set meshConfig.outboundTrafficPolicy.mode=REGISTRY_ONLY
  • –set meshConfig.outboundTrafficPolicy.mode=REGISTRY_ONLY: このオプションが肝です!

Step 3: 遮断を確認 🚫

設定が適用されるまで数秒待ってから、もう一度同じように接続を試みます。

Bash

kubectl exec tester -- 
    curl -sS -o /dev/null -D - http://httpbin.org/status/200 | 
    grep "HTTP/"

結果:

curl: (56) Recv failure: Connection reset by peer
command terminated with exit code 56

ご覧になりましたか?200 OKの代わりにConnection reset by peerエラーが表示されました。これはネットワークが切断されたのではなく、Istioサイドカープロキシが「君、登録されていない場所に行こうとしているね?ダメ!」と言って、接続を強制的に切断(TCP Reset)したものです。


4. では、外部通信はどうすればいいの? 🤔

「NaverもGoogleも行けないなら、私たちのサービスはどうすればいいの?」

ご心配なく!REGISTRY_ONLYモードでは、私たちがアクセスする必要がある外部の宛先を、ServiceEntryというリソースを通じてIstioに「ここは信頼できる場所だよ」と教えてあげればいいのです。

apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: external-httpbin
spec:
  hosts:
  - httpbin.org  # 許可する外部ドメインを登録
  ports:
  - number: 80
    name: http
    protocol: HTTP

このように登録すれば、httpbin.orgは「知っているサイト」となり、再び接続が可能になります。これこそが真のゼロトラストセキュリティの始まりです!


🏁 まとめ

利便性のためにALLOW_ANYを使うか、セキュリティのためにREGISTRY_ONLYを使って管理コストを負担するか?

正解は皆さんの環境によりますが、セキュリティ事故は予告なく発生するという点を覚えておいてください。少し面倒でも、REGISTRY_ONLYとServiceEntryの組み合わせを使用することが、安全なクラスターを構築する近道です。🛣️

今日の演習もお疲れ様でした!次回はServiceEntryの扱い方について、さらに詳しくお伝えします。さようなら!👋



Comments

コメントを残す

メールアドレスが公開されることはありません。 ※ が付いている欄は必須項目です