サービス間のAPI通信はHTTPSで保護しているから安全、と思っていませんか。通常のTLS(HTTPS)は「サーバーが正規のサーバーかどうか」をクライアントが確認する仕組みです。しかし逆に、サーバー側が「このクライアントは本当に正規のサービスか」を確認する手段がありません。
ゼロトラストの考え方が広まるにつれ、この「サーバー→クライアントの検証」を省いた設計がリスクとして改めて注目されています。その解決策が mTLS(相互TLS認証、Mutual TLS) です。
この記事では、mTLSの仕組み・通常のTLSとの違い・具体的な設定手順・証明書管理のポイントまで、現場で使えるレベルで解説します。マイクロサービス環境や内部APIを持つ情シス担当の方にとって、今日から検討できる実用的な内容になっています。

mTLS(相互TLS認証)とは?
mTLSは Mutual TLS(相互TLS) の略で、通信の両端 ―― クライアントとサーバーの双方が デジタル証明書 を提示し、お互いの正当性を確認し合う認証方式です。
通常のTLS(HTTPS通信)では、クライアント(ブラウザなど)がサーバーの証明書を検証することで「このサイトは本物だ」と確認します。しかしクライアント自身は証明書を持つ必要がなく、誰でもサーバーにアクセスできる前提の設計です。
一方mTLSでは、サーバーもクライアントに「あなたの証明書を見せてください」と要求します。信頼された認証局(CA: Certificate Authority)が発行したクライアント証明書を持たない相手は、TLSハンドシェイクの時点で接続を拒否されます。
この「両方向の証明書検証」こそが、ゼロトラストセキュリティの核心にある 「すべてのアクセスを検証する」 という原則をネットワーク層で実現する手段です。近年のマイクロサービスアーキテクチャやAPI連携の普及に伴い、サービス間通信をどう安全に保つかが重要な課題になっており、mTLSはその有力な解決策のひとつです。
ゼロトラストの概念全体については、ゼロトラストとは?概念・仕組み・導入手順をわかりやすく解説の記事で詳しく解説しています。
通常のTLSとmTLSの違い
両者の違いを整理すると、以下のようになります。
| 項目 | 通常のTLS(サーバー認証のみ) | mTLS(相互認証) |
|---|---|---|
| サーバー証明書の提示 | あり | あり |
| クライアント証明書の提示 | なし | あり(必須) |
| 証明書なしでも接続できるか | できる | できない |
| 主な用途 | WebサイトのHTTPS・一般公開API | サービス間通信・内部API・B2B連携 |
| 証明書管理のコスト | 低(サーバー側のみ) | 高(全クライアント分の発行・失効管理が必要) |
TLSハンドシェイクの流れ(通常版)
通常のTLSでは、大まかに次の順序で接続が確立されます。
# 通常TLSハンドシェイク(簡略) Client --> Server : ClientHello(対応する暗号スイートを提示) Server --> Client : ServerHello + サーバー証明書 Client : サーバー証明書の検証(CAのルート証明書と照合) OK → 鍵交換 → 暗号化通信開始
mTLSハンドシェイクの流れ
mTLSでは、サーバーがクライアントに証明書の提示を要求するステップが加わります。接続拒否はハンドシェイクの時点で発生するため、アプリケーション層に不正なリクエストが届く前に通信を遮断できます。
# mTLSハンドシェイク(簡略) Client --> Server : ClientHello Server --> Client : ServerHello + サーバー証明書 + CertificateRequest(クライアント証明書を要求) Client --> Server : クライアント証明書 + CertificateVerify(署名) Server : クライアント証明書の検証(CAのルート証明書と照合) OK → 鍵交換 → 暗号化通信開始
mTLSが有効なユースケース
mTLSがとくに効果を発揮する場面を整理します。
1. マイクロサービス間通信
Kubernetes環境などで複数のサービスが相互にAPI呼び出しをする構成では、各サービスがクライアント証明書を持つことで「注文サービスだけが在庫サービスにアクセスできる」という制御を暗号化レイヤーで実現できます。IstioやLinkerdなどのサービスメッシュは、mTLSをアプリケーション側の変更なしに透過的に自動管理する機能を持っています。
2. 内部APIの不正アクセス防止
社内向けAPIが攻撃者に内部ネットワークへの侵入を許した場合でも、mTLSが有効であればクライアント証明書を持たない攻撃者はAPIにアクセスできません。APIセキュリティの多層防御として、認証トークンとあわせて組み合わせると効果的です。
3. B2B(企業間)API連携
取引先や外部パートナーとのシステム連携で、接続を許可する相手を「証明書ベース」で識別できます。IPアドレス制限よりも偽装が困難なため、より堅牢なアクセス制御を実現できます。
4. ゼロトラストネットワークアクセス(ZTNA)の補完
ZTNAソリューションと組み合わせることで、ユーザー認証だけでなくデバイス・サービス単位の認証も実現できます。ZTNA(ゼロトラストネットワークアクセス)を導入済みの環境では、サービス間通信にmTLSを追加することでより完全なゼロトラスト実装に近づけます。
mTLSの具体的な設定手順
ここでは、オープンソースツールを使ったmTLSの基本的な設定の流れを解説します。PKIの基礎知識についてはPKI(公開鍵基盤)とは?の記事もあわせてご覧ください。
1. CA(認証局)の準備
まず、クライアント証明書を発行するための内部CAを用意します。小規模な環境ではopensslコマンドで自己署名CAを作成できます。
# CAの秘密鍵を生成(4096ビットRSA) openssl genrsa -out ca.key 4096 # CA証明書を自己署名で作成(有効期間10年) openssl req -new -x509 -days 3650 -key ca.key -out ca.crt -subj "/CN=Internal-CA/O=YourCompany" # ca.key は厳重に保管すること(漏洩するとすべての発行済み証明書の信頼が失われる) chmod 600 ca.key
2. クライアント証明書の発行
接続を許可するサービスごとにクライアント証明書を発行します。サービスが増えるほど発行・管理の手間も増えるため、HashiCorp VaultやAWS Private CAなどのマネージドPKIの活用も検討してください。
# クライアントの秘密鍵を生成 openssl genrsa -out client.key 2048 # 証明書署名要求(CSR)を作成 # CNにはサービス名など識別子を入れると管理しやすい openssl req -new -key client.key -out client.csr -subj "/CN=order-service/O=YourCompany" # CAで署名してクライアント証明書を発行(有効期間90日を推奨) openssl x509 -req -days 90 -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt # 発行された証明書の内容を確認 openssl x509 -in client.crt -text -noout | grep -E "Subject:|Not After"
3. nginxでのmTLS設定
サーバー側(nginx)にmTLSを有効化する設定例です。Linuxサーバーへのnginx設定については、姉妹サイトLinuxMaster.JPでも詳しく解説しています。
server { listen 443 ssl; server_name api.example.internal; ssl_certificate /etc/nginx/certs/server.crt; ssl_certificate_key /etc/nginx/certs/server.key; # mTLS設定: クライアント証明書を要求する ssl_client_certificate /etc/nginx/certs/ca.crt; ssl_verify_client on; # on = 証明書なしの接続を拒否 # TLS 1.2以上を強制(古いバージョンの既知脆弱性を回避) ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5; location / { # 検証済みのクライアント証明書のCNをバックエンドに転送 proxy_set_header X-Client-Cert-CN $ssl_client_s_dn_cn; proxy_pass http://backend; } }
設定変更後は nginx -t で構文チェックを行い、問題がなければ systemctl reload nginx でリロードしてください。
4. 証明書の失効管理(CRL / OCSP)
クライアント証明書を発行した後で、そのサービスが廃止になったり証明書が漏洩したりした場合は、証明書を「失効」させる仕組みが必要です。
・CRL(証明書失効リスト): 失効した証明書の一覧ファイルをCAが配布する方式。nginxでは ssl_crl ディレクティブで指定できます
・OCSP(Online Certificate Status Protocol): リアルタイムで失効状態を問い合わせる方式。CRLより即時性が高く、大規模環境に向いています
・短命証明書(Short-lived Certificates): 有効期限を30~90日程度と短く設定し、定期的な自動更新を義務づけることで、失効管理の複雑さを軽減できます
中小企業でも今日からできること
フルスケールのmTLS導入は証明書管理の運用コストがかかりますが、段階的に取り組む方法があります。
・まず重要な内部APIから始める: 全社一斉の導入は難しくても、管理コンソールや決済系など重要度の高いエンドポイントにだけmTLSを適用するところから始めると現実的です
・サービスメッシュを活用する: Kubernetes環境があるなら、IstioやLinkerdを導入するとmTLSをアプリケーション側の変更なしに透過的に適用できます
・マネージドPKIを使う: AWS Certificate Manager Private CA、HashiCorp Vault PKIなどを使うと、証明書の発行・更新・失効をAPI経由で自動化できます。自前でCAを運用するより運用負荷が下がります
・まずPKIの基礎を理解する: mTLSは証明書の仕組みの理解が前提になります。CAの信頼チェーン・証明書の構造・失効の概念を先に整理しておくと、導入検討がスムーズになります
よくある誤解と注意点
【誤解1】mTLSを導入すれば認証は完璧
mTLSは「このクライアント証明書を持つ相手が接続してきた」という事実を確認する仕組みです。証明書の秘密鍵が漏洩すれば、第三者がなりすましできます。秘密鍵の保管場所(環境変数への埋め込みは避け、HashiCorp VaultやAWSのSecrets Managerなどを使う)と、失効の仕組みをあわせて整備することが重要です。
【誤解2】mTLSはHTTPSの代替
mTLSはHTTPS(サーバー認証のみのTLS)の代わりではなく、上位互換です。通信の暗号化はそのままに、クライアント認証を追加したものです。インターネットに公開するWebサイトにmTLSを適用すると、一般ユーザーがアクセスできなくなります。用途に応じた使い分けが重要です。
【注意】TLS 1.0/1.1は使わない
mTLSを設定する際は、TLS 1.2以上のみを許可するよう ssl_protocols TLSv1.2 TLSv1.3; を明示的に設定してください。TLS 1.0はPOODLE攻撃、TLS 1.1はBEAST攻撃など既知の脆弱性が存在します。
【注意】証明書の期限切れで通信断が起きる
クライアント証明書の有効期限が切れると、突然すべての通信が遮断されます。本番環境では証明書の有効期限をモニタリングし、期限の30日前にはアラートが上がるよう設定しておきましょう。証明書の更新を自動化する仕組みも早めに整備することをおすすめします。

本記事のまとめ
mTLS(相互TLS認証)は、通常のTLSにクライアント証明書による認証を追加した仕組みです。「すべてのアクセスを検証する」というゼロトラストの原則をネットワーク層で実現する技術として、マイクロサービスや内部API保護に欠かせない役割を果たします。
| ポイント | 内容 |
|---|---|
| 通常TLSとの違い | クライアントも証明書を提示し、双方向で認証する |
| 有効なユースケース | マイクロサービス間通信・内部API・B2B連携・ZTNA補完 |
| 設定の要点 | 内部CA構築 → クライアント証明書発行 → ssl_verify_client on |
| 運用上の注意 | 秘密鍵の安全な保管・失効管理・有効期限の自動監視 |
| 中小企業の第一歩 | 重要な内部APIに限定して段階的に導入、マネージドPKIを活用 |
mTLSの導入にはPKIの基礎知識と証明書管理の運用体制が必要ですが、一度整備してしまえば強力なアクセス制御レイヤーになります。まずは重要度の高い内部APIから小さく始め、徐々に適用範囲を広げていくアプローチが現実的です。
