mTLS

クライアントとサーバーが互いに証明書を検証し、双方向で認証する TLS の拡張

セキュリティ認証

mTLS とは

mTLS (Mutual TLS) は、通常の TLS がサーバーの証明書のみを検証するのに対し、クライアントの証明書もサーバーが検証する双方向認証である。マイクロサービス間通信やゼロトラストアーキテクチャで使われる。

TLS vs mTLS

双方向と言っても別のプロトコルを使うわけではない。TLS のハンドシェイクでサーバーが CertificateRequest メッセージを送るかどうかだけが分かれ目で、これを省けば通常の TLS になる (RFC 8446)。CertificateRequest を受けたクライアントは、自分の証明書と、そこまでのハンドシェイク全体に秘密鍵で署名した CertificateVerify を返す。証明書を提示するだけでは認証にならず、対応する秘密鍵を持っている証明までが一組で必要になる。TLS 1.3 ではこのやり取りが ServerHello 以降の暗号化された区間で行われるため、クライアント証明書が経路上に平文で流れない点も TLS 1.2 との違いになる。

TLS (一方向):
  クライアント → サーバー証明書を検証 → 暗号化通信
  (サーバーはクライアントを検証しない)

mTLS (双方向):
  クライアント → サーバー証明書を検証
  サーバー → クライアント証明書を検証 → 暗号化通信
  (双方が相手を検証)
観点TLSmTLS
サーバー認証証明書でサーバーの正当性を確かめるTLS と同じ手順でサーバー証明書を検証する。ここは変わらない
クライアント認証行わない。利用者の確認はトークンなど別の層に任せるクライアント証明書で接続元を確かめる
用途Web サイト、APIマイクロサービス間、IoT
証明書管理サーバーのみサーバー + クライアント

ユースケース

代表的なユースケースを以下にまとめる。

ケース理由
マイクロサービス間通信サービス間の認証を証明書で行う
ゼロトラストネットワーク境界ではなく ID で認証
IoT デバイスデバイスの正当性を証明書で検証
B2B APIパートナー企業のクライアントを証明書で認証

AWS では API GatewayREST API が相互 TLS に対応している。信頼する CA 証明書を束ねた PEM ファイル (トラストストア) を Amazon S3 に置き、リージョナルのカスタムドメイン名からその S3 の場所を指定する構成で、クライアントはその CA が発行した証明書を提示する。設定で見落としやすいのは、相互 TLS を有効にしてもデフォルトの execute-api エンドポイントが生き残ることである。カスタムドメイン名を通さない呼び出し経路が残るため、デフォルトエンドポイントを無効化しないと証明書の検証を迂回できてしまう。

サービスメッシュでの mTLS

サービスメッシュを入れると、プロキシが証明書の発行・更新と mTLS のハンドシェイクを引き受けるため、アプリケーションコードは変更せずに済む。Istio の従来型 (サイドカーモード) では Pod ごとに Envoy が同居し、2026 年 8 月時点で選べるアンビエントモードではノードごとの ztunnel (DaemonSet) が同じ役割を担う。前者はアプリと同じ Pod 内で終端するため経路が理解しやすく、後者は Pod 数に比例したプロキシを持たない分、常駐リソースを抑えられる。

なお AWS App Mesh は 2026 年 9 月 30 日にサポート終了が予定されており、AWS 自身が案内する移行先は Amazon ECS Service Connect である。Kubernetes 上で新しく組むなら Istio や Linkerd が現実的な候補になる。

Pod A [App][Envoy Proxy] ←mTLS→ [Envoy Proxy][App] Pod B

証明書の管理

証明書の発行元には AWS Private CA (旧称 ACM Private CA)、Kubernetes 上で発行と更新を自動化する cert-manager、シークレット管理と PKI を兼ねる HashiCorp Vault などがある。どれを選んでも、CA の秘密鍵をどこに置き誰が触れるかが実質的な信頼の根になる点は変わらない。

よくある課題

  • 証明書の有効期限切れで通信が突然止まる → 自動更新を設定
  • 証明書のローテーション中に一時的に接続エラーが発生 → 新旧両方の証明書を信頼する期間を設ける
  • 漏洩したクライアント証明書を失効させたつもりが止まらない → 受け側が失効確認 (CRL・OCSP) に対応していなければ有効期限まで通る。有効期間を短くして自動更新で回すほうが確実
  • デバッグが困難 → openssl s_client -connect <host>:443 -cert client.crt -key client.key で、どちら側の検証で落ちているかを切り分ける

ロードバランサーで相互 TLS を受けるときの挙動 (ALB の verify モードと passthrough モードの違いなど) は TLS 終端 側で扱っている。mTLS を扱う関連書籍も多い。

この記事は役に立ちましたか?

関連用語

関連する記事