エラーメッセージ
x509: certificate relies on legacy Common Name field, use SANs instead
別の表記
- tls: failed to verify certificate: x509: certificate relies on legacy Common Name field, use SANs instead
TLS 接続の中では(Go 1.20 以降)、テキストの先頭に「tls: failed to verify certificate:」が付き、HTTP クライアントではさらに「Get \"https://…\":」が付きます。Go で作られたプログラム(kubectl、Terraform、Docker、Prometheus、Vault CLI)も同じテキストを出力します。
Go crypto/x509 — HostnameError for a certificate without subjectAltName (Go 1.15+)
このエラーの意味
サーバーの証明書にはサブジェクト代替名(SAN)拡張がないため、ホスト名はサブジェクトのコモンネームにしか存在しません。Go は RFC 6125 と CA/Browser Forum のルールに従い、Go 1.15 でコモンネームのホスト名を受け入れなくなり(1.17 で完全に廃止)、CN が一致していたはずの場合にはそのことを明示的に報告します。解決策は SAN を含む証明書だけで、クライアント側で切り替えられる設定はもう残っていません。
発生する理由
証明書が subjectAltName なしで生成されている
よくある-addext subjectAltName を付けずに openssl req -x509 -subj "/CN=host" を実行した場合や、-copy_extensions/-extfile を付けずに openssl x509 -req で CSR に署名した場合に、まさにこの種の証明書が生成されます。
SAN が必須になる前の社内 CA のプロファイル
よくある古い Active Directory 証明書サービスのテンプレート、レガシーなスクリプト、アプライアンスの CA は、CN のみの証明書を発行することがよくあります。
デバイスや古いソフトウェアが自動生成した証明書
ときどき一部のアプライアンス、データベース、ミドルウェアは、初回起動時に CN のみの証明書を生成します。
修正方法
- 1.
SAN 拡張がないことを確認する
返される証明書のサブジェクトと subjectAltName を出力してください。
bash echo | openssl s_client -connect api.example.com:443 -servername api.example.com 2>/dev/null \ | openssl x509 -noout -subject -ext subjectAltName # No "X509v3 Subject Alternative Name" in the output -> reissue the certificate - 2.
subjectAltName を含めて再発行する
すべての DNS 名(クライアントが IP アドレスを使う場合は IP アドレスも)を subjectAltName に入れてください。openssl x509 -req で CSR に署名する場合、-copy_extensions copy または -extfile を指定しない限り、CSR の拡張は破棄されます。
bash openssl req -new -key server.key -subj "/CN=api.example.com" \ -addext "subjectAltName=DNS:api.example.com" -out server.csr # when signing with "openssl x509 -req", keep the extension: openssl x509 -req -in server.csr -CA ca.pem -CAkey ca.key -days 90 -copy_extensions copy -out server.pem - 3.
Go のフラグを探さない
一時的な回避策だった GODEBUG=x509ignoreCN=0 は Go 1.17 で削除されたため、証明書を再発行する以外に解決策はありません。
text GODEBUG=x509ignoreCN=0 only worked in Go 1.15–1.16 and was removed in Go 1.17; there is no switch left in current Go releases. The certificate must carry SANs.
関連するエラー
x509: certificate is valid for example.com, not api.example.comGo crypto/x509x509: certificate is not valid for any names, but wanted to match api.example.c…Go crypto/x509No subject alternative names presentJava (JSSE HostnameChecker)tls: failed to verify certificate: x509: certificate signed by unknown authorityGo crypto/tls (Go ≥ 1.20)