タイトル: curl: (51) SSL: certificate subject name '~' does not match target host name '~'
エラー内容
| curl: (51) SSL: certificate subject name '~' does not match target host name '~' |
curl でHTTPS接続したとき、サーバー証明書の CN (Common Name) または SAN (Subject Alternative Name) に、接続先ホスト名が含まれていない場合に発生する SSL 検証エラーです。証明書のドメインと接続先のドメインが一致しないことを意味します。
発生条件 / 原因
- 証明書がそのホスト名向けに発行されていない — 例:
example.com用証明書をapi.example.comで使っている - IPアドレスで直接アクセスしている —
https://192.168.0.10/など。証明書はホスト名向けに発行されているので不一致になる - 証明書のSANが古い — ドメイン追加後に証明書を更新していない
- 自己署名証明書/社内CA — テスト環境向けの証明書で、ホスト名情報が合っていない
- SNI(Server Name Indication)を解釈できないクライアントで、共有ホストの別ドメイン証明書が返っている
対処法
1. 接続先ホスト名と証明書の中身を確認
まず証明書のCN/SANに、接続したいホスト名が含まれているかを確認します。
| $ openssl s_client -connect example.com:443 -servername example.com < /dev/null | openssl x509 -noout -subject -ext subjectAltName |
Subject の CN と X509v3 Subject Alternative Name に対象ホスト名が無ければ、証明書側の問題です。
2. 正しいホスト名で接続する
証明書が example.com 用なら、IPやサブドメインではなく example.com でアクセスします。
| $ curl https://example.com/path |
3. IP接続だが特定ホストで証明書を検証したい場合
--resolve オプションを使うと、ホスト名を保ったままIPを指定できます。
| $ curl --resolve example.com:443:192.168.0.10 https://example.com/path |
4. 開発・検証用に検証をスキップ(本番禁止)
-k または --insecure オプションでSSL検証を無視できます。セキュリティ上、開発/検証以外では使わないでください。
| $ curl -k https://192.168.0.10/path |
5. 証明書側を直す(サーバー管理者側)
- 必要なホスト名を SAN に追加して証明書を再発行する
- Let's Encrypt なら
certbotで対象ドメインを追加して再発行 - ワイルドカード証明書(
*.example.com)に切り替える
注意点
-kは暗号化はされるが認証は無い状態になり、中間者攻撃の検知ができなくなる- 本番ではホスト名と証明書を必ず一致させる。AWS ALB/CloudFront などのCDN/LBを通すときも証明書のSANに注意
- curl のエラーコード
(51)は SSL 名前検証失敗。他に(60)(CA信頼失敗)と混同しないこと