基于Netty实现HTTPS代理服务器出现SSL版本号错误问题咨询
问题排查与解决指南
核心错误根因
SSL routines:CONNECT_CR_FINISHED:wrong version number 错误本质是TLS握手阶段,接收方拿到了不符合TLS协议格式的报文,你当前的问题90%以上是HTTP处理器移除时机错误或响应格式不规范导致的。
排查步骤
- 排查点1:HTTP处理器移除顺序是否正确
你必须保证200 Connection established响应完全发送到客户端后,才能移除HTTP编解码器。如果先移除编解码器再发响应,HTTP响应对象无法被正确编码为字节流,客户端会把乱码的响应内容当成TLS握手报文解析,直接触发版本号错误。 - 排查点2:CONNECT响应格式是否规范
标准的CONNECT成功响应只需要返回如下内容,不能加多余的响应头也不能缺结束标记:
如果缺少末尾的两个HTTP/1.1 200 Connection established\r\n\r\n\r\n,客户端会认为响应还没接收完成,后续收到的TLS握手报文会被当成HTTP响应内容处理,导致握手失败。 - 排查点3:透传逻辑是否有多余处理
移除HTTP编解码器后,两端通道的处理器只能做纯字节透传:- 客户端→代理通道收到的ByteBuf要原封不动写给代理→远端服务器通道
- 代理→远端服务器通道收到的ByteBuf要原封不动写给客户端→代理通道
不能添加SslHandler,也不能对字节内容做任何解码、修改操作,普通隧道代理不需要参与TLS协商,完全透传即可。
- 排查点4:远端连接是否正常建立
确认返回200响应前,代理和远端HTTPS服务器的443端口TCP连接已经完成三次握手,避免还没连上远端就返回响应,导致客户端发的TLS握手包被丢弃。
正确实现流程
严格按以下顺序处理CONNECT请求即可解决问题:
- 收到客户端的CONNECT请求后,先发起和远端服务器对应端口的TCP连接
- 远端TCP连接建立成功后,构造
200 Connection establishedHTTP响应对象,写入客户端通道并主动flush - 监听写入响应的future回调,确认响应完全写入成功后,同时执行两个操作:
- 移除客户端→代理通道中的
HttpServerCodec、HttpObjectAggregator - 移除代理→远端服务器通道中的
HttpClientCodec、HttpObjectAggregator
- 移除客户端→代理通道中的
- 两端通道分别添加纯透传Handler,所有收到的ByteBuf直接转发到对端通道,不做任何修改
调试建议
如果按上述流程操作仍有问题,可以在透传阶段添加Netty自带的LoggingHandler,打印两端的流量字节,确认TLS握手报文是否被完整、未篡改的透传。
内容的提问来源于stack exchange,提问作者ray5273
相关产品推荐
相关产品推荐

