suricata提供了suricatasc这个工具用来与其进行通信,比如修改规则文件后,通知suricata重新加载规则,就可以通过suricatasc下发重新加载规则命令,suricatasc和suricata通过unix socket进行通信,unix socke好处就是不占用网络端口,避免对外暴露端口,性能也非常高。
下面,我们来看一下suricata command这一块的代码实现以及如何自定义一个command命令。
1、suricatasc目前支持的命令如下:
command-list:列出可用命令
shutdown:关闭Suricata
iface-list:列出Suricata嗅探数据包的接口
iface-stat:接口的列表统计信息
help:命令列表的别名
version:显示Suricata的版本
uptime:显示Suricata的正常运行时间
running-mode:显示运行模式(workers,autofp,simple)
capture-mode:使用的显示捕获系统
conf-get:获取配置项(参见下面的示例)
dump-counters:dump Suricata的性能指标
reopen-log-files:重新打开日志文件(在外部日志轮换后运行)
ruleset-reload-rules:重新加载规则集并等待完成
ruleset-reload-nonblocking:重新加载规则集,无需等待即可继续
ruleset-reload-time:上次重新加载的返回时间
ruleset-stats:显示已加载和失败的规则数
ruleset-failed-rules:显示失败规则列表
memcap-set:更新指定项的memcap值
memcap-show:显示指定项目的memcap值
memcap-list:列出所有可用的memcap值
reload-rules: ruleset-reload-rules的别名
register-tenant-handler:注册指定映射的租户处理程序
unregister-tenant-handler:注销指定映射的租户处理程序
register-tenant: 注册指定ID和文件名的租户
unregister-tenant: 注销指定ID和文件名的租户
reload-tenant: 重新加载指定ID和文件名的租户
add-hostbit: 在指定位名和到期时间的主机IP上添加
hostbit remove-hostbit: 在指定位名的主机IP上删除hostbit
list-hostbit: 列出特定主机的hostbit
suricatasc的使用示例如下:
也可以以非交互模式使用,例如suricatasc -c version,suricatasc -c iface-list
2、suricatasc相关源码分析:
unix-socket的初始化和命令注册相关代码的调用关系如下:
main
-->SuricataMain
-->PostConfLoadedSetup
-->RegisterAllModules
-->TmModuleUnixManagerRegister(注册UnixManager模块)
-->UnixManagerThreadSpawnNonRunmode(不是unix-socket运行模式才执行)
-->UnixManagerInit
-->UnixNew(创建unix-socket)
-->UnixManagerRegisterCommand(注册系统级的cmd)
-->UnixManagerRegisterCommand(注册网口相关的cmd)
-->UnixManagerThreadSpawn
-->TmThreadCreateCmdThreadByName
-->TmThreadCreate(创建ThreadVars线程变量)
-->TmSlotSetFuncAppend(把UnixManager模块加入到线程的slot中)
-->TmThreadSpawn(创建command线程,线程入口为TmThreadsManagement)
-->TmThreadsManagement
-->s->SlotThreadInit(即UnixManagerThreadInit函数)
-->s->Management (即UnixManager函数)
UnixManagerRegisterCommand函数将命令的关键字、命令执行函数和是否需要参数组成一个Command结构体,挂在全局变量UnixCommand command的commands链表上。
下面看一下command处理函数UnixManager的处理逻辑,UnixManager循环调用UnixMain,传入前面说的command链表,然后就是socket那一套select、accept和recv的逻辑,函数调用栈如下:
UnixManager
-->UnixMain
-->UnixCommandRun
-->UnixCommandExecute
-->lcmd->Func(对应的命令执行函数)
UnixCommandExecute中command传入的参数为json串,无参数的格式为:{"command": "iface-list"},如果有参数,格式为:{"command": "iface-stat","arguments": {"iface": "0000:0b:00.0"}},然后根据关键字"iface-list"找到注册的对应的命令节点Command *lcmd,然后调用lcmd->Func,即对应命令的执行函数LiveDeviceIfaceList进行处理。在LiveDeviceIfaceList中,将要返回的内容以json格式填充到第二个参数json_t *answer中即可。
suricatasc是一个用 python写的unix socket的客户端,就是将用户输入的命令发给suricata,将返回的结果回显出来。
3、如何自定义一个suricata命令:
1)注册命令:
在UnixManagerThreadSpawnNonRunmode函数中注册命令"just-test": UnixManagerRegisterCommand("just-test", Justtest, NULL, 0);
2) 命令执行函数Justtest:
TmEcode Justtest(json_t *cmd, json_t *answer, void *data)
{
SCEnter();
json_t *jdata;
int i = 0;
jdata = json_object();
if (jdata == NULL) {
json_object_set_new(answer, "message",
json_string("internal error at json object creation"));
return TM_ECODE_FAILED;
}
json_object_set_new(jdata, "desc", json_string("Just test command")); //回应一个字符串Just test command
json_object_set_new(answer, "message", jdata);
SCReturnInt(TM_ECODE_OK);
}
3)在suricatasc.py中添加命令:
在SuricataSC函数self.fn_commands数组中添加"just-test"命令(如果是有参数的,得在specs.py中添加参数以及个数说明)
4)重新编译suricata代码
5)启动suricata,执行suricatasc的just-test命令:
好了,关于suricata中使用unix-socket实现的command的代码分析以及自定义命令的方法,就讲到这里了。
有问题的朋友,可以进网络技术开发交流群提问(先加我微信,备注加群)。喜欢文章内容的朋友,记得加个关注哦~~