
网络安全网络IDS【免费下载链接】zeekZeek is a powerful network analysis framework that is much different from the typical IDS you may know.项目地址https://gitcode.com/gh_mirrors/ze/zeek点击查看免费下载本篇文章聚焦 Zeek 网络分析框架中 PostgreSQL 协议分析器基于 Spicy的两个核心状态变量——PostgreSQL::auth_ids与PostgreSQL::error_ids。它们分别将 PostgreSQL 前端/后端协议中的认证方式编号与错误/通知消息字段代码翻译为人类可读的字符串是理解postgresql.log日志中backend_arg字段内容的关键。读完本文你将掌握这两个表的默认映射、default与redef的扩展机制以及它们与 Spicy 解析器、事件处理链路的实际调用关系并能够据此自定义扩展自己的映射。一、这两个常量表解决什么问题PostgreSQL 线协议wire protocol版本 3.0是一个高度结构化的二进制协议所有消息都带有一个 1 字节的类型标签和 4 字节的长度前缀。其中有两类信息对安全监控与流量审计特别有价值但直接以编号或单字节代码出现在报文中认证方式编号AuthenticationRequest 消息中的 identifier 字段服务端用 4 字节整数告诉客户端使用何种认证机制例如5表示 MD5 密码认证、10表示 SASL 认证。错误/通知字段代码ErrorResponse 与 NoticeResponse 消息中的字段标签每个错误或通知由一组单字节代码 字符串值的字段组成例如S表示严重程度Severity、C表示错误码SQLSTATE、M表示消息正文。[consts.zeek](https://link.gitcode.com/i/e2ab2494e6ce2a25f57044756d0d7c69)中定义的两个全局表正是这两类信息的翻译字典PostgreSQL::auth_ids: table[count] of string——由认证编号到认证名称PostgreSQL::error_ids: table[string] of string——由字段代码到字段含义名称。两者都带defaultfunction ... redef属性即遇到表中没有的编号或代码时会通过默认函数生成一个UnknownAuthId编号/UnknownErrorId代码形式的占位字符串而不会直接崩溃或丢弃数据同时脚本可以通过redef自由补充或覆盖映射。这是 Zeek 脚本层宽容解析 可扩展设计哲学的典型体现。二、PostgreSQL::auth_ids认证方式编号映射官方文档 consts.zeek.rst 给出的默认映射如下来源为 consts.zeek{ [2] KerberosV5, [3] CleartextPassword, [5] MD5Password, [7] GSSAPI, [8] GSSAPIContinue, [9] SSPI, [10] SASL, [11] SASLContinue, [12] SASLFinal }这些编号与 PostgreSQL 官方协议文档中AuthenticationOk之后各种AuthenticationRequest子类型的标识一一对应编号认证方式说明0隐含AuthenticationOk无需认证即成功不进入该表2KerberosV5Kerberos V5 认证3CleartextPassword明文密码认证通过PasswordMessage发送5MD5PasswordMD5 加盐密码认证服务端会附带 4 字节盐值7GSSAPIGSSAPI 认证8GSSAPIContinueGSSAPI 多轮握手的继续消息9SSPIWindows SSPI 认证10SASLSASL 认证SCRAM-SHA-256 等机制11SASLContinueSASL 多轮握手的继续消息12SASLFinalSASL 握手完成消息注意表中并没有编号0因为在协议中identifier 0意味着AuthenticationOk。这一点在 Spicy 解析器中就已被特殊处理——postgresql.evt 使用两条带条件的on规则把 0 与非 0 分流on PostgreSQL::AuthenticationRequest if ( self.identifier ! 0 )- event PostgreSQL::authentication_request($conn, self.identifier, self.data); on PostgreSQL::AuthenticationRequest if ( self.identifier 0 ) - event PostgreSQL::authentication_ok($conn);而 postgresql.spicy 中AuthenticationRequest单元对identifier做了requires($$ 12)的范围校验并检查AuthenticationOK with wrong length超出已知范围的编号会被视为解析错误。默认函数与未知名处理auth_ids的完整定义还包括一个默认函数defaultfunction(id: count): string { return fmt(UnknownAuthId%s, id); }也就是说若未来 PostgreSQL 引入编号 13 以上的新认证方式或抓包中出现异常的编号Zeek 不会报错而是会在日志里以UnknownAuthId13的形式原样透出编号保证监控不中断。这与redef属性配合后用户可以在自己的脚本中redef PostgreSQL::auth_ids { [13] SomeNewAuth };及时跟上协议演进。三、PostgreSQL::error_ids错误/通知字段代码映射error_ids是一个table[string] of string覆盖 PostgreSQL 官方文档《Protocol Error Fields》中定义的全部 18 个字段代码来源为 consts.zeek{ [S] SeverityLocalized, // 本地化严重程度如 ERROR [V] Severity, // 非本地化严重程度 [C] Code, // SQLSTATE 错误码如 42P01 [M] Message, // 人类可读的主错误消息 [D] Detail, // 补充细节 [H] Hint, // 提示信息 [P] Position, // 在查询串中的字符位置 [p] InternalPosition, // 内部查询中的位置 [q] InternalQuery, // 内部查询文本 [W] Where, // 出错位置的上下文 [s] Schema, // 模式名 [t] Table, // 表名 [c] Column, // 列名 [d] Data, // 数据对象名 [n] Constraint, // 约束名 [F] File, // 产生错误的源码文件名 [L] Line, // 产生错误的源码行号 [R] Routine, // 产生错误的函数名 }字段代码与含义的对照关系是协议规范PostgreSQL 官方协议文档中 Error and Notice Message Fields 一节固定的[consts.zeek](https://link.gitcode.com/i/e2ab2494e6ce2a25f57044756d0d7c69#L4)中的注释也直接指向该规范。大小写敏感是这里的重点SSeverity与sSchema、CCode与cColumn、PPosition与pInternalPosition含义完全不同因此表键区分大小写。error_ids同样带有defaultfunction(c: string): string { return fmt(UnknownErrorId%s, c); }遇到未定义的字段代码会生成UnknownErrorIdcode占位值。四、在事件处理中的实际调用链这两个表本身不产生日志它们是在 main.zeek 的事件处理器中被消费的。理解调用链有助于知道表中字符串最终出现在日志的哪个位置。4.1 认证编号 →backend_arg当服务端返回认证请求时PostgreSQL::authentication_request事件被触发main.zeek 使用auth_ids将编号翻译成名称并拼入backend_argevent PostgreSQL::authentication_request(c: connection, identifier: count, data: string) { hook set_session(c); if ( c$postgresql?$backend ! ends_with(c$postgresql$backend, auth) ) c$postgresql$backend ,auth_request; else c$postgresql$backend auth_request; if ( c$postgresql?$backend_arg ) c$postgresql$backend_arg , auth_ids[identifier]; else c$postgresql$backend_arg auth_ids[identifier]; }认证成功后authentication_ok事件会把backend置为auth_ok、success置为Tmain.zeek。4.2 错误/通知字段代码 → 拼接为键值对error_response_identified_field与notice_response_identified_field都会为每个字段生成字段名值的字符串main.zeekevent PostgreSQL::error_response_identified_field(c: connection, code: string, value: string) { hook set_session(c); local errors c$postgresql_state$errors; errors fmt(%s%s, error_ids[code], value); } event PostgreSQL::notice_response_identified_field(c: connection, code: string, value: string) { hook set_session(c); local notice fmt(%s%s, error_ids[code], value); if ( c$postgresql?$backend_arg ) c$postgresql$backend_arg , notice; else c$postgresql$backend_arg notice; }随后error_response事件会把累积的字段用逗号拼接、清空状态向量并将success置为Fmain.zeek。这些事件本身由 Spicy 解析器通过 postgresql.evt 的规则触发on PostgreSQL::ErrorIdentifiedField - event PostgreSQL::error_response_identified_field($conn, (%c % self.code), self.value); on PostgreSQL::NoticeIdentifiedField - event PostgreSQL::notice_response_identified_field($conn, (%c % self.code), self.value);对应的 Spicy 单元定义在 postgresql.spicyErrorIdentifiedField/NoticeIdentifiedField由1 字节代码 以\x00结尾的值构成ErrorResponse/NoticeResponse则是该字段的数组加上结尾空字节。4.3 从测试基线看实际输出仓库的 btest 基线数据直观展示了翻译结果。以 psql-create-insert-select 测试基线 为例一条真实的postgresql.log记录长这样ts uid id.orig_h id.orig_p id.resp_h id.resp_p user database application_name frontend frontend_arg backend backend_arg success rows ... CHhAvVGS1DHFjwGM9 127.0.0.1 40190 127.0.0.1 5432 postgres postgres psql startup - auth_ok SASL,SASLContinue,SASLFinal T - ... CHhAvVGS1DHFjwGM9 127.0.0.1 40190 127.0.0.1 5432 postgres postgres psql simple_query DROP TABLE IF EXISTS t; - SeverityLocalizedNOTICE,SeverityNOTICE,Code00000,Messagetable t does not exist, skipping,Filetablecmds.c,Line1300,RoutineDropErrorMsgNonExistent T 0 ... CHhAvVGS1DHFjwGM9 127.0.0.1 40190 127.0.0.1 5432 postgres postgres psql simple_query SELECT * from t; - - T 2可以看到auth_ok行的backend_arg完整列出了SASL,SASLContinue,SASLFinal三个认证阶段对应编号 10/11/12DROP 语句产生的 NOTICE 被逐字段翻译为SeverityLocalizedNOTICE,SeverityNOTICE,Code00000,Message...,Filetablecmds.c,Line1300,RoutineDropErrorMsgNonExistent——这正是error_ids将S/V/C/M/F/L/R等单字节代码展开后的结果。仓库中还有 psql-login-fail、psql-insert-fail-drop-fail 等基线分别展示了登录失败与 SQL 执行失败时错误字段的完整翻译。五、扩展这两个表的正确姿势由于两个表都声明了redef最典型的使用场景是在站点级策略脚本中补充映射。例如在site/local.zeek或自定义脚本中load base/protocols/postgresql redef PostgreSQL::auth_ids { [13] CustomAuthMethod, }; redef PostgreSQL::error_ids { [X] CustomErrorField, };Zeek 的redef table { ... }语法会向表中追加条目default函数则保证任何未覆盖的编号/代码依然有兜底翻译。这种默认值 可重定义的组合让分析器既能保持前向兼容又能被用户按需定制。六、定位与调试建议映射定义集中在 consts.zeek该文件被 main.zeek 通过load ./consts加载属于base脚本随 Zeek 默认加载。底层解析逻辑位于 postgresql.spicy 与 postgresql.evt事件声明见 spicy-events.zeek。若要验证自己的扩展可以对照 testing/btest/Baseline/scripts.base.protocols.postgresql.* 系列基线或直接对真实 PostgreSQL 流量运行zeek -r trace.pcap并检查postgresql.log的backend_arg列。总结PostgreSQL::auth_ids与PostgreSQL::error_ids是 Zeek PostgreSQL 分析器中体量虽小却承上启下的两张常量表上游承接 Spicy 解析器产出的原始编号/代码下游将翻译结果写入postgresql.log的backend_arg字段。理解它们的默认映射、default兜底逻辑与redef扩展机制既能帮助你在排查日志时快速读懂SASL,SASLContinue,SASLFinal或SeverityLocalizedERROR,Code42P01,...这类字段的来历也能让你在协议演进或特殊需求面前自如地扩展映射。赞分享网络安全网络IDS【免费下载链接】zeekZeek is a powerful network analysis framework that is much different from the typical IDS you may know.项目地址https://gitcode.com/gh_mirrors/ze/zeek点击查看免费下载相关推荐Zeek 网络流量分析框架中的 PostgreSQL 协议分析base/protocols/postgresql 脚本深入解读Zeek 网络流量分析框架中的 PostgreSQL 协议分析base/protocols/postgresql 脚本深入解读 Zeek 内置的 Postgr网络安全网络IDSZeek 的 PostgreSQL 协议分析器postgresql.log 日志深度解析与源码级实现Zeek 的 PostgreSQL 协议分析器postgresql.log 日志深度解析与源码级实现 导读 Zeek 在 7.1 版本起内置了一个基于 Spi网络安全网络IDSZeek PostgreSQL 协议分析器深度解析从 Spicy 解析器到 postgresql.log 的完整链路Zeek PostgreSQL 协议分析器深度解析从 Spicy 解析器到 postgresql.log 的完整链路 本文以 Zeek 仓库中 scripts网络安全网络IDS创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考