📡 第五章 防火墙功能与防范威胁的对策
📄 一句话概括

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 秒实验

  1. 查一台服务器的半开连接上限(backlog)。
  2. 看防火墙的 SYN 洪水防护是「限速」还是「代理握手」。
  3. 想一想:为什么「应用层限流」是防 DoS 的最后一环?

常见误区

  1. 以为加了带宽就能防 DoS。占用的是表与 CPU,不是带宽。
  2. 以为 SYN Cookie 没有代价。它带不了 TCP 选项,影响长肥管道吞吐。
  3. 以为防火墙能全挡住。超出链路带宽的攻击,谁也挡不住。
自测三问(点开对答案) 1. SYN 洪水打的是哪种资源? —— 半开连接表(内存),因为它利用三次握手的成本不对等。 2. SYN Cookie 的原理是什么? —— 不建表,把连接信息哈希进序列号发回去,靠对方回带的序号验真。 3. 为什么很多设备默认关闭 SYN Cookie? —— 它会占用序号字段导致带不了 TCP 选项,影响高带宽高延迟链路的吞吐。

下一节:除了洪水,还有一类「靠构造畸形包」的攻击。

相关笔记