こんにちは!インフラやクラウドのセキュリティの世界へようこそ。
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行も書き換えることなく、堅牢なゼロトラストネットワークを構築できます。
ぜひ、皆さんの検証環境や開発環境から一歩ずつ試して、セキュアで安心なインフラづくりを楽しんでみてくださいね。それでは、また次回のセキュリティ解説でお会いしましょう!
コメント