【入門編】 KubernetesにおけるService Mesh(Istio)を用いたmTLSの強制 – インフラ・ネットワーク & クラウドセキュリティ防御ガイド

こんにちは!インフラやクラウドのセキュリティの世界へようこそ。
Kubernetes(クーベネティクス)を使ったシステム開発、日々の運用本当にお疲れ様です。

今回は、最近よく耳にする「ゼロトラスト」の要(かなめ)であり、Kubernetesのインフラを守るための強力な武器である 「Service Mesh(Istio)を用いたmTLSの強制」 について、一緒に紐解いていきましょう。

「セキュリティの専門用語が多くて、ちょっと難しそう…」と感じている方もご安心ください。身近な防犯の例えを交えながら、一つずつ優しく解説していきますね!

—

1. なぜKubernetesに「家の中の鍵」が必要なのか?

皆さんは、ご自宅の玄関の鍵はしっかり閉めてお出かけしますよね。では、「家の中に入った家族同士」はどうでしょうか? リビングから子供部屋に行くときに、わざわざ鍵を開けたりはしませんよね。

従来のKubernetesのネットワークも、これとまったく同じでした。
「一度クラスター(家の中)に入ってしまえば、どのサービス(部屋)同士の通信も安全(信頼できる)」という、いわば「境界防御モデル」が基本だったのです。

しかし、攻撃者が何らかの手段で一度この「家の中(クラスター内)」に侵入してしまったらどうなるでしょうか?
家の中のすべてのドアが全開状態なので、やりたい放題になってしまいますよね。「隣の部屋で何をやっているか丸見え」「勝手に機密データを盗まれる」といった最悪のシナリオが現実になってしまいます。

攻撃者は「境界」をいとも簡単に突破する

近年のサイバー攻撃は非常に巧妙です。アプリケーションの脆弱性を突いて侵入したり、内部の古いコンテナを足がかりにしたりして、あっという間に「家の中」に侵入してきます。

だからこそ、「家の中に入られたとしても、すべての部屋のドアに頑丈な鍵をかけ、誰と誰が通信しているかをお互いに証明し合う」というゼロトラスト(誰も信用しない)の考え方が、今のインフラにはどうしても必要になるのです。

—

2. mTLS(相互TLS認証)ってなに?超噛み砕き解説

ここで登場するのが、今回の主役である mTLS(Mutual TLS / 相互TLS認証) です。

通常のTLS(よくWebサイトのURLで見かける https:// あれです)は、私たちが「このWebサイトは本物かな?」と確認する片方向の身元確認でした。

これが mTLS になると、どうなるでしょうか?
イメージしやすいように、「スパイ映画の合言葉と身分証の提示」に例えてみましょう。

1. サービスAがサービスBに話しかけたいとき:
「私はサービスAです。証拠として、信頼できる機関が発行した身分証(証明書)を提示します!」
2. サービスBがそれを確認:
「よし、確かに本物のサービスAだ。ではこちらも私の身分証を提示します。」
3. お互いの身元が確認できたら、金庫のような頑丈なトンネル(暗号化通信)を作って会話スタート!

このように、「通信する両者がお互いの身分を証明し合い(Mutual)、なおかつ会話の内容を完全に暗号化する」のがmTLSの仕組みです。これなら、仮に悪い人がネットワークの途中で通信を盗み見ても、金庫の中身は解読できませんし、偽物のサービスが話しかけてきても即座に「お前は誰だ!」と追い返すことができます。

—

3. Istioの PeerAuthentication でmTLSを強制する

Kubernetes環境でこのmTLSを簡単に、かつ強力に実現してくれるのが Service Mesh(Istio) です。

Istioを導入すると、各アプリケーション(Pod)の隣に Envoy という名の「門番(サイドカープロキシ)」がこっそり配置されます。アプリ自身はセキュリティの面倒な実装を一切気にせず、ただ隣の門番にお願いするだけで、自動的にmTLSによる暗号化と身元確認を行ってくれる優れものです。

それでは、実際にすべての通信でmTLSを強制する設定ファイルを見てみましょう!

実践設定:PeerAuthenticationの適用

以下のYAMLファイルは、「この名前空間(またはクラスター全体)の中では、必ずmTLSを使った通信だけを許可するぞ!」という強力なルールを定義する設定になります。

apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: default
  namespace: production-apps # mTLSを強制したい名前空間を指定します
spec:
  mtls:
    # STRICTモードに設定することで、暗号化されていない平文の通信を一切拒否します
    mode: STRICT

この設定のポイント

  • mode: STRICT: この一行が最大のミソです。「厳格(Strict)」という意味ですね。これを発動させると、もし古いアプリや設定ミスで暗号化されていない(平文の)通信を送ってきた場合、門番(Envoy)が容赦なくアクセスを遮断します。
  • 最初は PERMISSIVE(暗号化されていなくても一旦受け入れるモード)で安全に移行し、移行が終わったらこの STRICT に切り替えるのが現場の現場猫…ではなく、プロの安全な進め方です。

—

4. さらに一歩進む:「誰からの通信か」を AuthorizationPolicy で制限する

mTLSで「暗号化され、お互いの身元が分かった状態」を作ったら、次は「どのサービスからどのサービスへのアクセスを許可するか」を制御しましょう。

玄関の鍵(mTLS)を閉めただけでなく、「リビングの住人は寝室に入っていいけど、客人は入れない」という部屋ごとのアクセス権限(認可)を設定するイメージです。

以下の設定では、frontend というサービスからしか、backend というバックエンドサービスにアクセスできないように制限しています。

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: allow-frontend-only
  namespace: production-apps
spec:
  selector:
    matchLabels:
      app: backend # ールを適用する対象のサービス(今回はbackend)
  action: ALLOW
  rules:
  - from:
    - source:
        # frontendサービスからの通信のみ許可する
        principals: ["cluster.local/ns/production-apps/sa/frontend-service-account"]

こうすることで、万が一 frontend 以外の別の怪しいPodからバックエンドにアクセスしようとしても、Istioの門番が「お前、名簿(プリンシパル)に載ってないからダメ!」とピシャリと追い返してくれます。

—

5. まとめ:ゼロトラストの第一歩を踏み出そう

今回は、KubernetesとIstioを使ったmTLSの強制について、防犯の例えを交えてお話ししました。

  • 境界防御の限界を知り、クラスター内であっても油断しないこと。
  • mTLS(相互TLS)を使って、通信の暗号化とお互いの身元確認を徹底すること。
  • Istioの PeerAuthentication(STRICTモード)を使って、簡単に、かつ強力に暗号化を強制すること。

セキュリティ対策というと「なんだか難しそう、面倒くさそう」と感じてしまいがちですが、Istioのようなツールを味方につければ、アプリケーションのコードを1行も書き換えることなく、堅牢なゼロトラストネットワークを構築できます。

ぜひ、皆さんの検証環境や開発環境から一歩ずつ試して、セキュアで安心なインフラづくりを楽しんでみてくださいね。それでは、また次回のセキュリティ解説でお会いしましょう!

コメント

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