24. 通过Unix套接字交互¶
24.1. 简介¶
Suricata可以监听Unix套接字并接受用户命令。通信协议基于JSON,消息格式通用。
安装/更新Suricata时会自动安装一个名为``suricatasc``的应用程序。
Unix套接字默认始终启用。
套接字创建通过在Suricata YAML配置文件的unix-command下将enabled设置为'yes'或'auto'来管理:
unix-command:
enabled: yes
#filename: custom.socket # 使用此项指定备用文件
``filename``变量可用于设置备用套接字文件名。文件名始终相对于本地状态基础目录。
已为某些编程语言实现了客户端,可用作编写自定义脚本的代码示例:
Rust: https://github.com/OISF/suricata/blob/master/rust/suricatasc (Suricata 8+版本提供)
Python: https://github.com/OISF/suricata/blob/main-7.0.x/python/suricata/sc/suricatasc.py (旧版Suricata的Python版本)
Perl: https://github.com/aflab/suricatac (带交互模式的简单Perl客户端)
C: https://github.com/regit/SuricataC (C语言的无交互模式Unix套接字客户端)
24.2. 标准运行模式下的命令¶
``suricatasc``命令应自动安装在主``suricata``程序相同的目录中。
现有命令集如下:
command-list: 列出可用命令
shutdown: 关闭Suricata
iface-list: 列出Suricata嗅探数据包的接口
iface-stat: 列出接口的统计信息
help: command-list的别名
version: 显示Suricata版本
uptime: 显示Suricata运行时间
running-mode: 显示运行模式(workers、autofp、simple)
capture-mode: 显示使用的捕获系统
conf-get: 获取配置项(见下方示例)
dump-counters: 导出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: 列出特定主机IP的hostbit
典型的``suricatasc``会话如下:
# suricatasc
命令列表: shutdown, command-list, help, version, uptime, running-mode, capture-mode, conf-get, dump-counters, iface-stat, iface-list, quit
>>> iface-list
成功: {'count': 2, 'ifaces': ['eth0', 'eth1']}
>>> iface-stat eth0
成功: {'pkts': 378, 'drop': 0, 'invalid-checksums': 0}
>>> conf-get unix-command.enabled
成功:
"yes"
24.3. 命令行提示符下的命令¶
可以直接在命令行提示符下使用``suricatasc``:
root@debian64:~# suricatasc -c version
{'message': '5.0.3 RELEASE', 'return': 'OK'}
root@debian64:~#
root@debian64:~# suricatasc -c uptime
{'message': 35264, 'return': 'OK'}
root@debian64:~#
注意: 需要为包含多个参数的命令添加引号:
root@debian64:~# suricatasc -c "iface-stat eth0"
{'message': {'pkts': 5110429, 'drop': 0, 'invalid-checksums': 0}, 'return': 'OK'}
root@debian64:~#
24.4. PCAP处理模式¶
此模式是此代码背后的主要动机之一。其思想是能够向Suricata提供不同的pcap文件,而无需为每个文件重新启动Suricata。这节省了时间,因为无需等待签名引擎初始化。
要使用此模式,请使用首选的配置YAML文件启动Suricata,并提供``--unix-socket``作为参数:
suricata -c /etc/suricata-full-sigs.yaml --unix-socket
也可以将套接字文件名作为参数指定:
suricata --unix-socket=custom.socket
在后一种情况下,需要向``suricatasc``提供套接字的完整路径。为此,需要将文件名作为``suricatasc``的第一个参数传递:
suricatasc custom.socket
启动Suricata后,可以使用``suricatasc``连接到命令套接字并提供不同的pcap文件:
root@tiger:~# suricatasc
>>> pcap-file /home/benches/file1.pcap /tmp/file1
成功: 成功将文件添加到列表
>>> pcap-file /home/benches/file2.pcap /tmp/file2
成功: 成功将文件添加到列表
>>> pcap-file-continuous /home/pcaps /tmp/dirout
成功: 成功将文件添加到列表
可以添加多个文件而无需等待每个文件处理完成;它们将按顺序处理,生成的日志/警报文件将放入pcap-file命令的第二个参数指定的目录中。需要提供文件和目录的绝对路径,因为Suricata不知道脚本从何处运行。如果传递的是目录而不是文件,将处理目录中的所有文件。如果使用``pcap-file-continuous``并传递目录,将监视目录中的新文件,直到使用``pcap-interrupt``或删除/移动目录。
要显示等待处理的文件数量,可以执行:
>>> pcap-file-number
成功: 3
要显示排队文件列表,执行:
>>> pcap-file-list
成功: {'count': 2, 'files': ['/home/benches/file1.pcap', '/home/benches/file2.pcap']}
要显示当前处理的文件:
>>> pcap-current
成功:
"/tmp/test.pcap"
传递目录时,可以查看上次处理时间(最后文件的修改时间),单位为自纪元以来的毫秒数:
>>> pcap-last-processed
成功:
1509138964000
要中断目录处理并终止当前状态:
>>> pcap-interrupt
成功:
"已中断"
24.5. 构建自己的客户端¶
协议文档位于以下页面: https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Unix_Socket#Protocol
以下会话显示服务器发送(SND)和接收(RCV)的内容。初始协商如下:
# suricatasc
SND: {"version": "0.1"}
RCV: {"return": "OK"}
完成后,可以发出命令:
>>> iface-list
SND: {"command": "iface-list"}
RCV: {"message": {"count": 1, "ifaces": ["wlan0"]}, "return": "OK"}
成功: {'count': 1, 'ifaces': ['wlan0']}
>>> iface-stat wlan0
SND: {"command": "iface-stat", "arguments": {"iface": "wlan0"}}
RCV: {"message": {"pkts": 41508, "drop": 0, "invalid-checksums": 0}, "return": "OK"}
成功: {'pkts': 41508, 'drop': 0, 'invalid-checksums': 0}
在pcap-file模式下,如下所示:
>>> pcap-file /home/eric/git/oisf/benches/sandnet.pcap /tmp/bench
SND: {"command": "pcap-file", "arguments": {"output-dir": "/tmp/bench", "filename": "/home/eric/git/oisf/benches/sandnet.pcap"}}
RCV: {"message": "Successfully added file to list", "return": "OK"}
成功: 成功将文件添加到列表
>>> pcap-file-number
SND: {"command": "pcap-file-number"}
RCV: {"message": 1, "return": "OK"}
>>> pcap-file-list
SND: {"command": "pcap-file-list"}
RCV: {"message": {"count": 1, "files": ["/home/eric/git/oisf/benches/sandnet.pcap"]}, "return": "OK"}
成功: {'count': 1, 'files': ['/home/eric/git/oisf/benches/sandnet.pcap']}
>>> pcap-file-continuous /home/eric/git/oisf/benches /tmp/bench 0 true
SND: {"command": "pcap-file", "arguments": {"output-dir": "/tmp/bench", "filename": "/home/eric/git/oisf/benches/sandnet.pcap", "tenant": 0, "delete-when-done": true}}
RCV: {"message": "Successfully added file to list", "return": "OK"}
成功: 成功将文件添加到列表
需要注意的一点是:Suricata消息通过多次发送操作发送。这可能导致客户端读取不完整。最差的解决方法是尝试recv调用前稍作休眠。另一种解决方案是使用非阻塞套接字,并在前一次recv失败时重试。
Pcap-file的JSON格式为:
{
"command": "pcap-file",
"arguments": {
"output-dir": "输出目录路径",
"filename": "要运行的文件或目录路径",
"tenant": 0,
"continuous": false,
"delete-when-done": false
}
}
`output-dir`和`filename`是必需的。`tenant`是可选的,应为数字,指示文件或目录应在哪个租户下运行。`continuous`是可选的,应为true/false,指示文件或目录应运行直到发送`pcap-interrupt`或调用ctrl-c。`delete-when-done`是可选的,应为true/false,指示处理完成后应删除`filename`指定的文件或目录下的文件。`delete-when-done`默认为false,表示处理后保留文件。