You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 04:55:18