3. TCP三次握手与并发:高并发下TCP连接建立的特征、SYN洪泛攻击的抓包特征

说到TCP三次握手,很多朋友觉得太基础了,不就是SYN、SYN-ACK、ACK嘛。但我要说,在高并发场景下,三次握手的表现完全不一样。你平时在实验室抓一个包看三次握手,跟线上几万个并发连接同时建立,那抓出来的东西简直是两个世界。

我个人习惯,每次接手一个新系统,第一件事就是在网关层抓一把握手阶段的包。为什么?因为握手阶段的异常,往往能提前暴露整个系统的瓶颈。今天我们就来聊聊,高并发下TCP连接建立到底长什么样,以及那个臭名昭著的SYN洪泛攻击,在Wireshark里到底怎么认。

3.1 标准三次握手的抓包回顾

先快速过一遍正常的三次握手,这是后面所有分析的基础。

步骤 方向 报文特征 关键字段
1 客户端 → 服务器 SYN Seq=0(相对值),Flags=0x002
2 服务器 → 客户端 SYN-ACK Seq=0,Ack=1,Flags=0x012
3 客户端 → 服务器 ACK Seq=1,Ack=1,Flags=0x010

在Wireshark里,你看到的就是三个包,时间间隔通常在毫秒级。但注意,这只是理想情况。我在项目中遇到过,有些中间件或者云厂商的负载均衡器,会在握手阶段插入额外的包,比如TCP选项协商、窗口缩放因子等。如果你看到握手包超过3个,别急着下结论,先看看是不是有TCP选项在搞鬼。

小技巧: 在Wireshark里用过滤表达式 tcp.flags.syn == 1 and tcp.flags.ack == 0 可以快速定位所有SYN包。配合 tcp.stream eq N 可以只看某个TCP流的握手过程。

3.2 高并发下的握手特征

好,现在进入正题。当并发量上来以后,三次握手会出现哪些肉眼可见的变化?我总结了三个核心特征。

3.2.1 握手延迟与重传

高并发下,服务器处理SYN包的能力是有限的。每个SYN包到达后,服务器需要分配一个传输控制块(TCB),这个操作涉及内存分配和哈希表操作。当并发量超过服务器的处理能力时,SYN包就会被丢进队列里排队。

你在抓包里会看到什么?

  • SYN包的响应时间变长:正常情况客户端发出SYN后,几十微秒就能收到SYN-ACK。高并发下可能变成几毫秒甚至几十毫秒。
  • SYN重传出现:如果服务器太忙,客户端等不到SYN-ACK,就会重传SYN。Wireshark里会标记为 [TCP Retransmission]。
  • 握手完成时间波动大:有些连接可能100ms完成,有些要500ms,甚至超时失败。
关键指标: 如果抓包中看到SYN重传比例超过1%,说明服务器已经接近瓶颈了。我曾经帮一个电商客户排查,双十一期间SYN重传率飙到8%,结果发现是后端应用层处理慢导致TCP backlog队列溢出。

3.2.2 Backlog队列与SYN丢包

这里要提一个重要的概念——半连接队列(SYN Queue)。服务器收到SYN后,连接状态是 SYN_RCVD,这个连接会放在半连接队列里。如果队列满了,新的SYN包就会被直接丢弃。

抓包特征非常明显:

  • 客户端发了SYN,服务器没有任何回应(没有SYN-ACK,也没有RST)。
  • 客户端等超时后重传SYN,重传几次后放弃。
  • Wireshark里显示 [SYN] 后面跟着 [TCP Retransmission],然后就没有然后了。

嗯,这里要注意:不是所有SYN无响应都是队列满了。也可能是防火墙丢包、路由问题、或者服务器宕机。怎么区分?看丢包模式。如果是队列满,通常是间歇性丢包——有些SYN能通,有些不能。如果是防火墙策略,往往是全部丢或者按规则丢。

3.2.3 全连接队列溢出

半连接队列之后,还有全连接队列(Accept Queue)。当三次握手完成,连接进入 ESTABLISHED 状态,但还没被应用层 accept() 取走时,就放在这个队列里。

全连接队列溢出的抓包特征更隐蔽:

  • 三次握手看起来是正常的(SYN、SYN-ACK、ACK都完成了)。
  • 但后续的数据包发不过去,或者服务器直接发RST断开连接。
  • Wireshark里你会看到完整的握手,然后紧接着一个 [RST] 或 [TCP Dup ACK]。
避坑指南: 我曾经排查过一个案例,抓包显示握手都成功了,但客户端就是收不到数据。查了两天,最后发现是应用层代码里 accept() 循环里加了一个耗时的数据库查询,导致全连接队列溢出。所以,握手成功不代表连接可用,一定要看后续的数据交互。

3.3 SYN洪泛攻击的抓包特征

说到高并发握手,就绕不开SYN洪泛攻击。这是最经典的DDoS攻击方式之一,原理很简单:攻击者发送大量SYN包,但不完成第三次握手,让服务器维护大量半连接,耗尽资源。

3.3.1 攻击包的典型特征

在Wireshark里,SYN洪泛攻击的包有几个非常明显的特征:

特征 描述 Wireshark中的表现
源IP随机 攻击者伪造源IP,每个SYN包来自不同IP 统计 → IPv4统计 → 源和目标,看到大量不同源IP
SYN包密集 短时间内大量SYN包,每秒数万甚至数百万 IO图表显示SYN包速率异常高
无后续包 攻击者不回应SYN-ACK,没有第三次握手 过滤 tcp.flags.syn==1 and tcp.flags.ack==0,看不到对应的ACK
TCP选项异常 部分攻击工具会省略TCP选项或使用异常值 查看SYN包的TCP选项,可能为空或格式错误
窗口大小固定 伪造的SYN包窗口大小往往是一个固定值 所有SYN包的Window size值相同

说白了,你打开Wireshark,看到满屏的 [SYN] 包,而且每个包的源IP都不一样,目标端口都是同一个(比如80或443),那就八九不离十了。

3.3.2 如何用Wireshark快速确认

我个人习惯用三步法确认SYN洪泛:

  1. 看速率:Wireshark → 统计 → IO图表,选择 tcp.flags.syn==1 and tcp.flags.ack==0 作为过滤条件。如果SYN包速率超过正常值的10倍以上,就要警惕了。
  2. 看源IP分布:统计 → 端点 → IPv4,按发送包数排序。如果前几个源IP的包数差不多,而且数量巨大,说明是伪造IP。
  3. 看握手完成率:用 tcp.flags.syn==1 and tcp.flags.ack==1 过滤出SYN-ACK包,跟SYN包数量对比。正常情况SYN-ACK数量应该接近SYN数量。如果SYN-ACK数量远小于SYN,说明大量握手没完成。
实战经验: 有一次我帮一个游戏公司排查,他们服务器每隔10分钟就卡死一次。抓包一看,SYN包速率从正常的200/s飙到50000/s,持续30秒后恢复。后来发现是竞争对手在整点定时攻击。用Wireshark的IO图表配合时间轴,一眼就看出规律了。

3.3.3 SYN Cookie与抓包表现

很多系统会开启SYN Cookie来防御洪泛攻击。开启后,服务器不再为每个SYN分配半连接,而是把连接信息编码到SYN-ACK的序列号里。这样即使半连接队列满了,服务器也能正常响应。

开启SYN Cookie后,抓包会有什么变化?

  • SYN-ACK包的序列号不再是0,而是一个经过特殊计算的值。
  • Wireshark可能会显示 [TCP Cookie: Present] 或类似提示。
  • 如果攻击流量过大,SYN Cookie本身也会消耗CPU,抓包中可能看到SYN-ACK的响应延迟增加。

但注意,SYN Cookie不是万能的。它只能防御半连接耗尽,如果攻击流量大到把带宽打满,那什么机制都没用。

3.4 高并发握手优化建议

最后,基于抓包分析的结果,我给出几个实用的优化方向:

问题 抓包特征 优化方案
半连接队列溢出 SYN重传,无SYN-ACK响应 增大 net.ipv4.tcp_max_syn_backlog,开启SYN Cookie
全连接队列溢出 握手成功但立即RST 增大 net.core.somaxconn,优化应用层 accept() 性能
SYN洪泛攻击 大量SYN无ACK,源IP随机 开启SYN Cookie,配置防火墙限速,使用CDN/高防IP
握手延迟高 SYN到SYN-ACK间隔大 优化服务器CPU/内存,使用多队列网卡,调整RPS/RFS

你想想看,这些优化其实都是基于抓包分析的结果。没有抓包,你根本不知道问题出在半连接还是全连接,也不知道是攻击还是正常流量。所以,抓包不是万能的,但不抓包是万万不能的。

一句话总结: 高并发下的三次握手,看SYN重传率、握手完成时间、以及SYN-ACK比例这三个指标就够了。这三个指标正常,你的TCP层基本没问题。
高并发TCP连接建立与SYN洪泛攻击分析框架 正常三次握手 SYN → SYN-ACK → ACK 高并发握手特征 SYN重传 / 延迟 / 队列溢出 SYN洪泛攻击 大量SYN / 无ACK / 伪造IP 抓包特征 • 3个包完成握手 • 时间间隔 < 1ms • Seq/Ack 正常递增 • TCP选项完整 抓包特征 • SYN重传比例 > 1% • 握手延迟 > 10ms • 半连接队列溢出:SYN无响应 • 全连接队列溢出:握手后RST • 握手完成时间波动大 抓包特征 • 每秒数万SYN包 • 源IP随机分布 • 无第三次ACK • TCP选项异常/固定 • 窗口大小固定 Wireshark诊断方法:IO图表看速率 → 端点统计看源IP → 握手完成率对比 优化方案 • 半连接溢出:增大 tcp_max_syn_backlog,开启SYN Cookie • 全连接溢出:增大 somaxconn,优化 accept() 性能 • SYN洪泛:开启SYN Cookie,配置防火墙限速,使用高防IP • 握手延迟:优化CPU/内存,使用多队列网卡,调整RPS/RFS