Wazuh部署避坑全指南:从快装脚本到Agent连接验证

发布时间:2026/9/16 2:16:06
Wazuh部署避坑全指南:从快装脚本到Agent连接验证 我第一次装 Wazuh 的时候整个流程拖了三个晚上其中有一个晚上全耗在同一个报错上wazuh-certs-tool.sh打印的 SQLite version too old。当时我根本没往系统环境上想反复重装了三遍最后才发现是 CentOS 7 自带的 SQLite 太旧。Wazuh 的安装踩坑十个里有八个不是 Wazuh 本身的问题而是包管理器、系统参数、网络源这些前置条件的问题。这篇东西就是把我这两年装 Wazuh、帮朋友排 Wazuh 的坑集中梳理一遍覆盖官方快速安装脚本的完整流程、组件架构和端口规划、Agent 注册不上时的排查方法以及装完之后怎么验证告警链路真的通了。适合第一次碰 Wazuh 的人也适合已经在单机跑通、准备往多节点迁移的人参考。1. 为什么踩坑的都踩在同一处先搞清Wazuh组件再谈安装1.1 indexer、server、dashboard、agent 分别是谁很多人一上来就执行bash wazuh-install.sh -a看到屏幕上滚动一堆输出特别兴奋结果装完根本不知道哪一层出了问题。Wazuh 的架构其实很清晰它脱胎于 OSSEC但比 OSSEC 多了完整的检索、可视化和集群能力。一套 Wazuh 环境由四类角色组成Wazuh indexer基于 OpenSearch 的存储与检索引擎负责接收、索引和存储告警与事件数据对外暴露 9200 端口。你可以把它理解成一个带安全认证的数据库集群。Wazuh server核心处理层内含 Wazuh manager 和 Filebeat 两个部分。manager 负责与 Agent 通信、做日志分析、规则匹配、生成告警Filebeat 则把生成出来的告警转发给 indexer。Wazuh dashboard可视化界面基于 OpenSearch Dashboards登录之后能看到安全事件、规则命中、Agent 状态、漏洞列表和 SCA 合规检查结果。Wazuh agent部署在被监控机器上的轻量采集器采集系统日志、文件完整性信息、配置审计数据然后加密传给 server。这三层的关系可以这样看agent 是触角server 是大脑indexer 是记忆dashboard 是脸面。任何一个环节断了UI 上都会出现异常但异常的表现各不相同。最常见的误解是“Dashboard 打不开Wazuh 没装好”其实 Dashboard 打不开往往只是 dashboard 组件本身的问题indexer 和 server 可能完全正常。所以我的建议永远是开始安装之前先在纸上把每个节点的角色写清楚再想清楚端口规划。快速安装脚本虽然能一键完成但出问题时你脑子里必须有一个完整拓扑否则日志都无从查起。1.2 All-in-One 还是分布式根据规模选形态Wazuh 官方提供了几种部署路径最常见的是快速安装脚本。脚本支持-a参数一次性安装全部组件也支持--generate-config-files、-n indexer、-n server、-n dashboard等参数分角色部署。还有一种更省事的方式是直接导入官方 OVA 虚拟机镜像它内部已经是一个 All-in-One 环境适合功能验证。选型上没有绝对标准但有一个大致的经验监控 50 台以下主机且只需要基础日志分析和入侵检测All-in-One 完全够用。一台 8 核、16GB 内存、100GB SSD 的虚拟机就能跑得比较舒服。监控规模到几百台或者你希望 dashboard 挂了不影响数据采集就拆成两个节点indexer 单独一台server 和 dashboard 一台。再往上走才需要真正的三节点 indexer 集群和独立 server 节点。我看到许多人犯的错是生产环境只有一台 2C4G 的云主机硬塞 All-in-One跑三天索引就 OOM。Wazuh 本身不重但 OpenSearch 是 Java 应用内存管理非常敏感资源不足时表现出的症状是“服务还在但 UI 响应极慢、索引经常只有主分片没有副本”。如果你的目的只是快速体验 Wazuh 的告警规则和 Dashboard 展示那推荐直接用 OVA 或在本地虚拟机跑 All-in-One。如果是为了生产环境建议静态资源规划时宁可多给内存也不要贪省机器。2. 装前不看这三项配置脚本必挂内存、主机名、系统限制2.1 内存门槛和OOM现象Wazuh 官方对 All-in-One 的最低内存要求是 4GB但这个数字是“能启动”的标准不是“能干活”的标准。实际跑起来OpenSearch 的 JVM 堆内存默认会占系统内存的一半再加上 Wazuh manager 的 analysisd、remoted 进程以及 Dashboard 的 Node.js 进程4GB 内存下系统会持续处于 swap 边缘。最常见的内存相关故障是 wazuh-indexer 启动后出现 OOM 崩溃或者在初始化的时候卡在Waiting for Wazuh indexer to be ready然后脚本直接失败。journalctl 里能看到类似java.lang.OutOfMemoryError: GC overhead limit exceeded的记录。装之前用free -h看一眼free -h如果 total 少于 7.5GB我建议要么加内存要么把 Wazuh 拆到两台机器上。不要企图改 jvm.options 把堆内存压到不合理的小JVM 堆太小会导致频繁 Full GC运行一会儿就假死比 OOM 还难排查。还有一个容易被忽略的是 swap。OpenSearch 官方建议禁用 swap因为磁盘交换对检索性能影响极大。如果服务器上必须保留 swap至少要在 opensearch.yml 里设置bootstrap.memory_lock: true或者忍受性能打折。2.2 hostname 与证书生成器的强绑定Wazuh 的快速安装脚本会自动生成一套用于组件间通信的 SSL 证书而证书生成流程使用 wazuh-certs-tool.sh它会读取当前节点的 hostname 作为证书的 CN 值。也就是说你的主机名决定了证书能不能被正确信任。两个高频翻车点主机名是localhost。生成的证书 CN 就是 localhost组件之间用实际 IP 或 FQDN 互相访问时证书校验直接失败。如果已经生成过证书只改 /etc/hostname 是不行的需要重新生成证书并重装相关组件。主机名包含下划线或特殊字符。证书工具解析时会把下划线等符号处理得很奇怪后续 OpenSearch 安全插件可能直接拒绝加载证书。装之前检查hostname -f如果显示的不是合法的主机名比如只是localhost先用hostnamectl set-hostname改掉再在 /etc/hosts 里把新主机名和本机 IP 对应起来。这里有个细节/etc/hosts 里不要保留两行以上对同一 IP 的不同主机名映射否则脚本生成配置时可能取到错误的节点名。我还遇到过一种情况DNS 解析正常但 /etc/hosts 里有一行127.0.1.1 oldhostname导致 OpenSearch 节点之间 transport 通信出现“target node is not a cluster member”的报错。这个报错特别容易让人误以为是集群配置错了其实只是主机名残留。2.3 nofile、vm.max_map_count 以及其他隐性变量如果说主机名是证书层的坑文件句柄和内存映射就是内核层的坑。这两个参数不调好indexer 进程起来也会异常退出。第一个是文件描述符限制。OpenSearch 的索引写入和网络连接会消耗大量句柄默认的 1024 完全不够。官方要求至少 65535可以用ulimit -n查看。临时修改ulimit -n 65535永久生效需要写到 /etc/security/limits.conf* soft nofile 65535 * hard nofile 65535第二个是 vm.max_map_count。这一步几乎每次安装都会遇到OpenSearch 报错文案非常直观max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]解决办法sysctl -w vm.max_map_count262144 echo vm.max_map_count262144 /etc/sysctl.d/99-wazuh.conf sysctl --system此外还有两个隐性变量。一个是时区安装前用date看一下系统时区偏差太大会导致 agent 上报的时间戳和 server 本地时间不一致报警时间在 UI 上看起来是乱的甚至某些基于时间的规则误判。另一个是文件系统类型如果数据盘用了 ZFS 或某些网络存储OpenSearch 的索引锁和 fsync 行为会有各种兼容性问题生产环境尽量用 ext4 或 xfs。3. 官方快装脚本全流程中的四个中断点与对应解法3.1 从下载脚本到 -a 跑通的完整命令序列快速安装脚本的入口很简单curl -sO https://packages.wazuh.com/4.9/wazuh-install.sh bash wazuh-install.sh --help官方推荐先执行--generate-config-files生成配置文件再根据节点角色安装。但对多数只想快速上手的用户直接执行bash wazuh-install.sh -a脚本会依次做这几件事检查系统版本和依赖、安装配置管理器、生成证书并创建证书包、安装 wazuh-indexer 并启动集群、安装 wazuh-manager 和 filebeat、安装 wazuh-dashboard最后把随机生成的 admin 密码打印到屏幕上同时写到脚本同级目录下的 wazuh-passwords.txt。装完之后访问https://server-ip用 admin 加密码登录。这一步能成功说明全链路基本是通的。但正是这个看起来顺理成章的过程隐藏了四个高频中断点。我按遇到的频率排一下。3.2 中断点一证书生成器的 SQLite 版本校验文章开头说的那个坑就是第一个中断点。wazuh-certs-tool.sh 在生成 OpenSearch 安全插件内部配置时依赖系统的 sqlite3 命令行工具而且要求 SQLite 版本不低于 3.22.0。CentOS 7 自带的 SQLite 是 3.7.17一跑就报错ERROR: You need SQLite version 3.22.0 or later to run this script很多人看到这个报错会去重新下载 Wazuh 安装包其实完全没有用。解决方式是升级 SQLite 或者换一个受支持的系统。我的建议是后者因为 CentOS 7 本身已经停止维护用它跑 Wazuh 后续还会踩 OpenSSL、Python 依赖等各种坑。Ubuntu 20.04 及以上版本自带的 SQLite 3.31 完全满足要求这也是我推荐新用户直接用 Ubuntu 22.04 LTS 的原因。如果系统里确实没有 sqlite3 命令可以用apt install sqlite3或yum install sqlite补上再检查sqlite3 --version3.3 中断点二indexer 初始化失败与安全配置错误快速安装脚本在启动 indexer 之后还会执行安全插件的初始化流程也就是往 OpenSearch 里写入 admin、kibanaserver 等内部用户和角色。这一阶段失败屏幕上通常会出现类似indexer-security-init.sh的报错日志里能看到证书文件找不到、连接被拒或 Java 异常。我见过最多的是两类原因。一是 vm.max_map_count 没有调OpenSearch 进程根本没起来安全初始化当然失败。二是证书文件权限不对。脚本会自动把证书分配到 /etc/wazuh-indexer/certs 目录默认属主为 wazuh-indexer。如果你之前手动跑过某些命令或从其他机器拷贝过证书目录文件属主变成了 rootOpenSearch 进程启动时没有读取权限就会出现“Access denied”或“Permission denied”。检查方法ls -l /etc/wazuh-indexer/certs/ systemctl status wazuh-indexer journalctl -u wazuh-indexer -n 100如果只是权限问题递归改一下属主chown -R wazuh-indexer:wazuh-indexer /etc/wazuh-indexer/certs这里我额外提醒一点wazuh-indexer 一旦初始化成功过在集群配置没有大变动的情况下不要随便重新执行 indexer-security-init.sh。安全插件的内部索引一旦重建可能出现数据索引还在但用户角色丢失的情况到时候 Dashboard 会一直转圈。3.4 中断点三下载源、代理与残留进程惹的祸安装脚本的执行过程需要从 packages.wazuh.com 拉取 RPM 或 DEB 包也需要从系统自带源安装依赖。如果你所在网络环境访问外网受限或者配置了代理环境变量就会看到 curl 下载超时、校验和不一致等报错。排查方式分两步。第一步检查代理变量env | grep -i proxy如果有 http_proxy 或 https_proxy 指向一个失效的代理脚本里的 curl 会一直尝试往代理走表现为下载特别慢或卡住不动。临时清掉再跑unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY第二步确认 DNS 和连通性curl -sI https://packages.wazuh.com/4.9/wazuh-install.sh | head -5如果这一步都失败问题在网络层换源和重试都没有意义先解决到官方源的连通性再说。还有一个隐蔽问题机器上之前装过 OSSEC 或其他叫 ossec 的服务导致 wazuh-manager 安装时出现文件冲突或者ossec-initd服务名字冲突。快速安装脚本不会帮你清理旧环境。遇到这种情况先把老的服务卸载干净尤其是 /var/ossec 目录如果存在旧的 agent 文件要一并备份后清理。3.5 中断点四端口被占与 Dashboard 空转最后一个中断点在 Dashboard。快速安装脚本默认让 Wazuh Dashboard 监听 443 端口。如果机器上已经有 Nginx、Apache、Kubernetes 或者其他 Web 服务占着 443Dashboard 会起不来journalctl 里能看到地址被占用的报错。ss -lntp | grep 443确认是端口占用之后要么停掉占用进程要么在配置阶段自定义 Dashboard 端口。改端口不是改一行配置就完事还需要同步调整 dashboard 访问地址和 Filebeat 的对端配置所以我建议简单粗暴All-in-One 测试环境不要放在已经在跑 Web 服务的机器上。Dashboard 能打开但一直显示加载中或者登录之后出现“No data”的空白页这是另一类问题放在后面第 5 节细讲。这里先记住一个原则安装脚本中断不可怕可怕的是你不知道它停在哪一步。看到报错先看脚本输出的最后几行然后对应查 wazuh-indexer、wazuh-manager、wazuh-dashboard 三个服务的日志不要盲目重装。4. Agent 装完连不上从 enrollment 到 1514 端口的完整排查4.1 Enrollment 阶段1515 通了为什么还报认证失败服务端装好之后接下来是在被监控机器上装 agent。以 Ubuntu/Debian 为例curl -s https://packages.wazuh.com/4.x/apt/wazuh-agent.deb -o wazuh-agent.deb WAZUH_MANAGERmanager_ip WAZUH_AGENT_NAMEagent01 dpkg -i ./wazuh-agent.deb systemctl enable --now wazuh-agent这里的环境变量WAZUH_MANAGER会被写进 agent 的 ossec.confagent 启动后先向管理端 1515 端口发起注册请求也就是 enrollment。管理端的 auth 服务会校验注册密码校验通过后生成 agent key下发到 /var/ossec/etc/client.keysagent 才能开始后续通信。如果 agent 状态一直显示为 Disconnected看 agent 端日志cat /var/ossec/logs/ossec.log最常见的错误有两类。第一类是 enrollment 密码不对报错类似ERROR: Invalid enrollment password。快速安装时管理端默认启用 enrollment密码在 wazuh-passwords.txt 里agent 安装脚本没有自动传入的话需要手动指定WAZUH_REGISTRATION_PASSWORDpassword dpkg -i ./wazuh-agent.deb第二类是服务器地址配置错误。检查 agent 端 /var/ossec/etc/ossec.conf 里 address 标签是否写成了 localhost。很多人从文档复制安装命令忘了替换地址。4.2 日志上报阶段不要只放行 TCP 1514Enrollment 成功之后agent 会定期向管理端上报事件。这段通信默认走 UDP 1514注意是 UDP不是 TCP。如果你在云安全组或本机防火墙里只放行了 TCP 1514agent 在 UI 上会显示为 Active但事件一个都收不到因为 agent 的注册连接和日志上报是两个完全不同的通道。我整理了一个端口对照表排查时直接对照端口/协议用途放行范围1515/TCPAgent 注册Enrollment对 agent 网段放行1514/UDPAgent 日志上报对 agent 网段放行1514/TCP如果配置了 TCP 模式则使用对 agent 网段放行55000/TCPWazuh server RESTful API仅管理段9200/TCPIndexer REST API内部组件间443/TCPDashboard Web 界面管理员访问来源如果你在防火墙层面已经放行了 UDP但事件依然收不到还要检查管理端 remoted 服务的协议配置。快速安装默认是 UDP但也有人为了可靠传输改成 TCP两边的协议必须对齐。agent 端可以在 ossec.conf 的 client 段里显式指定协议client server addressmanager_ip/address protocoludp/protocol port1514/port /server /client顺便说一句UDP 模式下事件是单向的管理端不会返回确认包所以你光在 agent 上看日志很多时候看不出事件有没有成功送达。排查时必须同时看管理端 /var/ossec/logs/ossec.log 的 remoted 部分确认有没有来自该 agent 的握手记录。4.3 时间偏差、重复注册和旧 ossec 残留Agent 连不上的另一个隐蔽原因是时间偏差。Wazuh 的 agent 与 server 通信时会带时间戳虽然它不像 Kerberos 那样严格校验 5 分钟窗口但如果 agent 的时钟和 server 差太多告警时间线会乱某些依赖事件顺序的关联分析规则也会失灵。装 agent 之前顺手做一次时间同步timedatectl set-ntp true chronyc sources再说重复注册。如果同一台 agent 在管理端已经被删掉又重新注册了一次/var/ossec/etc/client.keys 里可能残留旧 key。新旧 key 不一致时agent 显示 Active 但管理端不接收它的消息。处理方式是把 agent 端 client.keys 备份后删掉重启 wazuh-agent让它走一次全新的 enrollment必要时在管理端先把旧的 agent 删掉。还有一种情况是机器上以前装过 OSSEC HIDS/var/ossec 目录里残留了旧版的 agent 配置和二进制。新装 Wazuh agent 时包管理器会覆盖多数文件但旧配置里的某些自定义规则或解码器可能被保留下来导致 agent 反复重启或注册异常。稳妥的做法是在安装 Wazuh agent 之前先彻底卸载老 ossecdpkg -P ossec-hids-agent # 或者 rpm -e ossec-hids-agent清理完确认 /var/ossec 目录要么不存在要么内容干净再开始安装。5. 用一条伪造日志验证整条告警链路5.1 端到端验证从 auth.log 到 Dashboard 告警很多人装完 Wazuh 之后看到 Dashboard 上 agent 状态是 Active就以为大功告成。实际上 Active 只代表 agent 能和 manager 通信不代表日志采集、规则匹配、告警写入、Dashboard 展示这条链路是通的。我最推荐的做法是主动触发一条可以识别的安全事件做完整的端到端验证。在测试 agent 上执行echo Mar 5 10:00:00 testserver sshd[12345]: Failed password for root from 192.168.1.1 port 22 ssh2 /var/log/auth.log如果你用的是 RHEL 系日志文件是 /var/log/secure。过 10 到 30 秒在 Dashboard 的“安全事件”页面搜索应该能看到一条类型为authentication_failed、规则编号为5710或5750的错误信息。再验证一下文件完整性监控FIMecho wazuh-test /etc/wazuh_test_fim.txt rm /etc/wazuh_test_fim.txtDashboard 的“文件完整性监控”模块里会出现“新增”和“删除”两条记录。能同时看到这两类事件说明 agent 的日志采集、管理端解码、规则匹配、索引写入和 UI 展示全部正常。5.2 只有事件没有告警解码器与规则的问题验证时一个非常常见的现象是Dashboard 能看到原始事件但告警级别不高或者没有命中任何规则。这时候问题通常出在解码器或规则上。先用管理端自带的 logtest 工具判断/var/ossec/bin/wazuh-logtest在提示符下粘贴一条测试日志它会告诉你解码器匹配情况、规则命中情况和最后告警级别。如果显示没有规则命中说明这条日志虽然被采集了但 Wazuh 内置规则里没有覆盖该日志类型的告警条件。这不是安装问题而是规则配置问题。处理方式有两种一是接受它作为常规事件因为 Wazuh 不可能对所有日志都产生告警二是给这类日志写一条自定义规则放到 /var/ossec/etc/rules/local_rules.xml然后重启 wazuh-manager。写自定义规则时注意规则 ID 不要和系统规则冲突一般使用 100000 以上的号段。顺带提另一个常见坑管理端默认只对部分日志文件启用监控agent 的 ossec.conf 里localfile段没有配置 /var/log/nginx/access.log 之类的路径Nginx 日志就不会被采集。Dashboard 上一片空白不是 Wazuh 坏了是采集源没配置。这一步很多人忽略排查时可以打开 agent 的 ossec.conf确认确有对应的localfile段落。5.3 验证不算完密码文件、备份与访问控制端到端验证通过之后我建议做一轮最基础的加固不然这套系统很容易在后续使用中出问题。密码文件 wazuh-passwords.txt 是快速安装脚本生成的随机密码列表包含 indexer admin、dashboard、filebeat 等内部用户的密码。脚本执行完会把密码打印在终端也会写到执行目录下的 wazuh-passwords.txt。这个文件不要丢。dashboard 登录密码弄丢后虽然可以用安全插件重新设置用户密码但过程比较绕还会涉及重启 indexer没必要给自己找麻烦。正确做法是把文件备份到离线位置或者放进密码管理器。再检查证书目录。All-in-One 环境里/etc/wazuh-indexer/certs、/etc/wazuh-dashboard/certs、/etc/filebeat/certs 三套证书缺一不可。如果做多节点扩容这些证书就是组件互信的凭证丢了就得重新生成并全部重装。我在迁移时会把整个 certs 目录压缩带走tar czf wazuh-certs-backup.tar.gz /etc/wazuh-indexer/certs /etc/wazuh-dashboard/certs /etc/filebeat/certs最后是访问控制。Dashboard 和 Wazuh API 默认不对来源 IP 做限制只要网络可达就能试密码。在云环境里安全组只放行管理员的办公 IP 到 443 和 55000是最基本的要求。Wazuh manager 的 API 监听在 55000如果需要远程管理建议在代理层限制访问而不是直接把端口裸奔到公网。6. 部署形态和容量规划别让 Wazuh 装完三天就卡死6.1 单点探针、三节点集群、分离部署怎么选Wazuh 这类 SIEM 系统有一个特点刚装好的时候看起来轻巧但随着监控的 agent 数量增加索引体积和 CPU 消耗会曲线上升。所以容量规划不是可选步骤而是必答题。我按经验分了三档规模建议架构参考配置1-50 个 agentAll-in-One8C / 16GB / 100GB SSD50-500 个 agentserverdashboard 一台indexer 独立一台indexer 可加副本server 8C/16GBindexer 16C/32GB / 500GB SSD500 agentindexer 三节点集群server 独立dashboard 独立每节点 16C/64GB磁盘按日志量扩容这里有个容易偏的理解Wazuh indexer 集群的副本数不是越多越好。OpenSearch 的三副本会吃掉三倍存储而 Wazuh 的告警数据本身量不大多数场景主分片加一个副本就够。集群的价值主要在可用性不在性能叠加。如果只是在内网做功能验证比如研究告警规则怎么写、FIM 怎么配不需要一上来就搭集群。单台 All-in-One 跑一个月观察索引增长情况和系统负载再决定是否扩容是最务实的路径。6.2 存储膨胀与索引生命周期管理Wazuh 默认按天创建索引每天会生成 wazuh-alerts-4.x.yyyy.MM.dd 这样的索引。如果 agent 数量多、日志采集范围广索引占据的磁盘会迅速膨胀。很多人装完不管等到磁盘打满才发现这时候 indexer 可能已经停止写入新索引整个 Dashboard 都会卡死。解决办法是配索引生命周期策略也就是 OpenSearch 的 ISM。Wazuh indexer 本身会在 Dashboard 的 Index Management 界面提供策略管理可以定义一个滚动策略索引达到一定大小或时间后自动滚转旧索引超过保留天数后删除。比如设置保留 30 天- hot活跃写入保留 30 天 - delete30 天后删除索引生效之后磁盘占用会保持在一个稳定水位不会无限增长。具体保留天数根据你和安全团队的审计要求定但至少不要低于 7 天不然误报回溯和调查取证都无从谈起。我还在生产环境里做了一件事把 Wazuh indexer 的数据目录单独挂到独立的数据盘上而不是放在系统盘。这样即使系统盘被日志灌满索引层的数据也不会立刻被拖垮。数据盘建议用 ext4 或 xfs挂载时关闭 atime 更新能减少一部分不必要的磁盘写入。就我个人而言装 Wazuh 最大的感悟是它的安装脚本已经做得足够自动化真正花时间的从来不是“跑脚本”而是理解组件关系、把前置环境调干净、以及建立一套可以复现的检查清单。第一次装遇到报错不要在同一个方向反复试先确认系统层参数再排查证书和防火墙最后看日志定位这条路径能帮你少走一大半弯路。