内容扫描要先把流重组出来,再拿特征去比——两步都比「看包头」贵得多。 而它的准确性天生有限:特征一多就慢,特征一少就漏。
前面几节都在看包头,从这一节开始看载荷。 这是防火墙第一次碰到「内容」,也是最容易让人产生过高期待的地方。
一、两步:先重组,再匹配
第一步是流重组:把属于同一条连接的包按序号拼回完整的字节流。 因为特征可能跨越两个包,不重组就找不到。
第二步是特征匹配:拿一堆「特征串」在这条流里找。 找得到就是命中。
两步各有各的代价: 重组要缓冲(内存),而且要等(延迟);匹配要 CPU(算力),而且特征越多越慢。 这就是「深度检测设备一定贵、一定慢」的结构性原因。
注意「等」这件事:重组意味着「不到齐不能判」, 所以哪怕只有一个包丢了,后面所有包都得等重传。 表现在用户侧就是「卡一下」,而不是「一直慢」。
二、匹配算法决定了快慢
最朴素的做法是「一条一条比」:N 条特征 × M 字节的流 = N × M 次比较。 100 条特征、1 MB 的流,就是一亿次。
改进的做法是「把所有特征组织成一棵树」: Aho-Corasick 自动机把「逐条比」变成「一次扫描同时找所有特征」。 代价与特征条数几乎无关,只与流的长度有关。
这个改进的量级可以实测:100 条特征、500 条文本,逐条比与合并成一条正则,差一个数量级。 而真实设备的特征库有几万条,差距会更大。
但算法再快也有天花板:因为「每个字节都要过一遍」这件事躲不掉。 10 Gbps 的流量就是每秒 12.5 亿字节,每个字节都要进一次状态机。 这就是为什么高带宽场景要用「只扫前 N 个字节」或者「抽样扫描」来折中。
三、它的边界在哪
三条边界,一条比一条难绕:
一、加密就看不见:HTTPS 的载荷对设备是不透明的。 要扫就得做「中间人解密」,而这会带来证书、隐私、性能三方面的麻烦。
二、特征只能对应「已知」:新漏洞、新变种、加壳混淆,都躲得过特征匹配。 所以它天生是「事后」的防护。
三、误报与漏报无法同时消掉:特征放宽就误报多,收紧就漏报多。 这条没有技术解,只有「按业务调阈值」。
所以正确的期待是:内容扫描挡的是「已知的、没有伪装的」那一批攻击, 而这一批恰好是量最大的——和防火墙挡「扫描与未授权访问」是同一个逻辑。 不追求全挡,只追求挡掉最大的一批。
四、动手 Demo:特征匹配,一条一条比和一次扫完
这段用 100 条特征在 502 条文本里做匹配,比较「逐条 in 判断」与「合并成一条正则」两种写法的耗时, 看差多少倍。
for t in texts:
for s in sigs:
if s in t:
hit_naive += 1
joined = re.compile(u"|".join(sigs))
for t in texts:
hit_fast += len(joined.findall(t))
实跑输出:
--------------------------------------------------------------------
特征匹配,一条一条比和一次扫完
--------------------------------------------------------------------
**内容扫描的本质是多模式匹配**,**而「怎么组织这些模式」决定了它快不快。**
100 条特征 × 502 条文本
逐条 in 匹配:命中 2 次,耗时 2.144 毫秒。
合并成一条正则:命中 2 次,耗时 0.111 毫秒。
快 19.3 倍。
**两条路的命中结果一样,速度差一个数量级。**
**真实设备用的 Aho-Corasick 就是这个思路的极致版**——
**所有特征共用一次扫描,代价与特征条数几乎无关。**
**但内容扫描还有个绕不过的代价**:
100 Mbps 的流量,要逐字节扫完整份载荷。
1,000 Mbps 的流量,要逐字节扫完整份载荷。
10,000 Mbps 的流量,要逐字节扫完整份载荷。
**所以真实部署里,内容扫描只在「必要的方向、必要的协议」上开**,
**不会全量全开——那会把设备变成瓶颈。**
两条路的命中结果一样,速度差一个数量级——这个对比说明「算法」比「硬件」更能决定内容扫描的速度。真实设备的特征库有几万条,逐条比根本不可能。
注意这段测的是 Python 的开销,不是设备的真实性能: 它只能证明「合并扫描比逐条比快」,不能证明「某台设备能跑多少 Gbps」。 这种「只证明方向、不证明数值」的实验,写文案时要说清楚。
最后那句「只在必要方向、必要协议上开」是工程上的答案:全量全开一定把设备变成瓶颈。 所以真实部署里,内容扫描通常只开在「外到内的 Web 与邮件」上。
30 秒实验
- 找一台开了 IPS 的设备,看它开启后吞吐下降了多少。
- 查一下你单位有没有做 HTTPS 解密,为什么做或不做。
- 想一想:特征匹配能挡住「改了三个字节的变种」吗?
常见误区
- 以为内容扫描能防未知攻击。特征只能对应已知,未知一定漏。
- 以为开了就万无一失。误报率一高,运维就会关掉它。
- 以为 HTTPS 也能扫。不解密就看不见,解密是另一个决定。
自测三问(点开对答案)
1. 内容扫描的两步分别是什么?各有什么代价? —— 流重组(要缓冲与等待)与特征匹配(要算力,特征越多越慢)。 2. Aho-Corasick 解决了什么问题? —— 把所有特征组织成自动机,一次扫描同时匹配全部,代价与特征条数几乎无关。 3. 内容扫描的三条边界是什么? —— 加密看不见、特征只对应已知、误报与漏报无法同时消掉。下一节:设备自己怎么记账、怎么把账报出来。
- ☐ (本节完,下一节 05.07.10 监视、报告功能)