服务器返回RST标志异常关闭TCP/IP连接的原因排查
TCP RST断连故障排查指南
先定界,别上来瞎猜责任
所有排查的第一步是实锤RST是谁发的,不要跟SAP方空口扯皮:
- 抓包时加
-e参数看二层源MAC地址:RST包的源MAC如果和SAP正常回包的源MAC一致,就是SAP侧主机或其直属网关发的;如果源MAC是云厂商负载均衡、防火墙、本地出口网关的MAC,就是对应中间设备发的。 - 对比RST包的IP头TTL值:和同链路正常SAP业务回包的TTL做对比,TTL一致就是SAP端主机发的,TTL差值超过2以上就是中间路径的设备伪造RST截断连接。
- 多节点同步抓包:在业务容器、nginx节点、VPC出口、SAP侧边界同时抓同一条失败请求的全量包,看RST第一次出现在哪段链路,直接定界责任方。
按概率从高到低排查根因
1. 最高概率:PMTU黑洞(MTU/MSS不匹配)
这个和描述的现象100%吻合:
- 小请求数据包小,不会超过路径MTU,所以只会偶发失败;大于100KB的文件上传会连续发满MSS大小的数据包,只要路径上有设备的MTU小于连接协商的MSS,且设备拦截了ICMP fragmentation needed报文(即常说的PMTU黑洞),大包直接被丢弃,部分设备会直接回RST断连。
- 直连故障率高、nginx代理故障率低的特征也完全匹配:Java客户端默认协商的TCP MSS是1460,nginx上游连接默认的MSS更小,触发概率自然低。
- 验证方法:在业务主机、nginx主机上配置iptables规则,把出口发往SAP网段的TCP SYN包的MSS钳制到1380,测试大文件上传,如果故障直接消失,就坐实是MTU问题。
2. 次高概率:SAP侧透明上线了安全策略
SAP方说没改配置没有任何参考价值,托管SAP的运维经常在不通知客户的情况下改网关规则:
- 如果RST出现在TLS握手阶段:大概率是SAP侧升级了TLS策略,禁用了旧版TLS协议、弱密码套件,Java客户端默认启用的TLS版本/密码套件和SAP侧不兼容,握手直接被重置;nginx带的OpenSSL版本更新,默认用的TLS版本和密码套件符合SAP要求,所以故障率低。
- 如果RST出现在数据传输阶段:大概率是SAP侧开启了IPS/应用层防火墙深度检测,匹配到上传文件的特征、单连接流量阈值、连接时长阈值后直接发RST断连。
3. 中间链路NAT网关问题
如果多套环境共用同一个出口NAT网关,大文件上传时连接占用时间长,NAT网关的连接跟踪表项超时被回收,会主动给两端发RST断连。Java客户端默认的连接复用率比nginx低,会占用更多NAT端口资源,触发故障的概率更高。
4. SAP侧TCP内核参数配置错误
如果SAP侧内核开启了tcp_tw_recycle,同时NAT环境下时间戳不匹配,会直接判定连接无效回RST;另外如果SAP侧TCP接收缓冲区配置过小,大流量上传时缓冲区溢出也会直接重置连接。
现有nginx配置修正点
当前的nginx配置有几个会放大故障的问题,先改完再测试:
- 简化location块的rewrite逻辑:现在的规则里
return 400写在proxy_pass前面,虽然rewrite break会跳过return,但正则匹配异常时会直接返回400,直接把rewrite逻辑合并到proxy_pass路径里,删掉多余的rewrite和return规则。 - 显式配置上游TLS参数:加
proxy_ssl_protocols TLSv1.2 TLSv1.3;,指定兼容的密码套件,临时关闭proxy_ssl_session_reuse测试,排除TLS会话复用导致的握手失败。 - 显式配置MSS值:nginx 1.19以上版本直接加
proxy_mss 1380;,低版本就靠主机侧iptables做MSS钳制。 - 临时开启
proxy_buffering on;测试:当前配置关了代理缓冲,大文件上传时nginx直接透传字节流,客户端和上游的收发速率不匹配时很容易导致连接队列溢出触发RST,开缓冲后如果故障率下降,就可以进一步佐证是传输速率不匹配或MTU问题。
跟SAP方对线的实锤依据
拿到抓包证据后,不用跟他们扯配置变更的事,直接甩材料:
- 标注清楚RST包的源MAC、TTL和SAP正常回包一致的抓包截图。
- MSS钳制后故障消失的测试记录,要求他们检查边界防火墙的MTU配置、ICMP报文放行规则。
- 用不同TLS版本测试握手的结果,要求他们提供官方支持的TLS版本、密码套件列表,以及边界防火墙的安全策略配置。
内容的提问来源于stack exchange,提问作者jSebestyén
相关产品推荐
相关产品推荐

