跳到主要内容
ecdsa.com
OpenSSL 3OpenSSL CLI

错误信息

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 只通过系统调用错误路径报告它。

原因

修复方法

  1. 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. 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. 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.

相关错误

浏览完整的签名错误库