suricata之规则去重
一、环境和背景
1.1 环境
OS: Ubuntu 22.04.5 LTS
IDE: vscode
suricata: suricata 7.0.5
1.2 背景
在添加规则时,为了给规则分类,将不同类别的规则写入不同的文件。
在规则加载时两条不同的规则却被认为是重复的,因此记录一下去重逻辑。
a.rule
alert ip any any -> any any (msg:"SURICATA Applayer Mismatch protocol both directions"; flow:established; app-layer-event:applayer_mismatch_protocol_both_directions; flowint:applayer.anomaly.count,+,1; classtype:protocol-command-decode; sid:2260000; rev:1;)
b.rule
alert http any any -> any any (msg:"SURICATA HTTP unknown error"; flow:established; app-layer-event:http.unknown_error; flowint:http.anomaly.count,+,1; classtype:protocol-command-decode; sid:2260000; rev:1;)
suricata.yaml
rule-files:- a.rule- b.rule
二、 Suricata 规则去重
suricata 规则通过一个hashtable进行去重。
2.1 hashtable 建立
// src/suricata.c
PostConfLoadedDetectSetup// src/detect-engine.c-> DetectEngineCtxInit// src/detect-engine.c-> DetectEngineCtxInitReal// src/detect-parse.c-> DetectParseDupSigHashInit// src/suricata.c-> LoadSignatures
int DetectParseDupSigHashInit(DetectEngineCtx *de_ctx)
{de_ctx->dup_sig_hash_table = HashListTableInit(15000,DetectParseDupSigHashFunc,DetectParseDupSigCompareFunc,DetectParseDupSigFreeFunc);if (de_ctx->dup_sig_hash_table == NULL)return -1;return 0;
}
2.2 检测重复
// src/detect-parse.cSignature *DetectEngineAppendSig(DetectEngineCtx *de_ctx, const ch
{// 1. 解析规则Signature *sig = SigInit(de_ctx, sigstr);if (sig == NULL) {return NULL;}// 2. 检测重复/* checking for the status of duplicate signature */int dup_sig = DetectEngineSignatureIsDuplicate(de_ctx, sig);...
}static inline int DetectEngineSignatureIsDuplicate(DetectEngineCtxSignature *sig)
{/* we won't do any NULL checks on the args *//* return value */int ret = 0;SigDuplWrapper *sw_dup = NULL;SigDuplWrapper *sw = NULL;/* used for making a duplicate_sig_hash_table entry */sw = SCMalloc(sizeof(SigDuplWrapper));if (unlikely(sw == NULL)) {exit(EXIT_FAILURE);}memset(sw, 0, sizeof(SigDuplWrapper));sw->s = sig;/* check if we have a duplicate entry for this signature */sw_dup = HashListTableLookup(de_ctx->dup_sig_hash_table, (void *)sw, 0);/* we don't have a duplicate entry for this sig */if (sw_dup == NULL) {...}...
}
2.3 重复条件
static char DetectParseDupSigCompareFunc(void *data1, uint16_t len1, void *data2,uint16_t len2)
{SigDuplWrapper *sw1 = (SigDuplWrapper *)data1;SigDuplWrapper *sw2 = (SigDuplWrapper *)data2;if (sw1 == NULL || sw2 == NULL ||sw1->s == NULL || sw2->s == NULL)return 0;/* sid and gid match required */if (sw1->s->id == sw2->s->id && sw1->s->gid == sw2->s->gid) return 1;return 0;
}
以sid
和gid
作为重复条件,全部相等时则认为重复,不看具体的规则内容。
三、总结
- suricata规则通过
sid
和gid
进行去重,并不关注规则中的具体内容 - 通过
sid
和gid
唯一区分规则,整个工程里对规则的处理相较于字符串,整数值处理更简单高效 - 如果需要将规则拆分成多个文件时,需要注意sid的值