- 网络安全
- 网络
- IDS
【免费下载链接】zeek
Zeek is a powerful network analysis framework that is much different from the typical IDS you may know.
导读
本文围绕 Zeek 仓库中 base/protocols/syslog 脚本包及其生成的文档(load.zeek.rst、consts.zeek.rst、main.zeek.rst、spicy-events.zeek.rst),系统讲解 Zeek 如何识别、解析并记录 Syslog 消息。读完本文,你将掌握 Syslog 日志流的注册方式、Syslog::Info记录结构的全部字段、设施/严重级别编码映射表、端口重定义方法,以及基于 Spicy 的 UDP/TCP 双栈解析器(RFC 6587)底层实现,能够直接在真实环境中启用、扩展和验证 Syslog 日志。
一、包结构总览:base/protocols/syslog 是什么
根据 doc/scripts/base/protocols/syslog/index.rst 的说明,base/protocols/syslog是一个提供Syslog 协议分析支持的脚本包,由四个文件构成:
| 文件 | 作用 |
|---|---|
| load.zeek | 包加载入口,按顺序导入其余三个模块 |
| spicy-events.zeek | 定义 Syslog 分析器生成的事件(syslog_message) |
| consts.zeek | 定义 Syslog 设施(facility)与严重级别(severity)的编码映射表 |
| main.zeek | 核心脚本,负责将一条 Syslog 消息表示为一条日志记录(log record)并写入日志流 |
其中__load__.zeek的内容极为简洁,只有三条@load指令:
@load ./spicy-events @load ./consts @load ./main它是整个包的"装配入口",保证事件原型、常量表和日志逻辑按依赖顺序全部生效。与之对应,load.zeek.rst 明确列出该包导入的三个模块:consts.zeek、main.zeek、spicy-events.zeek。
二、常量映射表:consts.zeek 的设施与严重级别
consts.zeek 属于Syslog命名空间,定义了两张table[count] of string类型的编码映射表,用于把 Syslog 消息<PRI>部分解出的数字编码翻译成人可读的字符串。其 API 文档为 consts.zeek.rst。
2.1 设施编码表Syslog::facility_codes
facility_codes覆盖 RFC 3164 定义的 0~23 号标准设施,外加一个保留值999 = "UNSPECIFIED"(用于无法识别或缺失的情况):
[0] = "KERN" [1] = "USER" [2] = "MAIL" [3] = "DAEMON" [4] = "AUTH" [5] = "SYSLOG" [6] = "LPR" [7] = "NEWS" [8] = "UUCP" [9] = "CRON" [10] = "AUTHPRIV" [11] = "FTP" [12] = "NTP" [13] = "AUDIT" [14] = "ALERT" [15] = "CLOCK" [16] = "LOCAL0" [17] = "LOCAL1" [18] = "LOCAL2" [19] = "LOCAL3" [20] = "LOCAL4" [21] = "LOCAL5" [22] = "LOCAL6" [23] = "LOCAL7" [999] = "UNSPECIFIED"表的关键设计在于&default属性:
&default=function(c: count): string { return fmt("?-%d", c); };当查询的键不在表中时(例如出现超出 0~23 的设施编号),会返回?-(编号)格式的字符串,例如?-24。这保证了日志字段永远不会因索引缺失而报错或输出空值,属于防御性编码实践。
2.2 严重级别编码表Syslog::severity_codes
severity_codes覆盖 0~7 的八级严重度(数字越小越紧急),同样带999 = "UNSPECIFIED"兜底:
[0] = "EMERG" [1] = "ALERT" [2] = "CRIT" [3] = "ERR" [4] = "WARNING" [5] = "NOTICE" [6] = "INFO" [7] = "DEBUG" [999] = "UNSPECIFIED"实用提示:Syslog 经典编码中,
PRI = facility × 8 + severity。因此<13>表示 facility=1(USER)、severity=5(NOTICE)。两张表配合,恰好覆盖了这种编码的全部解算结果。若想让日志中出现?-x之外的自定义名称(如厂商扩展设施),可对这两张&redef能力外的常量表进行扩展或另建映射。
三、核心日志逻辑:main.zeek
main.zeek 是包的核心,其 API 文档见 main.zeek.rst。它依次完成四件事:注册日志流、声明端口、定义记录结构、挂接事件处理。
3.1 端口注册:Syslog::ports与Syslog::tcp_ports
两个端口集合均带&redef属性,允许用户在local.zeek或策略脚本中覆盖:
| 常量 | 类型 | 默认值 | 说明 |
|---|---|---|---|
Syslog::ports | set[port] | { 514/udp } | 传统 Syslog 使用的 UDP 端口 |
Syslog::tcp_ports | set[port] | { 514/tcp } | RFC 6587 定义的 TCP 传输端口 |
在zeek_init中,它们被注册到对应的分析器(main.zeek L40-45):
Analyzer::register_for_ports(Analyzer::ANALYZER_SYSLOG, ports); Analyzer::register_for_ports(Analyzer::ANALYZER_SYSLOG_TCP, tcp_ports);即:UDP 流量交给ANALYZER_SYSLOG,TCP 流量交给ANALYZER_SYSLOG_TCP。要监听非标准端口(例如企业内部日志服务器使用 5514/udp),只需重定义:
redef Syslog::ports = { 514/udp, 5514/udp };3.2 日志流与记录结构Syslog::Info
包通过redef enum Log::ID += { LOG }扩展了Log::ID枚举,新增Syslog::LOG日志流 ID。同时把Info记录挂到连接记录上:
redef record connection += { syslog: Info &optional; };Syslog::Info是 syslog 日志的记录结构,全部七个字段都带&log属性(即全部落盘):
| 字段 | 类型 | 含义 |
|---|---|---|
ts | time | 看到该 Syslog 消息的时间戳 |
uid | string | 连接的唯一标识 |
id | conn_id | 连接四元组(两端地址/端口) |
proto | transport_proto | 承载该消息的传输层协议 |
facility | string | 消息的 Syslog 设施(字符串形式,来自facility_codes) |
severity | string | 消息的 Syslog 严重级别(字符串形式,来自severity_codes) |
message | string | 纯文本消息内容 |
3.3 日志流的创建
zeek_init(优先级 5)中完成流注册:
Log::create_stream(Syslog::LOG, Log::Stream($columns=Info, $path="syslog", $policy=log_policy));$columns=Info:日志列即Info记录;$path="syslog":输出文件名基址为syslog,默认生成syslog.log;$policy=log_policy:挂接策略钩子(见下)。
3.4 策略钩子Syslog::log_policy
log_policy的类型是Log::PolicyHook,是扩展日志输出的标准入口。例如在消息写入前追加一条字段或过滤特定设施:
redef Syslog::log_policy += function(rec: Syslog::Info, id: string) { if ( rec?$facility && rec$facility == "AUTH" ) # 例如为认证相关消息打标记,或直接修改字段 ; };3.5 事件处理:从解析结果到日志记录
main.zeek用两个不同优先级的syslog_message事件处理器完成"组装记录 → 写入日志"的分离(L47-64):
event syslog_message(c: connection, facility: count, severity: count, msg: string) &priority=5 { local info: Info; info$ts = network_time(); info$uid = c$uid; info$id = c$id; info$proto = get_port_transport_proto(c$id$resp_p); info$facility = facility_codes[facility]; info$severity = severity_codes[severity]; info$message = msg; c$syslog = info; } event syslog_message(c: connection, facility: count, severity: count, msg: string) &priority=-5 { Log::write(Syslog::LOG, c$syslog); }优先级 +5 的处理器负责把解析出的数字编码经两张映射表翻译成字符串,并填充Info记录、暂存到c$syslog;优先级 -5 的处理器负责把暂存记录写入日志流。这样其他脚本可以在两个处理器之间插入自定义逻辑(优先级介于 -5 与 +5 之间),对日志记录进行就地修改——这是 Zeek 事件优先级机制的典型用法。
四、事件定义:spicy-events.zeek 与 syslog_message
spicy-events.zeek 定义分析器对外暴露的唯一事件syslog_message,其 API 文档见 spicy-events.zeek.rst:
global syslog_message: event(c: connection, facility: count, severity: count, msg: string);参数含义:
| 参数 | 类型 | 含义 |
|---|---|---|
c | connection | 承载该消息的传输层连接记录 |
facility | count | 消息中包含的设施编码(数字) |
severity | count | 消息中包含的严重级别编码(数字) |
msg | string | 实际记录的日志文本 |
注意两点:
- 依赖 Spicy 分析器:该原型被
@if ( have_spicy_analyzers() ) ... @endif包裹,意味着启用该事件要求 Zeek 使用 Spicy 实现的 Syslog 分析器,而非旧版(legacy)binpac 分析器。legacy 分析器位于 src/analyzer/protocol/syslog/legacy/(syslog.pac、syslog-analyzer.pac、events.bif等),其事件通过 BIF 定义。 - 文档中的历史说明:
spicy-events.zeek.rst的 note 声称"Zeek 目前仅解析 UDP syslog 流量",但从当前仓库的syslog.evt看,Spicy 版分析器已同时注册 UDP 与 TCP 两种传输(见第五节),该 note 属于沿袭旧版分析器能力的过时表述。
五、源码级透视:Spicy 解析器的 UDP/TCP 实现
Syslog 的 Spicy 分析器位于 src/analyzer/protocol/syslog/,由syslog.spicy定义解析语法、syslog.evt定义分析器到 Zeek 的桥接。
5.1 分析器注册(syslog.evt)
syslog.evt 注册了两个协议分析器:
protocol analyzer Syslog over UDP: parse with Syslog::Message; protocol analyzer Syslog_TCP over TCP: parse with Syslog::Frames;对应main.zeek中注册的两组端口(514/udp与514/tcp)。事件桥接为:
on Syslog::Message -> event syslog_message($conn, self.facility, self.severity, self.msg); on Syslog::NonTransparent -> event syslog_message($conn, self.facility, self.severity, self.msg);这正是main.zeek中事件处理器的数据来源。
5.2 UDP 消息解析(syslog.spicy)
syslog.spicy 中Message单元描述了一条 Syslog 消息:优先匹配<PRI>前缀,若没有则整体作为纯文本消息处理(msg: bytes &eod取余下全部字节):
public type Message = unit { switch { -> prio: Priority; -> : void; }; msg: bytes &eod; ... }; type Priority = unit { : b"<"; value: /[[:digit:]]+/ &convert=$$.to_uint(); : b">"; on %done { self.severity = (self.value & 0x07); self.facility = (self.value & 0x03f8) >> 3; } ... };解码逻辑与 RFC 3164 的PRI = facility × 8 + severity完全一致:低 3 位是 severity,其余高位右移 3 位是 facility。若消息没有<PRI>前缀,severity与facility默认取999,最终经consts.zeek的映射表译为"UNSPECIFIED"。
5.3 TCP 传输的两种帧格式(RFC 6587)
对 TCP 流量,Frames单元按 RFC 6587 处理两种帧格式(syslog.spicy L42-80):
type Frame = unit { switch { -> octet_counting: OctetCounting; # 八位字节计数法,帧首为 [1-9][0-9]* + 空格 + 长度定界消息 -> non_transparent: NonTransparent; # 非透明帧,以 < 开头,消息以 \x00\n\r 分隔 }; };- Octet Counting(八位字节计数):
OctetCounting先解析以非零数字开头的长度值,再按&size=self.len.to_uint()读取精确字节数的消息——长度字段与 RFC 6587 要求一致,杜绝模糊分隔; - Non-Transparent(非透明帧):
NonTransparent解析<PRI>后,将[^\x00\n\r]+作为消息体,并跳过[\x00\n\r]+分隔符。
因此,当前 Spicy 实现是"UDP + TCP 双栈",TCP 侧完整覆盖 RFC 6587 的两种主流封装。
六、实际使用:启用、验证与扩展
6.1 启用 Syslog 分析
base/protocols/syslog属于 Zeek 的 base 脚本集,随默认配置(init-default.zeek)自动加载。若你的配置为精简模式,可显式加载:
@load base/protocols/syslog运行 Zeek 后,捕获的 Syslog 流量会写入syslog.log。日志列由Syslog::Info决定:ts、uid、id、proto、facility、severity、message。
6.2 验证:用 btest 测试用例对照
仓库测试目录 testing/btest 中包含大量与 Syslog 相关的用例(*.zeek脚本 +.stdout/.err期望输出)。测试脚本通常先@load base/protocols/syslog,再通过redef Syslog::ports += { ... }指向测试端口,并利用Log::write的过滤与print输出验证解析结果,例如检查<PRI>解码后的 facility/severity 是否与facility_codes/severity_codes一致。你可以使用:
cd testing/btest && btest -f 'syslog*'运行全部 Syslog 相关回归测试,作为功能验证与自定义脚本的对照基线。
6.3 常见自定义场景
- 修改端口:
redef Syslog::ports = { 514/udp, 5514/udp };或redef Syslog::tcp_ports += { 6514/tcp }; - 调整输出路径:重定义流时修改
$path,例如Log::create_stream(Syslog::LOG, Log::Stream($columns=Info, $path="syslog-audit")) - 扩充日志字段:
redef record Syslog::Info += { tag: string &optional &log; };并在log_policy钩子中填充 - 按严重级别过滤:在
log_policy中依据rec$severity丢弃低价值消息,控制存储开销
七、小结
base/protocols/syslog包通过load.zeek 装配、consts.zeek 提供编码字典、spicy-events.zeek 暴露事件、main.zeek 完成日志化,构成了一个"解析 → 事件 → 记录 → 落盘"的完整链路;底层由 syslog.spicy 与 syslog.evt 提供 UDP 与 TCP(RFC 6587)双栈支持。掌握了上述常量表、记录结构、端口重定义与优先级事件机制,你便可以在真实部署中自如地开启、定制和扩展 Zeek 的 Syslog 日志能力。
- 网络安全
- 网络
- IDS
【免费下载链接】zeek
Zeek is a powerful network analysis framework that is much different from the typical IDS you may know.
相关推荐
Zeek Syslog 协议分析:base/protocols/syslog 包结构与 syslog 日志详解
Zeek Syslog 协议分析:base/protocols/syslog 包结构与 syslog 日志详解 本文围绕 Zeek 官方脚本包 base/pro
网络安全网络IDSZeek Syslog 协议日志记录全解析:base/protocols/syslog 脚本与 Spicy 解析器实战指南
Zeek Syslog 协议日志记录全解析:base/protocols/syslog 脚本与 Spicy 解析器实战指南 Zeek 将每个 Syslog 消息
网络安全网络IDSZeek 网络分析框架 SMB 协议分析脚本包(base/protocols/smb)完全指南
Zeek 网络分析框架 SMB 协议分析脚本包(base/protocols/smb)完全指南 SMB(Server Message Block)/CIFS 是
网络安全网络IDS
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考