流 ---- 流信息通过 ``suricata.flow`` 库暴露给 Lua 脚本。使用时需要先引入该库,例如:: local flow = require("suricata.flow") 以下是当前可用的流信息访问函数。 初始化 ~~~~~~~~~~~~~~ ``get`` ^^^^^^^ 初始化当前引擎正在处理的流对象以供脚本使用:: f = flow.get() 时间相关 ~~~~ ``timestamps`` ^^^^^^^^^^^^^^ 获取流中首尾数据包的时间戳(以UTC时间`1970-01-01 00:00:00`为基准的秒和微秒值),返回4个数值:: f = flow.get() local start_sec, start_usec, last_sec, last_usec = f:timestamps() ``timestring_legacy`` ^^^^^^^^^^^^^^^^^^^^^ 获取流中首个数据包的时间戳字符串,格式为:`11/24/2009-18:57:25.179869`。该格式与`fast.log`、`http.log`等传统输出格式一致:: f = flow.get() print f:timestring_legacy() ``timestring_iso8601`` ^^^^^^^^^^^^^^^^^^^^^^ 获取流中首个数据包的时间戳字符串,格式为:`2015-10-06T15:16:43.136733+0000`。该格式与EVE输出格式一致:: f = flow.get() print f:timestring_iso8601() 端口与地址 ~~~~~~~~~~~~~~~~~~~ ``tuple`` ~~~~~~~~~ 通过`tuple`方法获取IP版本号(4或6)、源IP/目的IP(字符串形式)、IP协议号(整型)及端口号(整型)。 协议号取自IP头,详见:https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml :: f = flow.get() ipver, srcip, dstip, proto, sp, dp = f:tuple() 应用层协议 ~~~~~~~~~~~~~~~~~~~ ``app_layer_proto`` ^^^^^^^^^^^^^^^^^^^ 获取流的`alproto`字符串(若未知则返回"unknown")。返回5个值:, , , , 。 示例:: f = flow.get() alproto, alproto_ts, alproto_tc, alproto_orig, alproto_expect = f:app_layer_proto() `orig`和`expect`用于协议变更场景。例如SMTP STARTTLS场景中,`orig`通常为"smtp"而`expect`为"tls"。 其他功能 ~~~~ ``has_alerts`` ^^^^^^^^^^^^^^ 若流中存在告警则返回`true`:: f = flow.get() alerted = f:has_alerts() ``id`` ^^^^^^ 获取流ID。注意直接打印`id`可能输出科学计数法,建议使用以下方式:: f = flow.get() id = f:id() id_str = string.format("%.0f", id) print ("Flow ID: " .. id_str .."\n") ``stats`` ^^^^^^^^^ 获取流中双向数据包计数和字节数(返回4个数值):: f = flow.get() tscnt, tsbytes, tccnt, tcbytes = f:stats() 示例 ~~~~~~~ 一个简单的日志函数,在流触发告警时输出流详情:: function log(args) local f = flow.get() ts = f:timestring_iso8601() has_alerts = f:has_alerts() ipver, srcip, dstip, proto, sp, dp = f:tuple() alproto, alproto_ts, alproto_tc, alproto_orig, alproto_expect = f:app_layer_proto() start_sec, start_usec, last_sec, last_usec = f:timestamps() id = f:id() if has_alerts then file:write ("[**] Start time " .. ts .. " [**] -> alproto " .. alproto .. " [**] " .. proto .. " [**] alerted: true\n[**] First packet: " .. start_sec .." [**] Last packet: " .. last_sec .. " [**] Flow id: " .. id .. "\n") file:flush() end end 完整脚本示例可参考Suricata-verify项目:https://github.com/OISF/suricata-verify/tree/master/tests