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``变量可用于设置备用套接字文件名。文件名始终相对于本地状态基础目录。

已为某些编程语言实现了客户端,可用作编写自定义脚本的代码示例:

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,表示处理后保留文件。