干安全这行,最怕的不是没工具,而是工具太多。去年年中我被要求在一周内给部门搭一套能够常态化运行的检测能力,当时手头的局面是这样的:OSSEC负责主机侧文件完整性检查,ELK负责日志检索,Suricata负责流量侧告警,三个平台三套账号、三套规则,数据还互相打不通。我花了两天时间做工具选型,最后把检测实验室的主平台定在了Wazuh上。选择它的理由很直接——Wazuh本身就是一个把日志分析、入侵检测、文件完整性监控、漏洞检测、合规基线整合在一起的方案,而且底层复用OpenSearch/Elastic生态,告警和分析体验跟ELK几乎一致。这篇文章是我搭建这套检测实验室的完整记录,从组件选型、安装部署、Agent接入,到规则验证和几个典型坑位的排查过程,都是我在实际操作中做过、验证过的。不管你是刚接触主机安全的新人,还是正准备评估Wazuh的运维或安全工程师,照着这套路线走,至少能少走两三天弯路。
1. 为什么我把检测实验室押在Wazuh上
1.1 从OSSEC走出来的Wazuh到底强在哪
Wazuh的前身是OSSEC,OSSEC在HIDS(主机入侵检测系统)领域是老牌玩家,但它的界面和告警查看体验确实老了,看告警基本靠翻日志文件,规则写起来也比较原始。Wazuh保留了OSSEC最拿手的文件完整性监控和rootkit检测能力,但把老框架几乎重写了一遍,扩展出三大块新能力:一是统一的告警通道,Manager端所有分析结果都能以JSON格式结构化输出;二是与Elastic/OpenSearch生态深度集成,安装脚本直接帮你把Indexer、Dashboard、Filebeat、Agent全串起来;三是增加了大量开箱即用的检测规则和解码器,而且社区还在持续更新规则库。在一个检测实验室里,这三点刚好就是我最需要的:数据能查、规则能改、结果能可视化。
1.2 它和其他开源检测工具的定位差异
很多人会把Wazuh和ELK、Suricata、Osquery放到一起比较,其实它们解决的是不同层次的问题。ELK本身不是安全平台,它擅长日志聚合和检索,但检测逻辑、告警规则、资产梳理都需要你自己从零搭;Suricata专注网络流量侧,对主机内部的文件变化、账户操作、权限提升这些行为无能为力;Osquery能做很细的终端采集,但偏被动查询,主动检测和事件响应的闭环不如Wazuh完整。Wazuh的角色是主机侧检测和日志分析,正好和流量侧工具形成互补。我当时定下的原则是:实验室里以Wazuh为核心,后续有条件再外接流量检测,形成主机加网络的两层感知,这一层定位想清楚,后面做架构规划才不会被各种噪音干扰。
2. 单机实验室的架构与资源规划
2.1 三个核心组件各管什么
先讲清楚Wazuh安装完以后,你实际上会得到哪些进程,这对后面排查问题非常关键。
Wazuh indexer基于OpenSearch,负责索引、存储和搜索所有日志与告警,相当于整条流水线的仓库;Wazuh server里面跑着wazuh-manager这个核心进程,负责接收Agent上报的日志、运行解码器和规则分析、产生告警,同时还有Filebeat把告警转发到indexer;Wazuh dashboard由OpenSearch Dashboards改造而来,是操作界面。三者装在同一台机器上,就是all-in-one模式,这也是检测实验室最合适的起步形态。受监控主机上装的Wazuh agent负责采集日志、做文件完整性快照、收集系统审计信息,然后通过加密通道上报给Manager。
组件之间如果用一句话概括关系:Agent是眼睛,Server是大脑,Indexer是记忆,Dashboard是手。我刚开始接触Wazuh时没搞清indexer和server的区别,结果在配置文件里瞎找半天,后来把这个对应关系梳理清楚,问题定位就快多了。
| 组件 | 核心作用 | 实验室部署建议 |
|---|---|---|
| Wazuh indexer | 存储、索引、搜索告警与日志 | 可与Server同机 |
| Wazuh server | 接收Agent日志、规则分析、告警生成 | 可与Indexer同机 |
| Wazuh dashboard | 可视化界面、告警检索、报表 | 与Server同机 |
| Wazuh agent | 部署在受监控主机上采集信息 | 每台受监控主机一个 |
2.2 给实验室定一个不浪费的配置清单
在实验环境里,我给自己的配置是虚拟机4核CPU、8GB内存、120GB磁盘。如果内存只有4GB,整套组件是能装完,但运行一段时间后Indexer容易因为内存不够被系统OOM杀掉,Dashboard访问也会变得很慢,体验非常折磨。我建议实验室起步内存直接8GB,因为你不光要跑Wazuh,还要同时开浏览器、终端、模拟攻击的机器,资源竞争比想象中严重。
磁盘方面,告警和索引增长得比你想象中快。尤其是开了漏洞检测之后,CVE数据和Agent资产数据会持续写入,实验室用120GB比较从容,等索引膨胀后再考虑快照清理策略。这里还要提醒一句:安装之前把主机名提前规划好,不建议用太长的名字或带下划线的hostname,因为Wazuh安装时会生成绑定主机名和IP的证书,主机名不规范可能导致后续证书校验阶段报错。
端口规划是另一个容易忽略的细节。Agent到Manager的通信用1514/TCP,Agent注册用1515/TCP,Manager的API是55000/TCP,Dashboard页面是443/TCP,Indexer本身的REST接口是9200/TCP。如果Agent主机装了防火墙,只需要放行这几类方向的流量;Manager服务器如果启用UFW,至少要允许这些端口。我吃过一次亏:一开始只放行了443,Agent一直注册不上,在服务端日志里看到timeout,排查半天才发现是防火墙没放行1515,这类问题最浪费实验时间。
3. 服务端部署:半小时跑完Wazuh Indexer/Server/Dashboard
3.1 安装前的三个小动作
服务端部署我是在一台Ubuntu 22.04 LTS上完成的。动手之前做了三件事:第一,apt update升级系统包,避免依赖版本太旧;第二,把主机名设置为短名字,比如wazuh-lab,并确认/etc/hosts里有一条指向本机IP的记录;第三,确认这台机器上没有占用443、9200、1514、1515这些端口。尤其是9200,如果你之前装过OpenSearch或Elasticsearch,端口被占用会导致安装脚本起不了indexer。
Wazuh的官方安装脚本是wazuh-install.sh,它会自动处理证书生成、配置文件生成、组件安装和初始化。不同大版本的脚本URL路径会变,我用的是4.9版本系列,命令很简洁:
curl -sO https://packages.wazuh.com/4.9/wazuh-install.sh sudo bash wazuh-install.sh -a如果你在阅读本文时Wazuh已经发布了更高版本,把路径里的4.9替换成对应主版本即可,整体流程保持一致。
3.2 执行一键安装与配置生成
脚本运行过程大概10到15分钟,取决于网络状况。它会检查系统是否满足条件,然后下载wazuh-indexer、wazuh-manager、wazuh-dashboard,生成内部证书和密码,启动服务并做初始化配置。安装完成后,控制台会直接显示Dashboard的访问地址、admin账号和随机生成的密码,同时当前目录下会保留一份wazuh-passwords.txt,里面是所有组件的账号密码,务必保存好。
如果你希望把Manager和Indexer分机部署,或者以后要上集群,可以先用--generate-config-files参数生成配置文件,再分别用install参数逐个安装;对于检测实验室这种场景,直接用-a全自动装在同一台机器上最省事,先把链路跑通比什么都重要。
这里顺便说一个我在生产环境踩过的坑:不要在安装到一半的时候做虚拟机快照或者强制重启,否则证书目录可能出现错位,管理端和agent握手异常,清理起来比重新装一遍还麻烦。实验室虽然是测试环境,但安装过程尽量一气呵成。
3.3 装完之后的健康检查清单
安装完成后,我习惯按下面四步做健康检查:
systemctl status wazuh-manager wazuh-indexer wazuh-dashboard --no-pager第一步看systemd服务状态,确保wazuh-manager、wazuh-indexer、wazuh-dashboard都是active;第二步用curl测试本机Dashboard端口,能返回登录页就说明Web服务起来了;第三步打开浏览器用admin账号和生成的密码登录,确认没有意外的报错;第四步到/var/ossec/logs/ossec.log里看一眼日志输出,确认没有反复刷新的报错关键字。
curl -kI https://127.0.0.1:443这里插一句:Dashboard默认使用自签名证书,浏览器第一次访问会提示不安全,这是正常现象,实验室环境不用管。如果你担心安全问题,之后可以替换成内部CA签发的证书,不影响这套方案本身。
4. 接入第一台Agent:注册、启动与状态确认
4.1 Linux Agent的安装与注册
服务端跑起来后,接下来就是把受监控主机接入平台。我在实验室里先接了一台Ubuntu的Agent,从packages.wazuh.com页面找到对应架构的Agent包后,用dpkg方式安装并写入Manager地址:
curl -sO https://packages.wazuh.com/4.x/wazuh-agent_4.x.x-1_amd64.deb sudo WAZUH_MANAGER='192.168.1.10' dpkg -i wazuh-agent_4.x.x-1_amd64.deb sudo systemctl daemon-reload sudo systemctl enable --now wazuh-agent这里WAZUH_MANAGER环境变量是安装包在postinst阶段会读取的,它会把Manager地址写进/var/ossec/etc/ossec.conf的address字段。如果你用的是RPM系发行版,安装后手动编辑ossec.conf里的address字段再启动Agent,效果是一样的。
Agent启动后会自动向Manager的1515端口发起注册请求。Wazuh默认启用了自动注册,Manager会给Agent分配一个唯一ID,同时生成对应的认证密钥。注册完成后,Agent和Manager之间会通过加密通道传输日志事件。
4.2 从Dashboard确认监控状态
验证Agent是否注册成功,我常用的命令是下面这条:
sudo /var/ossec/bin/agent_control -l输出结果是一个Agent列表,包含ID、名称、IP和状态。也可以在Dashboard的Endpoints页面看,Agent状态会从Pending变成Active。如果一直显示Disconnected,多半是端口不通、地址写错或者认证密钥没生成成功,后面第七部分我会详细讲排查过程。
我在实验室同时接了一台Ubuntu和一台CentOS的Agent,目的就是验证不同系统的日志采集路径。Ubuntu的SSH日志在/var/log/auth.log,CentOS在/var/log/secure,Wazuh的Agent会自动识别这些路径并做解析,不需要额外配置。这一设计对刚接触HIDS的人来说很友好,部署成本比想象中低。
5. 实战验证规则引擎:让告警真正响起来
5.1 日志从Agent到告警的四步链路
平台跑起来了,Agent也接了,但你可能还没真正看到一条告警。这一阶段我们来把规则引擎跑通,理解告警的完整生命周期。
Agent采集到的日志首先发给Manager的remoted监听进程,然后进入预处理阶段,被拆成基础字段;下一步是解码器识别日志类型,比如一行SSH日志,解码器能抽出program_name=sshd、srcip=192.168.1.20、user=root这些结构化字段;最后规则引擎根据字段做匹配,命中后生成告警,写入alerts.json并推送给Indexer。整个过程是流水线式的,Agent负责采集,Manager负责解析和判定,Indexer负责存储,Dashboard负责展示。
这条链路决定了你排错时的思路:告警没出来,可能是Agent没采到日志,也可能是解码器没识别,也可能是规则没有命中,还可能是索引写入失败。按这个顺序逐层排查,比在Dashboard里瞎翻高效得多。
5.2 模拟SSH异常登录并追踪命中规则
为了触发一条真实告警,我在Agent主机上手动输入了几次错误密码的SSH登录,动作本身不复杂,重点是观察日志和告警的生成过程。稍等一两分钟,进入Dashboard的Threat Hunting页面,搜索rule.id为5712或5715,正常情况下能看到SSH失败登录相关告警。这些规则来自Wazuh自带的sshd规则集,规则ID主要集中在5700到5800区间,不同版本编号可能有微调,你直接搜sshd关键词也能筛选出来。
如果搜不到告警,优先检查三件事:Agent和Manager系统时间是否一致,日志是否真的写入了/var/log/auth.log或/var/log/secure,以及Dashboard右上角的时间范围有没有限制住。时间不同步会造成告警时间偏移,时间范围太窄则直接看不到历史数据,这两个是新手最容易忽略的因素。
5.3 写一条属于自己的本地规则
为了让实验室更贴近自己的检测需求,我再演示一条自定义规则的写法。比如我希望专门记录sudo执行失败的事件,这在排查提权异常时很有参考价值。在Manager上打开/var/ossec/etc/rules/local_rules.xml,追加一个规则:
<group name="local,labsudo,"> <rule id="100100" level="7"> <decoded_as>syslog</decoded_as> <field name="program_name">sudo</field> <match>not in the sudoers</match> <description>Local lab: sudo permission denied</description> </rule> </group>这里的id我选择100100,是为了避开Wazuh自带的系统规则区间,降低冲突风险;level设成7,比默认syslog中级告警高一点,方便在告警列表里一眼看到。保存后重启wazuh-manager,再到Agent上执行一次sudo -u root ls /root这种肯定会失败的sudo命令,状态码返回非0的同时会在日志里留下记录,Dashboard上应该很快出现这条自定义告警。
自定义规则最常见的坑是match关键字里的文本与日志实际内容不完全匹配,导致一条都匹配不上。排查方法是先在Agent的日志文件里找到那行原始日志,确认program_name字段,再到Manager上执行ossec-logtest做调试:
sudo /var/ossec/bin/ossec-logtest把复制的日志粘贴进去,回车,工具会直接告诉你能否解码、有没有匹配到规则。这应该是整个检测实验室里除了Dashboard之外最常用的调试工具,强烈建议收藏。
6. FIM与漏洞检测:把实验室能力补全
6.1 文件完整性监控:从配置到可视化事件
文件完整性监控是Wazuh从OSSEC时代就有的核心能力,在Wazuh里叫FIM。它的原理不难理解:Agent对受监控目录做哈希快照,之后周期性或实时比对当前文件和快照的差异,一旦发现新增、修改、删除,就上报事件。默认syscheck配置会监控/etc、/usr/bin、/usr/sbin等关键目录,但为了让实验室效果更直观,我给Agent建了一个专门目录/data/protected,并在ossec.conf里添加监控配置:
<syscheck> <directories check_all="yes" whodata="yes">/data/protected</directories> </syscheck>whodata属性表示启用who-data模式,在Linux上依赖fanotify内核机制,能记录哪个用户、哪个进程修改了文件。这个模式对高I/O场景有额外开销,生产环境建议谨慎开启,但实验室里开着非常直观。配置完成后重启Agent,去/data/protected目录touch一个新文件,几十秒内Integrity Monitoring模块就会出现一条新增文件事件,事件详情页会给出文件路径、权限、属主和哈希值。可以拿这个哈希值手动计算一遍,会更容易理解FIM为什么能发现敏感文件的篡改。
6.2 漏洞检测:开启后为什么先别着急
漏洞检测模块是Wazuh 4.x重点强化的一部分,它不直接扫端口,而是收集Agent上已安装的软件包和操作系统信息,再和CVE库做匹配。在Manager的ossec.conf里启用相关配置:
<vulnerability-detector> <enabled>yes</enabled> <interval>12h</interval> <provider name="nvd"> <enabled>yes</enabled> </provider> </vulnerability-detector>实验室配置我建议只开NVD一个数据源,interval保持12小时或24小时就够。第一次启用时,Manager需要先下载并解析CVE库,这个数据量很大,在部分网络环境下下载可能要几个小时甚至更久,这段时间Dashboard的Vulnerability面板是空的,不用慌。查看进度的方式很简单,在Manager上tail日志文件并检索vulnerability-detector关键字:
sudo tail -f /var/ossec/logs/ossec.log | grep -i vulnerability能看到下载进度或解析条数输出,就说明模块在工作。等第一次同步完成,Agent的漏洞列表才会逐步填充起来。
6.3 离线环境怎么喂CVE数据
如果你是在隔离网络里搭实验室,NVD在线同步是走不通的,这时候需要提前规划CVE数据源。Wazuh支持从离线文件导入CVE库,具体做法是把官方提供的NVD JSON文件放入指定目录,并在provider配置里设置更新路径。这个流程在官方文档里有详细说明,我在这里只提醒一点:离线导入前认真看日志,确认文件格式和版本是否匹配,我见过有人下了旧版本NVD文件,导入时反复报解析失败。如果只是做检测和规则实验,离线漏洞检测不是必选项,可以放在网络互通后再补上。
7. 实操中踩过的坑:四次排查的完整过程
7.1 服务反复重启,第一反应是看日志而非加资源
我在第2节提到内存最好直接8GB,因为第一次安装时我只给了4GB,结果wazuh-indexer用着用着就退出,状态变成failed,Dashboard时不时504。我当时第一反应是扩容,但手动扩到6GB之后依然偶尔崩,才发现问题的关键不只是总内存,而是OpenSearch和Dashboard这两个Java进程的堆内存设置太大,和系统内存不匹配。解决方式是把/etc/wazuh-indexer/jvm.options里的-Xms和-Xmx调低到1g,然后重启indexer。实验环境这样改能稳定运行,但生产环境一定要按真实容量重新规划堆大小,不能在低配硬扛。
这个坑给我的教训是:排在扩容前面的,永远是先看日志和进程指标。通过dmesg或journalctl能看到OOM Killer的击杀记录,确认是内存不足还是配置原因,再动手改配置,方向才不会错。
7.2 注册成功但状态一直Disconnected
第二个坑是Agent已经完成注册,但Dashboard端显示Disconnected。这个问题我排查了小半天,一开始怀疑是防火墙,放行了端口仍然无济于事;最后在Agent上执行ss -ant确认到Manager的1514端口没有建立连接,才想到去看Agent端ossec.conf,发现里边的address字段写的是服务端主机名,而Agent的/etc/hosts里没有对应解析。改成IP地址后,重启Agent,状态秒变Active。
这里建议所有Agent的Manager地址统一写成IP,除非你的内部DNS非常可靠。生产环境里因为主机名解析导致的连接问题非常常见,尤其当Agent分布在不同网段时。
7.3 告警面板空空如也,问题出在索引和时间范围
第三个坑是数据明明在往Indexer写,但Dashboard的Security events模块就是看不到告警。最开始我怀疑是Filebeat转发有问题,后来发现索引里其实有数据,只是Dashboard的时间范围停留在昨天凌晨,而我的测试发生在当天下午,平台默认把时间窗口卡住了。把时间范围切到Last 15 minutes后,告警立刻出现。
另一种情况是索引模式不一致。告警索引默认在wazuh-alerts-*系列下,如果手动创建过索引模板或做过索引别名调整,数据可能写到错误索引,导致Dashboard搜不到。遇到这种问题,先去Indexer的索引管理页面看实际索引名,再回头检查Dashboard的索引模式,基本能定位。
7.4 漏洞模块数据不出来,等还是不等
第四个坑是漏洞检测模块打开很久,Dashboard还是空白。除了下载慢,还有一种可能是NVD Provider初始化失败,日志里会出现无法解析CVE条目之类的输出。解决办法是把provider配置里的update_from_year调得靠后一些,比如只更新最近一年的漏洞记录,能显著减少首次同步的数据量;或者把interval调短一些,让模块定时重试。判断要不要继续等,还是看日志里有没有持续增长的进度输出,如果日志长时间不动,大概率是卡住了,果断改配置重启。
8. 实验室走上正轨之后,我做了这些调优
8.1 性能与噪音的平衡
检测实验室运行稳定后,真正需要花时间的不是功能,而是规则噪音治理。Wazuh自带规则数量很大,很多level较低的告警在生产环境没有太大价值,我建议实验室里先保留全部规则,目的是理解每类告警的字段结构、触发条件和误报模式。等你熟悉了告警数据,再在local_rules.xml里用if_sid对某些高频规则做降级或豁免。
另外要注意日志采集范围。很多Agent默认采集大量应用日志,如果实验室Agent只用于功能验证,可以在ossec.conf里只保留syslog和必要的FIM配置,关闭不必要的日志通道。日志量降下来之后,索引创建速度快、检索响应快、告警定位也更快,这个体会在Agent数量增多后会特别明显。
8.2 下一步可以怎么扩展
实验室稳定之后,我沿着两个方向做了扩展。一个方向是告警通知:把Dashboard的告警通过webhook转发到内部协同软件,做到重要安全事件即时触达,这样即使不常看Dashboard,也能第一时间知道异常。另一个方向是数据关联:把扫描器发现的资产信息与Wazuh的Agent资产数据做对照,填补由日志分析之外的盲区。
如果你打算把Wazuh方案带到生产环境,建议不要把Indexer和Server放在同一台机器上,尤其当Agent数量超过50台之后,存储和计算压力会明显上升。生产级部署还要认真设计索引生命周期管理,定期轮转、清理、归档旧索引,避免磁盘被历史数据撑爆。权限方面,至少要把普通查看账号和admin账号分开,Wazuh自带RBAC模型,配置并不复杂,但很多人会忘记这一步。
最后说一点个人体会。搭建Wazuh检测实验室,表面上是在安装软件、跑通流程,本质上是在训练自己对告警链路的敏感度。我第一次看到那条SSH失败登录告警时,真正有触动的不是工具本身多厉害,而是日志从Agent到Manager、再到索引器、最后在Dashboard呈现,每一步都可以被观察和验证,这种能力很难通过看文档获得。先让环境跑起来,再亲手把每一次告警的链路走一遍,比任何速成教程都更扎实。希望这篇记录能帮你在自己的实验室里,少踩几个我踩过的坑。