私のサービスだけ暗号化? 🔒 Istio mTLS、むやみにSTRICTモードを使うと大変なことになる理由

サービスメッシュ、特にIstioを導入する際に最も期待することの一つは、まさに強力な「相互TLS(mTLS)」暗号化でしょう。すべてのサービス間の通信を暗号化し、途中でデータが奪取されても内容を知ることができないようにする、考えるだけでも心強いですよね。💪

そのため、多くの方がIstioを適用するとすぐにセキュリティ設定をSTRICTモードに変更しがちです。「どうせやるなら、最も強力なセキュリティでいこう!」という考えです。しかし、このような性急な決定が、かえってサービス全体を麻痺させる原因になる可能性があることをご存知でしたか?

今日は、なぜSTRICTモードをむやみに適用してはいけないのか、そしてより安全で柔軟なマイグレーション戦略のための重要な鍵であるPERMISSIVEモードについて深く掘り下げていきます。


🤔 「私たちのサービスはすべてメッシュ内にあるので大丈夫ではないですか?」

もちろん、開発環境やすべてのサービスが最初からIstioサービスメッシュ内で一緒に開始されたのであれば、STRICTモードは素晴らしい選択です。STRICTモードは、その名の通り、Istioプロキシ(サイドカー)を介したmTLSで暗号化されたトラフィックのみを許可する「厳格な」ポリシーです。

このポリシーをYAMLで表現すると次のようになります。

# apiVersion: security.istio.io/v1beta1
# kind: PeerAuthentication
# metadata:
#   name: "default-strict-mtls"
#   namespace: "your-namespace"
# spec:
#   mtls:
#     mode: STRICT

STRICTモードは、メッシュ内部のサービス同士が通信する際には全く問題ありません。どちらもサイドカーを持っており、お互いにmTLSで通信する方法を知っているからです。

しかし、現実世界のシステムはこれほど理想的ではありません。😥

💥 本当の問題は「メッシュ外部」から始まります

実際の運用環境は、次のような複雑な状況に置かれています。

  1. 漸進的マイグレーション:すべてのサービスを一度にサービスメッシュに移行することはほぼ不可能です。一部はメッシュ内に、一部はまだ外部に残っている過渡期が長く続きます。
  2. レガシーシステム:サービスメッシュへのマイグレーション計画がない古いレガシーシステムが存在します。
  3. 外部ソリューション:モニタリングシステム(例:Prometheus)や特定のヘルスチェックシステムのように、メッシュ外部から内部サービスのステータスを直接確認する必要がある場合があります。

このような状況でSTRICTモードを適用するとどうなるでしょうか?

状況例:メッシュ外部にあるlegacy-monitorが、メッシュ内部にあるuser-serviceのヘルスチェックエンドポイント(/healthz)を呼び出すと仮定してみましょう。

  • user-service: Istioメッシュ内にあり、STRICTモードが適用されています。(mTLS通信のみ許可)
  • legacy-monitor: メッシュ外部にあるためIstioサイドカーがありません。(平文、Plaintext HTTP通信を試行)

結果:legacy-monitorが送信した平文HTTPリクエストは、user-serviceのサイドカーでブロックされます。サイドカーは「あれ?これはmTLS暗号化されたリクエストじゃないぞ?通せない!」と言って接続を切断してしまいます。💥

# legacy-monitor Podで実行
$ curl http://user-service.your-namespace.svc.cluster.local/healthz

# 予想される結果
curl: (56) Recv failure: Connection reset by peer

結局、モニタリングシステムはサービスが停止したと判断し、障害アラートを送信することになります。サービスは正常に稼働しているにもかかわらずです!


🌉 過渡期の賢い橋、PERMISSIVEモード

このような大混乱を防ぐために存在するものが、まさにPERMISSIVE(許容)モードです。

PERMISSIVEモードは、mTLSで暗号化されたトラフィックと平文トラフィックの両方を受け入れる柔軟なポリシーです。まるで空港のセキュリティ検査場で、内国人専用レーンと外国人専用レーンを両方運営しているようなものです。✈️

YAML設定は非常に簡単です。`mode`を変更するだけです。

apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: "default-permissive-mtls"
  namespace: "your-namespace"
spec:
  mtls:
    mode: PERMISSIVE # <--- まさにこの部分!

PERMISSIVEモードでは、ワークロードは次のように動作します。

  • メッシュ内部サービス間の通信:相手もサイドカーを持っていれば、自動的にmTLSで暗号化して通信します。(セキュリティ維持 ✅)
  • メッシュ外部から入ってくる通信:相手がサイドカーを持っておらず平文でリクエストを送ってきても、ひとまず受け入れます。(互換性維持 ✅)

全体マイグレーションの旅路 🗺️

PERMISSIVEモードを活用することで、システム全体を中断することなく安全にサービスメッシュへ移行できます。

ステップ1:導入と移行(PERMISSIVE)

  • 新しいサービスをIstioメッシュ内にデプロイし、`PeerAuthentication`をPERMISSIVEモードに設定します。
  • 結果:
  • メッシュ内のサービス同士はmTLSで安全に通信します。
  • メッシュ外のレガシーサービスも、これまで通り平文で問題なく通信します。
  • システムは中断なく安定的に運用されます。😌

ステップ2:安定化と検証

  • すべてのサービスがメッシュ内に入ったか、外部依存性がすべてなくなったかを注意深く確認します。
  • Kialiのようなダッシュボードを通じて、すべてのトラフィックが鍵(🔒)アイコンで表示されているか(mTLS)を確認し、確信を持ちます。

ステップ3:最終強化(STRICT)

  • すべてのサービスがメッシュ内に正常に定着し、もはや外部からの平文トラフィックを許可する必要がないと判断されたら、その時点で`PeerAuthentication`をSTRICTモードに切り替えます。
  • 結果:これで私たちのサービスメッシュは、外部からの暗号化されていないアクセスを根源的に遮断する堅固な要塞となります。🏰

✨ 結論:状況に合わせた戦略が最高のセキュリティです

IstioのSTRICTモードは、確かに強力で理想的なセキュリティ目標です。しかし、すべての旅路には過程があるように、サービスメッシュへの移行過程ではPERMISSIVEモードが不可欠な「飛び石」の役割を果たします。

むやみに最も強力な設定を固執するのではなく、現在のシステム構成とマイグレーション段階を理解し、それに合った柔軟な戦略を選択することこそが、真の意味で安定したシステムを構築する道です。

皆さんのサービスメッシュは今、どの段階にありますか?もしもの障害を防ぐために、今すぐ`PeerAuthentication`設定を点検してみてください!



Comments

コメントを残す

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