实习工作涉及到了snort,正巧毕业设计也打算做snort相关的内容,所以开始学习snort相关内容。
今日成果
- 编译安装snort3
- 安装Sourcetrail,并导入snort3
- 运行snort并解决错误
编译安装
安装snort的方法在git上有,一共就三句话,比较麻烦的还是安装其他的依赖
1 | ./configure_cmake.sh --prefix=$my_path |
安装依赖
- PkgConfig
apt install pkg-config
- libdaq
git clone https://github.com/snort3/libdaq.git
- LIBTOOL
apt install libtool
- LIBTOOL
- dnet
git clone https://github.com/dugsong/libdnet.git
https://github.com/jncornett/libdnet/commit/034d60b6c62ccb547590dfa2a9301cea50fcd13d
- hwloc
https://www.open-mpi.org/software/hwloc/v2.1/
- luajit
git clone http://luajit.org/git/luajit-2.0.git
- OpenSSL
apt install libssl-dev
- Libpcap
http://www.tcpdump.org
- flex
apt install flex
- Bison
apt install bison
- flex
- Libpcre
https://ftp.pcre.org/pub/pcre/
- ZLIB
apt install zlib1g zlib1g-dev
只要执行configure_cmake.sh没有错误了,编译就十分简单了,但最好在编译之前执行/sbin/ldconfig
。编译出来的可执行文件在$my_path/bin/snort
.
1 | ,,_ -*> Snort++ <*- |
Sourcetrail
Sourcetrail是一个很方便阅读源代码的程序,它可以全局搜索函数、变量、结构体等等,而且也支持模糊匹配。同时还可以分析出引用、定义、调用关系等,是一个阅读开源代码十分方便的工具。
此工具是跨平台的,但是在导入项目的时候也会涉及到编译器、头文件等东西,所以如果是Linux项目,还是建议使用Linux版的Sourcetrail。
第一次使用的时候,导入项目是个麻烦的事情,建议直接看官方文档,还有视频讲解,导入snort还是十分简单的。
https://www.sourcetrail.com/documentation/#CreatingaNewProject
排错
安装以上方法安装完snort,进行测试,测试命令为./snort -r test.pcap
,会发现报错。
1 | Could not find requested DAQ module: pcap |
Google或者官方论坛去搜索这个错误,会发现都只给了一个解决办法就是--daq-dir=/usr/local/lib/daq
,但是我试了很多次发现是没有用的。
下面记录一下这个错误的踩坑记录:
首先搜索报错信息
Couldn't construct a DAQ instance
./src/packet_io/sfdaq_instance.cc:76: ErrorMessage("Couldn't construct a DAQ instance: %s (%d)\n", buf, rval);
1
2
3
4
5
6
7
8
9
10
11
12
13bool SFDAQInstance::init(DAQ_Config_h daqcfg, const std::string& bpf_string)
{
char buf[256] = "";
int rval;
/* Reuse the main DAQ instance configuration with the input specification specific to this instance. */
daq_config_set_input(daqcfg, input_spec.c_str());
if ((rval = daq_instance_instantiate(daqcfg, &instance, buf, sizeof(buf))) != DAQ_SUCCESS)
{
ErrorMessage("Couldn't construct a DAQ instance: %s (%d)\n", buf, rval);
return false;
}
......
再去找
daq_instance_instantiate
函数,这个函数在libdaq的源码里面./api/daq_mod_ops.c:163:DAQ_LINKAGE int daq_instance_instantiate(const DAQ_Config_h config, DAQ_Instance_t **instance_ptr, char *errbuf, size_t len)
1
2
3
4
5
6
7
8
9
10
11
12DAQ_LINKAGE int daq_instance_instantiate(const DAQ_Config_h config, DAQ_Instance_t **instance_ptr, char *errbuf, size_t len)
{
/* Don't do this. */
if (!errbuf)
return DAQ_ERROR;
if (!config)
{
snprintf(errbuf, len, "Can't instantiate without a configuration!");
return DAQ_ERROR_INVAL;
}
......
知道错误的原因是第一个参数
config
为空,也就是daqctg
为空,查看SFDAQInstance::init
的引用,发现只在SFDAQ::init_instance
中调用,且从这里可以看出daqctg
是一个全局变量。1
2
3
4bool SFDAQ::init_instance(SFDAQInstance* instance, const string& bpf_string)
{
return instance->init(daqcfg, bpf_string);
}查看全局变量
daqctg
的引用,发现了一个函数AddDaqModuleConfig
,并且在这个函数中发现了另一句报错文本Could not find requested DAQ module: pcap
1
2
3
4
5
6
7
8
9
10static bool AddDaqModuleConfig(const SFDAQModuleConfig *dmc)
{
const char* module_name = dmc->name.c_str();
DAQ_Module_h module = daq_find_module(module_name);
if (!module)
{
ErrorMessage("Could not find requested DAQ module: %s\n", module_name);
return false;
}
......可以看出了,出错原因是因为
daq_find_module
失败了。再去libdaq的源码中寻找这个函数。./api/daq_base.c:105:DAQ_LINKAGE const DAQ_ModuleAPI_t *daq_find_module(const char *name)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15DAQ_LINKAGE const DAQ_ModuleAPI_t *daq_find_module(const char *name)
{
DAQ_ListNode_t *node;
if (!name)
return NULL;
for (node = module_list; node; node = node->next)
{
if (!strcmp(name, node->module->name))
return node->module;
}
return NULL;
}
函数遍历了一个链表,去寻找
pcap
这个module
。很可惜的是,修改源码打印module_list
,的确没找到。1
2
3node->module->name: trace
node->module->name: fst
node->module->name: afpacket再次执行
libdaq
的./configure
,发现显示pcap
是成功的。1
2
3
4
5
6
7
8
9Build AFPacket DAQ module.. : yes
Build BPF DAQ module....... : yes
Build Divert DAQ module.... : no
Build Dump DAQ module...... : yes
Build FST DAQ module....... : yes
Build NFQ DAQ module....... : no
Build PCAP DAQ module...... : yes
Build netmap DAQ module.... : no
Build Trace DAQ module..... : yes暂时陷入僵局,查看
libdaq
的文档,发现其中一个README
提到了libpcap
的版本建议是1.9.0
1
2
3
4
5
6cat ./libdaq/modules/pcap/README.pcap.md
Requirements
------------
* libpcap >= 1.5.0
(LibPCAP 1.9.0 is available at the time of writing and is recommended.)重新安装
libpcap
,版本由1.9.1
修改为1.9.0
,并没有任何改变。突发奇想,再次执行编译snort
的命令./configure_cmake.sh --prefix=$my_path
,发现DAQ Modules
中没有pcap
1
2Feature options:
DAQ Modules: Static (afpacket;fst;trace)重新分析一遍安装流程,发现
libpcap
是在libdaq
后安装的,所以在编译安装libdaq
时候,是没有libpcap
的,但是那时候没注意configure
中Build PCAP DAQ module
是No
,而在之后检查的时候,已经安装了libpcap
,所以再次执行libdaq
的configure
的时候,会显示Build PCAP DAQ module
是Yes
的,因此解决办法十分简单,重新编译安装一次libdaq
即可。 再次执行snort3
的./configure_cmake.sh
1
2Feature options:
DAQ Modules: Static (afpacket;bpf;dump;fst;pcap;trace)既然
DAQ Modules
中已经出现了pcap
,那么在编译安装一次snort3
即可,再次执行测试命令./snort -r test.pcap
,成功无报错1
2
3
4pcap DAQ configured to read-file.
Commencing packet processing
++ [0] test.pcap
-- [0] test.pcap
总结
总的来说还是不错的,迈出了第一步,成功运行了snort3
,并已经开始尝试读源码,感觉并没有想象中的困难,但也还有一些改进之处。
- 现有的工作流十分复杂,命令操作和文本编辑都在
Mac OS
上,但snort虚拟机
在新装的Windows
上,而两边无法共享剪贴板,操作繁琐,之后考虑购入罗技鼠标解决剪贴板共享问题 - 此次复杂的排错本来是可以避免的,主要是在执行完
configure
应该仔细阅读结果,而不能只看有没有报错。 - 经过
b'5p2O'
同学的提醒,对snort
安装,官网有十分详细文档https://snort.org/documents
,按照官网的安装,可以多出很多其他的功能,包括Hyperscan
、FlatBuffers
、LZMA
等,所以按照官网流程还是很有必要的。由于暂时用不到这些功能,所以之后有必要在安装吧。