こんにちは!セキュリティチームで日々インフラや認証基盤の守りを固めているエンジニアです。
新しいシステムやクラウドの開発に携わるようになると、「mTLS」や「SPIFFE」といった、なんだか聞き慣れない強そうな言葉によく出会いますよね。「セキュリティの専門用語が多くて、正直お腹いっぱい……」と感じている新人エンジニアの方も多いのではないでしょうか?
大丈夫です!一歩ずつ、身近な例えから紐解いていけば決して難しくありません。今回は、クラウドネイティブな世界で必須の技術となっている「サービス間認証(mTLS / SPIFFE)」について、泥臭い現場のリアルな視点も交えながら、優しく丁寧に解説していきますね。
—
1. 家の鍵で例える「TLS」と「mTLS」の違い
まずは、私たちが普段ウェブサイトを見るときに使っている暗号化通信の仕組みからおさらいしましょう。
皆さんがスマホでネットショッピングをするとき、URLの先頭に https:// がついていますよね。これは通信が盗み見られないように暗号化されているサインです。これをTLS(Transport Layer Security)と呼びます。
これを「一軒家の防犯」に例えてみましょう。
- 通常のTLS(片方向の認証):
あなたがネットショップ(お店)に行くとき、そのお店が「偽物ではなく本物のAmazonや楽天であること」を確認して、安全な地下通路を通って買い物をする状態です。お店側は「お客さんが誰であるか」を厳密には証明せず、とりあえず「安全な通信のトンネル」だけを作っています。
しかし、マイクロサービスと呼ばれる「小さなプログラムがたくさん協力して動くクラウドの世界」では、これだけだと少し不安です。サービスAがサービスBに「ねえ、顧客データ教えて!」と頼んだとき、「本当にサービスAからの依頼なの?実は悪意ある侵入者がサービスAになりすましてない?」という問題が発生するのです。
そこで登場するのが、今回の主役であるmTLS(相互TLS認証:Mutual TLS)です。
- mTLS(相互TLS認証):
お店に入るあなた(サービスA)も、お店(サービスB)も、お互いに「身分証明書(デジタル証明書)」を提示し合います。「あ、あなたは本物のサービスAですね」「はい、あなたも本物のサービスBですね。お互い身元が確認できたので、秘密の会話を始めましょう!」と確認し合うのがmTLSの仕組みです。
家同士の通信で例えるなら、宅配業者が家に来たとき、インターホン越しに身分証を見せ合うだけでなく、あなた(家)側も宅配業者に対して「本当にその会社の社員証ですか?」と身分証の提示を求める状態ですね。これなら泥棒が宅配業者になりすますことはできません。
—
2. サービスメッシュ(Istio / Linkerd)がやってくれること
「じゃあ、その身分証明書のやり取りを、自分たちのプログラムコードで毎回書かないといけないの?」と思いますよね。安心してください。それを自動でやってくれるのが、Istio(イスティオ)やLinkerd(リンカード)といったサービスメッシュと呼ばれるツールたちです。
現場のエンジニアとしての本音を言うと、もしこれを開発者がアプリのコードごとに実装しようとすると、証明書の有効期限切れ対応やエラー処理で発狂しそうになります。
サービスメッシュは、アプリケーションのコードのすぐ隣に「サイドカープロキシ」と呼ばれる小さな警備員(例えば、IstioならEnvoyというソフトウェア)をピタッと配置します。
[ サービスAのコード ] <---通信---> [ サイドカー(Envoy) ]
│
(★自動でmTLSの暗号化トンネルを張る)
▼
[ サービスBのコード ] <---通信---> [ サイドカー(Envoy) ]
アプリ側は「隣の警備員に荷物を渡せば、勝手に安全に宛先まで届けてくれる」という状態になり、暗号化や認証の複雑な処理をすべてインフラ側に丸投げできるようになります。これがクラウドネイティブなアーキテクチャの強力なメリットです。
—
3. 「SPIFFE(スパイフィ)」ってなに? 認証の共通規格
さて、mTLSで「身分証明書を見せ合う」と言いましたが、クラウドの世界(Kubernetesなど)では、ポッド(プログラムの入れ物)が消えたり生まれたり、IPアドレスが秒速で変わったりします。
「IPアドレスが 10.244.0.5 だから、さっきのサービスAだ!」という古いやり方は、クラウドでは全く通用しません。
そこで使われるのが SPIFFE(Secure Production Identity Framework for Everyone) です。
一言で言うと、「クラウドの世界共通の身分証明書のフォーマット(規格)」だと思ってください。
SPIFFEの身分証明書(SPIFFE ID)は、以下のようなURLに似た形式をしています。
spiffe://cluster.local/ns/default/sa/my-service-account
「どのKubernetesクラスターの、どのネームスペースにいて、どのサービスアカウント権限を持っているか」がこの一文で一意に表現されます。これなら、コンテナが引っ越してIPアドレスが変わろうとも、「あ、お前はあの時の信頼できるサービスだな!」と一目で分かります。
—
4. 実務で触れる設定例(IstioのPeerAuthentication)
百聞は一見にしかず。実際にIstioを使って、クラス全体の通信をmTLSで強制(Strict)する設定を見てみましょう。現場のYAMLファイルの一例です。
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default
namespace: production # 適用するネームスペース(本番環境など)
spec:
mtls:
mode: STRICT # すべての通信でmTLSを強制する(平文の通信は拒否!)
この mode: STRICT を設定するということは、いわば「我が家のマンションは、住民以外の立ち入りを完全にお断りします。合言葉(mTLS証明書)がない人は、たとえ家族のフリをしていても玄関で追い返しますよ」と宣言するようなものです。
もし、一部の古いレガシーシステムと通信しなければならない場合は、一時的に PERMISSIVE(許容) モード(mTLSが来たら受け付けるし、普通の平文でも一応受け付ける)にすることもありますが、セキュリティの最終目標は常に STRICT です。
—
5. まとめと、今日からできる一歩
今回は、クラウドネイティブなサービス間認証である「mTLS」と「SPIFFE」について、防犯の例えを交えながら解説しました。
- TLS は通信の覗き見を防ぐ暗号化。
- mTLS は「お前誰だ?」をお互いに証明し合う仕組み。
- サービスメッシュ(Istio等) は、その面倒な身分確認をアプリの代わりに自動でやってくれる心強い相棒。
- SPIFFE は、クラウドの世界で変わらない「身分証明書の共通フォーマット」。
「セキュリティの仕組みって、突き詰めると現実世界の人間関係や防犯と同じなんだな」と感じてもらえたら嬉しいです。
実務でIstioやLinkerdを触る機会があれば、ぜひ「あ、今裏側でサイドカー同士が身分証を見せ合って握手しているんだな」と想像してみてください。一歩ずつ、確実に対策の引き出しを増やしていきましょう!
コメント