20.3.21. 数据包¶
可以通过 suricata.packet
库将数据包暴露给 Lua 脚本。例如:
local packet = require("suricata.packet")
20.3.21.1. 初始化¶
20.3.21.1.1. get
¶
初始化数据包以便在脚本中使用。该数据包是引擎当前正在处理的数据包。
p = packet.get()
20.3.21.2. 时间¶
20.3.21.2.1. timestamp
¶
获取数据包时间戳,返回两个数字:自 1970-01-01 00:00:00 UTC 以来的秒数和微秒数。
p = packet.get()
local sec, usec = p:timestamp()
20.3.21.2.2. timestring_legacy
¶
获取数据包时间戳,格式为:11/24/2009-18:57:25.179869。这是 fast.log、http.log 和其他传统输出使用的格式。
p = packet.get()
print p:timestring_legacy()
20.3.21.2.3. timestring_iso8601
¶
获取数据包时间戳,格式为:2015-10-06T15:16:43.137833+0000。这是 eve 使用的格式。
p = packet.get()
print p:timestring_iso8601()
20.3.21.3. 端口和地址¶
20.3.21.3.1. tuple
¶
使用 tuple 方法可以获取 IP 版本(4 或 6)、源 IP 和目标 IP(作为字符串)、IP 协议(整数)以及端口(整数)。
协议值来自 IP 头,详见 https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml
p = packet.get()
ipver, srcip, dstip, proto, sp, dp = p:tuple()
如果协议是 ICMPv4 或 ICMPv6,即当 proto == 1 或 proto == 58 时,最后两个结果是 icmp 类型 和 icmp 代码。
p = packet.get()
ipver, srcip, dstip, proto, itype, icode = p:tuple()
if ipver == 6 and proto == 1 then
-- 奇怪,IPv6 上的 ICMPv4
return 1
end
20.3.21.3.2. sp
¶
获取数据包的 TCP、UDP 或 SCTP 源端口(整数)。对于其他协议返回 nil。
p = packet.get()
source_port = p:sp()
if source_port == 31337 then
return 1
end
20.3.21.3.3. dp
¶
获取数据包的 TCP、UDP 或 SCTP 目标端口(整数)。对于其他协议返回 nil。
p = packet.get()
dest_port = p:dp()
-- 不是 443 端口
if dest_port ~= 443 then
return 1
end
20.3.21.4. 数据¶
20.3.21.4.1. payload
¶
数据包的有效载荷。
payload = p:payload()
20.3.21.4.2. packet
¶
完整的数据包,包括 TCP、以太网、VLAN 等协议的头部。
raw_packet = p:packet()
20.3.21.5. 杂项¶
20.3.21.5.1. pcap_cnt
¶
从 pcap 文件读取时的数据包编号。
p = packet.get()
print p:pcap_cnt()
20.3.21.6. 示例¶
一个 match 函数示例,该函数接收一个数据包,逐行检查有效载荷,查找 HTTP 请求行。 如果找到,则记录一条 notice 日志,包含数据包详细信息。
local logger = require("suricata.log")
function match (args)
p = packet.get()
payload = p:payload()
ts = p:timestring()
for line in payload:gmatch("([^\r\n]*)[\r\n]+") do
if line == "GET /index.html HTTP/1.0" then
ipver, srcip, dstip, proto, sp, dp = p:tuple()
logger.notice(string.format("%s %s->%s %d->%d (pcap_cnt:%d) match! %s", ts, srcip, dstip, sp, dp, p:pcap_cnt(), line));
return 1
end
end
return 0
end