一次真实的 40 台 VPS 批量入侵事件全记录:从漏洞发现到后门清理、根因定位、复发处置、自动化加固的完整过程。
事件时间:2026-06-19 至 2026-06-20 影响范围:40 台服务器,主控 Nezha dashboard 2.2.3,34 台 agent 被植入后门 事件性质:利用 Nezha 低版本安全漏洞投放持久化后门
一、事件背景
我有 40 台 VPS 分布在多个云服务商(腾讯云、阿里云、华为云等),全部接入同一套 Nezha 监控面板。主控运行 dashboard v2.2.3。
2026-06-19,我注意到 Nezha 官方发布了多个安全公告(security advisories),涉及低版本的远程命令执行、路径穿越泄露密钥等严重漏洞。我需要确认:
我的 dashboard 和 40 台 agent 是否受影响?
攻击者是否已经利用漏洞入侵了我的服务器?
如果被入侵了,植入了什么后门?怎么清理?
二、漏洞分析
受影响版本
Nezha 官方安全公告显示,关键修复分界点是 2.2.0:
Dashboard/Agent
< 2.2.0:受多个中危漏洞影响更老版本叠加高危/严重漏洞
关键 CVE
攻击链路
攻击者获取面板访问权限
├─ 方式1:利用 CVE-2026-53519 路径穿越泄露 jwt_secret_key → 伪造管理员 JWT
├─ 方式2:利用 CVE-2026-46716 cron 接口直接执行命令
└─ 方式3:弱口令 / 泄露的面板账号
↓
通过面板的远程命令能力(cron / terminal / force-update)
在 Agent 节点上执行任意命令
↓
植入持久化后门

三、版本排查
Dashboard 版本
主控 dashboard 是 Docker 部署,版本确认:
docker exec nezha-dashboard /dashboard/app -v
# 输出:2.2.3dashboard 2.2.3 > 2.2.0,不受 advisory 影响。
Agent 版本(40 台)
这里踩了一个大坑:公开 WebSocket 返回的 host.version 在访客视图下是 null,必须用管理员 JWT 才能看到真实版本。
最终通过以下步骤获取 40 台 agent 版本:
从主控 SQLite 数据库读取
jwt_secret_key和未过期 session 的key_id用 Go + sqids-go 生成管理员 JWT(Nezha 用 idcodec 对 user_id 做 sqids 编码)
用 JWT 连接管理员 WebSocket 读取
host.version
结果:
主控 agent:2.2.2(最新)
31 台在线 agent:2.2.2(最新)
5 台在线 agent:1.9.7(受漏洞影响)
4 台离线无版本
5 台旧版 agent:狗云-MG-V6、hostyun-us、绿云-日本大版、狗云-MG-V4、racknerd-DC02。
四、第一轮清理:sysmon 后门
发现
对主控做深度只读检查时,发现 /etc/systemd/system/sysmon.service 和 sysmon-guard.timer,进一步排查发现完整的后门体系:
后门结构:
/usr/local/sysmon/ ← 伪装 Nezha agent 的假二进制 + config.yml
└─ config.yml ← server: 51.254.44.35:8008(攻击者面板)
/usr/local/.sysmon-guard/ ← 守护进程
/usr/local/lib/libsysmon.so ← preload 注入库
/etc/systemd/system/sysmon.service
/etc/systemd/system/sysmon-guard.service
/etc/systemd/system/sysmon-guard.timer ← 30 秒触发自恢复
/etc/ld.so.preload ← 加载 libsysmon.so
后门行为:
伪装成
sysmon系统监控服务,实际运行类似 Nezha Agent 的二进制配置文件
server:指向攻击者控制的 Nezha 面板51.254.44.35:8008sysmon-guard.timer每 30 秒检查一次,如果 sysmon 被杀就重新拉起/etc/ld.so.preload加载libsysmon.so做全局钩子(可能用于隐藏进程/文件)日志显示守护进程每 30 秒执行
SELF-HEAL: Re-installing cron
环境变量泄露的后门设计:
STEALTH_NAME=sysmon
INSTALL_DIR=/usr/local/sysmon
GUARD_DIR=/usr/local/.sysmon-guard
LIB_PATH=/usr/local/lib/libsysmon.so
PRELOAD_FILE=/etc/ld.so.preload
清理
清理顺序非常重要(顺序错了守护器会重建文件):
停止并禁用
sysmon-guard.timer、sysmon-guard.service、sysmon.servicekill -9杀掉所有 sysmon 相关进程删除 systemd unit 文件
清理
/etc/ld.so.preload中的libsysmon.so引用删除
/usr/local/lib/libsysmon.so删除
/usr/local/sysmon和/usr/local/.sysmon-guard目录systemctl daemon-reload
清理后复查:主控 sysmon 后门已彻底删除,无残留进程/文件/外连。

五、批量清理 40 台
用 paramiko 线程池(10 并发)批量清理所有服务器,密码只在内存中不落盘。
清理结果
主控 + 大部分感染节点:sysmon 后门已清理
3 台 SSH 超时:raksmart-圣何塞、云曦幻境、geelinx-b,需手动处理
Agent 版本升级:通过面板
force-updateAPI + 手动 SSH 升级,5 台 1.9.7 升级到 2.2.2
升级 Agent 的坑
force-updateAPI 对disable_force_update: true的 agent 无效主控显示旧版本不一定是二进制旧,可能是进程没重启
有些机器有多个 nezha-agent 服务,只重启了一个
hostyun-us 的 IP 从 45.155.222.112 换到了 207.57.137.18
六、复发!发现真正的根因
清理 sysmon 后做全量复查,发现 sysmon 后门 0 复发,但发现了更危险的东西。
第二份 config 后门
34 台服务器的 /opt/nezha/agent/ 目录下,除了合法的 config.yml,还存在随机命名的 config-XXXXX.yml:
关键证据:
IP(我的主控),确认config.yml是合法配置207.58.173.192:8088当前无法连接,但配置和进程仍在主控上恶意 agent 进程(PID 911,config-etp0h.yml → 207.58.173.192:8088)一直在运行
34 台的恶意配置文件名都是随机 5 位后缀,说明是自动化批量投放
为什么这比 sysmon 更危险
这是真正的复发根因:攻击者不植入独立二进制,而是利用合法 nezha-agent 二进制 + 额外配置文件。即使清理了 sysmon,攻击者仍可通过合法 nezha-agent + 恶意配置维持对 34 台服务器的远程命令执行能力。
七、第二轮清理:第二份 config 后门
清理逻辑
# 1. 找出所有 config-*.yml(带随机后缀的恶意配置)
for cfg in /opt/nezha/agent/config-*.yml; do
# 2. 找对应 service 并停用
for svc in $(systemctl list-units | grep nezha-agent-); do
svc_cfg=$(systemctl cat "$svc" | grep -oE "/opt/nezha/agent/config[^ ]*\.yml")
if [ "$svc_cfg" = "$cfg" ]; then
systemctl stop "$svc"
systemctl disable "$svc"
rm -f "/etc/systemd/system/$svc"
fi
done
# 3. 杀进程
pkill -9 -f "$(basename $cfg .yml)"
# 4. 删配置
rm -f "$cfg"
done
systemctl daemon-reload
# 5. 加固合法 config.yml
sed -i 's/^disable_command_execute:.*/disable_command_execute: true/' /opt/nezha/agent/config.yml
systemctl restart nezha-agent.service清理结果
37 台成功清理:删除 35 个恶意配置 + 35 个恶意服务
3 台超时:raksmart-圣何塞、云曦幻境、geelinx-b
所有成功清理的服务器:AFTER 状态只剩
config.yml+nezha-agent.service,网络检查全部 CLEAN

八、深度复查
清理后对 40 台服务器做 19 项深度 IOC 扫描:
sysmon 后门文件
ld.so.preload 注入
第二份 config 后门
合法 config 加固状态
nezha 服务列表
挖矿木马进程
sysmon 相关进程
攻击者网络连接
cron 持久化
systemd 可疑服务
SSH authorized_keys
登录记录
SUID 文件
/tmp 隐藏文件
可疑定时器
CPU 占用
异常监听端口
rc.local/profile.d
内核模块
结果
结论:sysmon 后门和第二份 config 后门均无复发,未发现新的木马或黑客遗留。

九、自动化加固
1. 关闭远程命令能力
所有 34 台 nezha 节点的 config.yml 已设置:
disable_command_execute: true # 关闭远程命令执行(terminal/webssh)
disable_nat: true # 关闭 NAT 穿透2. Dashboard 自动更新(Watchtower)
部署 Watchtower 容器实现 dashboard 自动更新:
docker run -d \
--name watchtower \
--restart always \
-v /var/run/docker.sock:/var/run/docker.sock \
containrrr/watchtower \
--cleanup \
--interval 3600 \
nezha-dashboard每小时检查
ghcr.io/nezhahq/nezha:latest是否有新镜像有新版自动拉取并重启
nezha-dashboard容器只监控 nezha-dashboard,不影响其他容器
GitHub 发布新版后,最多 1 小时内自动更新,无需手动介入
3. Agent 自动更新
修改 agent 配置:
disable_auto_update: false # 开启自动更新
disable_force_update: false # 允许主控下发强制更新
disable_command_execute: true # 保持远程命令关闭GitHub 发布新版 agent 后,各节点自动更新,无需手动介入。
十、复发根因分析
后门清理后再次出现,通常是以下原因之一:
★第二份 config 后门未清理(最隐蔽):清理了 sysmon 但没检查
config-XXXXX.yml,攻击者通过合法 nezha-agent + 恶意配置维持控制。这是本次事件复发的真正根因。残留自恢复链路:sysmon-guard.timer / cron / ld.so.preload / 隐藏脚本任一残留
攻击者仍有登录入口:root 密码、SSH key、面板账号、Agent Secret、JWT Secret 任一泄露
Nezha 远程命令未及时关闭:低版本暴露期间攻击者拿到面板 token,能继续下发命令
同机其他面板漏洞:1Panel / 宝塔 / x-ui / MCSManager / phpMyAdmin / MySQL / Redis 暴露公网
清理顺序错误:先删文件没先停守护 → 守护器重建文件
密码未轮换:清理后没换 root 密码 / SSH key
十一、经验教训
1. 不要只查一种后门
sysmon 后门特征明显(独立路径 + ld.so.preload),容易发现也容易清理。但第二份 config 后门极隐蔽(合法二进制 + 混在配置目录),清理完 sysmon 后必须复查是否有 config-XXXXX.yml。
2. 清理顺序很重要
停守护 → 杀进程 → 删文件 → 清 ld.so.preload → daemon-reload
顺序错了,守护器会重建文件,等于白清理。
3. Nezha 版本读取的坑
公开 WebSocket 的 host.version 在访客视图下是 null,必须用管理员 JWT 才能看到真实版本。这会导致误判"所有 agent 版本未知",延迟发现旧版节点。
4. Windows SSH 中文路径
Windows 上 OpenSSH 对含中文/空格的私钥路径处理不可靠,必须复制到 ASCII 临时路径 + icacls 收紧 ACL + 用系统自带 C:\Windows\System32\OpenSSH\ssh.exe。
5. 批量操作用 paramiko
系统无 sshpass/expect 时,paramiko 是批量 SSH 的最佳选择。密码只在内存中,绝不落盘。
6. 自动更新很重要
这次事件根因是低版本漏洞被利用。部署 Watchtower + 开启 agent 自动更新后,未来 GitHub 发新版会自动更新,不再需要手动介入。
7. 安全加固清单
升级 Dashboard 到最新版(2.2.3)
升级所有 Agent 到最新版(2.2.2)
清理 sysmon 后门
清理第二份 config 后门
关闭远程命令执行(disable_command_execute: true)
部署 Watchtower 实现 Dashboard 自动更新
开启 Agent 自动更新
轮换 root 密码
轮换 SSH key
轮换 Nezha 面板密码
轮换 Agent Secret
轮换 JWT Secret
关闭非必要公网面板入口
十二、开源工具
本次事件中开发的清理脚本已开源:
仓库:https://github.com/motao123/clean_malware_and_harden_nezha
完整清理脚本:
clean_malware_and_harden_nezha.sh(覆盖三类后门)轻量版:
manual_clean_second_config.sh(仅清理第二份 config 后门)
一键使用
curl -fsSL https://raw.githubusercontent.com/motao123/clean_malware_and_harden_nezha/main/clean_malware_and_harden_nezha.sh -o /root/clean.sh
bash /root/clean.sh群发排查命令
如果你也想检查自己的服务器是否中招:
# sysmon 后门排查
ls -ld /usr/local/sysmon /usr/local/.sysmon-guard /usr/local/lib/libsysmon.so /etc/systemd/system/sysmon* /etc/ld.so.preload 2>/dev/null
# 第二份 config 后门排查
ls /opt/nezha/agent/config-*.yml 2>/dev/null && echo "WARNING: second config backdoor detected"
# 挖矿木马排查
ps auxww | grep -Ei "sysmon|kworker|kdevtmpfsi|kinsing|xmrig" | grep -v grep
# 攻击者连接排查
ss -tnp | grep -E "51.254.44.35|207.58.173.192"十三、事件时间线
2026-06-19 攻击者利用低版本漏洞植入 sysmon 后门 + 第二份 config 后门
2026-06-20 00:30 发现 Nezha 安全公告,开始排查
2026-06-20 00:45 确认主控 dashboard 2.2.3 不受影响,5 台 agent 为 1.9.7
2026-06-20 00:51 发现主控 sysmon 后门,开始清理
2026-06-20 01:00 sysmon 后门清理完成(主控)
2026-06-20 01:15 批量清理 40 台 sysmon 后门
2026-06-20 01:30 批量升级旧版 agent 到 2.2.2
2026-06-20 02:00 hostyun-us IP 变更,手动修复
2026-06-20 10:25 第一次复发复查:sysmon 0 复发,但发现 34 台第二份 config 后门
2026-06-20 11:00 定位复发根因:第二份 config 后门(config-XXXXX.yml → 207.58.173.192:8088)
2026-06-20 11:47 批量清理第二份 config 后门(37 台成功)
2026-06-20 11:52 更新清理脚本并推送 GitHub
2026-06-20 12:00 深度复查 40 台(19 项检查全部通过)
2026-06-20 12:07 部署 Watchtower + 开启自动更新
2026-06-20 12:13 撰写本文档
总结
这次事件的核心教训:清理了一种后门不等于清理了所有后门。sysmon 后门特征明显容易被发现,但第二份 config 后门利用合法二进制 + 混在配置目录里,隐蔽性极强。如果不是做了深度复查,攻击者仍可通过 34 台服务器的合法 nezha-agent 维持远程命令执行能力。
安全是一个持续的过程,不是一次性的操作。清理后门只是第一步,还需要:升级版本、关闭远程能力、开启自动更新、轮换凭据、关闭非必要公网入口。只有全链路加固,才能避免再次被入侵。
本文档基于真实事件整理,相关清理工具已开源:https://github.com/motao123/clean_malware_and_harden_nezha