想了解一个程序的核心逻辑,最好调试下,跑跑程序,在调试的过程中,对整个结构才有个很好的把握。
suricata有多种模式,其中,single这种单线程模式,容易了解整个程序的核心逻辑,其他的多线程模式调试起来相对来说更加麻烦,而各种抓包模式显然要比读本地pcap的方式复杂,所以最简单的办法是调试单线程读取pcap的模式的办法。
一 单线程跑pcap模式线程情况
如下图所示,加了马赛克的非suricata的原生线程,可以忽略。其他线程说明:
- main 线程,主线程,最终一直定时执行循环,做文件定期滚动标志;如果需要重新加载规则库的,则加载规则库。
- 管理线程分出两个: 流超时管理线程和流重应用线程。
- 统计唤醒线程和统计管理线程。
最重要的就是现在光标指出来的W#1线程,核心的函数就是FlowWorker,这个函数就是flow-worker.c中的FLowWorker函数。

二 FLowWorker的总体说明
学习FlowWorker,先了解下其整体执行过程,总的来说主要有三大核心功能:
- 1.协议解析:
StreamTcp(tv, p, fw->stream_thread, &fw->pq, NULL);
- 2.规则检测:
Detect(tv, x, detect_thread, NULL, NULL);
- 3.日志输出。
OutputLoggerLog(tv, p, fw->output_thread);
这也就是整个suricata的核心了,当然这里面还牵扯到tcp包重组和一些基础协议的decode等,但是整体架子就这三个。
三 调用解析
如下图所示,tcp包需要先进行包重组和状态更新,只有状态是连接状态后,才会进入流分析。
流分析的特点:
- 并不是分析此包的信息,而是分析相反方向上的流信息。
举个例子,假如收到了一个客户端发送到服务器端的报文,那么分析的数据是服务器端对客户端发送数据的缓存内容,因为收到了客户端的报文,说明反方向上的数据接受完毕了,可以进行分析了,这点要特别注意。 - 流分析的时候,需要先进行协议的检测,通过识别到协议,再调用这个协议以前注册的解析函数进行相关解析的工作。
协议识别的调用过程:
TCPProtoDetect
-->AppLayerProtoDetectGetProto
-->AppLayerProtoDetectPPGetProto;
--> pe->ProbingParserTs/pe->ProbingParserTc
-->进入到各个协议注册的检测函数
协议解析:
AppLayerParserParse
-->p->Parser[(flags & STREAM_TOSERVER) ? 0 : 1](f, alstate, pstate,
input, input_len,
alp_tctx->alproto_local_storage[f->protomap][alproto])
调用指针进行协议的解析。

网友评论