3. Zeek配置体系与启动流程
Zeek 单机运行时,只需要一条 zeek -i eth0 命令即可抓包分析。但在生产网络中,流量往往分散在多个网段、多个采集口,甚至需要多台机器协同处理。这时就要引入 Zeek 自带的集群管理框架 zeekctl。理解 zeekctl 与几个核心配置文件的分工,是搭建可运维 Zeek 集群的第一步。
一、zeekctl 的角色:集群的“控制面”
zeekctl 是一个 Python 编写的命令行管理工具,它本身不解析流量,而是负责生成配置、启动/停止进程、监控状态、轮转日志。它把一份份声明式配置翻译成实际的 Zeek 进程拓扑。常用子命令包括:
zeekctl check # 校验配置语法与节点定义
zeekctl deploy # 安装配置并启动/重启集群
zeekctl status # 查看各节点运行状态
zeekctl stop # 停止全部节点
zeekctl diag # 输出诊断信息(崩溃、日志、配置快照)
可以把 zeekctl 理解为“控制面”,而真正跑在网卡上抓包的是它拉起的“数据面”进程。控制面与数据面分离,是 Zeek 集群化设计的核心。
二、四类配置文件的职责划分
Zeek 集群的配置集中在安装目录(通常 /opt/zeek/etc 与 /opt/zeek/share/zeek/site)下,各文件职责边界清晰:
- node.cfg:定义“有哪些节点、各自是什么角色、监听哪个接口”。这是集群拓扑的唯一来源。每个节点用一段
[节点名]描述,关键字段有type(standalone / manager / proxy / worker / logger)、host(所在主机)、interface(抓包接口)、lb_method(负载均衡方式)、lb_procs(worker 进程数)。 - networks.cfg:定义“哪些网段属于本地网络”。每行一个 CIDR,用于让 Zeek 判断源/目的地址是内网还是外网,直接影响
local_orig、local_resp等字段以及扫描、外联类告警的判定。 - site/local.zeek:定义“加载哪些脚本、启用哪些策略”。它是站点级脚本入口,通过
@load引入框架脚本和自定义脚本,并可覆盖变量、调整阈值。它决定“分析什么、告警什么”。 - zeekctl.cfg:定义“zeekctl 自身的行为”,如日志目录
LogDir、邮件通知MailTo、崩溃重启策略CrashesToReport等,属于运维参数而非分析逻辑。
一句话概括分工:node.cfg 管拓扑,networks.cfg 管地址空间,local.zeek 管分析逻辑,zeekctl.cfg 管运维行为。四者互不越界,修改后由 zeekctl deploy 统一生效。
三、node.cfg 的典型写法
下面是一个双 worker 的集群示例(示例参数,非实测环境):
[manager]
type=manager
host=localhost
[proxy-1]
type=proxy
host=localhost
[worker-1]
type=worker
host=localhost
interface=eth0
lb_method=custom
lb_procs=2
[logger-1]
type=logger
host=localhost
其中 lb_procs=2 表示在该 worker 节点上启动 2 个抓包进程,配合 lb_method 实现多进程负载均衡。若只有单机单口,可只保留一个 type=standalone 节点,此时不需要 manager/proxy/logger。
四、networks.cfg 与 local.zeek 的配合
networks.cfg 内容非常简洁,每行一个网段:
10.0.0.0/8
192.168.0.0/16
172.16.0.0/12
它不产生任何脚本逻辑,但为脚本提供“本地/外部”判断依据。例如 scan.zeek 判断某地址是否在本地网段内,从而决定是否触发扫描告警。若漏配内网段,内网横向扫描可能被误判为外网扫描,告警质量明显下降。
site/local.zeek 则是脚本入口,典型内容:
@load base/protocols/conn
@load base/protocols/http
@load base/protocols/dns
@load policy/protocols/ssl/validate-certs
@load policy/frameworks/notice/community-id
redef Site::local_nets += { 10.10.0.0/16 };
redef Notice::emailed_types += { Scan::Address_Scan };
这里 @load 决定加载哪些分析脚本,redef 用于覆盖默认变量。注意:Site::local_nets 与 networks.cfg 存在关联——zeekctl 会把 networks.cfg 的内容注入到 Site::local_nets,因此两者应保持一致,避免冲突。
五、集群化启动与状态管理
配置完成后,标准启动流程是:
zeekctl check:校验 node.cfg 语法、接口是否存在、脚本能否加载。任何一项失败都会给出明确报错,先修配置再继续。zeekctl deploy:安装配置、生成各节点脚本、按拓扑启动进程。首次部署会创建日志目录与状态文件。zeekctl status:查看每个节点状态。正常输出类似worker-1 running;若显示crashed,需用zeekctl diag worker-1查看崩溃原因。zeekctl stop/zeekctl restart:停止或重启集群,常用于脚本更新后重新加载。
状态管理的关键在于理解“进程状态”与“配置状态”是两回事。zeekctl status 反映的是进程是否存活;而配置是否生效,要看 deploy 是否成功执行。修改 local.zeek 后若不 deploy,运行中的进程仍使用旧脚本。因此运维习惯应是:改配置 → check → deploy → status 确认。
zeekctl status 显示某 worker 反复 crashed,优先检查三处:接口名是否写错(interface=)、是否有权限抓包(需 root 或 CAP_NET_RAW)、local.zeek 中 @load 的脚本路径是否存在。用 zeekctl diag 可一次性拿到崩溃日志与配置快照,比逐个文件排查高效得多。