.. role:: example-rule-action .. role:: example-rule-header .. role:: example-rule-options .. role:: example-rule-emphasis

10.83. 规则类型与分类

解析完成后,Suricata规则会根据性能和处理需求进行分类(不同规则类型由特定引擎模块处理)。签名类型定义在`src/detect.h <https://github.com/OISF/suricata/blob/master/src/detect.h>`_中:

src/detect.h
enum SignatureType {
    SIG_TYPE_NOT_SET = 0,
    SIG_TYPE_IPONLY,      // rule is handled by IPONLY engine
    SIG_TYPE_LIKE_IPONLY, // rule is handled by pkt engine, has action effect like ip-only
    /** Proto detect only signature.
     *  Inspected once per direction when protocol detection is done. */
    SIG_TYPE_PDONLY, // rule is handled by PDONLY engine
    SIG_TYPE_DEONLY,
    SIG_TYPE_PKT,
    SIG_TYPE_PKT_STREAM,
    SIG_TYPE_STREAM,

    SIG_TYPE_APPLAYER, // app-layer but not tx, e.g. appproto
    SIG_TYPE_APP_TX,   // rule is handled by TX engine

    SIG_TYPE_MAX,
};

更易读的表述如下:

Suricata规则类型及其引擎分析术语

规则类型

代码符号

引擎分析表示

仅解码事件

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() <https://github.com/OISF/suricata/blob/master/src/detect-engine-build.c#L1642-L1704>`_中实现。

``SignatureSetType()``的整体流程如下:

表示SignatureSetType函数的流程图。

扩展未覆盖函数或算法部分的流程图详见 detailed-flowcharts-sig-type 部分。

下表列出所有Suricata签名类型及其对上述方面的影响。

Suricata规则类型

类型

动作范围

检测钩子

暴露数据

关键词示例

(非穷举)

仅解码事件

(de_only)

数据包

每个损坏/无效数据包

解码事件

decode-event

数据包

(pkt)

数据包

每个数据包

数据包级信息(如:头部信息)

tcp-pkt, itype, tcp.hdr, tcp.seq, ttl

仅IP

(ip_only)

流(若存在)。数据包(若不属流)

每个方向一次

流上的IP地址

规则的源/目标字段

仅IP(含否定地址) 2

(like_ip_only)

所有数据包

流上的IP地址

含否定地址的规则源/目标字段

仅协议检测

(pd_only)

协议检测完成时每个方向一次

流检测到的协议

app-layer-protocol

数据包流

(pkt_stream)

流(若状态化):sup:1

每个流块(若状态化),否则每个数据包

(流负载和/或数据包负载)

重组流及/或负载数据

带``startswith``或``depth``的``content``

(stream)

流(若状态化):sup:1

流块(若状态化),否则仅数据包

流重组负载或数据包负载数据

协议字段中的``tcp-stream``;简单``content``;byte_extract

应用层协议

(app_layer)

每个数据包

规则中的'protocol'字段

规则的`协议字段 <https://suri-rtd-test.readthedocs.io/en/doc-sigtypes-et-properties-v5/rules/intro.html#protocol>`_

应用层协议事务

(app_tx)

每次 事务 更新

缓冲区关键词

应用层协议相关,如``http.host``, rfb.secresult, dcerpc.stub_data, ``frame``关键词

Note

动作范围:流(若状态化)

  1. 应用于流。若因任何原因(如数据包异常、错误、达到内存限制等)未接受段入流,规则将在数据包级应用。

Warning

尽管两者都涉及应用层协议匹配,但如表格所示,自Suricata 7起,使用``app-layer-protocol``关键词的协议检测规则在内部分类上与仅在``protocol``字段匹配应用层协议的规则不同。

10.83.1. 签名属性

上述`动作范围`与签名属性相关,见`src/detect-engine.c <https://github.com/OISF/suricata/blob/master/src/detect-engine.c>`_:

src/detect-engine.c
const struct SignatureProperties signature_properties[SIG_TYPE_MAX] = {
    /* SIG_TYPE_NOT_SET */      { SIG_PROP_FLOW_ACTION_PACKET, },
    /* SIG_TYPE_IPONLY */       { SIG_PROP_FLOW_ACTION_FLOW, },
    /* SIG_TYPE_LIKE_IPONLY */  { SIG_PROP_FLOW_ACTION_FLOW, },
    /* SIG_TYPE_PDONLY */       { SIG_PROP_FLOW_ACTION_FLOW, },
    /* SIG_TYPE_DEONLY */       { SIG_PROP_FLOW_ACTION_PACKET, },
    /* SIG_TYPE_PKT */          { SIG_PROP_FLOW_ACTION_PACKET, },
    /* SIG_TYPE_PKT_STREAM */   { SIG_PROP_FLOW_ACTION_FLOW_IF_STATEFUL, },
    /* SIG_TYPE_STREAM */       { SIG_PROP_FLOW_ACTION_FLOW_IF_STATEFUL, },
    /* SIG_TYPE_APPLAYER */     { SIG_PROP_FLOW_ACTION_FLOW, },
    /* SIG_TYPE_APP_TX */       { SIG_PROP_FLOW_ACTION_FLOW, },
};

10.83.1.1. 签名:需要真实数据包

除签名动作范围外,某些规则条件要求其匹配*真实数据包*(而非*伪数据包*)。这些规则会被引擎标记``SIG_MASK_REQUIRE_REAL_PKT``,并在规则的``requirements``中列出``real_pkt``。(参见 数据包 规则类型的``engine-analysis``示例输出。)

*伪数据包*是引擎在流结束但仍有数据处理时使用的内部资源,如流超时。此时会注入伪造数据包以完成处理。

这两类将很快有更多文档(跟踪`#7424 <https://redmine.openinfosecfoundation.org/issues/7424>`_)。

10.83.2. 签名类型与变量类关键词

诸如流变量(flowint, flowbits)、``datasets``等类似关键词若出现在签名中,可能改变规则类型。

这是因为变量条件可能随数据包变化。因此,签名被分类为`数据包`规则。

影响以下规则类型:
  • 应用层 (app_layer)

  • 仅协议检测 (pd_only)

  • 仅解码事件 (de_only)

  • 仅IP (ip_only) 3

  • 类仅IP (like_ip_only) 3

后续示例规则涵盖部分情况,下表详细列出这些关键词:

变量类关键词

关键词

关键词选项

规则类型变化?

flow

to_server, to_client

无类型变化 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

  1. 与其他受影响类型不同,原本分类为``ip_only``或``like_ip_only``的签名若使用``flow``关键词(无论选项)将变为数据包规则。

Note

``dataset``虽看似类似上述关键词,但不在此列,因其仅能与粘性缓冲区关键词共用,故仅适用于应用层事务规则(app_tx),不受此影响。

10.83.2.1. Flowbits: isset

若非状态化规则(如``pkt``规则)检查``flowbit``是否设置(如*flowbits:fb6,isset*),而设置该变量的规则是状态化规则(如``app_tx``规则),引擎将设置标志表明该规则也是状态化——但不改变其签名类型。当前标志为``SIG_FLAG_INIT_STATE_MATCH``(参见工单`#7483 <https://redmine.openinfosecfoundation.org/issues/7483>`_)。

正在添加此信息至``engine-analysis``报告(工单`#7456 <https://redmine.openinfosecfoundation.org/issues/7456>`_)。

10.83.3. 各类型签名

本节简要描述每种规则类型,并展示示例。可通过在:ref:`引擎分析模式 <config:engine-analysis>`下运行Suricata了解签名类型及其他重要信息。

每种规则类型还包含一个或多个规则的引擎分析报告示例。

10.83.3.1. 仅解码事件

检查损坏或无效数据包的签名。暴露Suricata解码事件。

更多示例见https://github.com/OISF/suricata/blob/master/rules/decoder-events.rules。

10.83.3.1.1. 示例

alert pkthdr any any -> any any (msg:"SURICATA IPv6重复Hop-By-Hop选项扩展头"; decode-event:ipv6.exthdr_dupl_hh; classtype:protocol-command-decode; sid:1101;)

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;)

10.83.3.1.2. 引擎分析报告

{
  "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"
        }
      ]
    }
  }
}

10.83.3.2. 数据包

暴露/检查数据包级信息(如头部)的规则。某些流关键词若需逐包检查也可能将规则转为``pkt``规则(参见:ref:variable-like-keywords-sig-type)。

10.83.3.2.1. 示例

alert tcp-pkt any any -> any any (msg:"tcp-pkt, 锚定内容"; content:"abc"; startswith; sid:203;)

alert tcp any any -> any any (msg:"ttl"; ttl:123; sid:701;)

alert udp any any -> any any (msg:"带流方向的UDP"; flow:to_server; sid:1001;)

alert tcp any any -> any 443 (flow: to_server; flowbits:set,tls_error; sid:1604; msg:"允许TLS错误处理(出站数据包)- 非状态化规则";)

alert tcp-pkt any any -> any any (msg:"Flowbit isset"; flowbits:isset,fb6; flowbits:isset,fb7; sid:1919;)

10.83.3.2.2. 引擎分析报告

{
  "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
  }
}

10.83.3.3. 仅IP

当规则仅匹配源和目标IP地址,且不含其他流或内容修饰符时使用此类型。

10.83.3.3.1. 示例

alert tcp-stream any any -> any any (msg:"tcp-stream, 无内容"; sid:101;)

alert tcp-pkt [192.168.0.0/16,10.0.0.0/8,172.16.0.0/12] any -> any any (msg:"tcp-pkt, 无内容"; sid:201;)

alert ip any any -> any any (hostbits:set,myflow2; sid:1505;)

alert udp any any -> any any (msg:"带流方向的UDP"; sid:1601;)

10.83.3.3.2. 引擎分析报告

{
  "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",