Сообщение об ошибке
SSL routines:tls_validate_record_header:wrong version number
Также выводится как
- error:0A00010B:SSL routines:ssl3_get_record:wrong version number
- error:0A00010B:SSL routines::wrong version number
- error:1408F10B:SSL routines:ssl3_get_record:wrong version number
OpenSSL 3.5 указывает функцию tls_validate_record_header, OpenSSL 3.0 — ssl3_get_record («error:0A00010B:SSL routines:ssl3_get_record:wrong version number»), а OpenSSL 1.1.1 использует старый код 1408F10B. Приложения, которые форматируют ошибки без имени функции (curl, сообщения Node.js), выводят «error:0A00010B:SSL routines::wrong version number». Префикс перед «error:» — идентификатор потока, а суффикс — место в исходном коде; оба меняются.
OpenSSL 3 (openssl s_client and any OpenSSL-based client) — SSL_R_WRONG_VERSION_NUMBER
Что это означает
OpenSSL ожидал запись TLS и проверил поле версии протокола в её заголовке, но полученные байты вообще не относятся к TLS — обычно это начало HTTP-ответа или текстовое приветствие почтового сервера, прочитанное как номер версии. Название ошибки вводит в заблуждение: другая сторона работает на этом порту по другому протоколу (или вообще без шифрования), а не с неподдерживаемой версией TLS.
Почему это происходит
На порту работает обычный HTTP или другой протокол без шифрования
частоHTTP на портах 80/8080, бэкенд за прокси, завершающим TLS, или сервис, который принимает TLS на другом порту.
Порт STARTTLS приняли за порт с неявным TLS
частоSMTP (25, 587), IMAP (143), POP3 (110), LDAP (389), PostgreSQL, MySQL и XMPP начинают сеанс без шифрования и переходят на TLS по запросу; при прямом TLS-рукопожатии их приветствие читается как мусор.
Прокси или captive-портал отвечает без шифрования
иногдаЕсли для прокси, который работает по обычному HTTP, в клиенте указан URL прокси с https:// или если сеть перехватывает соединения, вместо ожидаемого TLS приходит HTTP.
Как исправить
- 1.
Используйте -starttls для протоколов с переходом на TLS внутри соединения
openssl s_client поддерживает smtp, imap, pop3, ftp, xmpp, ldap, postgres, mysql и другие протоколы; с этим флагом TLS-рукопожатие начинается после команды перехода на TLS, которую предусматривает протокол.
bash # Protocols that upgrade in-band need -starttls openssl s_client -connect mail.example.com:587 -starttls smtp -servername mail.example.com </dev/null openssl s_client -connect db.example.com:5432 -starttls postgres </dev/null openssl s_client -connect ldap.example.com:389 -starttls ldap </dev/null - 2.
Посмотрите, что на самом деле отправляет порт
Если netcat показывает текстовый баннер или строку состояния HTTP, на порту нет неявного TLS.
bash # What does the port answer with? A readable banner means it is not TLS printf 'HEAD / HTTP/1.0\r\n\r\n' | timeout 3 nc api.example.com 8080 | head -3 timeout 3 nc mail.example.com 587 </dev/null | head -1 # "220 ... ESMTP" = SMTP, STARTTLS port - 3.
Подключитесь к порту с неявным TLS
Если клиент не поддерживает STARTTLS, используйте TLS-порт этого протокола.
bash # Implicit TLS ports: 443 (HTTPS), 465 (SMTPS), 993 (IMAPS), 995 (POP3S), 636 (LDAPS) openssl s_client -connect mail.example.com:465 -servername mail.example.com -brief </dev/null
Связанные ошибки
curl: (35) TLS connect error: error:0A00010B:SSL routines::wrong version numbercurl (OpenSSL backend)[SSL: WRONG_VERSION_NUMBER] wrong version numberPython ssl module (OpenSSL)code: 'ERR_SSL_WRONG_VERSION_NUMBER'Node.js tls.connect / fetch (undici)tls: first record does not look like a TLS handshakeGo crypto/tls