轉自:
http://blog.csdn.net/firedb/article/details/7581853 最近看了一下suricata-1.2.1的源代碼,加之之前在網上沒有搜到關于suricata的分析資料,所以就把看源碼時的一些筆記整理了一下,發到網上,供其他對suricata感興趣的網友參考。由于是第一次在csdn上寫技術博客,不足之處還望看到此文章的網友見諒!先還是進行簡要的介紹一下,Suricata 是一個網絡入侵檢測和阻止引擎,由開放信息安全基金會以及它說支持的提供商說開發。該引擎是多線程的,內置 IPv6 的支持,可加載預設規則,支持 Barnyard 和 Barnyard2 工具。
由于我只對Suricata的IPS模式感興趣,所以就只看了IpsNFQ的源代碼部分,但個人覺得,只要把一種模式看懂了,其它的模式理解起來就是順其自然的事情了,各模式之間最主要的不同就是數據包的來源不同。下面就開始對suricata的IpsNFQ模式進行分析。
1. IpsNFQ三種模式圖
IpsNFQ模式下還有三種模式,先來看看這三種模式的分析圖。
a) Auto模式

b) AutoFP模式

c) Worker模式

對上圖中的一些值說明一下。Queue數量是指NFQ的Queue數量;CPU數是指CPU的核心數;ratio是一個比率值,在suricata.yaml配置文件中設定,一般設置成0.5、1或1.5。
2. 各模塊功能分析
-
Receive:從NFQUEUE中接收數據包,并將封裝在Packet結構中,然后放入下一個緩沖區。
Decode:對數據包進行解碼,主要是對數據包頭部信息進行分析并保存在Packet結構中。
StreamTCP:對數據包進行TCP流重組。
Detect:檢測數據包是否包含入侵行為。
Verdict:對檢測后的數據包進行判定,并將判定結果告訴內核(通過ipq_set_verdict函數),方便內核對數據包進行接收、丟棄等處理。
RespondReject:通過libnet對那些要執行Reject操作的數據包進行相應的回應。
3. Tm-queue&Tm-queuehandler分析
3.1Tm-queue
Tm-queue是各個模塊(線程)之間傳遞數據的緩沖區(圖中橢圓),這在多線程編程中經常會被用到,用來緩存數據。在這里提醒一下,不要將這里的Tm-queue與NFQ中的Queue混淆了,后者是內核中的Queue(Netfilter Queue),這里的Tm-queue只是suricata各模塊間的緩沖區。
一個Tm-queue在程序中包括structTmq_和struct PacketQueue兩個結構,前者只存了簡單的信息,用于檢索,后者用于實際存儲數據包,兩者之間通過Tmq->id進行關聯。這兩個結構的定義分別如下:
Tm-queue.h:
typedef struct Tmq_ {
char *name;
uint16_t id;
uint16_t reader_cnt;
uint16_t writer_cnt;
/* 0 for packet-queue and1 for data-queue */
uint8_t q_type;
} Tmq;
Decode.h:
typedef struct PacketQueue_ {
Packet *top;
Packet *bot;
uint32_t len;
#ifdef DBG_PERF
uint32_t dbg_maxlen;
#endif /* DBG_PERF */
SCMutex mutex_q;
SCCondT cond_q;
} PacketQueue;
Tmq的創建是在程序調用TmThreadCreate()(Tm-threads.c)函數創建線程時調用TmqCreateQueue()(Tm-queues.c)函數進行創建。
在NFQ模式中用到的Tm-queue除了packetpool是循環隊列之外,其它的(pickup-queue、decode-queue等)都是FIFO隊列。所以,這里只對packetpool這個特例進行一下說明。
Packetpool這個Tm-queue其實在源碼中是用ringbuffer這個循環隊列表示,所以對packetpool的操作其實是在操作ringbuffer。Ringbuffer是存放Packet*指針的一個數組,數組的大小由max_pending_packets(在配置文件中配置,默認為50)的值決定。main()(suricata.c)函數對ringbuffer數組進行了初始化,創建一定數量的Packet,在程序的整個運行中循環使用,直到程序完全退出才釋放。
3.2 QueueHandler
QueueHandler是各緩沖區的操作接口,用來對緩沖區進行輸入輸出操作。該結構在Tm-queuehandlers.h文件中的定義如下:
typedef structTmqh_ {
char *name;
Packet *(*InHandler)(ThreadVars *);
void (*InShutdownHandler)(ThreadVars *);
void (*OutHandler)(ThreadVars *, Packet *);
void *(*OutHandlerCtxSetup)(char *);
void (*OutHandlerCtxFree)(void *);
void (*RegisterTests)(void);
} Tmqh;
其中InHandler和OutHandler就是分別指向緩沖區的輸入、輸出操作函數。
所有的QueueHandler組成了一個數組存放在tmqh_table[]中。Tm-queuehandlers.c中的Tmqh_Setup()函數被main()調用來對tmqh_table[]數組進行初始化,并將所有會用到的QueueHandler注冊到tmqh_table[]數組中。下面是NFQ模式中用到的三種QueueHandler:
1) Packepool
通過read和write兩個位置標記對packetpool(ringbuffer)這個循環隊列進行進出操作。
2) Simple
按照FIFO(先進先出)原則對緩沖區內容進行進出操作。
3) Flow
出隊的時候是按照FIFO進行,入隊的時候對數據包的頭部信息進行hash,然后將具有相同hash值的數據包放到一個緩沖區。
posted on 2012-09-07 15:13
老馬驛站 閱讀(1171)
評論(0) 編輯 收藏 引用 所屬分類:
snort