错误信息
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:”之前的前缀是线程 ID,后缀是源代码位置;两者都会变化。
OpenSSL 3 (openssl s_client and any OpenSSL-based client) — SSL_R_WRONG_VERSION_NUMBER
含义
OpenSSL 按 TLS 记录解析收到的数据,检查了记录头中的协议版本字段,但收到的字节根本不是 TLS——通常是 HTTP 响应的开头或邮件服务器的文本问候语,被当成了版本号来解读。这个名称有误导性:对端在该端口上使用的是另一种协议(或明文),而不是不受支持的 TLS 版本。
原因
该端口提供的是纯 HTTP 或其他明文协议
常见80/8080 端口上的 HTTP、位于 TLS 终止代理之后的后端,或者 TLS 监听器在另一个端口上的服务。
把 STARTTLS 端口当作隐式 TLS 使用
常见SMTP(25、587)、IMAP(143)、POP3(110)、LDAP(389)、PostgreSQL、MySQL 和 XMPP 以明文开始,收到请求后才切换到 TLS;直接发起 TLS 握手会把它们的问候语当成乱码读取。
代理或强制门户以明文应答
偶见客户端为纯 HTTP 代理配置了 https:// 代理 URL,或者网络拦截了连接,于是在本应是 TLS 的地方返回了 HTTP。
修复方法
- 1.
对带内升级的协议使用 -starttls
openssl s_client 支持 smtp、imap、pop3、ftp、xmpp、ldap、postgres、mysql 等协议;使用这个选项时,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