Сообщение об ошибке
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 (альтернативное имя субъекта), поэтому имя хоста есть только в общем имени (CN) субъекта. Go перестал принимать имена хостов из CN в Go 1.15 (полностью — в 1.17), следуя RFC 6125 и правилам CA/Browser Forum, и прямо сообщает об этом, если бы CN совпал. Исправление одно — сертификат с SAN; переключателя на стороне клиента больше нет.
Почему это происходит
Сертификат создан без subjectAltName
частоИменно такой сертификат получается, если вызвать openssl req -x509 -subj "/CN=host" без -addext subjectAltName или подписать CSR командой openssl x509 -req без -copy_extensions/-extfile.
Профиль внутреннего CA, появившийся до требования SAN
частоСтарые шаблоны Active Directory Certificate Services, устаревшие скрипты и 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
Внесите в subjectAltName все DNS-имена (и IP-адрес, если клиенты подключаются по нему). При подписи CSR командой openssl x509 -req расширения из CSR отбрасываются, если не передать -copy_extensions copy или -extfile.
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)