ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Zeek Cluster 集群框架完全指南:从 cluster-layout 布局到节点池、发布订阅与遥测

Zeek Cluster 集群框架完全指南:从 cluster-layout 布局到节点池、发布订阅与遥测 网络安全网络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 的 Cluster 框架scripts/base/frameworks/cluster用于建立并控制一组 Zeek 实例组成的集群把流量分析worker、策略管理manager、日志汇聚logger与中间代理proxy等职责拆分到不同节点实现横向扩展。读完本文你将掌握如何通过cluster-layout.zeek声明集群拓扑、如何用CLUSTER_NODE环境变量与load base/frameworks/cluster启用框架、节点池与话题topic机制的底层原理以及围绕集群的发布订阅、publish_on_change表格同步和遥测指标等实战接口。一、框架概览一个集群如何建立与运转根据官方文档索引doc/scripts/base/frameworks/cluster/index.rstCluster 框架提供了建立和控制一组 Zeek 实例的完整能力。它的模块组织如下main.zeek框架主体负责集群建立与控制types.zeek定义节点类型、节点记录、WebSocket 选项等核心类型pools.zeek节点池管理接口用于在集群节点间分发工作或数据pubsub.zeek话题订阅/退订接口publish-on-change.zeekpublish_on_change属性的支撑脚本telemetry.zeek集群遥测指标nodes/logger.zeek集群 logger 节点的核心脚本nodes/manager.zeek、nodes/proxy.zeek、nodes/worker.zeek其余节点类型的专用脚本。使用前提三要素要启用 Cluster 框架必须同时满足以下条件见main.zeek的模块说明存在cluster-layout.zeek该脚本必须出现在 Zeek 的脚本搜索路径ZEEKPATH中的某个位置其中包含对Cluster::nodes变量的集群定义设置节点身份通过环境变量CLUSTER_NODE或脚本变量Cluster::node告知当前实例是哪个节点加载框架像普通包一样执行load base/frameworks/cluster。从__load__.zeek可以看到实际加载流程先加载main、pools、publish-on-change、pubsub、telemetry、types六个核心文件然后在Cluster::is_enabled()为真时进一步设置节点行为——把peer_description重定义为当前节点名、开启轮询日志时把Broker::log_topic绑定到Cluster::rr_log_topic、为脚本前缀加上cluster标签最后按节点类型加载nodes/manager、nodes/logger、nodes/proxy、nodes/worker等专用脚本。值得注意的自动加载逻辑若Cluster::nodes为空框架会回退加载cluster-layout脚本若ZEEKPATH中找不到该脚本Zeek 会直接退出。zeekctl工具会自动管理这个文件。如果通过 Supervisor 框架运行受管集群则从 Supervisor 提供的节点表填充Cluster::nodes见supervisor.zeek与__load__.zeek。重要警告cluster-layout.zeek 的约束官方文档main.zeek.rst给出了明确警告cluster-layout.zeek应只包含Cluster::nodes的定义。具体而言避免加载其他 Zeek 脚本也避免对除Cluster::nodes以外的任何东西使用redef。原因是cluster-layout.zeek在加载流程中非常早被加载很容易引入循环加载circular loading问题。这是配置集群布局时的第一纪律。二、集群拓扑Cluster::nodes 与节点类型节点类型枚举types.zeek定义了参与集群配置的节点类型枚举Cluster::NodeType枚举值职责Cluster::NONE空节点类型表示本节点不运行在集群中Cluster::CONTROL允许查看/操作集群中其他节点配置的节点Cluster::LOGGER负责日志管理的节点Cluster::MANAGER负责策略管理的节点Cluster::PROXY负责中继 worker 通信并同步 worker 状态的节点Cluster::WORKER实际执行全部流量分析的节点Node 记录结构Cluster::Nodetypes.zeek用于在Cluster::nodes表中描述每个节点type Node: record { node_type: NodeType; # 节点类型 ip: addr; # 节点 IP 地址 zone_id: string default; # 非全局 IPv6 时的 RFC 4007 zone_id p: port default0/unknown; # 节点监听对等连接的端口0/unknown 表示未预配置监听 manager: string optional; # 该节点使用的 manager 节点名worker/proxy 使用 id: string optional; # broker 框架分配的节点唯一标识仅在连接期间设置 metrics_port: port optional; # 暴露给 Prometheus 的指标端口覆盖 Telemetry::metrics_port };其中的NamedNode记录types.zeek则把节点名与Node记录打包在一起用于带名字地引用集群节点。布局定义与节点身份Cluster::nodesmain.zeek是集群布局定义类型为table[string] of Cluster::Node默认{}。它应当放在ZEEKPATH中某个名为cluster-layout.zeek的脚本里并在设置了CLUSTER_NODE环境变量时被自动加载zeekctl会全自动处理这一切。表格通常以节点名称/标签为索引例如manager、worker-1。Cluster::nodemain.zeek默认值直接来自环境变量const node getenv(CLUSTER_NODE) redef;——每个集群实例启动时通常在命令行上提供它。启动某个实例时该实例根据Cluster::node在Cluster::nodes中的索引确定自己扮演什么角色。三、核心可重定义选项redef一览框架在main.zeek中提供了大量redef选项下表汇总详细说明见main.zeek.rst选项类型默认值含义Cluster::nodestable[string] of Cluster::Node{}集群布局定义置于cluster-layout.zeekCluster::nodestring当前实例的节点名通常由命令行CLUSTER_NODE提供Cluster::manager_is_loggerboolTmanager 是否兼任 logger 接收日志仅在Cluster::nodes未指定 logger 时才应为真Cluster::enable_round_robin_loggingboolT是否在可用 logger 节点间轮询分发日志消息Cluster::retry_intervalinterval1.0 sec集群节点间失败连接的重试间隔环境变量ZEEK_DEFAULT_CONNECT_RETRY以秒为单位可覆盖此选项Cluster::default_store_dirstring为未显式指定文件路径的持久化后端自动基于数据存储名在此目录内创建路径Cluster::logger_topicstringzeek/cluster/logger与 logger 节点相关消息的话题名Broker 后端Cluster::manager_topicstringzeek/cluster/manager与 manager 节点相关消息的话题名Broker 后端Cluster::proxy_topicstringzeek/cluster/proxy与 proxy 节点相关消息的话题名Broker 后端Cluster::worker_topicstringzeek/cluster/worker与 worker 节点相关消息的话题名Broker 后端Cluster::node_topic_prefixstringzeek/cluster/node/与具名节点相关消息的话题前缀Broker 后端Cluster::nodeid_topic_prefixstringzeek/cluster/nodeid/与唯一节点相关消息的话题前缀Broker 后端注意logger_topic、manager_topic、proxy_topic、worker_topic在 ZeroMQ 后端policy/frameworks/cluster/backend/zeromq/options.zeek下会被重定义为zeek.cluster.logger、zeek.cluster.manager、zeek.cluster.proxy、zeek.cluster.worker形式。广播话题集合Cluster::broadcast_topicsmain.zeek是一个set[string]常量默认包含四个话题{ zeek/cluster/manager, zeek/cluster/logger, zeek/cluster/proxy, zeek/cluster/worker }官方文档特别解释了为什么没有公共广播话题当前不存在一个对所有节点广播的公共话题因为启用隐式 Broker 转发会为该话题造成路由环路routing loop。四、话题Topic机制向指定节点发送消息话题获取函数框架提供两个可重定义的话题函数定义于 ZeroMQ 后端options.zeekCluster::node_topic(name: string): string根据节点名如manager返回该节点专属话题字符串用于向指定集群节点独占发送消息Cluster::nodeid_topic(id: string): string根据节点 ID来自Broker::EndpointInfo或Broker::node_id返回专属话题Cluster::node_id(): string返回当前节点标识符。默认是Broker::node_id可被其他集群后端重定义该标识符是短生命周期的节点重启时会被重置。节点身份换算Cluster::nodeid_to_node(id: string): Cluster::NamedNodemain.zeek根据后端特有的节点 ID 换算出集群级命名若未知则返回一个名字为空的nullNamedNode实例。发布订阅接口pubsub.zeek提供了最朴素的订阅接口# 订阅话题成功返回 T否则 F Cluster::subscribe(topic: string): bool # 退订话题 Cluster::unsubscribe(topic: string): bool每一次subscribe调用都会触发钩子Cluster::on_subscribe每一次退订触发Cluster::on_unsubscribe——这两个钩子的签名均为hook (topic: string): bool从钩子中 break 不会产生任何效果仅作观察用途。注意文档中on_unsubscribe的描述文字写的是invoked for every subscribe call但结合源码位置pubsub.zeek可以推断它实际服务于退订流程。节点状态事件Broker 后端下框架会在本地触发以下事件main.zeekCluster::node_up(name: string, id: string)集群节点连接或重连时在本地触发Cluster::node_down(name: string, id: string)已连接的集群节点断开时在本地触发Cluster::hello(name: string, id: string)节点广播自己的用户定义名与生命周期内唯一的标识字符串该字符串在节点死亡并重连后可能变化。连接控制钩子Cluster::connect_node_hook(connectee: Cluster::NamedNode): boolmain.zeek在本节点根据集群布局连接其他节点时被调用从该钩子中 break 将阻止连接建立。该钩子仅适用于 Broker 集群后端。五、节点池Pools分发工作与数据的抽象pools.zeek定义了管理集群节点池的接口。池是在集群节点间分发工作或数据的有用方式框架自动维护池内节点的成员关系与可用性。三个内建池池对应规范PoolSpec说明Cluster::logger_poolCluster::logger_pool_spec包含集群全部 logger 节点Cluster::proxy_poolCluster::proxy_pool_spec包含集群全部 proxy 节点Cluster::worker_poolCluster::worker_pool_spec包含集群全部 worker 节点各PoolSpec默认值如下logger_pool_spec示例其余类似{ topiczeek/cluster/pool/logger node_typeCluster::LOGGER max_nodesuninitialized # 未设置则加入所有可用节点 exclusiveF }ZeroMQ 后端会将其重定义为Cluster::PoolSpec($topiczeek.cluster.pool.logger, $node_typeCluster::LOGGER)形式。PoolSpec 与 PoolNodeCluster::PoolSpec记录pools.zeek字段如下topic可用于到达池内全部节点的话题字符串node_type池内节点类型max_nodes可选池内最大节点数。未设置时加入所有可用节点设置后框架按阈值自动限制池成员数exclusive可选默认F池是否要求独占节点。若为T则max_nodes个节点不会被分配给任何其他池使用此标志时必须同时设置max_nodes。Cluster::PoolNode记录pools.zeek保存池内节点的运行状态name节点名、alias用于避免生成site_id时的哈希碰撞、site_id由 name/alias 派生的 32 位唯一标识、alive节点当前是否存活可接收工作默认F、topicCluster::node_topic的预计算结果。池操作函数Cluster::register_pool(spec: Cluster::PoolSpec): Cluster::Pool注册并初始化一个池pools.zeekCluster::hrw_topic(pool: Cluster::Pool, key: any): string通过任意 key 的Rendezvous hash最高随机权值哈希把 key 均匀映射到可用节点返回对应话题若无存活节点返回空串pools.zeek。底层使用scripts/base/utils/hash_hrw.zeekCluster::rr_topic(pool: Cluster::Pool, key: string default optional): string以轮询方式返回存活节点的话题pools.zeek。key用于标识请求话题的目的例如使用命名空间化的 key如Intel::cluster_rr_key可保证一组消息按既定模式分发而不与其他消息交错通常共享默认 key 对负载均衡已足够Cluster::rr_log_topic(id: Log::ID, path: string): string在 logger 节点间轮询分发日志话题pools.zeek。当Cluster::enable_round_robin_logging开启时自动赋给Broker::log_topic若没有存活 logger 节点则返回Broker::default_log_topic的值。六、publish_on_change 表格同步publish-on-change.zeek是publish_on_change属性的支撑脚本。核心接口# 把带 publish_on_change 属性的表用多条 table_change_infos 事件发布到指定话题 Cluster::publish_table(topic: string, table_val: any, batch_size: count defaultCluster::default_publish_table_batch_size optional): booltopic发布Cluster::table_change_infos事件的目标话题通常由Cluster::node_topic或Cluster::nodeid_topic生成table_val要发布的表必须带publish_on_change属性batch_size每个事件携带的Cluster::TableChangeInfo记录数默认取Cluster::default_publish_table_batch_size。Cluster::default_publish_table_batch_size默认值为10000用于控制大批量表格同步时每个事件的消息条数避免单条事件过大。七、集群遥测Telemetrytelemetry.zeek位于Cluster::Telemetry命名空间为集群通信提供可观测性。Cluster::Telemetry::Type枚举定义了三个指标层级枚举值生成内容Cluster::Telemetry::INFO为入站/出站事件创建无标签的计数器指标Cluster::Telemetry::VERBOSE为入站/出站事件创建带 handler 名与规范化话题名标签的计数器指标Cluster::Telemetry::DEBUG使用序列化消息大小创建直方图指标按话题、handler 与脚本位置仅出站标记可重定义选项Cluster::Telemetry::core_metrics: set[Type] redef默认{ Cluster::Telemetry::INFO }——core 后端启用的遥测类型Cluster::Telemetry::websocket_metrics: set[Type] redef默认{ Cluster::Telemetry::INFO }——WebSocket 后端启用的遥测类型Cluster::Telemetry::message_size_bounds: vector of double redef默认[10.0, 50.0, 100.0, 500.0, 1000.0, 5000.0, 10000.0, 50000.0]——DEBUG 指标使用的直方图分桶Cluster::Telemetry::topic_normalizations: table[pattern] of string ordered redef默认{ [/^?(^zeek\/cluster\/nodeid\/.*)$?/] zeek/cluster/nodeid/__normalized__ }——用于规范化含随机部分的话题名映射为空字符串可完全跳过记录某指标。ZeroMQ 后端追加zeek.cluster.nodeid.*的对应规则。八、集群日志Cluster::log 与 Info 记录框架定义了Cluster::Info记录main.zeek作为集群日志流的列结构带log属性ts: time log集群消息生成时间node: string log产生日志记录的节点名message: string log描述集群运行状态的消息。配合日志流标识Cluster::LOG对Log::ID枚举的重定义可用Cluster::log(msg: string)向集群日志流写入消息。Cluster::log_policy是该流的默认Log::PolicyHook策略钩子。九、Logger 节点日志汇聚与 zeek-archiver 兼容轮转nodes/logger.zeek是支持集群 logger 概念的核心脚本。logger 是被动角色——其他 Zeek 实例连接到它连接建立后 logger 接收来自其他实例的日志。脚本会根据所启动节点的类型被自动加载。关键日志重定义该脚本对日志框架做了一系列针对 logger 角色的设置prefixes cluster-logger ## 打开本地日志logger 应只在本地写日志 redef Log::enable_local_logging T; ## 关闭远程日志 redef Log::enable_remote_logging F; ## 日志轮转间隔 redef Log::default_rotation_interval 1 hrs; ## 告警摘要邮件间隔 redef Log::default_mail_alarms_interval 24 hrs;多 logger 时的日志后缀当Cluster::nodes配置了多个 logger 时脚本在加载时自动在archiver_log_metadata表中加入[log_suffix] Cluster::node条目——这样每个 logger 轮转出的日志文件名会带上自身节点名避免多 logger 写同一路径时互相覆盖。zeek-archiver 兼容轮转archiver_log_metadata: table[string] of string redef渲染进文件名、供 zeek-archiver 解释的通用日志元数据archiver_encode_log_metadata(tbl: table[string] of string): string把元数据表编码为 zeek-archiver 理解的keyvalue,keyvalue形式值为空视为有意跳过键或值包含,或时发出Reporter::warning并跳过该条目archiver_rotation_format_func(ri: Log::RotationFmtInfo): Log::RotationPath以 zeek-archiver 兼容格式轮转日志生成path__open__close__metadata__形式的基础文件名。若使用 Supervisor 框架会自动采用此函数否则可手动将Log::rotation_format_func设为它。受管supervised模式下还会把Log::default_rotation_dir重定义为log-queue。十、WebSocket 服务端listen_websocket 与 TLS框架支持把 Zeek 实例作为 WebSocket 服务端供外部客户端连接。核心入口为Cluster::listen_websocket(options: Cluster::WebSocketServerOptions): boolmain.zeek成功返回T。Cluster::WebSocketServerOptionstypes.zeek字段listen_addr: addr optional监听地址不能与listen_host同时使用listen_port: portWebSocket 服务器监听端口max_event_queue_size: count defaultCluster::default_websocket_max_event_queue_size optional本服务器最大事件队列长度ping_interval: interval defaultCluster::default_websocket_ping_interval optionalping 间隔不响应 ping 的客户端会被断开设为负值可禁用 ping目前不支持亚秒级间隔tls_options: Cluster::WebSocketTLSOptions optionalTLS 选项默认禁用 TLS。相关默认选项Cluster::default_websocket_max_event_queue_size默认32——队列满时来自外部 WebSocket 客户端的事件将被暂停处理直到队列排空此时内部指标cluster_onloop_queue_stalls带WebSocketEventDispatcher:host:port标签会被递增。Cluster::default_websocket_ping_interval默认5.0 secs。Cluster::WebSocketTLSOptionstypes.zeek字段cert_file、key_file、enable_peer_verification默认F期望对端发送客户端证书、ca_file默认为空时在启用对端验证的情况下使用实现默认 CA、ciphers默认使用实现默认密码套件。TLS 启用规则cert_file与key_file同时设置则启用 TLS两者都不设置则禁用 TLS其他任何组合都是错误配置。与 WebSocket 相关的辅助类型还有Cluster::EndpointInfoid、network、可选的application_name——来自X-Application-NameHTTP 头与Cluster::NetworkInfoaddress、bound_port。十一、实用查询函数运行时自省框架提供一组随时可调用的自省函数main.zeekCluster::is_enabled(): bool——集群框架是否为本运行启用等价于Cluster::node是否已被设置Cluster::local_node_type(): Cluster::NodeType——当前实例将扮演的节点类型未启用时返回Cluster::NONECluster::local_node_metrics_port(): port——当前实例为 Prometheus 配置的指标端口未启用或找不到节点时返回0/unknownCluster::get_node_count(node_type: Cluster::NodeType): count——布局中定义的某类型节点数量Cluster::get_active_node_count(node_type: Cluster::NodeType): count——调用节点当前已连接的某类型节点数量主要供 manager 判断应有多少节点响应请求Cluster::init(): bool——初始化集群后端集群后端通常从zeek_init处理器调用成功返回T。十二、后端抽象与序列化标签框架通过枚举抽象出可插拔的通信后端与序列化格式main.zeekCluster::BackendTagCLUSTER_BACKEND_BROKERBroker 后端、CLUSTER_BACKEND_BROKER_WEBSOCKET_SHIMBroker 的 WebSocket shim 后端、CLUSTER_BACKEND_ZEROMQZeroMQ 后端、CLUSTER_BACKEND_NONECluster::EventSerializerTagEVENT_SERIALIZER_BROKER_BIN_V1、EVENT_SERIALIZER_BROKER_JSON_V1事件序列化格式Cluster::LogSerializerTagLOG_SERIALIZER_ZEEK_BIN_V1日志序列化格式。这解释了文档中提到的话题默认值在 ZeroMQ 后端下被改写为zeek.cluster.*风格的原因——不同后端拥有独立的话题命名空间与序列化约定。相关后端策略脚本位于scripts/policy/frameworks/cluster/backend/。十三、快速上手清单综合以上内容搭建一个最小集群的步骤归纳如下在ZEEKPATH中的某处创建cluster-layout.zeek仅定义Cluster::nodes# cluster-layout.zeek —— 只允许包含 Cluster::nodes 定义 redef Cluster::nodes { [manager] Cluster::Node($node_typeCluster::MANAGER, $ip127.0.0.1, $p5000/tcp), [worker-1] Cluster::Node($node_typeCluster::WORKER, $ip127.0.0.1, $p5001/tcp, $managermanager), };为每个实例通过环境变量指定身份并加载框架CLUSTER_NODEmanager zeek -i eth0 load base/frameworks/cluster CLUSTER_NODEworker-1 zeek -i eth1 load base/frameworks/cluster运行中用Cluster::local_node_type()确认角色用Cluster::node_up/Cluster::node_down观察节点连断用Cluster::rr_topic(Cluster::worker_pool, ...)或Cluster::hrw_topic(Cluster::worker_pool, key)把工作分发到池内节点。延伸阅读框架主体实现scripts/base/frameworks/cluster/main.zeek类型定义scripts/base/frameworks/cluster/types.zeek官方脚本文档索引doc/scripts/base/frameworks/cluster/index.rst及各模块的.zeek.rst文档如doc/scripts/base/frameworks/cluster/main.zeek.rst、doc/scripts/base/frameworks/cluster/pools.zeek.rst集群集群化部署的高级话题可参考doc/frameworks/cluster.rst与doc/cluster-setup.rstBroker 通信框架scripts/base/frameworks/brokerSupervisor 受管集群支持scripts/base/frameworks/cluster/supervisor.zeek对应框架文档doc/frameworks/supervisor.rst。赞分享网络安全网络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 集群手动拉起Spawning a Zeek Clustercluster-layout 与进程启动全指南Zeek 集群手动拉起Spawning a Zeek Clustercluster layout 与进程启动全指南 导读 本文是 Zeek 8.1 起面向网络安全网络IDSZeek Cluster 发布订阅 API 深入解析Cluster::subscribe 与 Pub/Sub 主题管理实战Zeek Cluster 发布订阅 API 深入解析Cluster::subscribe 与 Pub/Sub 主题管理实战 导读本文以 Zeek 集群框架网络安全网络IDSRatchet表单与Toggle组件教程输入组、标签与原生风格开关一步到位Ratchet表单与Toggle组件教程输入组、标签与原生风格开关一步到位 Ratchet 是一个基于简单 HTML、CSS 和 JavaScript 构建移网络安全网络IDS上一篇NAS媒体库管理工具常见问题解决方案下一篇快速调优与排障GPUStack 混合集群模型部署 FAQ 全解析创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表