Files
cpp-httplib/docs-src/pages/ja/cookbook/t04-mtls.md
yhirose 86abc9a0ea Give WebSocketClient the PemMemory client certificate constructor SSLClient has
Adds ws::WebSocketClient::PemMemory and a constructor overload that
installs an in-memory client certificate on the TLS context, enabling
mutual TLS for wss:// connections. The certificate is silently ignored
for ws:// URLs, consistent with the existing TLS-only setters such as
set_ca_cert_path().

Part of the interface alignment discussed in #2531.
2026-08-07 16:34:12 -04:00

91 lines
3.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: "T04. mTLSを設定する"
order: 45
status: "draft"
---
通常のTLSはサーバー証明書だけを検証しますが、**mTLS**mutual TLS、相互TLSではクライアントも証明書を提示し、サーバーがそれを検証します。API間通信のゼロトラスト化や、社内システムの認証でよく使われるパターンです。
## サーバー側の設定
`SSLServer`のコンストラクタ第3、第4引数に、クライアント証明書を検証するためのCA証明書を渡します。
```cpp
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で設定する
```cpp
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`のコンストラクタにクライアント証明書と秘密鍵を渡します。
```cpp
httplib::SSLClient cli("api.example.com", 443,
"client-cert.pem",
"client-key.pem");
auto res = cli.Get("/");
```
`Client`ではなく`SSLClient`を直接使う点に注意してください。秘密鍵にパスワードがある場合は第5引数で渡せます。
## WebSocketクライアントの場合
`ws::WebSocketClient`にも同じ`PemMemory`構造体があり、`wss://`接続でクライアント証明書を使えます。
```cpp
httplib::ws::WebSocketClient::PemMemory pem{};
pem.cert_pem = client_cert.data();
pem.cert_pem_len = client_cert.size();
pem.key_pem = client_key.data();
pem.key_pem_len = client_key.size();
httplib::ws::WebSocketClient ws("wss://api.example.com/ws", pem);
if (ws.connect()) {
ws.send("hello");
}
```
`ws://`非TLSのURLに`PemMemory`を渡した場合は黙って無視されます。ファイルパスから直接読み込むコンストラクタは用意されていないので、`SSLClient`と違いPEMをメモリ上に読み込んでから渡す必要があります。
## ハンドラからクライアント情報を取得する
ハンドラの中で、どのクライアントが接続してきたかを確認したいときは`req.peer_cert()`を使います。詳しくは[T05. サーバー側でピア証明書を参照する](../t05-peer-cert)を参照してください。
## 用途
- **マイクロサービス間通信**: サービスごとに証明書を発行して、証明書で認証する
- **IoTデバイスの管理**: デバイスに証明書を焼き込み、APIへのアクセス制御に使う
- **社内VPNの代替**: 公開されているエンドポイントに証明書認証をかけて、社内リソースへ安全にアクセスさせる
> **Note:** クライアント証明書の発行と失効管理は、普通のパスワード認証より運用コストが高いです。内部PKIを回すか、ACMELet's Encryptなど系のツールで自動化する体制が必要です。