当你管理的不再是一台 VPS,而是多台网站服务器、数据库、跳板机和员工终端时,只看 CPU、内存和在线状态无法回答更关键的问题:谁在反复尝试 SSH 登录?系统文件是否被篡改?哪台机器安装了存在已知漏洞的软件包?某条高危告警发生后,能否追溯到具体主机和时间?
Wazuh 是开源 SIEM/XDR 平台,能够集中接收 Agent 安全事件,提供文件完整性监控、漏洞检测、安全配置评估、日志分析和主动响应。本文以 Wazuh 4.14.7、Ubuntu 24.04、Docker Compose 单节点和 Caddy 为基准,从零完成服务端部署、端口收敛、HTTPS、Linux Agent 接入、告警验证、备份和升级。版本与命令依据 2026 年 9 月的 Wazuh 官方文档核对;Wazuh 5.0 仍处于预发布阶段,不应直接用于本文的生产环境。
三者关注的对象不同,不是简单替代关系:
| 工具 | 主要回答的问题 | 典型数据 | 更适合的场景 |
|---|---|---|---|
| Wazuh | 主机是否遭到攻击、篡改或存在风险 | 安全日志、文件变化、漏洞、配置基线 | SIEM、XDR、合规与终端安全 |
| Zabbix | 服务器和服务是否健康 | CPU、内存、磁盘、端口、SNMP | 基础设施可用性与容量监控 |
| Sentry | 应用为什么报错、哪次发布引入问题 | 异常、堆栈、Trace、Release | 应用错误与性能追踪 |
如果你的主要目标是性能、容量和设备状态,先看Zabbix 监控部署教程;如果要定位代码异常,选择Sentry 自托管教程。生产环境常见组合是:Zabbix 负责“系统是否正常”,Sentry 负责“应用为什么出错”,Wazuh 负责“是否发生安全事件”。
Wazuh 官方 Docker 文档给出的单节点最低要求是 4 核 CPU、8GB 内存、50GB 磁盘。这只是启动和小规模接入的下限,不是所有场景的容量承诺。日志量、Agent 数量、索引保留期和规则数量都会影响内存与磁盘。
一个实用的起步建议是:
| 规模 | 建议配置 | 说明 |
|---|---|---|
| 测试、1–5 个 Agent | 4 vCPU、8GB RAM、80GB NVMe | 控制日志量,验证流程 |
| 小型生产、5–30 个 Agent | 8 vCPU、16GB RAM、200GB NVMe | 为索引增长和升级留余量 |
| 更多 Agent 或高日志量 | 先压测,再考虑多节点 | 不要只按 Agent 数量估算 |
本文的流量路径如下:
浏览器 -> Caddy :443 -> Wazuh Dashboard :5601(仅本机)
|
+-> Wazuh Indexer(内部网络)
+-> Wazuh Manager(内部网络)
Linux Agent -> Wazuh Manager :1514(事件)
Linux Agent -> Wazuh Manager :1515(注册)
管理 API 55000/TCP、Indexer API 9200/TCP 和 Dashboard 容器端口都不应直接暴露公网。514/UDP 只在确实接收传统 Syslog 时开放。Agent 最好经 WireGuard、Tailscale 或私网接入;若只能走公网,就在云安全组和 UFW 中按 Agent 出口 IP 白名单放行 1514/1515。
准备一个域名,例如 wazuh.example.com,将 A 记录指向 VPS。没有可用 IPv6 时不要添加错误的 AAAA 记录。Ubuntu 24.04 上安装基础组件:
sudo apt update
sudo apt full-upgrade -y
sudo apt install -y git curl ca-certificates caddy
docker --version
docker compose version
如果尚未安装 Docker,请使用 Docker 官方 Ubuntu 仓库,而不是来源不明的一键脚本。部署前也建议先阅读Docker Compose 生产配置清单,理解日志轮转、健康检查、资源限制和回滚。
Wazuh Indexer 基于 OpenSearch,需要较高的虚拟内存映射数量。官方要求宿主机设置:
sudo sysctl -w vm.max_map_count=262144
printf 'vm.max_map_count=262144\n' | sudo tee /etc/sysctl.d/99-wazuh.conf
sudo sysctl --system
sysctl vm.max_map_count
最终输出应为 vm.max_map_count = 262144。若这里未生效,Indexer 常见表现是容器不断退出或无法完成启动。
不要直接检出会持续变化的默认分支。固定官方发布标签,便于复现和回滚:
sudo git clone https://github.com/wazuh/wazuh-docker.git \
-b v4.14.7 /opt/wazuh-docker
sudo chown -R "$USER":"$USER" /opt/wazuh-docker
cd /opt/wazuh-docker/single-node
git describe --tags --exact-match
预期输出是 v4.14.7。官方单节点 Compose 会启动三个核心容器:Wazuh Manager、Wazuh Indexer 和 Wazuh Dashboard,并通过命名卷持久化配置、日志、队列和索引数据。
先生成组件之间使用的 TLS 证书:
cd /opt/wazuh-docker/single-node
docker compose -f generate-indexer-certs.yml run --rm generator
find config/wazuh_indexer_ssl_certs -maxdepth 1 -type f -print
证书目录不应为空。不要把生成的私钥复制到公开仓库或工单。
官方 Compose 默认发布 Dashboard、Indexer API、Manager API 和 Syslog 等端口,适合快速体验,却不适合原样暴露到公网。为了保留官方原文件,复制一份生产配置再修改:
cd /opt/wazuh-docker/single-node
cp docker-compose.yml docker-compose.production.yml
sed -i 's/"9200:9200"/"127.0.0.1:9200:9200"/' docker-compose.production.yml
sed -i 's/55000:55000/127.0.0.1:55000:55000/' docker-compose.production.yml
sed -i 's/514:514\/udp/127.0.0.1:514:514\/udp/' docker-compose.production.yml
sed -i 's/- 443:5601/- "127.0.0.1:5601:5601"/' docker-compose.production.yml
docker compose -f docker-compose.production.yml config > /tmp/wazuh-compose-rendered.yml
grep -nE '127\.0\.0\.1|1514|1515|514|55000|9200|5601' \
/tmp/wazuh-compose-rendered.yml
不同 Compose 版本渲染格式可能不同,所以不要只相信 sed 没报错。必须检查最终配置,确认:
- Dashboard 的
5601、Indexer 的9200、Manager API 的55000和可选 Syslog514/UDP只绑定127.0.0.1; 1514/TCP和1515/TCP保留给远程 Agent,但随后要用防火墙限制来源;- 没有额外的
0.0.0.0:443映射,否则会与 Caddy 冲突。
若你完全不用 Syslog,可以直接从生产 Compose 中删除 514/UDP 映射。修改后的 docker-compose.production.yml 属于本地部署配置,升级时要与新版本官方文件重新比较,不能盲目覆盖。
拉取镜像并启动:
cd /opt/wazuh-docker/single-node
docker compose -f docker-compose.production.yml pull
docker compose -f docker-compose.production.yml up -d
docker compose -f docker-compose.production.yml ps
官方镜像版本应为 4.14.7。首次启动时 Dashboard 可能暂时显示无法连接 Indexer,通常需要等待组件初始化;不要在一分钟内看到连接警告就反复删除容器和卷。按顺序检查:
docker compose -f docker-compose.production.yml logs --tail=100 wazuh.indexer
docker compose -f docker-compose.production.yml logs --tail=100 wazuh.manager
docker compose -f docker-compose.production.yml logs --tail=100 wazuh.dashboard
curl -kI https://127.0.0.1:5601/
ss -lntup | grep -E ':1514|:1515|:514|:55000|:9200|:5601'
curl -k 只用于本机检查 Wazuh 自签名证书,不代表浏览器端可以忽略 TLS 校验。端口检查中,5601/9200/55000/514 应显示为回环地址。
Wazuh Dashboard 容器本身在 5601 使用自签名 HTTPS。Caddy 从本机回环连接它,再给外部浏览器提供受信任证书。编辑 /etc/caddy/Caddyfile:
wazuh.example.com {
encode zstd gzip
reverse_proxy https://127.0.0.1:5601 {
transport http {
tls_insecure_skip_verify
}
}
header {
Strict-Transport-Security "max-age=31536000; includeSubDomains"
X-Content-Type-Options "nosniff"
Referrer-Policy "strict-origin-when-cross-origin"
}
}
这里的 tls_insecure_skip_verify 只作用于同一台 VPS 上 Caddy 到 Wazuh 自签名上游的回环连接;外部浏览器仍由 Caddy 提供正常验证的 HTTPS。安全要求更高时,应让 Caddy 显式信任 Wazuh 的内部 CA,而不是跳过上游校验。
验证并重载:
sudo caddy validate --config /etc/caddy/Caddyfile
sudo systemctl reload caddy
curl -I https://wazuh.example.com/
证书申请失败时,检查域名解析、80/443 云安全组、UFW、错误 AAAA 记录和端口占用。可以结合UFW 导致 SSH 或服务失联的恢复指南排查,修改防火墙前始终保留一个已登录的 SSH 会话。
官方 Docker 部署的初始 Dashboard 登录是 admin / SecretPassword。这个账号只用于首次进入,不能带着默认密码对公网运行。
Wazuh 的密码不只出现在一个位置:Indexer 的 admin、Dashboard 使用的 kibanaserver,以及 Dashboard 连接 Manager API 的 wazuh-wui 分属不同配置。修改前先停止服务并备份 single-node/config/。Indexer 密码需要生成兼容哈希,并更新 config/wazuh_indexer/internal_users.yml 与 Compose 中相应引用;wazuh-wui 要同时更新 config/wazuh_dashboard/wazuh.yml 和 Compose。若密码含 $,Compose 文件中必须写成 $$。
生成 Indexer 密码哈希的官方镜像命令为:
docker run --rm -it wazuh/wazuh-indexer:4.14.7 \
bash /usr/share/wazuh-indexer/plugins/opensearch-security/tools/hash.sh
不要把真实密码直接写入 shell 历史、截图或 Git。完成所有引用的同步修改后,按照 Wazuh 官方修改默认密码文档应用安全配置并重启,再用旧密码确认登录已经失败。生产环境还应为管理员创建独立账号、启用最小权限,并尽量通过 VPN 或固定 IP 限制后台入口。
先允许当前 SSH 管理来源,再开放 Web。下面的 203.0.113.10 是文档保留示例地址,必须替换为真实 Agent 出口 IP或私网段:
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow from 203.0.113.10 to any port 1514 proto tcp
sudo ufw allow from 203.0.113.10 to any port 1515 proto tcp
sudo ufw enable
sudo ufw status numbered
不要执行无来源限制的 ufw allow 9200 或 ufw allow 55000。如果 Agent IP 经常变化,优先搭建 VPN,而不是把注册端口永久开放给整个互联网。系统基础加固还可参考VPS 安全加固清单。
Agent 应直接安装在被监控主机上。官方明确说明,容器化 Agent 无法直接访问和监控宿主机,因此不要为了“全 Docker”而把宿主机 Agent 塞进普通容器。
在被监控的 Ubuntu 24.04 主机上执行:
sudo apt-get update
sudo apt-get install -y gnupg apt-transport-https curl
curl -s https://packages.wazuh.com/key/GPG-KEY-WAZUH \
| sudo gpg --no-default-keyring \
--keyring gnupg-ring:/usr/share/keyrings/wazuh.gpg --import
sudo chmod 644 /usr/share/keyrings/wazuh.gpg
echo "deb [signed-by=/usr/share/keyrings/wazuh.gpg] https://packages.wazuh.com/4.x/apt/ stable main" \
| sudo tee /etc/apt/sources.list.d/wazuh.list
sudo apt-get update
sudo WAZUH_MANAGER="WAZUH_MANAGER_IP" apt-get install -y wazuh-agent
sudo systemctl daemon-reload
sudo systemctl enable --now wazuh-agent
sudo systemctl status wazuh-agent --no-pager
把 WAZUH_MANAGER_IP 换成 Agent 实际能够访问的 Manager 私网/VPN IP;不要填只在服务器本机有效的 127.0.0.1。Manager 版本必须不低于 Agent 版本。为了避免系统自动升级 Agent 后与 Manager 不兼容,官方建议先锁定包,规划升级时再解除:
echo "wazuh-agent hold" | sudo dpkg --set-selections
dpkg --get-selections | grep wazuh-agent
返回服务端 Dashboard,在 Agents management > Summary 查看新 Agent。若没有出现,在 Agent 上检查:
sudo tail -n 100 /var/ossec/logs/ossec.log
sudo grep -n '<address>' /var/ossec/etc/ossec.conf
nc -vz WAZUH_MANAGER_IP 1514
nc -vz WAZUH_MANAGER_IP 1515
同时在 Manager 端查看 wazuh.manager 日志和 UFW 计数。最常见原因是填错 Manager 地址、云安全组未放行、UFW 来源白名单不匹配、NAT 后出口 IP变化,或 Agent 版本高于 Manager。
“Agent 显示 Active”只代表连接成功,不代表检测链路已经验证。可以在一台测试 Agent 上创建受监控文件:
sudo mkdir -p /opt/wazuh-fim-test
echo "baseline" | sudo tee /opt/wazuh-fim-test/example.txt
在该 Agent 的 /var/ossec/etc/ossec.conf 中,将测试目录加入 <syscheck>:
<directories realtime="yes" report_changes="yes">/opt/wazuh-fim-test</directories>
修改后验证配置并重启 Agent:
sudo /var/ossec/bin/wazuh-control restart
echo "changed $(date -Is)" | sudo tee -a /opt/wazuh-fim-test/example.txt
随后在 Dashboard 的文件完整性监控事件中按 Agent 名称和路径搜索。只在测试目录使用 report_changes,不要未经评估就对包含密码、密钥或大量变化的目录开启内容差异上报,否则可能泄露敏感内容并制造告警风暴。
漏洞检测依赖 Agent 软件清单、平台支持和 Indexer 状态。可以从 Dashboard 查看 Vulnerability Detection,选择一条结果核对软件包、版本、CVE 和受影响主机。它适合帮助排序修复工作,但不能替代发行版安全公告、补丁窗口和人工确认;“检测到 CVE”也不等于该漏洞一定能在当前环境被利用。
直接把所有规则都发到邮箱或聊天群,很快会导致告警疲劳。建议先按三层设计:
- 高危、明确需要立即响应的事件,发送即时通知;
- 中危事件进入工单或日汇总;
- 低危事件只保留检索,不主动打扰值班人员。
先用前面的 FIM 测试和一次受控的失败 SSH 登录验证事件是否到达,再配置邮件、Slack、Webhook 或自定义集成。通知消息至少包含 Agent、规则 ID、等级、时间、来源地址和 Dashboard 查询入口,但不要直接附带可能含密钥的完整日志。
主动响应能够自动封禁攻击源或执行脚本,但误报可能把管理员自己锁在门外。上线前应先用仅告警模式观察,设定白名单、超时恢复和带外访问,再对少量高置信度规则启用。若 Fail2Ban 或 Wazuh 已经造成自锁,可参照Fail2Ban 解封与白名单指南恢复。
Wazuh 的命名卷让 docker compose down 后数据继续存在,但“卷还在”不是备份。误删卷、磁盘损坏和主机丢失都会同时带走数据。生产备份至少包含:
/opt/wazuh-docker/single-node/config/中的证书与组件配置;- Manager 的配置、注册密钥、队列数据库、自定义规则、解码器和集成;
- Indexer 的索引与集群状态;
- 本地生产 Compose、Caddyfile、当前 Git 标签和镜像清单;
- 一份放在另一台主机或对象存储、带校验和的副本。
先记录部署状态:
cd /opt/wazuh-docker/single-node
date -Is | sudo tee /var/backups/wazuh-backup-time.txt
git describe --tags --exact-match | sudo tee /var/backups/wazuh-version.txt
docker compose -f docker-compose.production.yml config --images \
| sudo tee /var/backups/wazuh-images.txt
docker compose -f docker-compose.production.yml config --volumes \
| sudo tee /var/backups/wazuh-volumes.txt
对索引使用 Wazuh/OpenSearch 支持的快照方案;对 Manager 数据库,官方流程会在复制数据库前停止 Manager,避免备份过程中继续写入。不要在业务持续写入时直接复制 Docker 卷,然后把它称为一致性备份。详细文件范围以 Wazuh 官方中央组件备份文档为准。
每次修改密码、规则、集成或升级前都做备份,并定期在隔离 VPS 恢复。恢复演练至少要验证:三个组件启动、管理员可登录、Agent 重新上线、历史索引可搜索、FIM 测试事件可产生。更完整的异地备份与恢复策略可参考VPS 备份策略指南。
本文固定的是 4.14.7,不代表以后永远不升级。升级前先阅读目标版本发布说明与官方 Docker 升级文档,不要把镜像标签改成 latest 后直接重启。
建议流程:
- 确认备份已离机并完成恢复抽查;
- 保存
docker-compose.production.yml与官方文件之间的差异; - 停止环境:
docker compose -f docker-compose.production.yml down; - 执行
git fetch --all --tags,检出明确的目标版本标签; - 基于目标版本新 Compose 重新应用端口收敛和密码配置;
- 用
docker compose config检查最终端口、卷和镜像; - 启动后逐项验证 Dashboard、Indexer、Manager、Agent 和测试告警。
Wazuh 官方当前升级示例同样要求检出明确标签,并说明数据和证书依靠挂载卷保持持久化。不过持久化不能替代升级前备份。Agent 也要按兼容顺序升级:先保证 Manager 不低于 Agent,再分批解除 hold、升级和观察。
先检查 sysctl vm.max_map_count 是否为 262144,再看内存和日志:
free -h
df -h
docker compose -f docker-compose.production.yml logs --tail=200 wazuh.indexer
如果日志出现内存不足,不要通过关闭安全检查掩盖问题。减少同机服务、扩容内存,或重新评估索引保留策略。
确认 Dashboard 已启动且本机 HTTPS 能访问:
curl -kI https://127.0.0.1:5601/
sudo journalctl -u caddy -n 100 --no-pager
sudo caddy validate --config /etc/caddy/Caddyfile
如果 curl 失败,问题在 Wazuh 容器或端口映射;如果本机成功而域名失败,再检查 Caddy、DNS 和防火墙。
从 Agent 到 Manager 逐层检查域名/IP、1514/1515 连通性、云安全组、UFW 来源规则、系统时间和 Agent 日志。不要为了快速恢复而开放所有端口到 0.0.0.0/0。
检查 Agent 是否 Active、Manager 是否收到事件、Indexer 是否健康,以及 Dashboard 时间范围是否覆盖测试时间。首次启动或重启后给索引初始化留出时间。
先确认是哪一个 Docker 卷增长,再看 Agent 日志量、规则噪声和索引保留。不要直接删除正在使用的 Indexer 数据目录。先做快照和恢复验证,再按官方方式调整保留或清理。
- Wazuh 固定在经过验证的发布标签,没有使用
latest - VPS 至少满足 4 核、8GB、50GB 的官方单节点下限
-
vm.max_map_count=262144已持久化 - Dashboard、Indexer API、Manager API 不直接暴露公网
-
1514/1515只允许 Agent 私网或白名单来源 - 默认
admin / SecretPassword已失效 - 每位管理员使用独立账号和最小权限
- Agent 连接、FIM 测试和通知链路已经验证
- 备份位于异机或对象存储,并做过恢复演练
- 升级前会重新检查版本说明、配置差异和回滚路径
不建议。官方 Docker 单节点最低要求是 4 核 CPU、8GB 内存和 50GB 磁盘。2GB 即使勉强拉起部分容器,也很容易在 Indexer 初始化或查询时因内存不足失败。
不能完全代替。Wazuh 重点是安全事件、漏洞、配置基线和终端检测;Zabbix 更擅长基础设施指标、容量、可用性和网络设备监控。两者可以同时使用。
本文架构主要由 Agent 连接 Manager 的 1514/1515,Agent 主机通常不需要为 Wazuh 向公网开放入站端口。Manager 端则必须让对应 Agent 网络能够访问这两个端口。
不应该。Indexer API 和 Manager API 都是高价值管理接口,应限制在容器网络、回环地址、VPN 或严格的管理网段内,不能依赖“端口不常见”来保护。
Wazuh Dashboard 默认使用自签名内部证书,Caddy 通过本机回环访问它。示例只跳过这一段上游校验,外部 HTTPS 仍正常验证。更严格的方案是让 Caddy 信任 Wazuh 内部 CA。
普通 down 不会删除命名卷,但 down -v 会删除卷。即使卷未删,也不能把它当成备份;你仍需离机保存配置、Manager 数据、Indexer 状态和恢复说明。
不建议。官方说明容器化 Agent 无法直接访问和监控宿主机。监控 VPS 宿主系统时,应把 Agent 安装到宿主机操作系统中。
Wazuh 的价值不在于“成功打开一个安全仪表盘”,而在于建立从终端采集、规则判断、告警通知到响应和恢复的闭环。稳妥的上线顺序是:先固定版本和收敛端口,再修改默认凭据、接入少量 Agent、验证 FIM 与通知,最后才逐步扩大覆盖范围。
对小型团队而言,单节点 Docker 部署足以验证和承载早期生产需求;随着 Agent、日志量和保留期增长,应根据实际索引规模评估多节点架构。无论规模大小,限制管理接口、验证备份恢复和避免告警泛滥,往往比堆叠更多规则更重要。
