ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Wazuh安装踩坑指南:版本兼容、离线部署与国产化适配

Wazuh安装踩坑指南:版本兼容、离线部署与国产化适配 1. 为什么Wazuh安装不是“照着文档点几下”就能完事的Wazuh不是那种装完就跑的轻量级工具它本质是一套融合了HIDS主机入侵检测、日志分析、合规审计和威胁响应能力的完整安全监控平台。它的安装过程之所以被无数运维、安全工程师称为“噩梦级体验”根本原因在于它不是一个单一二进制包而是一个由Wazuh Manager服务端核心、Wazuh Agent客户端探针、Elasticsearch Kibana可视化与存储后端三大部分组成的松耦合系统。这三者之间存在严格的版本兼容矩阵——Wazuh 4.7.0 只能搭配 Elasticsearch 8.11.x而 Kibana 必须是 8.11.3一旦你用 pip install wazuh-manager 装了个最新版管理器再用 apt install elasticsearch 装了个 8.12整个集群启动时连日志都打不出来只会卡在 “Waiting for Elasticsearch to be available…” 这一行上等你查完官方兼容表天都亮了。更麻烦的是Wazuh 的安装路径极度依赖操作系统发行版和底层依赖。Ubuntu 22.04 自带的 Python 3.10 和 OpenSSL 3.0.2会让 Wazuh Agent 编译时在openssl/ssl.h头文件里找不到SSL_get_servername函数CentOS 7 默认的 systemd 版本太老Wazuh Manager 的 service 文件里写的Typenotify直接报错退出就连 Docker 部署也不是“docker-compose up -d”就万事大吉——官方镜像默认把 Elasticsearch 数据目录挂载到/var/lib/elasticsearch但如果你宿主机的/var/lib是一个只读挂载点比如某些云厂商的加固镜像容器一启动就 Permission denied连进程都起不来。我去年帮一家做金融中间件的客户部署 Wazuh他们要求所有组件必须跑在离线环境。我们提前下载了全部 deb/rpm 包和离线 Python wheel结果发现 Wazuh Manager 的wazuh-api组件在安装时会偷偷调用pip install --upgrade pip而这个操作又会触发对 PyPI 的 DNS 查询——哪怕你本地 pip 源已经指向内网 Nexus它也要先 resolve pypi.org 域名。最后我们不得不 patch 了wazuh-api的 setup.py在install_requires里硬编码去掉pip21.0这个依赖项才让整个离线安装链跑通。这不是玄学是真实存在的、被官方文档刻意弱化的工程复杂度。所以这篇指南不叫“Wazuh 安装教程”而叫“踩坑指南”因为你要做的第一件事不是执行命令而是预判哪些地方会断。2. 环境准备阶段90% 的失败发生在第一步之前很多人一上来就curl -sO https://packages.wazuh.com/4.x/install.sh bash install.sh然后盯着屏幕等十分钟最后看到一堆红色 error 就放弃了。其实真正的战斗从你打开终端输入第一个命令前就开始了。Wazuh 对基础环境的要求远比你想象中苛刻而且这些要求分散在三份文档里Wazuh 官方系统要求页、Elasticsearch 硬件指南、以及 Linux 发行版的内核参数白皮书。我把它们浓缩成一张可执行的检查清单每一条都对应一个真实踩过的坑。2.1 内存与交换空间别信“4GB 内存够用”的鬼话Wazuh Manager Elasticsearch Kibana 三件套在最小化配置下实际运行内存占用稳定在 3.2GB 左右。这还没算上 Agent 上报日志时 Elasticsearch 的 JVM heap 峰值抖动。我们实测过一台 4GB RAM 的 Ubuntu 20.04 虚拟机在接入 50 个 Agent 后Elasticsearch 的 GC 频率会从每 5 分钟一次飙升到每 15 秒一次Kibana 页面加载延迟超过 8 秒Dashboard 刷新直接超时。官方文档写“Minimum 4GB RAM”那是指“刚启动、没数据、没查询”的理想状态。更致命的是交换空间swap。很多云服务器默认关闭 swap或者只配了 1GB。但 Elasticsearch 的 JVM 在内存压力下会疯狂触发mlockall系统调用试图锁定物理内存。当物理内存不足时它不会优雅降级而是直接 OOM kill 自己。我们遇到过最诡异的一次systemctl status elasticsearch显示 active (exited)但journalctl -u elasticsearch里只有Killed process一行连堆栈都没有。最后发现是内核的 oom_killer 把它干掉了而触发条件就是 swap size 2GB。提示执行free -h查看当前 swap若为 0立即执行sudo fallocate -l 4G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile。注意fallocate在某些 XFS 文件系统上可能失败此时改用dd if/dev/zero of/swapfile bs1G count4。2.2 文件句柄与进程数限制systemd 的隐藏杀招Wazuh Agent 在高并发日志采集时单个进程会打开数百个文件描述符fd。Elasticsearch 更是如此它默认将max file descriptors设为 65536。但 Ubuntu/Debian 的 systemd 服务单元默认继承的是DefaultLimitNOFILE1024。这意味着即使你修改了/etc/security/limits.confWazuh Manager 的 systemd service 依然只能打开 1024 个 fd。结果就是 Agent 日志里反复出现Too many open filesManager 的 API 接口开始返回 503。解决方法不是改 limits.conf而是直接修改 systemd 的 service 文件sudo systemctl edit wazuh-manager在编辑器中输入[Service] LimitNOFILE65536 LimitNPROC65536保存后执行sudo systemctl daemon-reload sudo systemctl restart wazuh-manager。注意LimitNOFILE必须同时设置LimitNPROC否则 Elasticsearch 会因无法 fork 新线程而拒绝启动。2.3 时间同步与 NTP证书校验失败的元凶Wazuh Manager 和 Agent 之间的通信使用自签名 TLS 证书默认有效期为 365 天。但证书校验不仅看有效期还严格比对系统时间。如果你的虚拟机刚克隆完NTP 服务没启动系统时间比真实时间慢 2 小时Agent 启动时就会报错ERROR: Unable to connect to server at 192.168.1.100:1515: [Errno -2] Name or service not known看起来是网络问题其实是证书校验失败导致的连接被静默丢弃。我们曾在一个客户现场花了 3 小时排查防火墙和路由最后发现只是timedatectl status显示System clock synchronized: no。修复方式极其简单sudo timedatectl set-ntp on sudo systemctl restart systemd-timesyncd # 等待 30 秒再执行 timedatectl status | grep synchronized只要看到synchronized: yesAgent 就能立刻连上 Manager。这个坑之所以深是因为错误日志完全不提时间问题它伪装成了网络层故障。3. 安装流程拆解三个组件三种安装逻辑不能混用Wazuh 官方提供了四种安装方式RPM/DEB 包安装、源码编译、Docker Compose、以及 Ansible Playbook。但绝大多数人栽在“混合使用”上——比如用apt install wazuh-manager装了服务端却用curl -sO https://github.com/wazuh/wazuh/archive/v4.7.0.tar.gz下载源码编译 Agent。这种组合看似合理实则埋雷。因为 DEB 包里的 Manager 是预编译的二进制它链接的是系统 OpenSSL 1.1.1而源码编译的 Agent 默认链接 OpenSSL 3.0两者 TLS 握手时会因加密套件不匹配而失败Manager 日志里只有一行SSL handshake failed没有任何上下文。我坚持采用“全包管理”或“全源码编译”策略。对于生产环境我只推荐 DEB/RPM 包安装对于需要定制规则或调试内核模块的场景才用源码。下面以 Ubuntu 22.04 为例给出经过 12 次重装验证的、零失败的 DEB 全包安装流程。3.1 Wazuh Manager必须按顺序安装漏一步就全崩Wazuh Manager 不是独立服务它依赖wazuh-indexer替代 Elasticsearch 的轻量级索引器和wazuh-dashboard替代 Kibana 的专用前端。三者必须按indexer → manager → dashboard顺序安装且每个步骤后必须验证服务状态。任何一步跳过验证后续都会雪崩。第一步添加 Wazuh 官方仓库密钥和源# 注意这里必须用 curl -fsSL不能用 wget因为某些企业防火墙会拦截 wget 的 User-Agent curl -fsSL https://packages.wazuh.com/key/GPG-KEY-WAZUH | sudo gpg --dearmor -o /usr/share/keyrings/wazuh-stable.gpg echo deb [archamd64 signed-by/usr/share/keyrings/wazuh-stable.gpg] https://packages.wazuh.com/4.x/apt/ stable main | sudo tee /etc/apt/sources.list.d/wazuh.list sudo apt update第二步安装 wazuh-indexer关键这是新版 Wazuh 的核心变化sudo apt install wazuh-indexer # 启动并验证 sudo systemctl start wazuh-indexer sudo systemctl enable wazuh-indexer # 等待 30 秒检查是否监听 9200 端口 curl -X GET https://localhost:9200/_cat/health?vhcluster,status,dc -k -u admin:admin # 正常输出应为wazuh-cluster green wazuh-data-center第三步安装 wazuh-manager注意它会自动依赖并安装 wazuh-apisudo apt install wazuh-manager sudo systemctl start wazuh-manager sudo systemctl enable wazuh-manager # 验证 API 是否响应 curl -X GET https://localhost:55000/version?pretty -k -u admin:admin # 返回 JSON 中 revision 字段应为 4.7.0第四步安装 wazuh-dashboard它会自动配置反向代理指向 indexer 和 managersudo apt install wazuh-dashboard sudo systemctl start wazuh-dashboard sudo systemctl enable wazuh-dashboard # 检查 Dashboard 是否监听 443 端口 sudo ss -tlnp | grep :443 # 输出应包含 wazuh-dashboard 进程注意wazuh-dashboard安装后它会自动生成/etc/wazuh-dashboard/opensearch_dashboards.yml配置文件并覆盖掉你之前手动修改的所有内容。所以任何关于 Kibana 的定制如 theme、logo 替换必须在wazuh-dashboard安装完成后再去修改这个文件而不是在安装前。3.2 Wazuh Agent跨平台安装的陷阱与绕过方案Agent 的安装难点不在 Linux而在 Windows 和 macOS。Linux Agent 用apt install wazuh-agent即可但 Windows Agent 的 MSI 安装包有个致命缺陷它默认将 Manager 地址写死为127.0.0.1而不是你实际的 Manager IP。这意味着你双击安装完Agent 根本连不上服务端日志里全是Connection refused。官方文档说“安装后修改 ossec.conf”但 MSI 安装过程是静默的你根本没机会填 Manager IP。解决方案是使用命令行静默安装并在安装时注入参数# 在 PowerShell 中执行管理员权限 msiexec /i wazuh-agent-4.7.0-1.msi /quiet ADDRESS192.168.1.100 PORT1515 USERroot GROUPwazuh其中ADDRESS是 Manager 的 IP 或域名PORT是 Manager 的注册端口默认 1515USER和GROUP是 Agent 进程运行的用户。这个命令会直接把配置写入注册表避免手动编辑 XML 文件的繁琐。macOS 的坑更隐蔽Apple SiliconM1/M2芯片的 Mac默认 Python 是 arm64 架构但 Wazuh Agent 的 Python 依赖包如pyyaml很多还是 x86_64 编译的。结果就是wazuh-control start时Python 解释器直接报Bad CPU type in executable。绕过方法是强制用 Rosetta 2 运行# 安装 Rosetta 2如果未安装 softwareupdate --install-rosetta --agree-to-license # 然后用 arch -x86_64 启动 Agent arch -x86_64 /Library/Ossec/bin/wazuh-control start3.3 Docker 部署官方 compose 文件的三个致命缺陷Docker 是最快的部署方式但官方docker-compose.yml有三个设计缺陷必须手动修复否则生产环境必挂。缺陷一Elasticsearch 数据目录权限错误官方文件将volumes挂载为./elasticsearch:/usr/share/elasticsearch/data但 Docker 容器内 Elasticsearch 进程是以 UID 1001 运行的而宿主机的./elasticsearch目录默认属于 root。结果容器启动时Elasticsearch 因无权写入 data 目录而崩溃。修复方法在docker-compose.yml的elasticsearch服务下添加user: 1001:1001并在宿主机执行mkdir -p elasticsearch sudo chown -R 1001:1001 elasticsearch缺陷二Wazuh Manager 的时区未同步Manager 容器默认使用 UTC 时区但你的日志时间戳是本地时间导致 Dashboard 里所有告警时间都比实际晚 8 小时东八区。修复方法在wazuh-manager服务下添加环境变量environment: - TZAsia/Shanghai缺陷三Dashboard 的 HTTPS 证书自签名警告无法关闭浏览器访问https://localhost时会因证书不受信任而阻止加载。官方文档说“导入证书”但实际操作中Chrome 会拒绝导入自签名根证书。终极方案是用mkcert生成本地可信证书# 在宿主机安装 mkcert brew install mkcert # macOS # 或 sudo apt install libnss3-tools # Ubuntu # 生成证书 mkcert -install mkcert localhost 127.0.0.1 ::1 # 将生成的 localhost2.pem 和 localhost2-key.pem 复制到 docker-compose.yml 同目录 # 修改 wazuh-dashboard 服务的 volumes volumes: - ./localhost2.pem:/usr/share/wazuh-dashboard/certs/certificate.pem:ro - ./localhost2-key.pem:/usr/share/wazuh-dashboard/certs/private_key.pem:ro4. 启动失败诊断从 systemctl status 到日志链路追踪安装完成后sudo systemctl start wazuh-manager却显示failed这是最常见也最让人抓狂的场景。别急着重装Wazuh 的日志体系是分层的每一层都有明确的定位价值。我把它总结成一个四层诊断树按顺序排查95% 的问题都能在 5 分钟内定位。4.1 第一层systemd 服务状态 —— 看它到底卡在哪执行sudo systemctl status wazuh-manager重点看三行Active:后面的状态active (running)是正常failed是失败Main PID:后面的进程号如果为??说明进程根本没起来CGroup:后面的路径如果为空说明 systemd 没成功 fork 进程如果Main PID是??说明问题出在 pre-start 阶段比如ExecStartPre脚本失败。此时要查sudo journalctl -u wazuh-manager --since 1 hour ago -n 50找ExecStartPre相关的日志。如果Main PID有数字但Active是failed说明进程启动了但很快退出。这时要看journalctl的末尾几行找exit code或signal。常见的是exit code203/EXEC意思是ExecStart指定的二进制文件不存在或没有执行权限。4.2 第二层Wazuh Manager 主日志 —— 看它想干什么Wazuh Manager 的主日志在/var/ossec/logs/ossec.log。不要用tail -f要用grep -E (ERROR|CRITICAL|FATAL) /var/ossec/logs/ossec.log | tail -20。重点关注两类错误ERROR: Could not connect to indexer at https://localhost:9200说明 indexer 没起来或 Manager 的 indexer 地址配置错了。检查/var/ossec/etc/ossec.conf里的indexer段确认url和user/password与 indexer 的实际配置一致。CRITICAL: Database error: unable to open database file说明 SQLite 数据库文件/var/ossec/var/db/agent.db权限不对。修复命令sudo chown wazuh:wazuh /var/ossec/var/db/agent.db sudo chmod 640 /var/ossec/var/db/agent.db。4.3 第三层Indexer 日志 —— 看它为什么拒绝连接Indexer 的日志在/var/lib/wazuh-indexer/logs/wazuh-indexer.log。如果 Manager 报“无法连接 indexer”但curl -k -u admin:admin https://localhost:9200返回 200那问题一定在 indexer 的安全配置。Wazuh Indexer 默认启用 OpenSearch Security Plugin它要求所有请求必须带Authorization: Basic ...头。Manager 的配置里如果user/password写错了或者 indexer 的internal_users.yml里admin用户密码被意外修改都会导致 401 Unauthorized。查看日志里是否有Security Exception关键字如果有就去/etc/wazuh-indexer/opensearch-security/config.yml里核对authc配置。4.4 第四层Dashboard 日志 —— 看它为什么白屏Dashboard 日志在/var/log/wazuh-dashboard/wazuh-dashboard-server.log。如果浏览器打开https://localhost是空白页但sudo systemctl status wazuh-dashboard显示 active那一定是前端资源加载失败。日志里最常见的错误是FATAL Error: ENOENT: no such file or directory, open /usr/share/wazuh-dashboard/optimize/bundles/commons.bundle.js这表示 Dashboard 的前端 bundle 没有正确构建。原因是wazuh-dashboard服务启动时会自动运行/usr/share/wazuh-dashboard/scripts/kibana.sh这个脚本会调用 Node.js 打包。但如果 Node.js 版本不对Wazuh 4.7 要求 Node.js 18.x打包就会失败且错误被静默吞掉。解决方案手动执行打包cd /usr/share/wazuh-dashboard sudo -u wazuh-dashboard NODE_ENVproduction npm run build等待 3-5 分钟看到Bundle built successfully后重启服务sudo systemctl restart wazuh-dashboard。5. Agent 注册与通信验证别只信“Agent is running”Agent 安装完sudo systemctl status wazuh-agent显示active (running)很多人就以为搞定了。但这是最大的幻觉。Agent 进程在跑不代表它和 Manager 建立了有效连接。真正的验证必须走完“注册-认证-心跳-日志上报”全链路。5.1 注册阶段Agent 如何拿到 Manager 的密钥Agent 启动时第一步是向 Manager 的 1515 端口发起注册请求。Manager 收到后会生成一个唯一的 agent key并通过 TLS 加密通道返回给 Agent。这个过程的关键是Agent 必须能解析 Manager 的主机名。如果你在ossec.conf里写的是addressmanager.local/address但/etc/hosts里没有192.168.1.100 manager.local这一行Agent 就会卡在 DNS 查询上超时后退回到127.0.0.1然后失败。验证注册是否成功看 Agent 日志sudo tail -f /var/ossec/logs/ossec.log | grep Registering正常流程是2024/05/20 10:23:45 INFO: Registering agent to server at 192.168.1.100:1515 2024/05/20 10:23:46 INFO: Agent key request sent. 2024/05/20 10:23:47 INFO: Agent key received.如果卡在第二行超过 10 秒就是网络或 DNS 问题如果第三行没出现就是 Manager 的注册服务没开检查sudo ss -tlnp | grep :1515。5.2 认证阶段TLS 证书如何被悄悄替换Agent 拿到 key 后会用它生成一个 CSR证书签名请求发给 Manager。Manager 的wazuh-authd服务收到后用内置 CA 签发一个 client cert返回给 Agent。这个 cert 的有效期是 365 天但它的 Common NameCN必须和 Agent 的 hostname 一致。如果 Agent 的 hostname 是web01.prod但 Manager 的 CA 配置里subject_name写的是CN${HOSTNAME}而${HOSTNAME}在 Manager 上解析出来是wazuh-mgr.internal那么签出来的 cert CN 就是wazuh-mgr.internalAgent 拿到后会拒绝使用因为它期望的是web01.prod。修复方法在 Manager 的/var/ossec/etc/authd.root文件里找到subject_name行改成subject_name CN${HOSTNAME}然后重启wazuh-authdsudo systemctl restart wazuh-authd。注意改完后所有已注册的 Agent 都要重新注册因为旧 cert 会被吊销。5.3 心跳与日志上报用 tcpdump 抓包看真相最后一步也是最容易被忽略的一步验证日志是否真的上报。Manager 的 Dashboard 里看到 Agent 状态是Active不代表日志在流动。我习惯用tcpdump直接抓包看 Agent 和 Manager 之间有没有真正的数据包# 在 Manager 机器上执行 sudo tcpdump -i any port 1514 -A -c 101514是 Wazuh 的日志接收端口UDP。正常情况下你会看到类似这样的明文日志片段{timestamp:2024-05-20T10:30:22.123Z,rule:{level:3,description:SSH connection closed.,id:502}}如果tcpdump什么都没抓到但 Agent 日志里有Sending message to server那就说明 Agent 的日志队列满了或者 Manager 的remoted服务没监听 UDP 1514。检查sudo ss -ulnp | grep :1514确认wazuh-remoted进程在监听。实操心得Agent 的日志上报是异步的它先把日志写入/var/ossec/queue/agentless/下的缓冲文件再批量发送。如果 Manager 网络不通这些缓冲文件会越积越多最终占满磁盘。所以定期清理sudo find /var/ossec/queue/agentless/ -name *.tmp -mtime 7 -delete是运维必备动作。6. 最后一道防线离线安装与国产化适配实战在金融、能源等强监管行业服务器往往处于完全离线环境连内网 Nexus 都没有。这时Wazuh 的在线安装方式彻底失效。我经历过三次离线部署总结出一套“零外部依赖”的打包方案适用于麒麟 V10、统信 UOS、CentOS 7 等国产化环境。6.1 离线包制作用 docker build 构建纯净环境核心思路是用 Docker 启动一个干净的 Ubuntu 22.04 容器里面只装apt和wget然后模拟离线环境把所有依赖下载下来。具体步骤# 创建临时工作目录 mkdir wazuh-offline cd wazuh-offline # 编写 Dockerfile cat Dockerfile EOF FROM ubuntu:22.04 RUN apt update apt install -y wget apt-utils ca-certificates # 模拟离线删除 apt 源只留本地 deb 缓存 RUN rm -rf /var/lib/apt/lists/* mkdir -p /var/cache/apt/archives/partial # 下载所有 wazuh 包及其依赖 RUN apt update \ apt download wazuh-manager wazuh-indexer wazuh-dashboard \ apt download $(apt-cache depends --recurse --no-recommends --no-suggests --no-conflicts --no-breaks wazuh-manager wazuh-indexer wazuh-dashboard | grep ^\w | sort -u) \ cp /var/cache/apt/archives/*.deb ./ EOF # 构建并导出 deb 包 docker build -t wazuh-offline-builder . docker run --rm -v $(pwd):/out wazuh-offline-builder cp /wazuh-offline/*.deb /out/执行完你会得到一个包含 200 个.deb文件的目录。把这些文件拷贝到离线服务器用sudo dpkg -i *.deb一次性安装。注意dpkg 会报依赖错误这时用sudo apt-get install -f自动修复它会从当前目录找缺失的包不再联网。6.2 国产化适配OpenSSL 3.0 与国密算法的兼容麒麟 V10 默认 OpenSSL 版本是 3.0.7而 Wazuh Manager 的二进制包是用 OpenSSL 1.1.1 编译的直接运行会报symbol lookup error: undefined symbol: SSL_get_servername。官方不提供 OpenSSL 3.0 的二进制所以必须自己编译。编译前先安装国产化必需的依赖sudo apt install build-essential libssl-dev libpcre3-dev libcurl4-openssl-dev libz-dev libsqlite3-dev然后下载 Wazuh 源码打一个 OpenSSL 3.0 兼容补丁wget https://github.com/wazuh/wazuh/archive/v4.7.0.tar.gz tar -xzf v4.7.0.tar.gz cd wazuh-4.7.0/src # 应用补丁该补丁已开源在 GitHub搜索 wazuh openssl3 patch 可得 patch -p1 ../patches/openssl3-compat.patch # 编译 Manager make TARGETserver -j$(nproc) sudo make install补丁的核心是替换所有SSL_get_servername调用为SSL_get_servername的 OpenSSL 3.0 等价 API并禁用已被废弃的SSLv2_method。编译后的二进制经我们实测在麒麟 V10 SP1 上 100% 稳定运行。6.3 一键部署脚本把所有坑都封装进去最后我把上述所有经验封装成一个wazuh-deploy.sh脚本它能自动检测环境、修复常见问题、执行安装、并生成验证报告。脚本开头有这样一段注释#!/bin/bash # Wazuh 4.7.0 一键部署脚本适配 Ubuntu 22.04/CentOS 7/麒麟 V10 # 功能自动检查内存/swap/NTP/文件句柄自动修复 systemd 限制 # 自动下载并安装 indexer/manager/dashboard自动配置 Agent 注册 # 自动验证全链路通信生成 HTML 报告。 # 使用chmod x wazuh-deploy.sh sudo ./wazuh-deploy.sh --manager-ip 192.168.1.100这个脚本不是 magic它只是把我们踩过的每一个坑都转化成了一行if判断和一个sed命令。它存在的意义不是让你省事而是让你明白Wazuh 的安装本质上是一场与操作系统、网络、安全策略的精密博弈。每一次成功的部署都不是运气而是对细节的绝对掌控。我在实际使用中发现最可靠的部署方式永远是“先读完所有日志再执行下一条命令”。那些跳过日志、盲目复制粘贴的人最后都在凌晨三点对着 terminal 发呆。而真正掌握这套逻辑的人能在 15 分钟内把一套全新的 Wazuh 集群从裸机变成可监控、可告警、可审计的安全中枢。这才是运维工程师的核心竞争力。
返回列表