.. role:: example-rule-action .. role:: example-rule-header .. role:: example-rule-options .. role:: example-rule-emphasis 规则类型与分类 ============================= 解析完成后,Suricata规则会根据性能和处理需求进行分类(不同规则类型由特定引擎模块处理)。签名类型定义在`src/detect.h `_中: .. literalinclude:: ../../../src/detect.h :caption: src/detect.h :language: c :start-after: // rule types documentation tag start: SignatureType :end-before: // rule types documentation tag end: SignatureType 更易读的表述如下: .. list-table:: Suricata规则类型及其引擎分析术语 :header-rows: 1 * - 规则类型 - 代码符号 - 引擎分析表示 * - 仅解码事件 - ``SIG_TYPE_DEONLY`` - ``de_only`` * - 数据包 - ``SIG_TYPE_PKT`` - ``pkt`` * - 仅IP - ``SIG_TYPE_IPONLY`` - ``ip_only`` * - 仅IP(包含否定地址) - ``SIG_TYPE_LIKE_IPONLY`` - ``like_ip_only`` * - 仅协议检测 - ``SIG_TYPE_PDONLY`` - ``pd_only`` * - 数据包流 - ``SIG_TYPE_PKT_STREAM`` - ``pkt_stream`` * - 流 - ``SIG_TYPE_STREAM`` - ``stream`` * - 应用层协议 - ``SIG_TYPE_APPLAYER`` - ``app_layer`` * - 应用层协议事务 - ``SIG_TYPE_APP_TX`` - ``app_tx`` 规则类型将影响: - 匹配时签名动作的适用范围(动作范围) - 规则与流量匹配的时机(检测钩子) - 规则匹配的对象(暴露的数据) 此分类基于特定规则元素的存在与否以及所用关键词类型。当前分类在`src/detect-engine-build.c:void SignatureSetType() `_中实现。 ``SignatureSetType()``的整体流程如下: .. image:: rule-types/OverallAlgoHorizontal.png :align: center :width: 600 :alt: 表示SignatureSetType函数的流程图。 扩展未覆盖函数或算法部分的流程图详见 :ref:`detailed-flowcharts-sig-type` 部分。 下表列出所有Suricata签名类型及其对上述方面的影响。 .. list-table:: Suricata规则类型 :widths: 10 17 22 29 26 :header-rows: 1 * - 类型 - 动作范围 - 检测钩子 - 暴露数据 - 关键词示例 (非穷举) * - :ref:`仅解码事件 ` (``de_only``) - 数据包 - 每个损坏/无效数据包 - 解码事件 - ``decode-event`` * - :ref:`数据包 ` (``pkt``) - 数据包 - 每个数据包 - 数据包级信息(如:头部信息) - ``tcp-pkt``, ``itype``, ``tcp.hdr``, ``tcp.seq``, ``ttl`` 等 * - :ref:`仅IP ` (``ip_only``) - 流(若存在)。数据包(若不属流) - 每个方向一次 - 流上的IP地址 - 规则的源/目标字段 * - :ref:`仅IP(含否定地址) ` :sup:`2` (``like_ip_only``) - 流 - 所有数据包 - 流上的IP地址 - 含否定地址的规则源/目标字段 * - :ref:`仅协议检测 ` (``pd_only``) - 流 - 协议检测完成时每个方向一次 - 流检测到的协议 - ``app-layer-protocol`` * - :ref:`数据包流 ` (``pkt_stream``) - 流(若状态化):sup:`1` - 每个流块(若状态化),否则每个数据包 (流负载和/或数据包负载) - 重组流及/或负载数据 - 带``startswith``或``depth``的``content`` * - :ref:`流 ` (``stream``) - 流(若状态化):sup:`1` - 流块(若状态化),否则仅数据包 - 流重组负载或数据包负载数据 - 协议字段中的``tcp-stream``;简单``content``;``byte_extract`` * - :ref:`应用层协议 ` (``app_layer``) - 流 - 每个数据包 - 规则中的'protocol'字段 - 规则的`协议字段 `_ * - :ref:`应用层协议事务 ` (``app_tx``) - 流 - 每次 :ref:`事务 ` 更新 - 缓冲区关键词 - 应用层协议相关,如``http.host``, ``rfb.secresult``, ``dcerpc.stub_data``, ``frame``关键词 .. note:: 动作范围:`流(若状态化)` (1) 应用于流。若因任何原因(如数据包异常、错误、达到内存限制等)未接受段入流,规则将在数据包级应用。 .. warning:: 尽管两者都涉及应用层协议匹配,但如表格所示,自Suricata 7起,使用``app-layer-protocol``关键词的协议检测规则在内部分类上与仅在``protocol``字段匹配应用层协议的规则不同。 签名属性 -------------------- 上述`动作范围`与签名属性相关,见`src/detect-engine.c `_: .. literalinclude:: ../../../src/detect-engine.c :caption: src/detect-engine.c :language: c :start-after: // rule types documentation tag start: SignatureProperties :end-before: // rule types documentation tag end: SignatureProperties 签名:需要真实数据包 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 除签名动作范围外,某些规则条件要求其匹配*真实数据包*(而非*伪数据包*)。这些规则会被引擎标记``SIG_MASK_REQUIRE_REAL_PKT``,并在规则的``requirements``中列出``real_pkt``。(参见 :ref:`pkt-rule-type` 规则类型的``engine-analysis``示例输出。) *伪数据包*是引擎在流结束但仍有数据处理时使用的内部资源,如流超时。此时会注入伪造数据包以完成处理。 这两类将很快有更多文档(跟踪`#7424 `_)。 .. _variable-like-keywords-sig-type: 签名类型与变量类关键词 ------------------------------------------ 诸如流变量(``flowint``, ``flowbits``)、``datasets``等类似关键词若出现在签名中,可能改变规则类型。 这是因为变量条件可能随数据包变化。因此,签名被分类为`数据包`规则。 影响以下规则类型: - 应用层 (``app_layer``) - 仅协议检测 (``pd_only``) - 仅解码事件 (``de_only``) - 仅IP (``ip_only``) :sup:`3` - 类仅IP (``like_ip_only``) :sup:`3` 后续示例规则涵盖部分情况,下表详细列出这些关键词: .. list-table:: 变量类关键词 :header-rows: 1 * - 关键词 - 关键词选项 - 规则类型变化? * - ``flow`` - ``to_server``, ``to_client`` - 无类型变化 :sup:`3` * - ``flow`` - ``established``, ``not_established`` - 变为`数据包` * - ``flowbits``, ``xbits``, ``hostbits`` - ``isset``, ``isnotset`` - 变为`数据包` * - ``flowbits``, ``xbits``, ``hostbits`` - ``set``, ``unset``, ``toggle`` - 无类型变化 * - ``flowint`` - ``isset``, ``notset``, 所有操作符 - 变为`数据包` * - ``flowint`` - 定义变量;取消设置; - 无类型变化 * - ``iprep`` - ``isset``, ``notset``, 所有操作符 - 变为`数据包` .. note:: 仅IP与类仅IP (3) 与其他受影响类型不同,原本分类为``ip_only``或``like_ip_only``的签名若使用``flow``关键词(无论选项)将变为数据包规则。 .. note:: ``dataset``虽看似类似上述关键词,但不在此列,因其仅能与粘性缓冲区关键词共用,故仅适用于应用层事务规则(`app_tx`),不受此影响。 Flowbits: ``isset`` ^^^^^^^^^^^^^^^^^^^ 若非状态化规则(如``pkt``规则)检查``flowbit``是否设置(如*flowbits:fb6,isset*),而设置该变量的规则是状态化规则(如``app_tx``规则),引擎将设置标志表明该规则也是状态化——但不改变其签名类型。当前标志为``SIG_FLAG_INIT_STATE_MATCH``(参见工单`#7483 `_)。 正在添加此信息至``engine-analysis``报告(工单`#7456 `_)。 各类型签名 ------------------- 本节简要描述每种规则类型,并展示示例。可通过在:ref:`引擎分析模式 `下运行Suricata了解签名类型及其他重要信息。 每种规则类型还包含一个或多个规则的引擎分析报告示例。 .. _de-only-rule-type: 仅解码事件 ^^^^^^^^^^^^^^^^^^^ 检查损坏或无效数据包的签名。暴露Suricata解码事件。 更多示例见https://github.com/OISF/suricata/blob/master/rules/decoder-events.rules。 示例 """"""" .. container:: example-rule alert pkthdr any any -> any any (msg:"SURICATA IPv6重复Hop-By-Hop选项扩展头"; :example-rule-emphasis:`decode-event:ipv6.exthdr_dupl_hh;` classtype:protocol-command-decode; sid:1101;) .. container:: example-rule drop pkthdr any any -> any any (msg:"SURICATA IPv4无效选项长度"; `:example-rule-emphasis:`decode-event:ipv4.opt_invalid_len;` classtype:protocol-command-decode; sid:2200005; rev:2;) 引擎分析报告 """""""""""""""""""""" .. code-block:: json { "raw": "alert pkthdr any any -> any any (msg:\"SURICATA IPv6重复Hop-By-Hop选项扩展头\"; decode-event:ipv6.exthdr_dupl_hh; classtype:protocol-command-decode; sid:1101;)", "id": 1101, "gid": 1, "rev": 0, "msg": "SURICATA IPv6重复Hop-By-Hop选项扩展头", "app_proto": "unknown", "requirements": [ "engine_event" ], "type": "de_only", "flags": [ "src_any", "dst_any", "sp_any", "dp_any", "toserver", "toclient" ], "pkt_engines": [ { "name": "packet", "is_mpm": false } ], "frame_engines": [], "lists": { "packet": { "matches": [ { "name": "decode-event" } ] } } } .. _pkt-rule-type: 数据包 ^^^^^^ 暴露/检查数据包级信息(如头部)的规则。某些流关键词若需逐包检查也可能将规则转为``pkt``规则(参见:ref:`variable-like-keywords-sig-type`)。 示例 """""""" .. container:: example-rule alert :example-rule-emphasis:`tcp-pkt` any any -> any any (msg:"tcp-pkt, 锚定内容"; :example-rule-emphasis:`content:"abc"; startswith;` sid:203;) .. container:: example-rule alert tcp any any -> any any (msg:"ttl"; :example-rule-emphasis:`ttl:123;` sid:701;) .. container:: example-rule alert udp any any -> any any (msg:"带流方向的UDP"; flow:to_server; sid:1001;) .. container:: example-rule alert tcp any any -> any 443 (flow: to_server; flowbits:set,tls_error; sid:1604; msg:"允许TLS错误处理(出站数据包)- 非状态化规则";) .. container:: example-rule alert tcp-pkt any any -> any any (msg:"Flowbit isset"; :example-rule-emphasis:`flowbits:isset,fb6; flowbits:isset,fb7;` sid:1919;) 引擎分析报告 """""""""""""""""""""" .. code-block:: json { "raw": "alert tcp-pkt any any -> any any (msg:\"tcp-pkt, 锚定内容\"; content:\"abc\"; startswith; sid:203;)", "id": 203, "gid": 1, "rev": 0, "msg": "tcp-pkt, 锚定内容", "app_proto": "unknown", "requirements": [ "payload", "real_pkt" ], "type": "pkt", "flags": [ "src_any", "dst_any", "sp_any", "dp_any", "need_packet", "toserver", "toclient", "prefilter" ], "pkt_engines": [ { "name": "payload", "is_mpm": true } ], "frame_engines": [], "lists": { "payload": { "matches": [ { "name": "content", "content": { "pattern": "abc", "length": 3, "nocase": false, "negated": false, "starts_with": true, "ends_with": false, "is_mpm": true, "no_double_inspect": false, "depth": 3, "fast_pattern": false, "relative_next": false } } ] } }, "mpm": { "buffer": "payload", "pattern": "abc", "length": 3, "nocase": false, "negated": false, "starts_with": true, "ends_with": false, "is_mpm": true, "no_double_inspect": false, "depth": 3, "fast_pattern": false, "relative_next": false } } .. _ip-only-rule-type: 仅IP ^^^^^^^ 当规则仅匹配源和目标IP地址,且不含其他流或内容修饰符时使用此类型。 示例 """""""" .. container:: example-rule alert tcp-stream :example-rule-emphasis:`any` any -> :example-rule-emphasis:`any` any (msg:"tcp-stream, 无内容"; sid:101;) .. container:: example-rule alert tcp-pkt :example-rule-emphasis:`[192.168.0.0/16,10.0.0.0/8,172.16.0.0/12]` any -> :example-rule-emphasis:`any` any (msg:"tcp-pkt, 无内容"; sid:201;) .. container:: example-rule alert ip :example-rule-emphasis:`any` any -> :example-rule-emphasis:`any` any (:example-rule-emphasis:`hostbits:set,myflow2;` sid:1505;) .. container:: example-rule alert udp :example-rule-emphasis:`any` any -> :example-rule-emphasis:`any` any (msg:"带流方向的UDP"; sid:1601;) 引擎分析报告 """""""""""""""""""""" .. code-block:: json { "raw": "alert ip any any -> any any (hostbits:set,myflow2; sid:1505;)", "id": 1505, "gid": 1, "rev": 0, "app_proto": "unknown", "requirements": [], "type": "ip_only",