10.1. 规则格式¶
签名在Suricata中扮演着非常重要的角色。大多数情况下,人们会使用现有的规则集。
官方安装规则集的方法在 使用 Suricata-Update 管理规则 中有描述。
通过suricata-update可以使用许多免费规则集。为了帮助学习编写规则,Emerging Threats Open规则集是免费的,并且是一个很好的参考,包含了广泛的签名示例。
这份Suricata规则文档详细解释了签名;如何阅读、调整和创建它们。
一个规则/签名由以下部分组成:
动作,决定规则匹配时会发生什么。
头部,定义协议、IP地址、端口和规则的方向。
规则选项,定义规则的具体内容。
以下是一个规则的示例:
alert http $HOME_NET any -> $EXTERNAL_NET any
在这个示例中,红色 是动作, 绿色 是头部, 是选项。
我们将使用上述签名作为本节示例,突出签名的不同部分。
10.1.1. 动作¶
alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP GET Request Containing Rule in URI"; flow:established,to_server; http.method; content:"GET"; http.uri; content:"rule"; fast_pattern; classtype:bad-unknown; sid:123; rev:1;)
有效的动作包括:
alert - 生成警报。
pass - 停止进一步检查数据包。
drop - 丢弃数据包并生成警报。
reject - 向匹配数据包的发送者发送RST/ICMP不可达错误。
rejectsrc - 与 reject 相同。
rejectdst - 向匹配数据包的接收者发送RST/ICMP错误数据包。
rejectboth - 向对话双方发送RST/ICMP错误数据包。
Note
在IPS模式下,使用任何 reject 动作也会启用 drop。
更多信息请参见 动作顺序。
10.1.2. 协议¶
alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP GET Request Containing Rule in URI"; flow:established,to_server; http.method; content:"GET"; http.uri; content:"rule"; fast_pattern; classtype:bad-unknown; sid:123; rev:1;)
签名中的这个关键字告诉Suricata它涉及哪个协议。您可以在四种基本协议之间选择:
tcp(用于tcp流量)
udp
icmp
ip(ip代表“全部”或“任意”)
还有一些与TCP相关的额外协议选项:
tcp-pkt(用于匹配单个tcp数据包中的内容)
tcp-stream(仅用于匹配重组后的tcp流中的内容)
还有一些所谓的应用层协议或第7层协议可供选择。这些包括:
http(HTTP1或HTTP2)
http1
http2
ftp
tls(包括ssl)
smb
dns
dcerpc
dhcp
ssh
smtp
imap
pop3
modbus(默认禁用)
dnp3(默认禁用)
enip(默认禁用)
nfs
ike
krb5
bittorrent-dht
ntp
dhcp
rfb
rdp
snmp
tftp
sip
websocket
这些协议的可用性取决于配置文件suricata.yaml中是否启用了该协议。
如果您的签名中协议声明为'http',Suricata会确保该签名仅在TCP流中包含http流量时匹配。
10.1.3. 源和目标¶
alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP GET Request Containing Rule in URI"; flow:established,to_server; http.method; content:"GET"; http.uri; content:"rule"; fast_pattern; classtype:bad-unknown; sid:123; rev:1;)
第一个突出部分是流量源,第二个是流量目标(注意方向箭头的方向)。
通过源和目标,您可以分别指定流量的来源和目的地。您可以分配IP地址(支持IPv4和IPv6)和IP范围。这些可以与操作符结合使用:
操作符 |
描述 |
---|---|
../.. |
IP范围(CIDR表示法) |
! |
例外/否定 |
[.., ..] |
分组 |
通常,您还会使用变量,如 $HOME_NET
和 $EXTERNAL_NET
。suricata.yaml配置文件指定了这些变量涉及的IP地址。相应的 $HOME_NET
和 $EXTERNAL_NET
设置将替换规则中的变量。
更多信息请参见 suricata-yaml-rule-vars。
规则使用示例:
示例 |
含义 |
---|---|
!1.1.1.1 |
除1.1.1.1外的所有IP地址 |
![1.1.1.1, 1.1.1.2] |
除1.1.1.1和1.1.1.2外的所有IP地址 |
$HOME_NET |
yaml中设置的HOME_NET |
[$EXTERNAL_NET, !$HOME_NET] |
EXTERNAL_NET且不包括HOME_NET |
[10.0.0.0/24, !10.0.0.5] |
10.0.0.0/24,不包括10.0.0.5 |
[..., [....]] |
|
[..., ![.....]] |
Warning
如果您将配置设置为如下内容::
HOME_NET: any EXTERNAL_NET: !$HOME_NET
您不能使用 $EXTERNAL_NET
编写签名,因为它会评估为“非任意”,这是一个无效值。
Note
请注意,源和目标地址也可以通过 ip.src
和 ip.dst
关键字匹配(参见 ipaddr)。这些关键字通常与数据集功能一起使用(参见 datasets)。
10.1.4. 端口(源和目标)¶
alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP GET Request Containing Rule in URI"; flow:established,to_server; http.method; content:"GET"; http.uri; content:"rule"; fast_pattern; classtype:bad-unknown; sid:123; rev:1;)
第一个突出部分是源端口,第二个是目标端口(注意方向箭头的方向)。
流量通过端口进出。不同的协议有不同的端口号。例如,HTTP的默认端口是80,而443通常是HTTPS的端口。但请注意,端口并不决定通信中使用的协议,而是决定哪个应用程序接收数据。
上述端口通常是目标端口。源端口,即发送数据包的应用程序,通常由操作系统分配一个随机端口。当为您自己的HTTP服务编写规则时,通常会写 any -> 80
,因为这意味着从任何源端口到您的HTTP应用程序(运行在端口80上)的数据包都会被匹配。
在设置端口时,您也可以使用特殊操作符。操作符如:
操作符 |
描述 |
---|---|
: |
端口范围 |
! |
例外/否定 |
[.., ..] |
分组 |
规则使用示例:
示例 |
含义 |
---|---|
[80, 81, 82] |
端口80、81和82 |
[80: 82] |
从80到82的范围 |
[1024: ] |
从1024到最高端口号 |
!80 |
除80外的所有端口 |
[80:100,!99] |
从80到100的范围,不包括99 |
[1:80,![2,4]] |
从1到80的范围,不包括端口2和4 |
[.., [..,..]] |
10.1.5. 方向¶
alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP GET Request Containing Rule in URI"; flow:established,to_server; http.method; content:"GET"; http.uri; content:"rule"; fast_pattern; classtype:bad-unknown; sid:123; rev:1;)
方向箭头指示签名将被评估的方向。在大多数签名中,使用向右的箭头(->
)。这意味着只有具有相同方向的数据包才能匹配。
还有双箭头(=>
),它像 ->
一样尊重方向性,但允许匹配双向事务,与匹配每个方向的关键字一起使用。
最后,也可以让规则匹配任一方向(<>
)::
source -> destination source => destination source <> destination (任一方向)
以下示例说明了方向。在这个示例中,有一个IP地址为1.2.3.4的客户端使用端口1024。一个IP地址为5.6.7.8的服务器监听端口80(通常是HTTP)。客户端向服务器发送消息,服务器回复其答案。

现在,假设我们有一个规则,其头部如下::
alert tcp 1.2.3.4 1024 -> 5.6.7.8 80
只有从客户端到服务器的流量会被此规则匹配,因为方向指定了我们不想评估响应数据包。
现在,如果我们有一个规则,其头部如下::
alert tcp 1.2.3.4 any <> 5.6.7.8 80
Suricata会复制它,并在两个方向上使用相同的规则头部:
alert tcp 1.2.3.4 any -> 5.6.7.8 80 alert tcp 5.6.7.8 80 -> 1.2.3.4 any
Warning
没有“反向”风格的方向,即没有 <-
。
10.1.5.1. 事务性规则¶
以下是一个事务性规则的示例:
alert http any any => 5.6.7.8 80 (msg:"matching both uri and status"; sid: 1; http.uri; content: "/download"; http.stat_code; content: "200";)
它将匹配流向5.6.7.8和端口80的流量。 并且它将匹配完整的事务,使用请求中的uri和响应中的stat_code。 因此,只有当Suricata同时获取请求和响应时才会匹配。
事务性规则可以使用方向模糊的关键字,通过指定方向。
alert http any any => 5.6.7.8 80 (msg:"matching json to server and xml to client"; sid: 1; http.content_type: to_server; content: "json"; http.content_type: to_client; content: "xml";)
事务性规则有一些限制:
它们不能使用方向模糊的关键字。
它们仅适用于首先向服务器发送请求,然后向客户端发送响应的事务,而不是相反(未经测试)。
如果它们还在服务器方向上有流缓冲区,则不能有
fast_pattern
或prefilter
到客户端方向,参见下面的示例。如果单个方向性规则足够,它们将拒绝加载。
此规则不能有 fast_pattern
到客户端,因为 file.data
是一个流缓冲区,并且会拒绝加载。
alert http any any => any any (file.data: to_server; content: "123"; http.stat_code; content: "500"; fast_patten;)
如果没有明确指定,事务性规则将默认选择服务器方向的 fast_pattern
。
10.1.6. 规则选项¶
规则的其余部分由选项组成。这些选项用括号括起来,并用分号分隔。一些选项有设置(如 msg
),由选项的关键字后跟冒号和设置指定。其他选项没有设置;它们只是关键字(如 nocase
)::
<关键字>: <设置>; <关键字>;
规则选项有特定的顺序,改变它们的顺序会改变规则的含义。
Note
字符 ;
和 "
在Suricata规则语言中有特殊含义,必须在规则选项值中转义。例如::
msg:"Message with semicolon;";
因此,您还必须转义反斜杠,因为它作为转义字符。
本文档的其余部分记录了各种关键字的使用。
以下是一些关于关键字的通用细节。
10.1.6.1. 禁用警报¶
有一种方法可以使用关键字 noalert
禁用规则的警报生成。当此关键字是规则的一部分时,如果规则的其他部分匹配,则不会生成警报。也就是说,其他规则动作 仍将被应用。使用 noalert
可以帮助规则使用 flowbits、datasets 或其他规则语言的状态维护构造来收集或设置状态。参见 阈值设置关键词 了解其他控制警报频率的方法。
以下规则展示了 noalert
的熟悉模式:
第一条规则标记状态而不生成警报。
第二条规则如果状态已设置且满足其他条件,则生成警报。
alert http any any -> $HOME_NET any
alert http any any -> $HOME_NET any
在IPS模式下,noalert
通常用于Suricata应 drop 网络数据包而不生成警报的情况(如下示例)。以下规则是一个简化示例,展示了 noalert
如何在IPS部署中用于丢弃入站SSH请求。
drop tcp any any -> any 22
10.1.6.2. 修饰关键字¶
一些关键字作为修饰符。有两种类型的修饰符。
较旧风格的 '内容修饰符' 会回溯规则,例如::
alert http any any -> any any (content:"index.php"; http_uri; sid:1;)
在上面的示例中,模式'index.php'被修改为检查HTTP uri缓冲区。
较新的类型称为 '粘性缓冲区'。它将缓冲区名称放在前面,所有后续关键字都应用于该缓冲区,例如::
alert http any any -> any any (http_response_line; content:"403 Forbidden"; sid:1;)
在上面的示例中,模式'403 Forbidden'被检查HTTP响应行,因为它跟在
http_response_line
关键字之后。
10.1.6.3. 规范化缓冲区¶
数据包由原始数据组成。HTTP和重组会复制这些类型的数据包数据。它们会消除异常内容,合并数据包等。剩下的被称为“规范化缓冲区”:

因为数据被规范化,所以它不再是原来的样子;它是一种解释。规范化缓冲区包括:所有HTTP关键字、重组流、TLS、SSL、SSH、FTP和dcerpc缓冲区。
请注意,有一些例外,例如 http_raw_uri
关键字。更多信息请参见 http.uri。