suricata學習筆記1--初步認識


1、前言
  最近工作需要對網站的關鍵字進行檢測,找出敏感詞。這個過程需要對報文進行收集、解碼、檢測和記錄日志。當前只是簡單實現功能,根據關鍵字進行簡單的匹配,而沒有進行關鍵字的語義分析。導致的結果就是JAVA可以匹配AV這個敏感關鍵字。報文檢測這方面,開源項目已經做得非常好了,我所了解的有snort、suircata、bro,這三個都是非常優秀的IDS(入侵檢測系統)。由於對bro沒有深入了解,我們對比了snort和suricata,結合suricata的多線程和模塊化,全面兼容snort規則,我們選用了suricata進行關鍵字檢測。
  剛開始接觸suricata的時候,壓根不知道這個單詞怎么發音,於是乎趕緊再詞典上查一下。suircata是一款支持IDS、IPS和NSM的系統。關於suircata的詳細介紹可以參考官網:https://suricata-ids.org/
備注:
  IDS:英文“Intrusion Detection Systems”的縮寫,中文意思是“入侵檢測系統”。依照一定的安全策略,通過軟、硬件,對網絡、系統的運行狀況進行監視,盡可能發現各種攻擊企圖、攻擊行為或者攻擊結果,以保證網絡系統資源的機密性、完整性和可用性。
  IPS是英文“Intrusion Prevention System”的縮寫,中文意思是入侵防御系統。隨着網絡攻擊技術的不斷提高和網絡安全漏洞的不斷發現,傳統防火牆技術加傳統IDS的技術,已經無法應對一些安全威脅。在這種情況下,IPS技術應運而生,IPS技術可以深度感知並檢測流經的數據流量,對惡意報文進行丟棄以阻斷攻擊,對濫用報文進行限流以保護網絡帶寬資源。
  NSM:英文“network security monitoring”的縮寫,中文意思是“網絡安全監控”。
2、總體架構
  報文檢測系統通常四大部分,報文獲取、報文解碼、報文檢測、日志記錄;suricata不同的功能安裝模塊划分,一個模塊的輸出是另一個模塊的輸入,suricata通過線程將模塊串聯起來。

  接下來以IDS為例來說明suircata的線程與模塊之間是如何連接起來的。
  首先注冊runmods,運行方式指定suricata獲取報文的方式,例如libpcap、netmap、af-packet等,代碼如下圖所示:

 

  然后再根據設置suricata的工作模式,找到對應獲取報文的處理模塊。suircata默認是通過af-packet mmap獲取報文,然后調用獲取報文模塊當然入口函數,
入口函數中函數添加了解碼模塊、流處理模塊(檢測報文)、日志處理模塊。通過slot鏈條安裝注冊順序串聯起來。每一個線程都包含一個slot的鏈表,每個結點都懸掛着不同的模塊,程序執行的時候會遍歷slot鏈表,按照加入鏈表的熟悉執行模塊。

創建線程,並將模塊添加到slot鏈表過程代碼如下所示:

 1 /* create the threads */
 2 for (thread = 0; thread < threads_count; thread++) {
 3         char tname[TM_THREAD_NAME_MAX];
 4         ThreadVars *tv = NULL;
 5         TmModule *tm_module = NULL;
 6         const char *visual_devname = LiveGetShortName(live_dev);
 7 
 8         if (single_mode) {
 9             snprintf(tname, sizeof(tname), "%s#01-%s", thread_name, visual_devname);
10         } else {
11             snprintf(tname, sizeof(tname), "%s#%02d-%s", thread_name,
12                      thread+1, visual_devname);
13         }
14         tv = TmThreadCreatePacketHandler(tname,
15                 "packetpool", "packetpool",
16                 "packetpool", "packetpool",
17                 "pktacqloop");
18         if (tv == NULL) {
19             SCLogError(SC_ERR_THREAD_CREATE, "TmThreadsCreate failed");
20             exit(EXIT_FAILURE);
21         }
22 
23         //添加收包模塊
24         tm_module = TmModuleGetByName(recv_mod_name);
25         if (tm_module == NULL) {
26             SCLogError(SC_ERR_INVALID_VALUE, "TmModuleGetByName failed for %s", recv_mod_name);
27             exit(EXIT_FAILURE);
28         }
29         TmSlotSetFuncAppend(tv, tm_module, aconf);
30         //添加解包模塊
31         tm_module = TmModuleGetByName(decode_mod_name);
32         if (tm_module == NULL) {
33             SCLogError(SC_ERR_INVALID_VALUE, "TmModuleGetByName %s failed", decode_mod_name);
34             exit(EXIT_FAILURE);
35         }
36         TmSlotSetFuncAppend(tv, tm_module, NULL);
37         //添加流處理模塊,用於檢測報文
38         tm_module = TmModuleGetByName("FlowWorker");
39         if (tm_module == NULL) {
40             SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName for FlowWorker failed");
41             exit(EXIT_FAILURE);
42         }
43         TmSlotSetFuncAppend(tv, tm_module, NULL);
44        //添加阻斷模塊
45         tm_module = TmModuleGetByName("RespondReject");
46         if (tm_module == NULL) {
47             SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName RespondReject failed");
48             exit(EXIT_FAILURE);
49         }
50         TmSlotSetFuncAppend(tv, tm_module, NULL);
51         //添加日志處理模塊
52         SetupOutputs(tv);
53 
54         TmThreadSetCPU(tv, WORKER_CPU_SET);
55 
56         if (TmThreadSpawn(tv) != TM_ECODE_OK) {
57             SCLogError(SC_ERR_THREAD_SPAWN, "TmThreadSpawn failed");
58             exit(EXIT_FAILURE);
59         }
60 }
61         

在AF-PACKET工作模式下提供三種工作方式:

關於工作方式可以參考:http://blog.csdn.net/firedb/article/details/7581853。
目前我只用過worker工作模式,整個流程通過一個線程來處理。

3、總結

  這是目前對suricata的一個整體的認識,接下來認真研究每個模塊之間是如何交互。需要深入學習suricata是如何收集報文,如何將收集的報文傳遞給解碼模塊,解碼模塊做哪些工作,輸出是什么。

suricata各模塊功能:
  Receive:從NFQUEUE中接收數據包,並將封裝在Packet結構中,然后放入下一個緩沖區。
  Decode:對數據包進行解碼,主要是對數據包頭部信息進行分析並保存在Packet結構中。
  StreamTCP:對數據包進行TCP流重組。
  Detect:檢測數據包是否包含入侵行為。
  Verdict:對檢測后的數據包進行判定,並將判定結果告訴內核(通過ipq_set_verdict函數),方便內核對數據包進行接收、丟棄等處理。
  RespondReject:通過libnet對那些要執行Reject操作的數據包進行相應的回應。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM