传输层对异常RST的处理策略比FIN更“狠”:只要序列号不在接收窗口内,多数协议栈会直接丢弃,避免被伪造报文干掉连接;而异常FIN则相对温和,协议栈会先进入半关闭状态,把决定权交给应用层。
异常RST和FIN的区别:一个像拉闸,一个像挥手
触发机制与报文特征差异
RST和FIN虽然都用于断开TCP连接,但性格完全不同,RST像直接拉电闸,不商量、不确认,收到就释放,FIN像挥手告别,需要对方点头,数据通道可以留一半。
- RST触发条件:端口未监听、序列号越界、SYN未完成、半开连接被拒绝。
- FIN触发条件:应用层调用close或shutdown、数据发送完毕、中间设备超时主动关闭。
- 确认机制:RST不需要ACK确认,接收方立即释放,FIN必须返回ACK,进入半关闭流程。
- 数据保护:RST可能直接丢弃缓冲区数据,FIN保留接收通道,应用层可以先把剩余数据读完。
表格对比更直观:
| 维度 | 异常RST | 异常FIN |
|---|---|---|
| 释放方式 | 立即释放,不经过四次挥手 | 优雅关闭,需要ACK确认 |
| 状态转换 | 直接到CLOSED | 进入CLOSE_WAIT或LAST_ACK |
| 是否需ACK | 否 | 是 |
| 应用感知 | recv返回ECONNRESET错误 | read返回0,表示对端写关闭 |
| 伪造难度 | 较低,只需序列号落在窗口内 | 较高,需要匹配确认号 |
为什么异常RST更具破坏性
RST不需要握手确认,攻击者只要伪造一个序列号恰好落在接收窗口内的报文,就能切断一条正常连接,FIN则不同,它必须携带正确的确认号,而且接收方进入CLOSE_WAIT后,应用层仍有机会抢救数据,行业共识认为,传输层对RST的序列号校验是防御伪造重置的关键门槛。
服务器收到异常RST包怎么处理:Linux与Windows内核动作拆解
Linux内核的tcp_validate_incoming路径
当网卡收到RST报文,内核首先在tcp_validate_incoming函数中做序列号检查,如果RST的序列号不完全落在当前接收窗口内,内核会直接丢弃这个报文,不产生任何日志,也不通知应用层,只有序列号完全匹配窗口的RST才会触发
tcp_reset,释放socket。
- 查看连接状态:
ss -tan state established - 抓取RST报文:
tcpdump -i eth0 'tcp[13] & 4 != 0' -nn - 内核参数
net.ipv4.tcp_abort_on_overflow控制全连接队列溢出时是否发送RST,默认关闭。
Linux还有一种“静默丢弃”策略:当RST报文的确认号不符合预期,直接丢弃,不回复任何内容,这样可以避免反射放大。
Windows协议栈的Reset处理逻辑
Windows使用WFP(Windows Filtering Platform)在传输层之前过滤报文,管理员可以通过高级防火墙规则对TCP标志位进行匹配,丢弃异常RST,操作路径:
- 打开“高级安全 Windows Defender 防火墙”
- 新建入站规则,选择“自定义”
- 协议类型选TCP,在“高级”选项卡中设置“仅包含带有RST标志的TCP段”
- 选择“阻止连接”
通过PowerShell也能完成:
New-NetFirewallRule -DisplayName "Block RST" -Direction Inbound -Protocol TCP -RemotePort 80 -Action Block
但该命令不直接支持标志位过滤,需要结合WFP驱动或第三方工具。
防火墙与中间设备的拦截策略
云服务器安全组通常不检查TCP标志位,只匹配IP、端口、协议,要处理RST洪泛,必须在操作系统层或前置防火墙配置规则。
nftables限速示例:
nft add table inet filter
nft add chain inet filter input '{ type filter hook input priority 0; policy accept; }'
nft add rule inet filter input tcp flags & rst == rst limit rate 10/second accept
nft add rule inet filter input tcp flags & rst == rst drop
iptables等价写法:
iptables -A INPUT -p tcp --tcp-flags RST RST -m limit --limit 10/s -j ACCEPT iptables -A INPUT -p tcp --tcp-flags RST RST -j DROP
异常FIN包会断开连接吗?半关闭状态与资源回收细节
FIN进入TCP状态机的完整路径
收到FIN后,接收端从ESTABLISHED进入CLOSE_WAIT,同时发送ACK确认,此时对端进入FIN_WAIT_2,接收端应用层read返回0,表示对端已关闭写方向,如果应用层不主动close,连接会一直停留在CLOSE_WAIT。
状态转换顺序:
- 接收端:ESTABLISHED → CLOSE_WAIT → LAST_ACK → CLOSED
- 发送端:ESTABLISHED → FIN_WAIT_1 → FIN_WAIT_2 → TIME_WAIT → CLOSED
应用层read返回0与shutdown操作
read()返回0:对端已经发送FIN,不再发送数据,但本端仍可发送。shutdown(sockfd, SHUT_WR):只关闭写方向,不释放socket,继续接收对端数据。close(sockfd):关闭双向,释放资源。
异常FIN的典型问题是:对端因超时或崩溃发出FIN,但服务端应用没有及时处理read返回0,导致大量CLOSE_WAIT堆积,可以用ss -tan state close-wait快速排查。
异常FIN的典型场景
移动网络NAT设备在空闲超时后,会主动向服务端发送FIN或RST,服务端误以为客户端主动关闭,实际上客户端毫无感知,这种假FIN会让服务端进入CLOSE_WAIT,而客户端仍处于ESTABLISHED,双方状态不一致。
传输层异常RST与异常FIN处理策略配置实操
Linux下用nftables限制RST洪泛
完整步骤:
创建表和链:
nft add table inet filter
nft add chain inet filter input '{ type filter hook input priority 0; policy accept; }'
对RST报文限速,超出丢弃:
nft add rule inet filter input tcp flags & rst == rst limit rate 10/second accept nft add rule inet filter input tcp flags & rst == rst drop
查看规则:
nft list ruleset
Windows防火墙高级安全配置
除了前面提到的图形界面操作,还可以用命令行快速添加阻止RST的规则,虽然标准netsh命令不直接支持标志位匹配,但可以通过“高级安全”界面完成,多数情况下,企业环境会在域控策略中统一配置。
抓包定位异常RST/FIN源头的命令
- 抓RST:
tcpdump -i eth0 'tcp[13] & 4 != 0' -nn -c 100 - 抓FIN:
tcpdump -i eth0 'tcp[13] & 1 != 0' -nn -c 100 - 分析字段:
tshark -r capture.pcap -T fields -e ip.src -e tcp.srcport -e tcp.seq -e tcp.flags
抓包时重点看源IP是否集中、序列号是否随机跳动,如果大量RST来自同一个IP,可能是扫描或攻击,如果来自不同IP但序列号有规律,可能是中间设备策略。
杭州服务器传输层安全配置的常见坑
云上安全组与RST/FIN策略
杭州地域的云服务器(如简米云华东1)安全组默认不区分RST和FIN,安全组只能基于IP、端口、协议做放行或拒绝,不支持TCP标志位过滤,很多运维以为安全组能拦RST洪泛,实际拦不住,正确做法是在操作系统内部署nftables规则,或者前置一台支持七层过滤的负载均衡器。
移动网络NAT超时导致的异常FIN
杭州用户使用移动4G/5G网络访问服务器时,运营商NAT设备的空闲超时时间通常较短,一旦连接空闲超过阈值,NAT设备会主动发送FIN或RST,服务端日志会看到大量“connection reset by peer”或read返回0。
解决思路:
- 调小应用层心跳间隔,确保小于NAT超时时间。
- 开启TCP keepalive:
sysctl -w net.ipv4.tcp_keepalive_time=300 - 应用层心跳推荐间隔:30秒到60秒。
传输层对异常RST与异常FIN的最终处理原则
异常RST要挡在窗口之外,靠序列号校验和防火墙限速,异常FIN要留给应用层抢救,靠CLOSE_WAIT状态和shutdown半关闭,无论是Linux还是Windows,核心策略都是精确匹配序列号、确认号和标志位,而不是一刀切丢弃。
传输层异常RST与异常FIN处理相关问答
问:服务器出现大量RST包原因有哪些?
答:常见原因包括端口未监听、TCP序列号越界、SYN cookie校验失败、防火墙或安全组主动发送RST阻断连接、以及NAT设备超时回收,使用tcpdump抓包查看源IP是否集中,可以初步判断是攻击还是配置错误。
问:RST和FIN关闭连接的区别是什么?
答:RST是异常终止,不经过四次挥手,可能丢弃未读数据,FIN是正常关闭,需要ACK确认,支持半关闭状态,应用层可以继续发送数据直到主动close。
问:异常FIN包会断开连接吗?
答:不会立即断开,接收方进入CLOSE_WAIT状态,应用层read返回0,但仍可发送数据,只有应用层调用close或shutdown后,连接才会真正释放。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/635929.html





