没经历过 Wazuh 安装的人,永远体会不到那种"装到一半想砸键盘"的绝望。这个在安全圈被吹上天的开源 HIDS/SIEM 平台,功能确实强——文件完整性监控、入侵检测、日志分析、漏洞检测、合规基线一把抓,跟 Elastic Stack 深度集成后,可视化能力直接拉满。但谁装谁知道,从环境准备到组件拉起,每一层都是坑,轻则端口不通,重则内存直接被打爆。
我前前后后给团队搭过三套 Wazuh 环境,从单机 all-in-one 到分布式多节点都趟过一遍,踩坑记录攒了满满一屏。这篇文章就把所有能避开的坑提前帮你排掉:从系统参数调整、组件启动顺序、证书权限问题,到索引器初始化失败、Agent 注册不上、Kibana 登录 401,全部带上排查思路和解决命令。不管是刚接触 Wazuh 的新手,还是准备从零搭一套生产环境的运维,这篇都值得存一份。
1. 安装前必须搞懂的事:Wazuh 到底由什么组成
1.1 别再被"装个包就行"骗了,它是一整套技术栈
很多人在安装 Wazuh 之前对它有个误解,觉得它跟装 Nginx 一样,一个命令下去就完事了。实际上 Wazuh 4.x 版本由四个核心组件组成,彼此依赖、互相通信,任何一个环节配置错了,整个系统就跑不起来。
Wazuh Manager(服务端):负责收集来自各个 Agent 的安全事件,做分析、告警、规则匹配,可以理解为整套系统的大脑。它监听 1514/UDP、1515/TCP 端口,前者接收事件,后者负责 Agent 注册。
Wazuh Indexer(数据存储与检索):这是一个基于 OpenSearch 的分布式搜索引擎,所有告警和日志都往这里写。它对外提供 9200 端口做 REST API,给上层的 Dashboard 查询数据用。这层对内存的消耗非常夸张,也是最常见的 OOM 重灾区。
Wazuh Dashboard(可视化面板):基于 OpenSearch Dashboards 改造的 Web 界面,默认跑在 5601 端口。日常查看告警、管理 Agent、配置规则都靠它。
Filebeat(日志搬运工):轻量级日志采集器,负责把 Wazuh Manager 产生的告警数据转发给 Indexer。这层看似不起眼,但证书配错、输出地址配错,都会导致数据"断流"——Manager 里能看到事件,但 Dashboard 里就是刷不出来。
这套架构本质上就是一个精简版的 Elastic Stack,所以安装时面临的很多问题,其实跟 ELK 踩坑高度相似:版本兼容、内存分配、证书信任、系统参数限制,一个都不能少。
1.2 版本选择和部署模式,决定了你后续是省心还是费命
Wazuh 的版本迭代很快,目前主流是 4.x 系列。个人学习或者小规模试水,我推荐直接用官方提供的快速安装脚本,一条命令装完所有组件。生产环境如果要扛住大量 Agent 并发上报,再考虑拆开部署——把 Indexer 独立到专用节点,Wazuh Manager 单独一台,Dashboard 单独一台,这样扩容和故障隔离都方便。
不过我得提醒一句:不要一上来就搞分布式。第一次装 Wazuh,老老实实先用单机 all-in-one 模式把全套流程跑通,让 Agent 注册、告警上报、Dashboard 展示这条链路走顺了,再考虑横向扩展。上来就分布式部署,遇到问题你会连排查切入点都找不到,因为日志分散在多个节点,很难定位是哪个组件出了问题。
另外官方脚本对操作系统有要求,CentOS 7/8、Rocky Linux 8/9、Ubuntu 18.04/20.04/22.04 都在支持列表里。选系统时优先考虑 Rocky Linux 8 或 Ubuntu 20.04 以上版本,老版本系统依赖库太旧,容易卡在 OpenSearch 启动阶段。
2. 动手装之前,先把系统底子打好
2.1 内存和 CPU 的硬门槛,低于这个配置就不要浪费时间
Wazuh 全家桶跑起来,内存是最大的瓶颈。官方文档建议的最低配置是 4GB 内存,但这只是"能启动"的标准。我实际测试下来,4GB 内存跑 all-in-one 模式,Indexer 一启动,可用内存就只剩不到 500MB,系统随时可能触发 OOM Killer 把进程杀掉。
个人体验,想要顺畅使用——至少保证 Dashboard 切页面不卡、Indexer 不频繁 Full GC——内存建议 8GB 起。CPU 方面,2 核能跑,但 4 核体验会好很多。硬盘空间也别抠,Wazuh Manager 默认会把告警数据写入/var/ossec/logs/,加上 OpenSearch 的索引数据、日志文件,跑上一周轻松吃掉几十 GB。最好留出 100GB 以上空间,否则后面清理索引时又得踩新坑。
检查配置没有问题后,别急着跑安装脚本。先把系统基础参数调好,这不难,但漏掉任何一个,后面排查起来都极其痛苦。
2.2 必调的三个系统参数:swap、文件句柄和 vm.max_map_count
第一个是 swap。OpenSearch 默认检测到系统有 swap 时会警告,但物理内存不足时,我建议还是留一点 swap 做兜底,避免内存瞬时峰值直接击穿系统。可以用以下命令创建一个 4GB 的 swapfile:
sudo fallocate -l 4G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab第二个影响很大但容易被忽略的参数是vm.max_map_count。OpenSearch 是基于 Lucene 的搜索引擎,运行时会创建大量内存映射区域。CentOS 系统默认值才 65530,这个数量在高负载下远远不够。不调高它,Indexer 运行一段时间后就会出现max virtual memory areas vm.max_map_count [65530] is too low的错误,然后进程崩溃。
sudo sysctl -w vm.max_map_count=262144 echo 'vm.max_map_count=262144' >> /etc/sysctl.conf sudo sysctl -p第三个是文件句柄数和线程数限制。OpenSearch 需要同时打开大量文件,默认的 1024 限制完全不够。设置方法如下:
sudo tee -a /etc/security/limits.conf <<EOF * soft nofile 65535 * hard nofile 65535 * soft nproc 4096 * hard nproc 4096 EOF调完这些参数后,重启一次系统,确认生效后再进入下一步。这几个参数其实在 Elasticsearch 部署文档里也有类似的说明,Wazuh 既然深度绑定了 OpenSearch,这些前置条件一条都躲不掉。
3. 正式安装 Wazuh 的完整过程与关键配置
3.1 官方快速安装脚本,一行命令背后的真实执行流程
Wazuh 官方提供了集成安装脚本,在联网环境下,下载并执行即可完成安装:
curl -sO https://packages.wazuh.com/4.7/wazuh-install.sh sudo bash wazuh-install.sh --generate-config-files这里的步骤值得解释一下,我在第一次安装时直接跳过第一步、想当然地运行了安装命令,结果脚本报错
“ERROR: No configuration file found”, 一头雾水地查了半天。--generate-config-files这个参数会生成一套部署所需的配置文件,包括各组件之间的通信证书、用于连接 Dashboard 的用户名密码、以及各个组件的配置模板。
生成完毕后,脚本会在当前目录下创建一个wazuh-install-files.tar.gz压缩包,里面有证书、配置文件等敏感信息。接下来才是真正的安装环节,用 all-in-one 模式部署:
sudo bash wazuh-install.sh -a-a表示安装所有组件,包括 Indexer、Manager、Filebeat 和 Dashboard。执行过程中,脚本会自动下载安装包、创建用户、生成随机密码。整个安装过程视网络情况可能需要 10-20 分钟。
安装完成后,终端会输出一段类似这样的信息:
INFO: --- Summary --- INFO: You can access the web interface https://<your-ip>:5601 INFO: User: admin INFO: Password: <random-generated-password>注意:这段密码只在安装结束时显示一次,一定要立刻保存下来。如果你像我一样手滑把终端滚过去了,别慌,安装生成的文件还在,密码会保存到/root/wazuh-install-files/wazuh-passwords.txt里,后面查密码也要靠它。
说到密码这块,我后来才发现 Wazuh 的账号体系是有玄机的。Dashboard 的管理员账号是admin,可以登录 Web 界面做配置;但如果你要调用 API,比如写脚本拉取告警数据,需要用wazuh-wui这个账号,它的密码也在wazuh-passwords.txt里。这两个账号别搞混。
3.2 证书权限:90% 的通信故障都跟它有关
Wazuh 各组件之间的通信是基于 TLS 双向认证的,安装脚本会自动生成一套 CA 证书和各组件证书。正常情况下这套证书的权限和属主都是预置好的,但很多人在后续运维中会犯一个低级错误——手动修改了证书文件的权限,导致组件之间无法互相认证。
如果你遇到了 Manager 日志里频繁刷SSL_ERROR_SSL或tlsv1 alert unknown ca,第一反应别去检查网络,先看证书权限。
Wazuh Manager 的证书必须满足以下条件:属主是wazuh,权限是400;Indexer 的证书属主是opensearch(或wazuh,视版本而定),权限也是400。用ls -l看一眼/etc/wazuh-server/目录下的证书文件,如果权限不是-r--------,立刻改回来:
sudo chown wazuh:wazuh /etc/wazuh-server/*.pem sudo chmod 400 /etc/wazuh-server/*.pem这个教训很深刻。我当时为了图省事,直接用chmod 644改了所有证书文件权限,结果重启后整个系统通信全部失败。排查了大半天,最后还是一行一行看官方文档才注意到权限要求。记住,证书文件权限宁紧勿松。
3.3 Filebeat 配置:告警数据能不能进 Indexer,全看它
安装脚本会自动配置好 Filebeat,但有一个场景需要手动检查:如果你修改了 Indexer 的监听地址或者端口,Filebeat 的配置文件也必须同步修改。
Filebeat 的配置文件在/etc/filebeat/filebeat.yml,关键配置段如下:
output.elasticsearch: hosts: - 127.0.0.1:9200 username: admin password: <password>这里有几个值得注意的地方。password是从安装时生成的密码文件中获取的,如果你重置过 Indexer 的密码,这里也要同步更新。另外hosts地址如果填的是localhost,但 Filebeat 解析时走了 IPv6 的::1,而 Indexer 只监听了 IPv4 的 9200 端口,数据就会悄悄丢失。我建议这里直接填 IP 地址,免得域名解析带来额外的麻烦。
检查 Filebeat 是否成功连接 Indexer,可以查看 Filebeat 日志:
sudo journalctl -u filebeat -f如果看到Connected to Elasticsearch的日志,说明链路是通的。如果一直报connection refused或401 Unauthorized,优先检查账号密码和 Indexer 监听状态。
3.4 Dashboard 登录 401 的快速处理
安装完成后打开https://<服务器IP>:5601会遇到浏览器拦截,提示证书不信任。
不要慌,这是正常现象,因为 Wazuh 用的是自签名证书,直接点击"高级 -> 继续前往"即可。但如果是通过 Nginx 反代访问 Dashboard,可能会遇到 WebSocket 无法连接的问题,这属于额外的代理配置,我在后面会详细展开。
进入登录页后输入admin和密码,如果提示Invalid credentials,八成是密码对不上。此时登录到服务器,执行:
sudo /usr/share/wazuh-dashboard/bin/opensearch-dashboards-keystore list这个命令可以查看 Dashboard 的密钥存储列表,但更方便的做法是直接重置密码。在wazuh-passwords.txt里找到admin的初始密码,确认无误后仍然无法登录,那就手动重置:
sudo bash /usr/share/wazuh-indexer/plugins/opensearch-security/tools/wazuh-passwords-tool.sh -u admin -p NewPassword执行完毕后会返回Done提示,然后用新密码登录即可。这里有个细节要注意:密码重置后,Filebeat 里配置的密码也需要一起更新,否则日志采集会断。
4. 部署 Agent 并完成注册,这里面的坑一个比一个隐蔽
4.1 Agent 安装与注册命令
Wazuh 管理端装好后,下一步就是在被监控的服务器上安装 Agent。Agent 支持多种操作系统,以 Linux 为例,安装命令如下:
curl -s https://packages.wazuh.com/4.x/wazuh-agent-4.7.0-1.x86_64.rpm -o wazuh-agent.rpm sudo rpm -ivh wazuh-agent.rpm安装完成后,在 Wazuh Dashboard 的 "Agents -> Deploy new agent" 页面,会生成带当前服务器地址的注册命令。复制后在客户机上执行:
sudo /var/ossec/bin/agent-auth -m <wazuh-manager-ip> -p 1515Agent 注册通过后,启动 Agent 服务:
sudo systemctl daemon-reload sudo systemctl enable wazuh-agent --now一切顺利的话,Dashboard 的 Agents 页面会立刻多出一条 active 状态的记录。但这里要注意一个关键点:Agent 注册和事件上报走的是不同端口。注册走1515/TCP,事件上报走1514/UDP。如果服务器上有防火墙(特别是云安全组),只放通 1515 却不放通 1514,会导致 Agent 状态显示 active,但告警永远传不回来。
4.2 Agent 状态一直是 disconnected,90% 是网络和密钥问题
最常遇到的问题是 Agent 注册成功了,但过几分钟状态变成disconnected。看到这个现象,优先查两件事。
第一,在客户机上执行:
sudo /var/ossec/bin/wazuh-control status如果提示wazuh-agent not running,先启动服务。启动后依然连接失败,查看 Agent 日志:
sudo tail -f /var/ossec/logs/ossec.log常见的错误是ERROR: Invalid key或ERROR: (1104) Invalid agent key format,这时需要回到 Wazuh Manager 上,查看当前已注册的 Agent 列表:
sudo /var/ossec/bin/manage_agents -l如果列表里有相应的 Agent ID,但状态异常,最直接的办法是删除后重新注册。在 Manager 上执行:
sudo /var/ossec/bin/manage_agents -r <agent-id> sudo /var/ossec/bin/manage_agents -f然后回到客户机,重新执行注册命令,重启 Agent 服务,一般就能恢复正常。
第二,检查 Wazuh Manager 的监听状态。有时候服务虽然启动了,但端口根本没监听:
sudo ss -tulnp | grep 151正常会看到1514/udp、1515/tcp、1516/tcp三个端口在监听。如果只有部分端口在监听,说明 Manager 没有完全起来,需要查看 Manager 日志:
sudo tail -f /var/ossec/logs/ossec.log常见的问题是磁盘空间满了,或者/var/ossec/etc/下的权限被改动,导致 Manager 无法写入状态文件。排错时优先看磁盘使用率,这个坑太容易踩了。
4.3 防火墙和安全组:不配好这个,告警数据永远传不回来
我帮一个朋友排查过一个问题:Agent 状态显示 active,但 Dashboard 里一条告警都刷不出来。他在服务器本地用curl测试 Agent 的事件上报接口,数据是通的,说明网络层没有完全阻隔,但告警就是不到 Dashboard。
后来我登录 Wazuh Manager,看到/var/ossec/logs/alerts/alerts.json这个文件里确实有告警产生。问题就出在 Filebeat 上,因为它无法把数据传送到 Indexer。查看 Filebeat 日志后,发现写的是Failed to connect to backoff(elasticsearch) (http://127.0.0.1:9200): Get http://127.0.0.1:9200: dial tcp 127.0.0.1:9200: connect: connection refused。
结果不是网络被墙,而是我帮朋友在系统上调整防火墙策略时,把 9200 端口规则顺手删掉了。这里有个经验要分享:Wazuh 管理端的 9200 端口只应该对内网开放,不要暴露到公网。但是本地回环地址127.0.0.1的访问一定不能被防火墙拦截,否则 Filebeat 和 Dashboard 都无法访问 Indexer。
如果你用的云服务器,记住四件事:
- 5601 端口只对你自己的办公网 IP 开放
- 1514/UDP、1515/TCP 对需要纳管 Agent 的网段开放
- 9200 端口禁止公网访问
- 如果你之后要从其他机器直接调 API 查数据,可以单独放行源 IP
5. 高频踩坑实录:这些问题你一定也能遇到
5.1 Indexer 启动失败,反复崩溃 or 无法初始化
这个问题我装了三套环境,遇到了两次。现象是安装完成后,wazuh-indexer服务一直处于failed (Result: exit-code)状态,日志里可以看到各种 es 相关的报错。
原因一:系统参数vm.max_map_count没调高。这个在前面已经说过了,OpenSearch 启动时对这种内存映射区域数量有硬性要求,不调高直接拒绝启动。处理方式就是执行sysctl -w vm.max_map_count=262144。
原因二:JVM 堆内存设置过大或过小。OpenSearch 的堆内存是修改/etc/wazuh-indexer/jvm.options文件中的-Xms和-Xmx参数。如果服务器只有 4GB 内存,而你把它设成了 4G,那系统几乎没有余量跑其他组件,极易触发 OOM。建议 4GB 内存的机器,堆内存设 2G;8GB 内存的机器,设 4G。-Xms和-Xmx必须保持一致,避免 JVM 运行时动态扩容造成性能抖动。
sudo vi /etc/wazuh-indexer/jvm.options # 修改这两个值 -Xms2g -Xmx2g改完后重启:
sudo systemctl restart wazuh-indexer原因三:数据目录权限不对。OpenSearch 如果无法写入数据目录,也会直接退出。数据目录默认在/var/lib/wazuh-indexer,检查它的属主是否为wazuh:
sudo chown -R wazuh:wazuh /var/lib/wazuh-indexer sudo chown -R wazuh:wazuh /etc/wazuh-indexer清理完这些问题后,手动启动一次 Indexer:
sudo systemctl start wazuh-indexer再执行集群健康检查:
curl -k -u admin:<password> https://localhost:9200/_cluster/health?pretty返回的status字段如果是green,说明 Indexer 正常。如果是yellow,索引副本未分配,通常是单节点部署的正常现象,不影响使用;如果是red,说明有主分片未分配,需要进一步排查磁盘容量和节点状态。
5.2 安装好之后,Dashboard 一直显示 no healthy upstream
Dashboard 安装完顺利启动,但访问时提示no healthy upstream,这个问题我第一次遇到时彻底懵了,因为从字面上看像是反向代理的问题,但 Wazuh 明明没有用 Nginx。
后来定位到,这其实是 Dashboard 无法连接到后端的 Indexer 或 API。Wazuh Dashboard 启动后会通过 9200 端口验证认证信息,如果认证失败,就会在页面友好地提示no healthy upstream。
处理方法是重启整个服务栈,按顺序来:
sudo systemctl restart wazuh-indexer sudo systemctl restart wazuh-server sudo systemctl restart filebeat sudo systemctl restart wazuh-dashboard如果重启后依旧,就查看 Dashboard 日志:
sudo journalctl -u wazuh-dashboard -f看到大量401 Unauthorized时,百分之百是 Dashboard 里配置的密码和 Indexer 的不一致。这时需要重新配置 Dashboard 的密钥:
sudo bash /usr/share/wazuh-dashboard/bin/opensearch-dashboards-keystore add opensearch.password输入正确的密码后重启 Dashboard 即可。
5.3 日志文件暴涨,磁盘空间告警
这个问题在跑了一段时间后必然会遇到。Wazuh Manager 默认会把告警写入/var/ossec/logs/alerts/alerts.json,Indexer 侧还会产生大量索引数据。时间一长,磁盘空间就被吃光了。
处理方式分两层。第一层,清理旧的索引数据。Indexer 提供了索引生命周期管理(ILM),但默认策略未必符合你的实际需求。可以在 Dashboard 的 "Index Management -> Index Policies" 里创建一条策略,比如30 天后删除,然后关联到wazuh-alerts-*开头的索引模板。
第二层,归档和清理 Manager 日志。/var/ossec/logs/ossec.log和alerts.json都自带轮转机制,但轮转后的压缩包不会自动删除。建议写个简单的定时任务,5 天前打的包直接清:
sudo find /var/ossec/logs/ -name "*.gz" -mtime +5 -delete把上面这行加进 crontab,每天凌晨执行一次,能省下不少磁盘空间。
5.4 Agent 数据上报延迟大,想排查疲于奔命
Agent 安装好后,理论上几十秒内告警就会出现在 Dashboard 上。如果你发现数据突然延迟很久甚至丢失,先检查 Wazuh Manager 的事件处理队列。
Wazuh 的 Manager 有一个分析队列,默认大小和线程数在配置文件里可以调。修改/etc/wazuh-server/wazuh-server.yml(旧版本是ossec.conf)里的配置:
analysis: threads: 4 queue_size: 131072threads可以根据 CPU 核数调整,一般 4 到 8 即可;queue_size决定内存中缓存的事件数,如果单台 Manager 接了上千个 Agent,这个值建议调大。改完后重启wazuh-server服务,注意重启会导致短时间内 Agent 连接中断,尽量选业务低峰期操作。
6. Wazuh 用起来之后的扩展玩法与建议
6.1 集成 ML 检测和告警通知
Wazuh 装好、Agent 纳管完之后,基础的安全监控链路就算建起来了。但只靠默认规则集,告警噪音会非常大。我自己实际使用下来,默认规则会疯狂触发各种 low 级别告警,像 SSH 登录失败、文件权限变更等,一天能刷几百条。
建议在上生产之前做两件事。第一是到 "Management -> Rules" 里把不关心的规则禁用掉,或者把规则 level 阈值调高。第二是配置告警通知,接入钉钉、Slack、飞书或邮件。Wazuh 的告警集成走的是 Manager 侧的一个集成脚本,在 Dashboard 的 "Management -> Integrations" 页面配置即可,选好平台、填好 Webhook 地址,告警就能实时推送。
另外 Wazuh 4.x 引擎还支持自动训练基线,简单理解就是它能根据 Agent 上报的数据自主学习"哪些行为算正常",偏离正常行为时再触发告警。这个功能对检测挖矿木马、隐蔽隧道这些场景尤其有用,但训练期会比较吃 CPU,建议先在测试环境跑几天再上生产。
6.2 规模化部署前,先想清楚这四件事
如果你的目标是纳管几十上百台服务器,有几件事建议先规划清楚。
第一,Manager 的性能边界。单个 Manager 能稳定处理多少 Agent,取决于硬件配置和规则数量,官方给的建议值是 200-300 个之间,超过这个量就要考虑多 Manager 架构或负载均衡了。
第二,Agent 分组和配置统一管理。给 Agent 打上合理的标签和分组,便于 Dashboard 上快速筛选,也方便下发不同的策略。
第三,备份和恢复策略。Wazuh 的配置、规则、Agent 列表,这些都在 Manager 的/var/ossec/etc/目录下。建议定期打包备份,Indexer 的索引数据可以只保留最近 30 天的,历史数据用快照方式归档到对象存储。
第四,升级流程。Wazuh 的版本升级不能跨大版本跳,比如 4.6 升 4.7 要按官方升级文档走,先升级 Indexer,再升级 Manager,最后升级 Agent。千万别图省事直接全量替换。
重要提示:Wazuh 组件之间对版本一致性要求很严格,Manager 和 Agent 版本差别过大会导致事件解析异常、插件加载失败。升级时建议先小范围测试,确认无误后再批量推送。
6.3 最后分享一个小技巧:用命令行快速定位问题
Wazuh 的 Web Dashboard 确实好用,但命令行的排查效率在很多场景下更高。我平时用得最多的几个命令,都在这里列出来供参考:
查看 Wazuh Manager 整体状态:
sudo /var/ossec/bin/wazuh-control status实时滚动查看事件日志:
sudo tail -f /var/ossec/logs/alerts/alerts.json查看主动响应日志:
sudo tail -f /var/ossec/logs/active-responses.log查看 Agent 端连接状态:
sudo /var/ossec/bin/agent_control -l查看 Indexer 集群健康:
curl -k -u admin:<password> https://localhost:9200/_cluster/health?pretty如果这些命令输出的内容和预期不符,下一步就是根据报错关键词去官方文档里查。Wazuh 的官方文档对报错信息覆盖度非常高,大多数问题都能在文档里找到答案。
这套系统折腾下来,踩过最多的坑反而都不是那些高深复杂的问题,而是证书权限、防火墙、端口监听这类基础得不能再基础的东西。但恰恰是这些"低级问题"最容易让人抓狂。希望这份踩坑指南,能帮你少熬几个通宵。