Сообщение об ошибке
state=error: certificate verify failed (hostname mismatch)
Также выводится как
- OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 peeraddr=127.0.0.1:8443 state=error: certificate verify failed (hostname mismatch)
Полное сообщение: «SSL_connect returned=1 errno=0 peeraddr=<ip>:<port> state=error: certificate verify failed (hostname mismatch)». Самого имени хоста в сообщении нет; сравните URL с сертификатом.
Ruby openssl (Net::HTTP verify_hostname, default true) — OpenSSL::SSL::SSLError from SSL_connect
Что это означает
Цепочка признана доверенной, но имени хоста, к которому подключился Net::HTTP, нет среди альтернативных имён субъекта (SAN) сертификата. Текущие версии Ruby поручают OpenSSL проверять имя хоста во время рукопожатия (verify_hostname), поэтому проблема проявляется как ошибка проверки сертификата; старые версии Ruby после подключения выбрасывали отдельную ошибку «hostname … does not match the server certificate».
Почему это происходит
Сертификат не покрывает это имя
частоПоддомены, домен без www или переименованные хосты, которых нет в списке SAN.
Подключение по IP или внутреннему псевдониму
частоКлиенты баз данных, Redis или API, в настройках которых указаны IP-адреса или имена контейнеров.
Сервер вернул сертификат по умолчанию
иногдаПрокси, которому неизвестно запрошенное имя, отдаёт сертификат другого сайта.
Как исправить
- 1.
Сравните список SAN с хостом
В сообщении имён нет, поэтому выведите их из сертификата.
bash echo | openssl s_client -connect api.example.com:443 -servername api.example.com 2>/dev/null \ | openssl x509 -noout -ext subjectAltName - 2.
Используйте имя из сертификата и закрепите адрес
С Net::HTTP#ipaddr= соединение устанавливается с заданным IP-адресом, а для SNI и проверки используется имя хоста.
ruby # Connect to a specific address but verify the certificate's name (Net::HTTP#ipaddr=) http = Net::HTTP.new("www.example.com", 443) http.ipaddr = "10.0.0.5" http.use_ssl = true http.get("/health") - 3.
Перевыпустите сертификат со всеми используемыми именами
Добавьте недостающие имена в subjectAltName.
bash openssl req -new -key server.key -out server.csr -subj "/CN=api.example.com" \ -addext "subjectAltName=DNS:api.example.com,DNS:www.example.com"