错误信息
error:0A000126:SSL routines::unexpected eof while reading
也可能输出为
- SSL routines::unexpected eof while reading
openssl CLI 输出“<thread id>:error:0A000126:SSL routines::unexpected eof while reading:<source>”;curl 将其包装为“curl: (56) OpenSSL SSL_read: … unexpected eof while reading, errno 0”,Python 则包装为“[SSL: UNEXPECTED_EOF_WHILE_READING] EOF occurred in violation of protocol”。
OpenSSL 3 — SSL_R_UNEXPECTED_EOF_WHILE_READING (peer closed the TCP connection without close_notify)
含义
在 OpenSSL 仍在等待数据时(握手期间或数据流中途),对端没有先发送 TLS close_notify 告警就关闭了 TCP 连接。OpenSSL 3 把这种情况报告为错误,因为静默关闭与攻击者截断数据流无法区分;OpenSSL 1.1.1 只通过系统调用错误路径报告它。
原因
服务器拒绝或断开了连接
常见服务器遇到不接受的握手(SNI 未知、没有共同的版本)时直接关闭连接而不发送告警,或者在响应中途崩溃或超时。
防火墙、代理或负载均衡器切断了连接
常见空闲超时、连接数限制以及过滤 TLS 的防火墙会直接结束 TCP 连接,而不执行 TLS 关闭。
从不发送 close_notify 的老旧对端
偶见一些嵌入式服务器和旧的实现在每次响应后都直接关闭套接字,不执行 TLS 关闭;在 OpenSSL 3 下,每个这样的响应都会以这个错误结束。
修复方法
- 1.
查明连接在何时结束
如果错误出现在出示任何证书之前,说明服务器或网络拒绝了握手;如果出现在数据传输之后,说明对端或中间设备切断了数据流。
bash # During the handshake (no certificate printed) -> the server or network refused the connection # After data was exchanged -> the peer stopped mid-stream echo | openssl s_client -connect api.example.com:443 -servername api.example.com -state 2>&1 | grep -E 'SSL_connect|error' - 2.
由你掌控的老旧对端:SSL_OP_IGNORE_UNEXPECTED_EOF
OpenSSL 3 可以把静默关闭视为正常的流结束。由于这会禁用截断检测,只应针对协议本身能检测截断(例如 Content-Length)的特定老旧对端使用它。
python # Only for peers you control that close without close_notify (legacy embedded servers): # OpenSSL 3 option SSL_OP_IGNORE_UNEXPECTED_EOF, exposed by Python 3.10+ as ssl.OP_IGNORE_UNEXPECTED_EOF import ssl ctx = ssl.create_default_context() ctx.options |= ssl.OP_IGNORE_UNEXPECTED_EOF # truncation is then no longer detected - 3.
修复对端:正确关闭 TLS
在关闭连接前发送 close_notify,所有客户端就都不会再出现这个错误。
text Server code: call SSL_shutdown() (or the library's close/unwrap) before closing the socket, and delimit HTTP responses with Content-Length or chunked encoding.
相关错误
curl: (56) OpenSSL SSL_read: error:0A000126:SSL routines::unexpected eof while…curl (OpenSSL 3 backend)[SSL: UNEXPECTED_EOF_WHILE_READING] EOF occurred in violation of protocolPython ssl module (OpenSSL)Client network socket disconnected before secure TLS connection was establishedNode.js tls / https / fetchGnuTLS recv error (-110): The TLS connection was non-properly terminated.git over HTTPS with libcurl-gnutls (Debian, Ubuntu)