Wazuh 4.x 的安装脚本把三个核心组件打包在一起,理论上一条命令就能装好。但真正动过手的人应该都有同感:最折磨人的不是装不上去,而是装完之后服务全是 active,日志里看不到明显报错,agent 也显示已连接,可告警出不来、Dashboard 里看不到数据,你根本不知道从哪下手。这篇文章就把我在安装 Wazuh 过程中踩过的那些坑,按排查路径整理了出现,适合刚接触 Wazuh、准备部署生产环境,或者已经被 one-liner 脚本劝退过的人。
1. 装之前先把这几件事定下来,能避开一半的坑
1.1 内存、CPU与部署形态:all-in-one没你想的那么万能
Wazuh 4.x 官方推荐的一体化安装听起来很美好。wazuh-install.sh会把 wazuh-manager、wazuh-indexer、wazuh-dashboard 三个核心组件全部放到同一台机器,还会顺手把 OpenSearch 安全插件、Filebeat、证书全部配好。对第一次接触的人来说,这比老版本手动配 Elasticsearch 加 Kibana 友好太多,但它也埋下了一个很现实的限制:一口吃不下太多 agent。
Wazuh 文档给出的硬件建议里,all-in-one 的最低配置是 2 核 4G,但我的实测感受是:这个配置只能让你看到登录页面,稍微推点数据就吃力。OpenSearch 的 JVM 堆默认分配 1G,manager 的 analysisd、remoted、wazuh-db 也要吃内存,三个组件挤在一起,2G 空闲内存很快见底。我在一台 4G 机器上部署后,agent 一接入,系统就频繁触发 OOM,最后进程被内核杀掉,现象是服务 state 显示 active,但 web 端口连不上。
所以我的建议是分档来:
- 纯粹学习、验证功能:2 核 4G 勉强可用,但别加太多 agent;
- 小规模生产(几十台):4 核 8G 起步;
- 几百台以上:老老实实把 indexer 和 manager 拆到不同机器。
官方也提供了分布式部署模式:生成配置时在 config.yml 里分别定义 indexer 节点、manager 节点和 dashboard 节点,然后到每台机器上跑对应的安装命令。这个选项虽然麻烦一点,但后面扩容、排障都轻松很多,值得在生产环境付出这个成本。
1.2 hostname、/etc/hosts 和时区:隐蔽性最强的三个默认值
说一个我踩得最冤的一次:装完 Wazuh 后,dashboard 能登录,但 Filebeat 始终报 x509 证书校验失败,后来排查半天发现是安装时机器 hostname 是localhost,证书 CN 也就成了localhost,配置文件里写的是管理 IP,当然校验不过。
Wazuh 的证书生成完全依赖当前机器 hostname 或 config.yml 里指定的 node name。如果你直接在一台改名过的虚拟机上跑脚本,或是 cloudinit 临时分配了主机名,证书就和实际通信地址对不上。因此安装前先固定 hostname:
sudo hostnamectl set-hostname wazuh-server然后在/etc/hosts里加一条解析:
127.0.0.1 wazuh-server注意,如果这台机器有公网访问场景,还要确认 hosts 里的内网 IP 与 config.yml 的 node IP 一致。证书里的 IP SAN 只包含你写在 config.yml 里的地址,一旦写错,后面所有组件互相访问都会出现证书校验失败。
另外,时区也是一个容易被当成故障的点。Dashboard 界面默认使用 UTC 展示时间,如果你的服务器时区是 CST,很可能会觉得告警时间快了 8 小时。这个不算安装故障,但会影响验收,建议在安装前用timedatectl set-timezone Asia/Shanghai之类的方式统一,或者在 dashboard 里手动调显示时区,并在文档里记录清楚。
1.3 出网策略和镜像源:安装报错里的“看不见的手”
Wazuh 的安装脚本执行时会做两件事:一是用系统包管理器安装依赖,二是从官方仓库下载 Wazuh 组件包。如果你的服务器处在受限网络环境(比如只能访问内网,访问外网要走公司出网网关),安装脚本很可能卡在 “Adding Wazuh repository...” 或者下载 manager 包超时。
如何判断是不是网络问题?在跑脚本前先手动验证官方仓库连通性:
curl -I https://packages.wazuh.com/4.x/如果通,再看系统仓库能不能正常更新。很多时候,安装脚本报 “Failed to download”,但你看日志又看不出具体原因,就是因为出网网关对某些域名做了限制,curl 能通,但包管理器下载大文件超时。
如果必须通过出网网关访问外部,记得把访问外部所需的网络设置同步到当前终端环境,并留意 sudo 是否继承了这些设置。不同 Linux 发行版对 sudo 环境变量的处理方式不太一样,一旦没继承,安装脚本的子进程就拿不到出网配置,会反复超时。如果完全离线,就不要硬跑官方脚本了,提前把 Wazuh 的安装包和系统依赖放到内网源里,再手工安装,这是生产环境最稳的一种做法。
2. 安装脚本中途挂了:日志、证书和“假活”状态
2.1 先学会读日志
一体化脚本跑起来以后,不管成功还是失败,都会在/root/wazuh-install-files/下生成两个重要文件:一个是config.yml(你编辑的节点配置),另一个是wazuh-install-st.log(安装过程的完整日志)。
遇到脚本红字不要慌,先看最后 200 行:
sudo tail -n 200 /root/wazuh-install-files/wazuh-install-st.log大部分错误在日志里都很直白,比如:
Failed to download packages:网络、源、出网网关问题;Unable to start service: wazuh-indexer:OpenSearch 起不来,去查它的日志;curl: (60) SSL certificate problem:证书或 hostname 问题。
我见过有人不看日志,一遍遍重复跑脚本,结果因为前一次安装残留的配置冲突,越跑越乱。正确姿势是每次失败后,先分析日志定位到具体组件,再决定是修配置还是清理重来。
2.2 证书重生成:不是重启一下脚本就行
如果问题出在证书(提示 x509、certificate mismatch、common name 之类),不要尝试手动修改已生成的.pem文件。Wazuh 的证书体系里,root CA、admin 证书、每个节点的证书都是成对存在的,改一个文件会造成链校验失败,比原来更难查。
正确做法是清掉旧文件重新生成。在 4.x 版本中:
cd /root/wazuh-install-files sudo rm -rf certs sudo bash wazuh-install.sh --generate-config-files重新生成前务必确认 config.yml 里的每台机器信息都是对的。config.yml 是证书和配置的分发蓝图,举个例子,如果你在 config.yml 里给 dashboard 节点填的 IP 是内网地址,而后端实际通过公网访问,就会一直报证书不匹配。这个文件我每次部署前都会对照服务器清单逐项核对,因为一旦跑完,再改它就需要重新生成全套证书。
2.3 服务显示 active,但功能不可用的“假活”现象
这是最容易被忽视的一类问题:脚本结束显示的 Summary 里全是 Success,systemctl status也是 active (running),但 web 端口就是打不开,或者 Dashboard 显示无法连接后端。
我第一次遇到时怀疑是防火墙,放行 443 后依旧不行,最后看 journal 才发现是 wazuh-dashboard 证书目录权限不对:
sudo journalctl -u wazuh-dashboard -n 100输出里会有Permission denied或failed to load certificate这类信息。这类权限问题通常来自之前某次失败安装留下的残留目录,root 属主挡住了服务进程的读取。解决办法是把证书目录的属主改成运行用户,或者干脆删掉 wazuh-install-files 后重新安装。
经验法则:装完以后,所有“看起来活着但不干活”的问题,都先看服务日志,别看安装日志。安装日志只告诉你安装过程是否成功,运行期的错误基本都在各自的journalctl和/var/log下。
3. OpenSearch 不健康:这个组件的问题最多
3.1 JVM 堆和系统限制:内存问题的真正位置
Wazuh indexer 本质上是 OpenSearch,它把大量索引放在内存映射里。JVM 堆分配太大会拖慢 GC,分配太小则频繁 Full GC,性能直线下降。
一体化安装后默认堆大小是 1G。对于单机学习没问题,生产环境建议根据物理内存调整:
sudo vim /etc/opensearch/opensearch-jvm.options把这两行改成合适值(比如物理内存一半,不超过 30G):
-Xms4g -Xmx4g改完重启:
sudo systemctl restart opensearch还有一个常见但文档里不容易注意的点:OpenSearch 需要较高的文件描述符和 memlock 限制。如果日志里出现max file descriptors [4096] for opensearch process is too low,就需要在/etc/security/limits.conf添加:
opensearch - nofile 65535 opensearch - memlock unlimited添加后要重新登录或重启进程才生效。这个坑在容器环境里更容易踩,很多容器默认 ulimit 很低。
3.2 yellow 不等于故障,red 才是
使用 OpenSearch 的人会习惯性看集群健康状态。如果是单节点部署,你大概率会看到状态是 yellow,因为默认每个索引的副本分片数是 1,单节点没法给副本分片分配位置。这不一定代表有问题,数据还在主分片上写着,读写正常。
但如果你在 dashboard 里看到 red,就要去查了。最常见的原因:
- 磁盘使用率超过默认的 85% watermark,分片无法分配;
- 节点反复重启,分片没恢复;
- 索引损坏或备份恢复失败。
排查分片未分配的原因:
curl -k -u admin:<password> 'https://localhost:9200/_cluster/allocation/explain?pretty'单节点部署的话,我建议直接调整索引模板把副本数设为 0,省得以后老是看到黄色状态心里发慌。方法是在 Dev Tools 里执行:
PUT /_template/wazuh { "index_patterns": ["wazuh-*"], "settings": { "number_of_replicas": 0 } }不过要说明,这只影响新建的索引。
3.3 Filebeat 与 indexer 之间的证书不对
Filebeat 负责把 manager 处理后的告警、事件转发给 indexer。很多人装完后 manager 正常,但 dashboard 里没有数据,问题基本出在 Filebeat。
先测输出连通性:
sudo filebeat test output如果报 x509 错误,说明 filebeat.yml 里配置的 host 和 indexer 证书 CN 不匹配。我一般建议写 hostname,而不是 IP:
output.elasticsearch: hosts: - https://wazuh-server:9200证书只看 CN 和 SAN,不会因为 IP 能通就通过校验。
如果输出正常,但模板没加载成功,dashboard 里可能能看到索引但字段全是原始结构。可以先手动加载模板再测试:
sudo filebeat setup --index-management4. Agent 连不上:先分清端口和注册链路
4.1 1514 和 1515 的区别要记牢
Wazuh manager 对 agent 开放两个默认端口:
- 1514/TCP(默认,也支持 UDP):事件上报通道,agent 把日志、告警发给 manager;
- 1515/TCP:agent 注册通道,首次安装时用来交换身份 key。
很多人的误区是:注册端口通了,就认为 agent 没问题。实际上 1514 没通,agent 即使注册成功,也会一直处于 disconnected 状态。
查看监听状态:
sudo ss -tlnp | grep -E '1514|1515'在部署文档里,我通常会把这两个端口单独列出来,并明确说明防火墙(firewalld、安全组、ACL)都需要放行。
4.2 注册成功的假象和 NAT 环境的坑
agent 注册有两种方式:手动运行agent-auth,或者配好<enrollment>后让 agent 自动注册。自动注册会在首次启动时连 manager 的 1515 端口,拿到 agent key 写入client.keys。
但如果 agent 和 manager 之间有 NAT、负载均衡或转发设备,这类环境特别容易出问题。比如 agent 配置里的<server_address>填的是对外 VIP,1515 端口能注册成功,但注册后 agent 会用同一个地址去连 1514 上报,如果 VIP 只映射了 1515 没映射 1514,agent 就一直连不上。这种问题从 manager 端看几乎没有报错,注册记录还是成功的。
建议在 NAT 环境里做仔细的路由核对,甚至用 tcpdump 抓包确认 1514 链路是否通:
sudo tcpdump -i any port 1514 -nn如果两端能看到握手,再查 manager 端/var/ossec/logs/ossec.log里有没有 agent 断开的具体原因。
4.3 agent 日志是你最好的朋友
agent 端出现问题时,先看:
sudo tail -n 100 /var/ossec/logs/ossec.log常见信息:
ERROR: Invalid password:注册 key 有问题;ERROR: Unable to connect to manager:网络不通或 1514 端口未监听;ERROR: (1210): Queue not accessible:本地 ossec 进程异常。
还有一个经常被忽视的兼容性点:agent 和 manager 的版本不能差太多,跨大版本通信协议可能变,虽然旧 agent 基本能上报,但很多新功能(比如某些解码规则)会失效。我一般保持主版本一致,升级时也是 manager 先升,再批量更新 agent。
5. Dashboard 能开但登录不上:密码体系要整体看
5.1 admin 是 admin,kibanaserver 是 kibanaserver
装完 Wazuh 4.x,第一次登录 dashboard 用的是admin用户,密码会在脚本输出末尾显示,也保存在/root/wazuh-install-files/wazuh-passwords.txt里。但很多人不知道,dashboard 后端访问 indexer 数据时用的是另一个内置用户kibanaserver。
如果你只改了 admin 密码,或者手动修改了 OpenSearch 里某个用户的密码但没同步,dashboard 的表现就是:登录页能打开,输入 admin 密码后反复提示认证失败,或者能登录但所有面板数据都加载不出来。
这种情况下,最省事的是用官方自带的密码重置工具把所有内置用户一次重置:
sudo /usr/share/wazuh-indexer/plugins/opensearch-security/tools/wazuh-passwords-tool.sh -a这个命令会把 admin、kibanaserver、wazuh-wui 等用户全部重置并打印新密码,然后你拿新的 admin 密码去登录 dashboard 即可。只依赖单一密码文件是不行的,因为 dashboard 里还存了一份内部连接信息的配置。
5.2 自签名证书和端口:访问不了不一定怪防火墙
Dashboard 默认 443,用的是刚生成的整套自签名证书。浏览器首次访问会有证书警告,这是正常的,选择信任即可。
如果 443 端口完全打不开,先不要急着怪防火墙,先看服务本身:
sudo systemctl status wazuh-dashboard sudo journalctl -u wazuh-dashboard -n 100证书读取失败、key 文件权限不对,都会让进程反复重启。这种情况服务 state 偶尔会是 active,但端口根本没有监听。
顺便说一句,API 端口也很关键:Wazuh manager 的 RESTful API 默认监听 55000,dashboard 里显示 agent 信息、配置策略都走这个 API。如果 55000 不通,dashboard 会显示“无法连接到 Wazuh API”,但其它页面可能正常。这又是一个容易误判的位置。
5.3 时区和显示问题:看着像故障,其实是默认值
我提过,Dashboard 默认时间显示是 UTC,如果你所在时区不是 UTC,所有告警聚合图都像慢 8 小时。不少人在验收时把这个问题当成安装故障,折腾半天。实际上 dashboard 右上角可以调整时区,但注意它是按浏览器保存的,不是全局设置。团队协作时最好在部署文档里统一约定时区,否则每个同事看到的时间可能不同。
6. 部署完成后的健康检查清单
6.1 九项检查,一项项过
安装过程到这里基本可以收尾了,但我强烈建议在接入真实 agent 之前,按下面清单完整过一遍,避免上线后再回头折腾:
- [ ]
sudo systemctl status wazuh-manager wazuh-indexer wazuh-dashboard:三个服务全部 active; - [ ]
curl -k -u admin:<password> https://localhost:9200:能返回 OpenSearch 版本信息; - [ ]
curl -k -u admin:<password> 'https://localhost:9200/_cluster/health?pretty':状态不是 red; - [ ]
sudo filebeat test output:输出显示连接成功; - [ ] 浏览器访问
https://<IP>:443,用新重置的 admin 密码能登录 dashboard; - [ ] 新增一台测试 agent,确认状态从 pending 变为 active;
- [ ] 在 dashboard 的 Security events 里能看到 agent 上报的事件;
- [ ] 防火墙和安全组放行 443、1514、1515、55000;
- [ ] 修改并保存好所有默认密码,备份 wazuh-install-files 目录。
这九项全过,才算是真正安装成功。
6.2 我踩完这些坑后形成的部署习惯
踩过几次 Wazuh 的坑之后,我现在每次部署前都会先在草稿纸上写好 hostname、IP 规划、时区、出网方式这几项,再开始跑脚本。很多看起来玄乎的报错,回头查基本都能归因到这些基础项。安装这类组件多、证书多的系统,越是相信文档里的“一条命令搞定”,越容易忽略配置细节。希望这篇踩坑记录能帮你少走几个弯。