试着部署一套开源EDR
本篇是基于开源 EDR 产品记录的完整部署过程涵盖架构设计、配置说明、AI 集成、成本控制与踩坑经验。需要说明的是本篇主要定位还是跑通一次相对完整的可行性验证可能达不到生产标准仅供参考。此外本篇不涉及相关的概念说明如什么是 EDR , ISM等大家有需求的可以自行 GPT。目录为什么要做这件事整体架构设计真实环境准备Wazuh 部署实战配置详解与日志控制AI 大模型集成测试验证成本分析与控制踩坑记录与经验总结写在最后01 为什么要做这件事商业 EDR 产品如 CrowdStrike Falcon、Microsoft Defender for Endpoint年费通常在数万元至十几万元对于小团队而言成本压力显著。但安全防护不能因为预算有限就放弃我们需要一种低成本、可落地的替代方案。核心目标利用开源 EDR 框架搭建端点检测能力结合 AI 大模型实现告警智能分析达到类 SaaS EDR 的防护效果。可行性验证在本地环境中完成 PoC验证架构可行性为后续小团队落地提供决策依据。经过调研我选择了Wazuh作为核心 EDR 框架来做可行性验证。原因很简单它是目前最活跃的开源 XDR/SIEM 项目社区支持好文档完善而且官方已经支持 AI/LLM 集成包括/llms.txt标准。注意并不是所有的团队都需要 EDR选型或者要上一个软件之前还是应该对其有一个相对比较深刻的理解以及对自己的业务线有清晰的认识看看自己面临的问题是否真的需要 EDR或者 EDR 是否真的能解决你的问题还有就是真上了 EDR你到底hold不hold的住。。。不要赔了夫人又折兵。02 整体架构设计我本人是有一台云端的轻量服务器但资源有限。如下图我的OpenClaw助手给我的总结所以我采用了全本地部署方案所有服务端组件运行在 WSL2 Docker 中Windows 宿主机作为被监控端点架构设计图如下。架构优势零服务器成本利用现有 Windows 机器部署简单Docker Compose 一键启动AI 分析按需调用仅分析高危告警token 成本极低。03 真实环境准备以下是我们实际测试使用的环境配置项目配置说明操作系统Windows 11宿主机内存32 GBWSL2 分配 12GB磁盘1TB SSD938GB 可用WSL2Ubuntu 22.04.5 LTSVERSION 2Docker29.6.1Docker Desktop WSL2 后端Docker Composev5.1.4随 Docker Desktop 安装Python3.10.12WSL2 内置Wazuh 版本4.14.6 (stable)从 GitHub 克隆关键配置项WSL2 内存限制通过.wslconfig文件配置# C:\Users\用户名\.wslconfig [wsl2] memory12GB processors4 swap6GBIndexer (OpenSearch) 需要vm.max_map_count262144每次 WSL2 重启后需要重新设置# 进入 WSL2 后执行sudosysctl-wvm.max_map_count262144# 持久化添加到 ~/.bashrcechosudo sysctl -w vm.max_map_count262144 2/dev/null~/.bashrc04 Wazuh 部署实战4.1 精准克隆指定稳定版由于国内网络环境直连 GitHub 较慢且默认分支可能包含不稳定的 Alpha/Beta 代码推荐直接使用-b参数精准克隆官方的稳定版 Tag并加上--depth1减少历史数据下载量# WSL2 终端cd/home/edr# 精准克隆 v4.14.6 稳定版只拉取当前版本数据gitclone-bv4.14.6[https://github.com/wazuh/wazuh-docker.git](https://github.com/wazuh/wazuh-docker.git)--depth1cdwazuh-docker注意版本选择我们最初克隆时默认分支是 5.1.0-alpha0这是一个不稳定的 alpha 版本。建议始终使用最新稳定版当前为 v4.14.6可通过git tag --sort-v:refname查看所有可用版本。4.2 生成 TLS 证书v4.14.6 使用专用的证书生成器比 5.x 更简单cd/home/edr/wazuh-docker/single-node# 使用仓库自带的证书生成配置dockercompose-fgenerate-indexer-certs.yml up# 等待证书生成完成后容器自动退出# 清理生成容器dockercompose-fgenerate-indexer-certs.yml down验证证书文件ls-laconfig/wazuh_indexer_ssl_certs/# 应包含root-ca.pem, wazuh.indexer.pem, wazuh.manager.pem,# wazuh.dashboard.pem, admin.pem 等文件4.3 启动全栈服务cd/home/edr/wazuh-docker/single-nodedockercompose up-d# 查看容器状态dockercomposeps# 等待 Indexer 就绪可能需要 1-2 分钟curl-sk-uadmin:SecretPassword https://localhost:9200/_cluster/health?pretty# 返回 status : green 或 yellow 即成功注意这一步构造的时候会拉取wazuh镜像这一步很可能因为网络问题出现一些EOF之类的异常多试几次就好。最后会拉取4个镜像包含前面那个生成证书的镜像启动3个容器在docker desktop里查看效果如下4.4 访问 Dashboard在 Windows 浏览器中打开https://localhost登录账号admin登录密码SecretPassword浏览器会提示证书不安全点击继续访问即可4.5 安装 Windows Agent# PowerShell管理员模式Invoke-WebRequest-Uri https://packages.wazuh.com/4.x/windows/wazuh-agent-4.9.0-1.msi -OutFile$env:TEMP\wazuh-agent.msi msiexec/i$env:TEMP\wazuh-agent.msi/q WAZUH_MANAGERlocalhost WAZUH_REGISTRATION_SERVERlocalhost# 验证服务Get-ServiceWazuhSvc在 Dashboard →Agents中查看 Agent 是否显示为Active。这个面板是基于Kibana构造的所以前面我们拉去Wazuh镜像的时候镜像很大所以要多等一会儿。05 配置详解与日志控制5.1 默认密码说明用途用户名密码配置文件Dashboard 登录adminSecretPassworddocker-compose.ymlIndexer APIadminSecretPassworddocker-compose.ymlWazuh REST APIwazuh-wuiMyS3cr37P450r.*-internal_users.ymlDashboard 内部用户kibanaserverkibanaserverinternal_users.yml5.2 ISM 索引保留策略防止日志积累导致磁盘爆满在 Dashboard 中创建 ISM 策略Indexer management → Index Management → State management policies → Create policy粘贴以下 JSON{policy:{policy_id:wazuh-alert-retention-policy,description:Auto-delete alert indices older than 30 days,schema_version:17,default_state:retention_state,states:[{name:retention_state,actions:[],transitions:[{state_name:delete_alerts,conditions:{min_index_age:30d}}]},{name:delete_alerts,actions:[{delete:{}}],transitions:[]}],ism_template:[{index_patterns:[wazuh-alerts-*],priority:1}]}}5.3 Manager 日志优化v4.14.6 的 Manager 配置文件从宿主机挂载可直接编辑# 宿主机路径vi/home/edr/wazuh-docker/single-node/config/wazuh_cluster/wazuh_manager.conf关键配置项globaljsonout_outputyes/jsonout_outputalerts_logyes/alerts_loglogallno/logall!-- 重要不开全量日志 --logall_jsonno/logall_json/globalalertslog_alert_level3/log_alert_level!-- 只记录 level 3 的告警 --/alerts06 AI 大模型集成这是本方案的核心亮点通过 AI 大模型自动分析 Wazuh 产生的安全告警弥补小团队缺少专业安全分析师的短板平替商业版 EDR 软件的最强大脑角色。6.1 架构设计Wazuh Manager → Integration (level 7 告警) → AI Analyzer (FastAPI :8080) → DeepSeek API6.2 智能过滤与成本控制直接将所有告警转发给 AI 会导致 token 消耗过快。我们在 AI 分析器中实现了四层过滤过滤层说明效果Level 过滤只分析 level 7 的告警Critical/High过滤约 60-70%规则白名单/黑名单只分析关心的规则 ID屏蔽低价值规则过滤约 10-20%频率限制同一规则 同一端点5 分钟内最多分析 3 次过滤约 10-15%内容去重相同告警内容 10 分钟内不重复分析过滤约 5-10%6.3 AI 分析器核心代码完整的 AI 分析器服务代码Python FastAPI说明以下代码由大模型生成Wazuh AI Alert Analyzer v2 - 带智能过滤和成本控制importjson,logging,timefromdatetimeimportdatetimefromcollectionsimportdefaultdictfromfastapiimportFastAPI,Request,HTTPExceptionfromopenaiimportAsyncOpenAI# 配置区 DEEPSEEK_API_KEYsk-YOUR_API_KEY# 替换为你的 KeyDEEPSEEK_MODELdeepseek-v4-flashMIN_ALERT_LEVEL7# 只分析 level 7RATE_LIMIT_WINDOW300# 5 分钟窗口RATE_LIMIT_MAX3# 窗口内最多 3 次DEDUP_WINDOW600# 10 分钟去重clientAsyncOpenAI(api_keyDEEPSEEK_API_KEY,base_urlhttps://api.deepseek.com/v1)appFastAPI(titleWazuh AI Alert Analyzer v2,version2.0.0)# 过滤状态rate_limit_storedefaultdict(list)dedup_store{}stats{total_received:0,analyzed:0,filtered:0}defshould_analyze(alert):四层过滤逻辑rulealert.get(rule,{})rule_idstr(rule.get(id,))rule_levelint(rule.get(level,0))agent_idstr(alert.get(agent,{}).get(id,))nowtime.time()# 第 1 层Level 过滤ifrule_levelMIN_ALERT_LEVEL:returnFalse,level_too_low# 第 2 层频率限制keyf{rule_id}:{agent_id}recent[tfortinrate_limit_store[key]ifnow-tRATE_LIMIT_WINDOW]iflen(recent)RATE_LIMIT_MAX:returnFalse,rate_limited# 第 3 层内容去重content_hashhash(json.dumps(alert.get(full_log,),sort_keysTrue))ifcontent_hashindedup_storeandnow-dedup_store[content_hash]DEDUP_WINDOW:returnFalse,dedupreturnTrue,passapp.post(/analyze)asyncdefanalyze_alert(request:Request):stats[total_received]1alertawaitrequest.json()should_proc,reasonshould_analyze(alert)ifnotshould_proc:stats[filtered]1return{filtered:True,reason:reason}stats[analyzed]1rulealert.get(rule,{})agentalert.get(agent,{})context(f规则:{rule.get(description,N/A)}\nf级别:{rule.get(level,N/A)}\nf端点:{agent.get(name,N/A)}\nf日志:{json.dumps(alert.get(full_log,),ensure_asciiFalse)[:2000]})respawaitclient.chat.completions.create(modelDEEPSEEK_MODEL,messages[{role:system,content:你是一名资深安全分析师。分析 EDR 告警并输出 JSON。},{role:user,content:context}],response_format{type:json_object},temperature0.1)resultjson.loads(resp.choices[0].message.content)returnresultapp.get(/health)asyncdefhealth():return{status:ok}app.get(/stats)asyncdefget_stats():查看过滤统计returnstats下面第7.3节部分会有脚本执行效果6.4 配置 Wazuh 转发告警在 Manager 配置文件中添加 integration 块!-- 在 wazuh_manager.conf 末尾添加 --integrationnamecustom-ai-analyzer/namehook_urlhttp://host.docker.internal:8080/analyze/hook_urlalert_formatjson/alert_formatlevel5/level!-- Wazuh 侧过滤 level 5 --/integration关于 hook_url 地址Docker 容器内的localhost指向容器自身不是 WSL2 宿主机。使用host.docker.internal指向宿主机。如果不可用改用 WSL2 的实际 IP。07 测试验证7.1 验证告警链路Wazuh 部署完成后系统会自动产生多种告警。以下是我实际测试中观察到的告警类型告警类型数量说明SCA 安全检查基线669 条Agent 首次连接后自动扫描 Windows 安全配置Windows 系统事件26 条Windows Event Log 中的系统事件Agent 状态变更若干Agent 启动/停止/连接事件通过 Indexer 直接查询告警推荐方式# WSL2 终端# 查询最近 5 条告警curl-sk-uadmin:SecretPassword-XPOSThttps://localhost:9200/wazuh-alerts-*/_search?pretty\-HContent-Type: application/json\-d{size:5,sort:[{timestamp:{order:desc}}],_source:[rule.description,rule.level,agent.name,timestamp]}# 查询 level 7 的高危告警curl-sk-uadmin:SecretPassword-XPOSThttps://localhost:9200/wazuh-alerts-*/_search?pretty\-HContent-Type: application/json\-d{size:5,query:{range:{rule.level:{gte:7}}},_source:[rule.description,rule.level,timestamp]}注意Wazuh 4.14.6 的 REST API 没有/alerts端点告警数据需要通过 Indexer (OpenSearch) 直接查询。这是与早期版本的一个重要区别。7.2 FIM文件完整性监控配置FIM 是 EDR 的核心能力之一但在实际配置中需要注意几个关键点配置 Windows Agent 的 FIM 监控目录在 Manager 上创建agent.conf下发给 Windows Agent# WSL2 终端dockerexecsingle-node-wazuh.manager-1bash-ccat /var/ossec/etc/shared/default/agent.conf EOF agent_config osWindows syscheck disabledno/disabled frequency300/frequency directories realtimeyesC:\wazuh-fim-test/directories /syscheck /agent_config EOF# 重启 Manager 使配置生效cd/home/edr/wazuh-docker/single-nodedockercompose restart wazuh.managerFIM 配置注意事项首次扫描耗时— FIM 首次扫描需要对所有监控文件计算哈希MD5SHA1SHA256大目录如C:\Windows\System32可能需要 10 分钟。建议先用小目录测试。避免过大目录— 监控C:\Windows、C:\Program Files等目录会产生大量告警和性能问题。建议只监控关键子目录。UTF-8 编码问题— 如果系统路径中包含非 UTF-8 字符如某些中文路径FIM 扫描可能报错invalid UTF-8 byte导致数据库为空。解决方法是避免监控包含特殊字符的目录。Realtime 模式— 添加realtimeyes属性可以启用实时检测但只在首次扫描完成后生效。7.3 AI 分析验证# 发送测试告警到 AI 分析器curl-XPOST http://localhost:8080/analyze\-HContent-Type: application/json\-d{ rule: {id: 5710, description: SSH brute force attempt, level: 7}, agent: {name: windows-pc, ip: 127.0.0.1}, full_log: Failed password for root from 10.0.0.1 }# 查看过滤统计curlhttp://localhost:8080/stats7.4 最终验证清单检查项预期结果状态WSL2 VERSION2PASSWazuh 容器3 个全部 runningPASSIndexer healthgreen 或 yellowPASSDashboard 访问https://localhost 可登录PASSWindows Agent状态 ActivePASSISM 保留策略已创建并应用PASSFIM 测试告警Dashboard 可见PASSAI 分析服务/health 返回 okPASSAI 分析结果返回 severity/analysisPASS08 成本分析与控制8.1 Token 消耗估算每条告警分析约消耗700-1000 token输入 500-700 输出 200-300。场景日告警量日消耗 token日成本 (元)月成本 (元)正常使用level 750-200 条35K-200K0.02-0.140.6-4.2频繁触发500-1000 条350K-1M0.14-0.74.2-21告警风暴10000 条7M2.884四层过滤的实际效果在我们的测试中四层过滤可以将实际需要 AI 分析的告警量减少80-95%。即使 Wazuh 每天产生 1000 条告警真正调用 API 的只有 50-200 条月成本控制在 5 元以内。8.2 推荐的过滤参数# AI Analyzer 配置MIN_ALERT_LEVEL7# 只分析 Critical/HighRATE_LIMIT_WINDOW300# 5 分钟窗口RATE_LIMIT_MAX3# 同规则 端点最多 3 次DEDUP_WINDOW600# 10 分钟去重09 踩坑记录与经验总结踩坑记录问题原因解决方案默认分支是 alpha 版本wazuh-docker 默认分支指向开发版始终git checkout v4.14.6切换稳定版vm.max_map_count 重置WSL2 每次重启会重置内核参数添加到~/.bashrc自动设置Dashboard 打不开端口转发问题尝试https://localhost:443或 WSL2 IPAgent 显示 DisconnectedManager 不可达检查Test-NetConnection localhost -Port 1514API 认证失败密码混淆API 用wazuh-wuiDashboard 用adminDocker 容器内无法访问宿主机服务容器 localhost 指向自身使用host.docker.internal或 WSL2 IP经验总结版本选择很重要— 始终使用稳定版避免 alpha/beta。通过git tag查看可用版本。密码要分清— v4.14.6 有三套密码Dashboard 登录admin/SecretPassword、API 用户wazuh-wui、内部用户kibanaserver。日志控制是必须的— 即使磁盘充裕也要设置 ISM 保留策略。FIM 监控目录不要太大避免告警风暴。AI 集成要做好过滤— 不要把所有告警都发给 AI四层过滤可以节省 80-95% 的 token 成本。利用 AI 智能体辅助部署— 把部署文档喂给 AI 智能体如 OpenClaw、Hermes可以大幅减少手动操作。10 写在最后通过本次实战验证了开源 EDR AI 大模型方案在小团队落地的可行性。核心结论技术可行Wazuh 4.14.6 WSL2/Docker 可以在普通 Windows 机器上流畅运行部署过程约 1-2 小时成本可控零软件许可费AI 分析月成本约 5-20 元取决于告警量和过滤策略效果可用AI 分析可以提供专业的安全建议弥补小团队缺少安全专家的短板可扩展后续可接入 Velociraptor取证、osquery资产发现、威胁情报等增强能力对于预算有限但需要基本安全防护能力的小团队这是一个值得尝试的方案。当然它无法完全替代商业 EDR如 CrowdStrike 的实时防护、EDR 响应能力但作为起点和过渡方案已经足够。此外今天我的测试过程只是本地部署 EDR 架构的冰山一角后续还有诸多操作步骤包括但不限于以下内容根据实际需求调整过滤参数优化 token 成本探索自定义检测规则覆盖团队特有的安全场景考虑接入飞书/钉钉通知实现告警实时推送评估是否需要 Velociraptor 做深度取证分析但就验证可行性来说这些工作已经足够。好了关于开源 EDR 的话题就先聊到这里。参考资源Wazuh Documentation - Getting Started: https://documentation.wazuh.com/current/getting-started/index.htmlWazuh Docker Repository: https://github.com/wazuh/wazuh-dockerWazuh AI/LLM Integration Guide: https://documentation.wazuh.com/current/getting-started/index.html#building-with-ai-and-llmsDeepSeek API Documentation: https://api-docs.deepseek.com/Wazuh Index State Management: https://documentation.wazuh.com/current/user-manual/wazuh-indexer/index.html本文基于实际测试环境编写所有命令和配置均经过验证。