Files
cpp-httplib/docs-src/pages/ja/cookbook/t04-mtls.md
2026-04-10 19:02:44 -04:00

3.0 KiB
Raw Blame History

title, order, status
title order status
T04. mTLSを設定する 45 draft

通常のTLSはサーバー証明書だけを検証しますが、mTLSmutual TLS、相互TLSではクライアントも証明書を提示し、サーバーがそれを検証します。API間通信のゼロトラスト化や、社内システムの認証でよく使われるパターンです。

サーバー側の設定

SSLServerのコンストラクタ第3、第4引数に、クライアント証明書を検証するためのCA証明書を渡します。

httplib::SSLServer svr(
  "server-cert.pem",    // サーバー証明書
  "server-key.pem",     // サーバー秘密鍵
  "client-ca.pem",      // クライアント証明書を検証するCA
  nullptr               // CAディレクトリ省略
);

svr.Get("/", [](const httplib::Request &req, httplib::Response &res) {
  res.set_content("authenticated", "text/plain");
});

svr.listen("0.0.0.0", 443);

この設定だと、クライアント証明書がclient-ca.pemで署名されていない接続はハンドシェイクの段階で拒否されます。ハンドラまで到達した時点で、クライアントはすでに認証済みです。

メモリ上のPEMで設定する

httplib::SSLServer::PemMemory pem{};
pem.cert_pem = server_cert.data();
pem.cert_pem_len = server_cert.size();
pem.key_pem = server_key.data();
pem.key_pem_len = server_key.size();
pem.client_ca_pem = client_ca.data();
pem.client_ca_pem_len = client_ca.size();

httplib::SSLServer svr(pem);

環境変数やシークレットマネージャから読み込む場合はこちらが便利です。

クライアント側の設定

クライアント側では、SSLClientのコンストラクタにクライアント証明書と秘密鍵を渡します。

httplib::SSLClient cli("api.example.com", 443,
                       "client-cert.pem",
                       "client-key.pem");

auto res = cli.Get("/");

ClientではなくSSLClientを直接使う点に注意してください。秘密鍵にパスワードがある場合は第5引数で渡せます。

ハンドラからクライアント情報を取得する

ハンドラの中で、どのクライアントが接続してきたかを確認したいときはreq.peer_cert()を使います。詳しくはT05. サーバー側でピア証明書を参照するを参照してください。

用途

  • マイクロサービス間通信: サービスごとに証明書を発行して、証明書で認証する
  • IoTデバイスの管理: デバイスに証明書を焼き込み、APIへのアクセス制御に使う
  • 社内VPNの代替: 公開されているエンドポイントに証明書認証をかけて、社内リソースへ安全にアクセスさせる

Note: クライアント証明書の発行と失効管理は、普通のパスワード認証より運用コストが高いです。内部PKIを回すか、ACMELet's Encryptなど系のツールで自動化する体制が必要です。