能开启规则性能统计,从统计输出中定位检查次数多、耗时高的规则。
上一课结束在一个可以对照的数字上:同一份 PCAP 回放,调优后告警量明显下降,真实攻击告警一条没少——噪声来源被 threshold 和 suppress 按住了。但告警变少了,不等于规则变快了。规则集越来越大,每个报文要过的规则越来越多,多数规则只花一点点时间,少数几条却悄悄吃掉大部分 CPU。靠感觉猜哪条规则慢,就像在没装水表的房子里找漏水点:你听到滴水声,却说不清哪里漏、漏了多少。没有数字,所有优化都是赌运气。
先装水表,再修管道。这一课只做一件事:让 Suricata 记录每条规则的工作量,从数字里找出“检查次数多、耗时高”的慢规则,把改写目标定下来。上一课先统计告警再动手调优,这一课顺序相同:先统计工作量,再决定改哪条。
统计的用途不是批评某条规则写得差,而是把“慢”从感觉变成数字。有了数字,优化才有顺序:先动最贵的,再动次贵的,而不是漫无目的地从头到尾改一遍。
前提你已经会:用测试模式验证规则、用 -r 回放 PCAP、读 fast.log 核对告警——上一课刚把这些工具用过一遍,这里只是把输出从“告警”换成“统计”。全程只回放本地授权 PCAP,不产生任何针对真实目标的流量。
这一课的产出很具体:一张排名表和一个结论——哪条规则最先动手。带着这个结论进入下一课,改写才有对比基准,就像上一课带着调优前后的告警量对比进入这一课一样。
核心概念
规则性能统计(rule profiling)
类比:安检通道里有十名安检员,每位对应一条规则,每位旅客的行李都要逐一经过他们。主管给每人发一块计时板:今天查了几件行李、拦下几件可疑物、每件平均花几秒。下班汇总,谁最拖速度、谁其实从没拦住过任何东西,一目了然。Suricata 的规则性能统计就是这块计时板。
定义:规则性能统计(rule profiling)是 Suricata 记录每条规则匹配开销的机制。它统计每条规则被检查的次数、命中的次数与处理耗时,汇总成可排序的明细,用于定位“检查次数多、耗时高”的慢规则。“被检查”和“命中”是两回事:被检查次数多,说明这条规则频繁参与比对;命中次数多,说明它经常匹配成功。两者加耗时才构成完整的开销画像。
它回答三个问题:哪条规则被查得最多?哪条规则最耗时?哪条规则又贵又没产出?排名靠前的规则不一定都要改:先排除掉命中真实告警的高价值规则,剩下又贵又没产出的,才是清理对象。
统计只做记录,不改变匹配结果;记录本身也要消耗资源,所以它是调优时用的工具,不是常开的开关。统计结果写入日志目录,具体输出格式随安装版本而异,以该版本官方文档为准。
输出与统计相关的设置,都在配置文件 /etc/suricata/suricata.yaml 里改;发行版安装包默认把这个文件放在该路径。改配置只是第一步,还要让引擎重新读取:要么重启服务,要么直接跑一次离线模式——离线模式启动时同样会读取配置。
引擎跑起来后,总体统计会持续写入日志目录 /var/log/suricata/ 下的 stats.log。默认每 8 秒更新一次,能看到已处理报文数、解码出的流量类型等运行状态。盯住总体统计,可以这样:
sudo tail -f /var/log/suricata/stats.log总体统计告诉你引擎“干得多不多”,规则级明细才告诉你“每条规则干了多久”。注意:测试模式只验证语法,不会产生运行统计;要拿到数字,必须真实跑一次,在线或离线回放都行。
日志目录下通常不止 stats.log 一个文件:suricata.log 记录引擎运行日志,fast.log 记录告警。统计出现异常时,先看 suricata.log 里有没有路径或加载错误。
规则级明细是更细的一层输出,落在哪个文件、列名叫什么,取决于你安装的 Suricata 版本。先查所装版本的官方文档,再回来读数字,不要照抄网上任意版本的配置。每次改动只动一处,回放对比一次,结论才干净;一次改十条,出了问题分不清是谁的功劳。
性能优化必须前后对比,对比的前提是流量相同。用 suricata -r path-to-pcap 回放同一份 PCAP:改规则前跑一遍,改完再跑一遍,检查次数和耗时的变化才有意义。回放时保持参数一致:同一份 PCAP、同一个规则集文件,中途换规则集,两次结论就作废。
回放只分析你本地的授权 PCAP,不产生任何针对真实目标的流量。告警仍会照常写进 fast.log,可以一并核对。想练手又缺样本时,可以按资料里的做法下载一份含恶意流量的 PCAP 文件离线分析——只下载、只离线回放,不在任何真实环境里重放。
拿到明细后,只看两类数字:检查次数和耗时。
检查次数多,说明这条规则参与的比对很频繁,每个报文都可能路过它。平均耗时高,说明它每比对一次都很贵。粗略估计总开销:检查次数 × 平均耗时。
举个例子。规则 A 检查次数 100 万、平均耗时 1;规则 B 检查次数 10 万、平均耗时 10。A 的总开销是 100 万,B 也是 100 万——总账相同,性质不同:A 贵在“每包都过”,B 贵在“过一次很慢”。优化时入手点也不同:A 要减少无谓检查,B 要让单次比对更快。这层区分,下一课动手改写时会用到。
排序之前还要看产出:一条规则又贵又不产生有效告警,等于白烧 CPU,最该处理;一条贵但精准命中真实攻击,先优化写法,而不是直接删。上一课你已经用 threshold 和 suppress 压过告警噪声;这里换个角度:压完噪声后,仍高开销且无产出的规则,才是删除或改写的第一候选。
数字会小幅波动:同一份 PCAP 在同一台机器上重跑,数值会变一点,但排名大体稳定;波动大的,说明这条规则本身不稳定,也要留意。按“总开销 × 产出价值”排出前三名,记下它们的 sid。排序是手段,不是目的:目标是回答“哪条规则值得动手”。如果前三名里有一条命中真实告警,先把它的改写优先级排到无产出规则之后;产出和开销都要看,只看一边都会选错。
高开销规则对吞吐的影响,可以这样理解:一条报文从进入引擎到处理完毕,路上要与一批规则比对。规则越多、每条规则越贵,单条报文停留越久,单位时间能处理完的报文就越少——吞吐就下来了。规则级统计把这种损耗拆到每条规则头上:检查次数多,说明这条规则反复出现在比对路上;平均耗时长,说明它每出现一次都要磨蹭很久。两者同时高的规则,是整条处理链上最占资源的环节,优先优化它们,比随机精简几十条小规则更见效。
判断口径:检查次数和平均耗时都高,这条规则几乎必然拖累吞吐;只有一项高,先看另一项有没有被异常放大。真正决定吞吐的是乘积,不是单个数字。衡量一次优化是否成功,就看同一份 PCAP 下这条规则的总开销降了多少;告警数是否下降,是上一课 threshold 关心的事。回放时规则集只保留你要测的规则,能放大对比差异,也更容易看出单条规则的变化。
开启统计、回放 PCAP、定位慢规则
- 1
先用测试模式验证规则集语法,排除规则错误对统计的干扰。
- 2
编辑配置文件,找到统计相关段落并开启规则级统计。具体键名以你安装版本的官方文档为准,不要照抄网上任意版本。
bashsudo vim /etc/suricata/suricata.yaml - 3
重启服务,让新配置生效。
bashsudo systemctl restart suricata - 4
用同一份测试 PCAP 做离线回放,让引擎记录规则开销。
bashsuricata -r path-to-pcap - 5
先看总体统计,确认引擎在正常处理:应能看到已处理报文数在增长。
bashsudo tail -f /var/log/suricata/stats.log - 6
打开规则级明细文件,按耗时与检查次数排序,记下前三名的 sid。
- 7
对照 fast.log,确认这几条规则是否真的产生过告警;无产出的高开销规则,优先标记为收紧或删除候选。
你应该看到
规则级统计输出中出现逐条规则的检查次数与耗时数据;你能报出总开销最高的三条规则 sid,并说出每条规则的告警产出情况;用同一份 PCAP 重复回放,排名结果稳定可复现。
回放得到的排名,只对这份 PCAP 和这台机器严格成立。流量特征变了,排名会变;换一台 CPU,绝对耗时也会变。所以优化决定按“相对排名 + 产出价值”来下,不看单个数字的绝对值。
改规则前先备份原文件,用带日期后缀的副本保存,改坏了一秒回退;改完用测试模式确认语法,再回放对比。如果统计里始终不出现规则明细,先按资料里的提示排查:核对 suricata.yaml 中每个路径是否与日志里报告的一致——路径错了,配置根本加载不到。
遇到问题:回放后只看到总体统计,找不到规则级明细。
可能原因
- 安装的版本未开启规则级统计,或对该功能的支持方式不同;开启位置与输出文件以版本文档为准。
- 改了 /etc/suricata/suricata.yaml 但没有重启服务,新配置未生效。
- 明细写到了别的文件或目录;日志目录默认在 /var/log/suricata/ 下,文件名随版本变化。
- suricata.yaml 里引用的路径与磁盘实际位置不一致,引擎启动阶段就报错,后续统计自然缺失。
排查步骤
- 按资料提示逐条核对日志中报告的路径:确认 suricata.yaml 里每个路径都指向实际存在的文件。
- 重启服务后再回放一次:sudo systemctl restart suricata。
- 不想动服务,就每次用离线回放验证配置;离线模式同样读取 suricata.yaml。
- 用测试模式确认规则集能正常加载,排除语法问题导致的启动失败。
- 查阅所装版本的官方文档,核对规则统计段落的准确名称与输出文件位置;不同版本不要混用配置。
自检:统计明细里:规则 A 检查次数是规则 B 的 10 倍,两者平均耗时接近;规则 B 平均耗时是 A 的 5 倍,两者检查次数接近。两条规则都从未产生告警,你只能先处理一条。先处理哪一条?为什么?
先处理规则 A。总开销约等于检查次数 × 平均耗时:A 是 10×1=10,B 是 1×5=5,A 的总开销是 B 的两倍。平均耗时相近时,检查次数决定影响面——A 在更多报文上反复消耗。两条规则都没有告警产出,都属于纯开销,按总开销排序处理:先 A,再 B。