浏览器

SSL_ERROR_RX_RECORD_TOO_LONG:443 端口没有开启 TLS

作者: · 最后核实

报错信息SSL_ERROR_RX_RECORD_TOO_LONG

SSL_ERROR_RX_RECORD_TOO_LONG 的意思是:Firefox 发出了 TLS 握手,收到的回应却不是 TLS,几乎总是一段明文 HTTP 响应。 “HTTP/1.1 400 Bad Request” 开头的几个字节,被当成 TLS 记录解析时长度远超上限,这个名字由此而来。修法在服务器上:在这个端口上启用 TLS。

先判断是网站的问题还是你电脑的问题

几乎都是网站的问题。用 SSL 检测 确认:

curl ssl.sh/example.com

检测提示端口不支持 TLS,就要改服务器。访客这边检查两点:是不是给一个本该用 HTTP 的端口加了 https://;Firefox 里有没有配置代理在替网站应答。

原因

Nginx 的 listen 443 少写 ssl 是最常见的原因,其余 4 种是 Apache、端口、负载均衡和代理配置错误。

1. Nginx:listen 443 没写 ssl

少了 ssl 参数,Nginx 会在 443 端口上照常提供明文 HTTP:

listen 443;        # 错:443 上跑明文 HTTP
listen 443 ssl;    # 对

用明文 HTTP 请求 443 端口来确认:

curl -s -o /dev/null -w "%{http_code}\n" http://example.com:443/

能返回 HTTP 状态码,就说明这个端口没用 TLS。

2. Apache:没开 SSLEngine 或没装 mod_ssl

*:443 虚拟主机有了,但缺 SSLEngine on,或者 mod_ssl 没加载。用 apachectl -M | grep ssl 检查。

3. 把 HTTPS 发到了只支持 HTTP 的端口

https://example.com:8080/ 这类链接或收藏,连到的是只会 HTTP 的应用服务器(Tomcat、Node 等)。要么用 http:// 访问这个端口,要么在前面加一层 TLS。

4. 负载均衡或 CDN 转发到了错误端口

四层负载均衡把 HTTPS 直接透传到期望 HTTP 的后端端口;或者阿里云/腾讯云 CDN 的回源设置成“HTTPS 回源”却回源到 80 端口。把协议和端口对齐。

5. 浏览器里配置了代理

本地或公司的 HTTP 代理不能正确处理 CONNECT 时,可能用 HTTP 错误页回应 HTTPS 请求。去掉代理测试。

在各浏览器/系统上的样子

Chrome 系浏览器把同一问题报成 ERR_SSL_PROTOCOL_ERROR,curl 和 OpenSSL 报 wrong version number 或 packet length too long。

浏览器 显示内容
Firefox “建立安全连接失败”,代码 SSL_ERROR_RX_RECORD_TOO_LONG
Chrome / Edge / 360 / QQ 浏览器 ERR_SSL_PROTOCOL_ERROR,“example.com 发送的响应无效。”
Safari Safari 无法建立安全连接
curl / OpenSSL wrong version number 或 packet length too long

站长怎么修

修法是让 443 端口上的每个监听地址都启用 TLS,然后重载并验证。

1. 给监听开启 TLS。 Nginx:

server {
    listen 443 ssl;
    server_name example.com;
    ssl_certificate     /etc/nginx/ssl/example.com.fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/example.com.key;
}

Apache:

<VirtualHost *:443>
    ServerName example.com
    SSLEngine on
    SSLCertificateFile    /etc/ssl/example.com.fullchain.pem
    SSLCertificateKeyFile /etc/ssl/example.com.key
</VirtualHost>

2. 检查 443 端口上的每个监听地址,包括 IPv6 的 [::]:443 和绑定具体 IP 的 203.0.113.10:443。每个不同的地址都要带 ssl,某个地址上没有任何 server 块写 ssl,它就会提供明文 HTTP。nginx -T | grep -n "listen" 能列出全部。宝塔面板用户手工改过站点配置文件的,尤其要检查这一点。

3. 重载并验证。 nginx -t && systemctl reload nginx,然后 curl ssl.sh/example.com 应当显示 TLS 握手完成。

常见问题

SSL_ERROR_RX_RECORD_TOO_LONG 会是我电脑的问题吗?

很少。配置错误的代理用 HTTP 错误页回应 HTTPS 请求时可能导致它,但绝大多数情况是服务器在用明文 HTTP 应答。用 curl ssl.sh/example.com 测一下。

Apache 装完证书就出现这个错误,为什么?

<VirtualHost *:443> 里缺了 SSLEngine on,或者没加载 mod_ssl,Apache 就在 443 上提供明文 HTTP。Debian/Ubuntu 用 a2enmod ssl 启用模块,CentOS 等系统安装 mod_ssl 包,然后在虚拟主机里加上 SSLEngine on。

我输入 https://example.com:8080 就报这个错,为什么?

那台服务器的 8080 端口提供的是明文 HTTP。访问这个端口要用 http://,如果它应该加密,就给它配上 TLS。

宝塔面板开了 SSL 还是报这个错,怎么查?

先在面板的网站设置里确认 SSL 已“部署成功”,再打开站点配置文件,看 listen 443 后面有没有 ssl。如果服务器上同时装了 Apache 和 Nginx,或者某个 Docker 容器直接占用了 443 端口,请求可能没到宝塔管理的 Nginx。用 ss -lntp | grep :443 看是哪个进程在监听 443,再决定改哪一边。

资料来源

  1. Mozilla Support: Secure Connection Failed and Firefox did not connect
  2. RFC 8446 5.1 节:记录层
  3. nginx ngx_http_ssl_module
  4. Apache mod_ssl