通过 Unix Socket 与 Suricata 交互

简介

Suricata 可以监听 Unix socket 并接受用户命令。交换协议基于 JSON,消息采用通用格式。

安装或更新 Suricata 时,会自动安装名为 suricatasc 的应用程序。

Unix socket 默认始终启用。是否创建 socket,由 Suricata YAML 配置文件中 unix-command 下的 enabled 控制,将其设为 yes 或 auto:

unix-command:
  enabled: yes
  #filename: custom.socket # use this to specify an alternate file

可以使用 filename 变量指定其他 socket 文件名。该文件名始终相对于本地状态基础目录。

以下语言已有客户端实现,可作为编写自定义脚本的代码示例:

  • Rust:Suricata 8 及更高版本提供的实现。
  • Python:较旧 Suricata 版本中的 Python 实现。
  • Perl:支持交互模式的简单客户端。
  • C:不含交互模式的 Unix socket 客户端。

标准运行模式下的命令

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。
get-flow-stats-by-id 列出指定 flow_id 的信息。

典型的 suricatasc 会话如下:

# suricatasc
Command list: shutdown, command-list, help, version, uptime, running-mode, capture-mode, conf-get, dump-counters, iface-stat, iface-list, quit
>>> iface-list
Success: {'count': 2, 'ifaces': ['eth0', 'eth1']}
>>> iface-stat eth0
Success: {'pkts': 378, 'drop': 0, 'invalid-checksums': 0}
>>> conf-get unix-command.enabled
Success:
"yes"

在命令提示符中使用

可以直接在命令提示符中使用 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:~#

PCAP 处理模式

这一模式是开发这部分代码的主要动机之一:向 Suricata 提供不同的 PCAP 文件,而不必为每个文件重新启动 Suricata。这样可以免去反复等待特征引擎初始化的时间。

要使用该模式,请使用选定的 YAML 配置文件启动 Suricata,并传入 --unix-socket 参数:

suricata -c /etc/suricata-full-sigs.yaml --unix-socket

也可以通过参数指定 socket 文件名:

suricata --unix-socket=custom.socket

后一种情况下,需要向 suricatasc 提供 socket 的完整路径,即将文件名作为 suricatasc 的第一个参数:

suricatasc custom.socket

Suricata 启动后,可以用 suricatasc 连接命令 socket,并提交不同的 PCAP 文件:

root@tiger:~# suricatasc
>>> pcap-file /home/benches/file1.pcap /tmp/file1
Success: Successfully added file to list
>>> pcap-file /home/benches/file2.pcap /tmp/file2
Success: Successfully added file to list
>>> pcap-file-continuous /home/pcaps /tmp/dirout
Success: Successfully added file to list

可以连续添加多个文件,无需逐个等待处理完成。文件会按顺序处理,生成的日志与告警文件会写入 pcap-file 命令第二个参数指定的目录。文件和目录必须使用绝对路径,因为 Suricata 不知道脚本从哪个位置运行。如果传入目录而不是文件,目录中的所有文件都会被处理。

使用 pcap-file-continuous 并传入目录时,系统会持续监视该目录中的新增文件,直到使用 pcap-interrupt,或者该目录被删除或移动。

要显示等待处理的文件数量:

>>> pcap-file-number
Success: 3

要显示排队文件的列表:

>>> pcap-file-list
Success: {'count': 2, 'files': ['/home/benches/file1.pcap', '/home/benches/file2.pcap']}

要显示当前正在处理的文件:

>>> pcap-current
Success:
"/tmp/test.pcap"

传入目录时,可以查看上次处理时间,即最后一个文件的修改时间,以 Unix epoch 起算的毫秒数表示:

>>> pcap-last-processed
Success:
1509138964000

要中断目录处理并终止当前状态:

>>> pcap-interrupt
Success:
"Interrupted"

构建自己的客户端

协议说明见 Unix Socket 协议文档。

以下会话展示服务器发送(SND)和接收(RCV)的消息。初始协商如下:

# suricatasc
SND: {"version": "0.1"}
RCV: {"return": "OK"}

完成后即可发送命令:

>>> iface-list
SND: {"command": "iface-list"}
RCV: {"message": {"count": 1, "ifaces": ["wlan0"]}, "return": "OK"}
Success: {'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"}
Success: {'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"}
Success: Successfully added file to list
>>> 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"}
Success: {'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"}
Success: Successfully added file to list

需要注意:Suricata 的一条消息可能通过多次发送操作传出,因此客户端一次读取可能无法得到完整消息。一种较差的变通方法是在调用 recv 前短暂等待。另一种方法是使用非阻塞 socket,并在前一次 recv 失败后重试。

pcap-file 的 JSON 格式如下:

{
  "command": "pcap-file",
  "arguments": {
    "output-dir": "path to output dir",
    "filename": "path to file or directory to run",
    "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,即处理后保留文件。


来源:Suricata 8.0.7 官方用户指南,第 20 章。Open Information Security Foundation 与 Suricata 项目贡献者。示例中显示的旧版输出按原文保留。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容