群晖 NAS 被 C3RB3R 锁了:本地备份一起被加密,RustFS 对象锁为什么删不掉

2026 年 10 月底(群晖官方 10 月 29 日确认、多家安全通告复盘),大量群晖 NAS 被 C3RB3R 勒索软件集中攻陷,共享文件夹里的文件被加密成 ".L0CK3D" 后缀,根目录和各级子目录都被写入写着 "C3RB3R INSTRUCTIONS" 的勒索信。最扎心的一幕是:很多人把 NAS 当成"最后的保险箱",结果同机上的日常备份、Hyper Backup 目录、甚至快照,只要是这台机器可写挂载的,全被当成普通文件一并锁死。RAID 阵列只防硬盘物理损坏,对操作系统层面的恶意改写毫无招架之力。

备份和原数据待在同一个被攻陷的边界里

勒索程序的入口是 DSM 管理面或容器逃逸,最终拿下的是这台机器的操作系统权限。它从根目录多线程遍历所有挂载的存储空间,凡是当前进程能写的地方,不分原数据还是备份,一律加密。本地日备、周备、Hyper Backup 的仓库,只要还挂在这台 NAS 的可写目录里,信任边界就和原数据完全重合,攻击者同样握着写权限。快照也不是天然安全:若快照以可写方式挂载、或快照服务本身运行在被攻陷的同一系统上,它同样在被改写的范围之内。

这不是某一家的特例。群晖自己在 2026-10-29 确认了这轮攻击,韩国 KISA 在 10-30 的通告里把"不可变快照 + 离线/断开连接的备份"列为应对要点。行业共识已经很清楚:能防勒索的备份,至少得满足两条。

防勒索备份的两条硬标准

第一条是不可变。副本写进去之后,在保留期内既不能删也不能改,连你自己都不能随手清掉一个误传的版本。这种特性在存储界叫 WORM(Write Once Read Many,一次写入多次读取),它专门堵住"攻击者拿到写权限后把备份也加密或删掉"这条路。

第二条是异地、且彼此断开信任。备份不能和原数据待在同一个被攻陷的边界里。这里的"异地"不一定是跨城市机房,核心是:即使原机器整个被拿下,备份那一侧仍然独立、仍然不能被这台机器的凭证改写。

对象存储的对象锁(Object Lock)恰好把这两件事都落到了存储层:RustFS 的对象锁依赖桶的版本控制,每次覆盖都产生新版本而不是覆盖旧版,对象锁再给指定版本上锁,保留期内删不掉也改不了。

对象锁是怎么把"删不掉"焊死的

以 RustFS 为例,对象锁依赖桶的版本控制。建桶时开启 Object Lock,控制台会同时把版本控制打开,因为锁定的就是"某个具体版本",不是整个对象键。RustFS 提供两种保留模式:

  • GOVERNANCE(治理模式):保留期内阻止删除、也阻止缩短保留期,除非调用方拥有 s3:BypassGovernanceRetention 权限并显式请求绕过。延长保留期不需要绕过。
  • COMPLIANCE(合规模式):即使有治理绕过权限也阻止删除,保留期只能延长不能缩短。

还有一种"依法保留"(Legal Hold),不绑定到期日,把对象锁在 ON 直到被显式设为 OFF,治理绕过也覆盖不了它。

一个中性边界得说在前面:RustFS 的 rc 命令行在 0.1.29 版本里,bucket create --with-lock 和 --with-versioning 虽然出现在帮助里,实际执行会返回 not implemented,对象锁桶目前要在控制台创建。上传带保留期的对象用 rc object copy 带上两个请求头即可,下面的命令已经针对 RustFS 验证过。

一条能直接照抄的落链

先在控制台建好对象锁桶,再用命令行把备份写进去并上锁。假设 RustFS 跑在 http://localhost:9000,别名 rustfs:

bash 复制代码
rc alias set rustfs http://localhost:9000 \
  <your-access-key> <your-secret-key> \
  --region us-east-1 --bucket-lookup path

rc object copy /path/to/backup.tar.gz rustfs/backup-bucket/backup.tar.gz \
  -H "x-amz-object-lock-mode:GOVERNANCE" \
  -H "x-amz-object-lock-retain-until-date:2027-01-01T00:00:00Z"

上锁之后,验证它真的删不掉,这是最关键的一步,别跳过:

bash 复制代码
rc bucket version list rustfs/backup-bucket --json

rc object rm rustfs/backup-bucket/backup.tar.gz \
  --version-id <version-id>

依法保留则把头换成 x-amz-object-lock-legal-hold:ON。要异地断开信任,再开桶复制(Replication),把对象复制到第二个站点;官方文档的运维注意事项明确:锁定对象的复制目标必须支持兼容的对象锁定行为,否则这条不可变链路会在异地一侧断掉。

对象锁不是银弹,它的代价得算清

保留期内,你想清理误传的垃圾版本也不行,这正是不可变的意义,但也意味着存储空间要按保留期规划,别把保留期设得过长把桶撑爆。COMPLIANCE 模式连治理绕过都挡,运维误操作也没后门。生命周期过期规则对受保护版本无效,不会偷偷替你删。

更关键的一点是:对象锁只防"删和改",不防"用攻击者的写凭证上传一个被加密的新版本"。如果 RustFS 的写密钥就躺在那台被攻陷的 NAS 上,对象锁也救不了新版本被覆盖式污染。所以凭证隔离是另一条防线:备份专用凭证只在备份任务里用、不挂在 NAS 的日常环境里,权限收到只允许写指定桶、只允许带保留头上锁。

把这两层叠起来,存储层的不可变加凭证层的隔离,备份才真正落到了原数据信任边界之外。

现在就能做的五件事

  1. 盘点:哪些备份还和原数据待在同一台被攻陷边界里,先标出来。
  2. 在 RustFS 控制台建一个对象锁桶(版本控制会随之开启)。
  3. 把备份工具的输出指到这个桶,上传时带上保留期请求头。
  4. 开桶复制到异地第二站点,确认目标也支持对象锁。
  5. 验证:删一个受保护版本,确认返回 AccessDenied,才算这条链路真的焊死了。

勒索软件盯着 NAS 备份,本质是因为备份和原数据在同一个被攻陷边界。把备份搬进带对象锁的对象存储、再断开信任,是这轮 C3RB3R 事件里最该补上的一课。

相关推荐
真好啊又活了一天35 分钟前
服务器和虚机配置IPV6
运维·服务器·github
zixu_star1 小时前
定时任务是什么?从日常自动化到 AI 应用,软件如何自动执行任务?
运维·人工智能·自动化
Cosolar1 小时前
极简简历:开源免费,希望帮助到更多求职者
开源·github·敏捷开发
AR-26710-1 小时前
Linux Day33——定时任务+lvm
linux·运维
用户576545744002 小时前
按键精灵安卓开发实战:手写可拖动、可最小化的运行日志悬浮窗|完整源码 + 踩坑记录
开源
润滑卫士2 小时前
液压系统工作粘度窗口等级选型:泵允许粘度范围与油温-粘度匹配计算
运维
panyz2 小时前
不想再开 7 个标签页查AI额度,我用 Node 写了个本地看板
人工智能·开源·github
炫酷的大高个2 小时前
3.2TB 权重开源了,我算了 4bit 之后还要几张卡
人工智能·架构·开源
字节跳动开源2 小时前
AI 原型几分钟,设计返工一整天?OpenViking 让 AI 用上你的 Figma 设计稿
人工智能·开源