Zeek
简介
Zeek(原名Bro)是一款开源的网络流量分析框架,专注于实时网络监控、安全检测与协议分析。它不仅是入侵检测系统(IDS),更是一个强大的网络取证和威胁狩猎平台。
Zeek的核心特性
-
协议深度解析
-
支持协议:HTTP、DNS、SSL/TLS、SSH、SMTP、FTP、DHCP等30+协议。
-
解析能力:自动提取协议字段(如HTTP URL、DNS查询、SSL证书信息)。
-
-
事件驱动模型
-
事件生成:将网络行为转化为事件(如http_request、dns_query、ssh_login)。
-
脚本扩展:通过.zeek脚本定义检测规则或自定义分析逻辑。
-
-
结构化日志输出
-
默认日志:生成conn.log(连接记录)、http.log(HTTP请求)、dns.log(DNS查询)等。
-
格式灵活:支持JSON、TSV格式,便于集成ELK、Splunk等分析平台。
-
-
高性能架构
-
多线程处理:支持分布式集群部署,处理高吞吐量网络流量(如10Gbps+)。
-
流量分片:按IP、端口等字段将流量分发到多个Worker节点。
-
Zeek的架构组成
-
流量捕获层
-
底层引擎:基于Libpcap/PF_RING/AF_Packet抓包,支持网卡旁路(Tap/SPAN端口)。
-
流量过滤:通过BPF表达式(如tcp port 80)过滤无关流量。
-
-
事件引擎
-
协议解析:将原始数据包解析为结构化事件。
-
事件触发:开发者通过事件(如http_request)编写检测逻辑。
-
-
策略脚本
-
内置脚本库:提供100+预置脚本(如检测端口扫描、SSL证书异常)。
-
自定义规则:用户可编写.zeek脚本实现特定检测需求。
-
-
日志与通知系统
-
日志分类:不同协议/行为生成独立日志文件。
-
实时告警:通过NOTICE事件触发告警(如邮件、Webhook)。
-
Zeek的典型应用场景
-
入侵检测(IDS)
-
暴力破解检测:识别SSH/RDP的频繁失败登录。
-
Web攻击识别:SQL注入、XSS、Web Shell访问。
-
恶意软件通信:检测C2服务器连接、DGA域名请求。
-
-
网络取证
-
文件提取:自动保存传输的文件(如恶意软件样本)。
-
数据外传分析:识别大文件传输、异常数据流。
-
-
威胁狩猎
-
异常行为分析:检测横向移动、内部扫描、隐蔽隧道。
-
JA3指纹追踪:通过TLS指纹识别特定恶意软件家族。
-
-
流量统计与合规
-
带宽监控:统计协议流量分布、TOP会话。
-
合规审计:记录DNS查询、HTTPS域名访问。
-
Zeek与其他工具对比
工具 | 定位 | 核心能力 | 适用场景 |
---|---|---|---|
Zeek | 网络流量分析框架 | 协议解析、行为建模、深度日志 | 威胁狩猎、取证、定制化检测 |
Suricata | 多线程IDS/IPS | 基于规则的实时流量检测与阻断 | 高性能签名匹配、威胁防御 |
Snort | 轻量级IDS | 基础流量检测、社区规则支持 | 中小型网络基础防护 |
Wireshark | 协议分析工具 | 数据包抓取与手动分析 | 网络调试、协议学习 |
官网:https://docs.zeek.org/en/master/
github:https://github.com/zeek/packages
安装使用
安装
官网提供多种安装方式:https://zeek.org/get-zeek/
这里使用Linux Binary Packages 为Ubuntu 22.04安装,命令如下:
echo ‘deb http://download.opensuse.org/repositories/security:/zeek/xUbuntu_22.04/ /’ | sudo tee /etc/apt/sources.list.d/security:zeek.list
curl -fsSL https://download.opensuse.org/repositories/security:zeek/xUbuntu_22.04/Release.key | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/security_zeek.gpg > /dev/null
sudo apt update
sudo apt install [zeek, zeek-6.0, zeek-7.0, or zeek-nightly] # 可选一个
检测安装,执行以下命令,成功会输出结果:
zeek --version
修改配置文件
- 在 $PREFIX/etc/node.cfg 文件中, 设置监测设备的正确接口interface。设置要监视的正确网卡,我的网卡是ens33,不知道安装在那个路径的可执行whereis zeek命令
[zeek]
type = standalone # 节点类型为独立运行
host = localhost # 本机运行
interface = eth33 # 监控的网络接口 - 在 $PREFIX/etc/networks.cfg 文件中,注释掉默认设置,然后添加监测环境的本地网络。
#语法:
#10.0.0.0/8 Private_Net # 内部网络
#192.168.1.0/24 DMZ_Zone # DMZ区域
#0.0.0.0/0 Public_Net # 所有公网流量(默认)# 示例:只监控特定子网
10.10.10.0/24 #注意:一定要使用子网掩码方式
- 设置环境变量
vim ~/.bashrc
export PATH=$PATH:/opt/zeek/bin
source ~/.bashrc
sudo chmod -R 777 /opt/zeek/ # 非root用户需要执行
启动
先在终端执行
zeekctl
由于是第一次使用,执行ZeekControl配置的初始化安装
[ZeekControl] > install
启动Zeek
start
如果尝试启动Zeek实例时遇到了错误,你可以使用 diag 命令查看细节。如果启动成功,Zeek实例就会开始根据默认策略分析流量,然后输出结果到 $PREFIX/logs (即/opt/zeek/logs)文件夹中。
启动之后它就会一直运行下去,如果想停止Zeek实例,可以命令:
[ZeekControl] > stop
文件介绍
Zeek的current目录文件解析
Zeek运行时生成的日志默认存储在 /opt/zeek/logs/current/(默认安装路径)中,每个文件对应不同的协议或分析模块。以下是常见文件及其用途:
文件名 | 描述 |
---|---|
conn.log | 所有网络连接记录(IP、端口、协议、流量大小、持续时间等) |
http.log | HTTP请求详情(URL、请求方法、User-Agent、状态码、MIME类型等) |
dns.log | DNS查询记录(查询域名、响应IP、TTL、DNS响应码等) |
ssl.log | TLS/SSL连接信息(证书、加密算法、TLS版本、JA3指纹等) |
files.log | 文件传输记录(文件名、哈希值、MIME类型、来源IP等) |
notice.log | 安全告警日志(如暴力破解、端口扫描等检测到的异常事件) |
weird.log | 异常协议行为记录(如畸形数据包、协议不匹配等) |
packet_filter.log | 数据包过滤规则匹配日志 |
x509.log | SSL/TLS证书详细信息(证书颁发者、有效期、公钥算法等) |
node.cfg 配置文件
作用:定义 Zeek 节点的角色和运行参数(单机或集群部署)。
单机模式:
[zeek]
type = standalone # 节点类型为独立运行
host = localhost # 本机运行
interface = eth0 # 监控的网络接口
关键参数:
-
interface:指定监听的网卡(如 eth0、ens192)。
-
lb_procs:指定Worker进程数(多核优化,如 lb_procs=4)。
-
pin_cpus:绑定CPU核心(如 pin_cpus=0,1,2,3)。
集群模式:
[manager]
type = manager # 管理节点(负责日志汇总)
host = 10.0.0.1 # 管理节点IP
pin_cpus = 0 # 绑定到CPU0
[worker-1]
type = worker # 工作节点(处理流量)
host = 10.0.0.2 # 工作节点IP
interface = eth0 # 监听的网卡
lb_procs = 4 # 启动4个Worker进程
pin_cpus = 1,2,3,4 # 绑定到CPU1-4
[proxy]
type = proxy # 代理节点(转发日志)
host = 10.0.0.3
pin_cpus = 5
关键角色:
-
Manager:汇总日志、协调集群。
-
Worker:实际处理流量(可配置多个)。
-
Proxy:转发日志到外部系统(如Elasticsearch)。
network.cfg 配置文件
作用:定义 Zeek 监控的网络范围(CIDR格式),用于过滤无关流量。
#语法:
10.0.0.0/8 Private_Net # 内部网络
192.168.1.0/24 DMZ_Zone # DMZ区域
0.0.0.0/0 Public_Net # 所有公网流量(默认)# 示例:只监控特定子网
10.10.10.0/24 Monitoring_Net
关键说明:
-
CIDR格式:指定IP范围(如 10.0.0.0/8)。
-
TAG:自定义标签(用于日志分类,如 Internal、External)。
-
默认行为:如果不配置,Zeek会监控所有流量。
集群部署方式
-
Zeek集群架构
典型的Zeek集群由以下节点组成:节点类型 作用 Manager 协调集群、汇总日志、存储状态信息(必须唯一) Worker 实际处理网络流量的节点(可水平扩展多个) Proxy 转发日志到外部系统(如SIEM、Kafka),可选部署 -
环境要求
-
硬件要求
-
Manager:2核CPU/4GB内存/50GB存储(管理元数据)
-
Worker:4核CPU+/8GB内存+/SSD硬盘(按流量负载扩展)
-
网络:节点间需低延迟通信(建议同机房或VPC内网)
-
-
环境要求
-
操作系统:所有节点使用相同Linux发行版(推荐Ubuntu 20.04+或CentOS 7+)
-
Zeek版本:所有节点安装相同版本的Zeek(建议6.0+)
-
SSH互信:Manager节点需要能免密SSH登录所有Worker节点
-
-
-
部署方式
-
配置Manager节点,编辑 /opt/zeek/etc/node.cfg
[manager] type=manager host=10.0.0.1 # Manager节点的IP pin_cpus=0 # 绑定到CPU0 [worker-1] type=worker host=10.0.0.2 # Worker1的IP interface=eth0 # 监听的网卡 lb_procs=4 # 启动4个Worker进程 pin_cpus=1,2,3,4 # 绑定到CPU1-4 [worker-2] type=worker host=10.0.0.3 # Worker2的IP interface=eth0 lb_procs=4 pin_cpus=1,2,3,4 [proxy] type=proxy host=10.0.0.4 # Proxy节点IP
-
配置网络范围,编辑 /opt/zeek/etc/networks.cfg
# 定义内部网络(不分析内部流量) 10.0.0.0/8 Private_Network 192.168.1.0/24 Office_LAN # 监控所有外部流量 0.0.0.0/0 EXTERNAL
-
同步配置文件,从Manager节点同步配置到所有Worker/Proxy节点
#使用scp或Ansible同步
scp -r /opt/zeek/etc/ root@10.0.0.2:/opt/zeek/
scp -r /opt/zeek/etc/ root@10.0.0.3:/opt/zeek/ -
在Manager节点执行:
#初始化集群
zeekctl install
# 启动服务
zeekctl deploy
# 检查状态
zeekctl status -
预期输出:
Name Type Host Status Pid Started
manager manager 10.0.0.1 running 12345 2023-08-01 10:00
worker-1 worker 10.0.0.2 running 12346 2023-08-01 10:00
worker-2 worker 10.0.0.3 running 12347 2023-08-01 10:00
proxy proxy 10.0.0.4 running 12348 2023-08-01 10:00
-
将 Zeek 与 ELK 栈集成
一、环境准备
-
操作系统:Ubuntu 22.04
-
ELK版本:8.10.1(需保持Elasticsearch、Logstash、Kibana版本一致)
-
服务器IP:
-
Elasticsearch: 10.0.0.10
-
Logstash: 10.0.0.11
-
Kibana: 10.0.0.12
-
Zeek: 10.0.0.20(日志目录 /opt/zeek/logs/)
-
二、安装与配置 Elasticsearch(带安全认证)
-
安装 Elasticsearch
# Ubuntu wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-8.10.1-amd64.deb sudo dpkg -i elasticsearch-8.10.1-amd64.deb # CentOS wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-8.10.1-x86_64.rpm sudo rpm -ivh elasticsearch-8.10.1-x86_64.rpm
-
配置安全认证
编辑 /etc/elasticsearch/elasticsearch.yml:cluster.name: zeek-cluster node.name: es-node-1 network.host: 10.0.0.10 http.port: 9200 # 启用安全功能 xpack.security.enabled: true xpack.security.authc.api_key.enabled: true # 配置TLS(自动生成证书) xpack.security.transport.ssl.enabled: true xpack.security.http.ssl.enabled: true
-
启动并设置密码
sudo systemctl start elasticsearch sudo systemctl enable elasticsearch # 自动生成内置用户密码 sudo /usr/share/elasticsearch/bin/elasticsearch-setup-passwords auto
保存输出的密码(如 elastic 用户的密码)。
三、安装与配置 Logstash
-
安装 Logstash
# Ubuntu wget https://artifacts.elastic.co/downloads/logstash/logstash-8.10.1-amd64.deb sudo dpkg -i logstash-8.10.1-amd64.deb # CentOS wget https://artifacts.elastic.co/downloads/logstash/logstash-8.10.1-x86_64.rpm sudo rpm -ivh logstash-8.10.1-x86_64.rpm
-
配置 Logstash 管道
创建配置文件 /etc/logstash/conf.d/zeek.conf:
input { beats { port => 5044 ssl => false # 如果跨公网需启用SSL } } filter { if [fileset][module] == "zeek" { grok { match => { "message" => "%{TIMESTAMP_ISO8601:timestamp} %{GREEDYDATA:logdata}" } } date { match => [ "timestamp", "ISO8601" ] } } } output { elasticsearch { hosts => ["https://10.0.0.10:9200"] index => "zeek-%{+YYYY.MM.dd}" user => "elastic" password => "您的elastic密码" ssl => true cacert => "/etc/logstash/http_ca.crt" # 从ES服务器复制证书 } }
复制Elasticsearch证书
```bash # 从Elasticsearch服务器复制证书 scp root@10.0.0.10:/etc/elasticsearch/certs/http_ca.crt /etc/logstash/ ```
-
启动 Logstash
sudo systemctl start logstash sudo systemctl enable logstash
四、安装与配置 Kibana
-
安装 Kibana
# Ubuntu wget https://artifacts.elastic.co/downloads/kibana/kibana-8.10.1-amd64.deb sudo dpkg -i kibana-8.10.1-amd64.deb # CentOS wget https://artifacts.elastic.co/downloads/kibana/kibana-8.10.1-x86_64.rpm sudo rpm -ivh kibana-8.10.1-x86_64.rpm
-
配置 Kibana
编辑 /etc/kibana/kibana.yml:server.host: "10.0.0.12" server.port: 5601 elasticsearch.hosts: ["https://10.0.0.10:9200"] elasticsearch.username: "elastic" elasticsearch.password: "您的elastic密码" elasticsearch.ssl.certificateAuthorities: ["/etc/kibana/http_ca.crt"]
-
复制证书并启动
# 从ES服务器复制证书 scp root@10.0.0.10:/etc/elasticsearch/certs/http_ca.crt /etc/kibana/ sudo systemctl start kibana sudo systemctl enable kibana
五、配置 Zeek 日志输出到 ELK
-
安装并配置 Filebeat
在Zeek服务器 (10.0.0.20) 操作:# 安装Filebeat wget https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-8.10.1-amd64.deb sudo dpkg -i filebeat-8.10.1-amd64.deb
-
方式一:
Filebeat 8.x 版本支持 Zeek 模块,可直接启用:
sudo filebeat modules enable zeek
然后编辑 Zeek 模块配置:
sudo nano /etc/filebeat/modules.d/zeek.yml
确保 var.paths 指向 Zeek 日志目录:
- module: zeek connection: enabled: true var.paths: ["/var/log/zeek/conn.log"] http: enabled: true var.paths: ["/var/log/zeek/http.log"] dns: enabled: true var.paths: ["/var/log/zeek/dns.log"]
编辑 Filebeat 主配置文件:
sudo nano /etc/filebeat/filebeat.yml
直接输出到 Elasticsearch(无 Logstash):
output.elasticsearch:
hosts: [“http://localhost:9200”]
username: “elastic”
password: “yourpassword”或者通过 Logstash 处理后存入 Elasticsearch:
output.logstash:
hosts: [“localhost:5044”] -
方式二(可选):
编辑 /etc/filebeat/filebeat.yml:filebeat.inputs: - type: log enabled: true paths: - /opt/zeek/logs/*.log # Zeek日志路径 fields: source: "zeek" output.logstash: hosts: ["10.0.0.11:5044"] # Logstash地址
-
启动 Filebeat
sudo systemctl start filebeat sudo systemctl enable filebeat
六、验证与使用
- 在Kibana中创建索引模式
-
访问 http://10.0.0.12:5601,使用 elastic 用户登录。
-
进入 Management > Stack Management > Index Patterns。
-
创建索引模式 zeek-*,选择时间字段 @timestamp。
-
2. 查看数据
进入 Discover,选择 zeek-* 索引,即可查看Zeek日志。
-
导入预置仪表板
- 下载Zeek的Kibana仪表板模板:
wget https://raw.githubusercontent.com/zeek/zeek/main/doc/frameworks/elasticsearch/zeek-dashboard.ndjson
- 在Kibana中进入 Stack Management > Saved Objects,点击 Import 上传文件。
快速入门示例
检测SSH暴力破解
event ssh_auth_failed(c: connection) {
SumStats::observe("ssh.fail", c$id$orig_h, 1);
}
event zeek_init() {
local reducer = SumStats::Reducer($stream="ssh.fail", $apply=set(SumStats::SUM));
SumStats::create([$name="ssh_bruteforce",
$epoch=5min,
$reducers=set(reducer),
$threshold_val(key: SumStats::Key, result: SumStats::Result) = {
return result["ssh.fail"]$sum;
},
$threshold=5,
$action=function(key: SumStats::Key, result: SumStats::Result) {
NOTICE([$note=SSH::Bruteforce,
$src=key$host,
$msg=fmt("%s 在5分钟内SSH登录失败%d次", key$host, result["ssh.fail"]$sum)]);
}]);
}