一、環境和背景
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的值