如何在Suricata的Lua脚本中获取Community ID
在Lua脚本中获取Suricata元组的Community ID实现方法
方法1:调用Suricata内置的Community ID生成函数
Suricata 5.0+版本提供了Lua绑定支持直接生成Community ID,你可以在脚本中通过C模块调用相关函数,示例代码如下:
-- 初始化Community ID生成器(可自定义seed,默认使用Suricata内置值) local cid_generator = C.communityid_new() -- 针对TCP流元组生成Community ID -- 参数顺序:协议号(6=TCP/17=UDP)、源IP、源端口、目的IP、目的端口 local community_id = C.communityid_calc(cid_generator, 6, "192.168.1.100", 12345, "10.0.0.5", 80) -- 输出或使用生成的ID print(community_id) -- 释放资源 C.communityid_free(cid_generator)
注意:确保你的Suricata编译时启用了Lua支持,否则无法使用该绑定。
方法2:手动实现Community ID算法
如果无法调用内置函数,可以自行实现核心逻辑——先标准化流元组(消除方向影响),再通过HMAC-SHA1生成ID。示例依赖luacrypto库,需提前安装:
local crypto = require("crypto") local function generate_community_id(protocol, src_ip, src_port, dst_ip, dst_port, seed) seed = seed or "SuricataCommunityID" -- 和Suricata默认seed保持一致 -- 标准化元组:按IP字符串排序,IP相同则按端口排序 local ip_a, port_a, ip_b, port_b if src_ip < dst_ip or (src_ip == dst_ip and src_port < dst_port) then ip_a, port_a = src_ip, src_port ip_b, port_b = dst_ip, dst_port else ip_a, port_a = dst_ip, dst_port ip_b, port_b = src_ip, src_port end -- 将IPv4地址转为字节串(大端序) local function ip_to_bytes(ip) local bytes = {} for octet in ip:gmatch("%d+") do table.insert(bytes, string.char(tonumber(octet))) end return table.concat(bytes) end -- 将端口转为2字节大端序 local function port_to_bytes(port) return string.char(math.floor(port / 256)) .. string.char(port % 256) end -- 构造哈希输入 payload local payload = string.char(protocol) .. ip_to_bytes(ip_a) .. port_to_bytes(port_a) .. ip_to_bytes(ip_b) .. port_to_bytes(port_b) -- 生成HMAC-SHA1哈希 local hmac = crypto.hmac.digest("sha1", payload, seed, true) -- 取前16字节转base64,添加标准前缀"1:" local base64_str = crypto.util.encodeBase64(hmac:sub(1, 16)) return "1:" .. base64_str end -- 使用示例 local cid = generate_community_id(6, "192.168.1.100", 12345, "10.0.0.5", 80) print(cid)
如果需要支持IPv6,需扩展ip_to_bytes函数处理IPv6地址的字节转换,确保和Suricata逻辑一致。
方法3:从Suricata日志中直接提取
如果你的Lua脚本是处理Suricata的EVE日志,可以先在Suricata配置中启用Community ID输出(在eve-log配置里添加community-id: true),之后在脚本读取日志时直接提取community_id字段即可,无需重新生成。
内容的提问来源于stack exchange,提问作者Vignesh
相关产品推荐
相关产品推荐

