DoS 攻击的目标不是「进去」,是「让你服务不了」。 它打的是「资源不对等」——攻击者花一分力,你要花十分力来应付。
上一节讲 VPN,这一节换个方向:从「保护隐私」转到「保住可用」。 注意 DoS 与「防火墙防得住什么」那一节的关系:DoS 属于「能缓解不能根除」的那一档。
一、打的是哪几种资源
带宽:把链路塞满。这种最粗暴,也最难挡,因为「包已经到了,只是你处理不过来」。
连接表:把会话表或半开队列占满。SYN 洪水就是打这个。
CPU:让设备忙于计算。比如大量分片重组、大量需要深度检测的连接。
应用资源:让服务器线程池或数据库连接池耗尽。 这一档防火墙基本管不了,因为它看起来全是「合法请求」。
四档的防守难度是递增的:带宽最好防(加带宽、清洗),应用资源最难防(要业务层自己限流)。
二、SYN 洪水为什么有效
因为三次握手的成本是不对等的: 客户端发一个 SYN(几十字节,不占内存),服务器要回 SYN+ACK 并留一块内存等最后一个 ACK(占内存)。
按每条半开连接 200 字节算:10 万 pps 的 SYN 洪水,每秒就往表里塞 20 MB, 几分钟就能把 8 GB 的内存吃干净。
所以「攻击者花的是带宽,你花的是内存」——而内存是有限的、带宽是可以买的,这就是它难防的原因。
三种挡法,只有第三种是「从根上解决」: 加大表容量(只是拖延)、缩短半开超时(有效但有副作用)、SYN Cookie(不分配任何资源)。
三、SYN Cookie 的代价
它的做法很聪明: 收到 SYN 时不建表,而是把「源地址、目的地址、端口、时间」用哈希算成一个序列号,放进 SYN+ACK 里发回去。 如果对方真的存在,它会带着这个序号回来,服务器验算一下就知道「这条连接是真的」。
结果是:半开状态下零内存占用。 代价是「SYN+ACK 里带不了 TCP 选项」, 因为序号字段已经被哈希占满了,没有空间放窗口缩放、选择性确认这些选项。
而「带不了窗口缩放」的后果很实在: 窗口最大只有 65535 字节,在长肥管道(高带宽高延迟)上吞吐会掉得很厉害。 这就是为什么很多设备默认把它关掉,只在检测到洪水时才临时打开。
所以「安全与性能的取舍」在这里表现得最清楚:同一个功能,平时开着伤性能,攻击时不开会挂。 工程上的答案是「动态切换」,而动态切换本身就要求设备能识别攻击。
四、动手 Demo:SYN 洪水打的是什么资源
这段按「每条半开连接 200 字节」,算 1000、10000、100000 pps 三种攻击速率下内存每秒涨多少, 再对比三种挡法的效果。
per = 200
for pps in (1000, 10000, 100000):
T([u"%s pps" % format(pps, u","),
u"%s" % format(pps, u","),
u"%.1f MB" % (pps * per / 1048576.0)], [0, 0, 0])
实跑输出:
--------------------------------------------------------------------
SYN 洪水打的是什么资源
--------------------------------------------------------------------
**SYN 洪水不靠带宽赢,靠「占着不放」。**
**它打的是服务器的半开连接表。**
**三次握手第二步的代价**:**服务器发出 SYN+ACK 后,必须留一块内存等最后一个 ACK。**
每个半开条目约 200 字节(五元组 + 重传计时器)。
攻击速率 半开条目/秒 占内存/秒
-----------------------------------------------
1,000 pps 1,000 0.2 MB
10,000 pps 10,000 1.9 MB
100,000 pps 100,000 19.1 MB
**10 万 pps 只要 20 MB/秒就往上涨**,**几分钟就能把 8 GB 的表吃干净。**
**三种挡法,账不一样**:
加大表容量 只是把时间从 3 分钟拖到 30 分钟
缩短半开超时 从 75 秒降到 5 秒,内存峰值降 15 倍
SYN Cookie 根本不分配,用序列号编码状态,内存零增长
**SYN Cookie 是唯一「不给资源也不影响正常用户」的解法**,
**代价是不能带 TCP 选项(窗口缩放之类)**。**这也是很多设备默认关掉它的原因。**
「10 万 pps 每秒 20 MB」这个数要记住: 它说明 SYN 洪水不需要很大的带宽就能打垮一台设备——10 万 pps 按 64 字节算只有 51 Mbps,一条百兆链路都不到。
注意三种挡法里「缩短超时」那一行:从 75 秒降到 5 秒,内存峰值降 15 倍, 这是最便宜、最有效的临时手段,代价是「慢速连接」会被误杀(比如卫星链路、老式拨号)。
最后那句「不给资源也不影响正常用户」是 SYN Cookie 的全部价值: 它把「攻击成本」还给了攻击者——因为服务器不再为半开连接付任何代价。 而它的代价(带不了选项)恰好是「正常用户也受影响」,所以要动态开。
30 秒实验
- 查一台服务器的半开连接上限(backlog)。
- 看防火墙的 SYN 洪水防护是「限速」还是「代理握手」。
- 想一想:为什么「应用层限流」是防 DoS 的最后一环?
常见误区
- 以为加了带宽就能防 DoS。占用的是表与 CPU,不是带宽。
- 以为 SYN Cookie 没有代价。它带不了 TCP 选项,影响长肥管道吞吐。
- 以为防火墙能全挡住。超出链路带宽的攻击,谁也挡不住。
自测三问(点开对答案)
1. SYN 洪水打的是哪种资源? —— 半开连接表(内存),因为它利用三次握手的成本不对等。 2. SYN Cookie 的原理是什么? —— 不建表,把连接信息哈希进序列号发回去,靠对方回带的序号验真。 3. 为什么很多设备默认关闭 SYN Cookie? —— 它会占用序号字段导致带不了 TCP 选项,影响高带宽高延迟链路的吞吐。下一节:除了洪水,还有一类「靠构造畸形包」的攻击。
- ☐ (本节完,下一节 05.07.08 防范基于分组的攻击)