金融、医疗、政企的归档数据,监管往往要求写入后不可改不可删,保留期动辄五六年起步。一旦被误删或被勒索软件改了内容,合规审计直接过不去。对象存储默认是"谁有写权限谁就能覆盖删除",把这道保护怎么落进存储层,是很多团队上线前的硬门槛。RustFS 的对象锁(Object Lock)把这个约束直接做进存储引擎:对象版本在保留期内锁死,某些模式下连治理绕过权限都被拒。
三档保护,分别挡什么
对象锁(Object Lock,业界叫 WORM,Write Once Read Many,一次写多次读)提供三档可叠加的保护,作用在"对象版本"上而不是整个键。
第一种是合规保留(COMPLIANCE)。保留期到期之前,即使具有治理绕过权限,也会被阻止删除或缩短这个期限。到期日只能往后延,不能往前挪。这档最硬,适合监管强约束场景。
第二种是治理保留(GOVERNANCE)。它也会挡删除和缩短保留期,但持有s3:BypassGovernanceRetention权限、并且在请求里显式带绕过头的调用者可以突破。延长保留期不需要绕过。这档适合"普通用户删不了、管理员按需放行"的内部治理。
第三种是合法持有(Legal Hold)。它没有到期日,只有被显式设成 OFF 才解除,治理绕过也盖不过它。常用于诉讼保全、调查期冻结这类不知道要冻多久的场景。
一个容易忽略的点:对象锁保护的是版本,不是键。删一个不带版本 ID 的键只会生成一个删除标记(delete marker),被锁住的那个版本还在,照样能按版本 ID 取回来。这正好解释了为什么对象锁桶必须先开版本控制,保护是靠版本机制承载的。
桶怎么开,对象怎么锁
开启方式上,控制台在建桶时勾 Object Lock(会一并打开 Version);对已启用版本控制的现有桶,也可以调 S3PutObjectLockConfigurationAPI 补开。按 S3 通用惯例(AWS 的口径是对象锁配置一旦为桶启用便无法停用),开之前想清楚;RustFS 官方文档也明确要求:不应暂停对象锁定存储桶的版本控制——暂停只是停止生成新版本、旧版本仍保留,但会把保护的地基抽掉。当前rc0.1.29 的bucket create --with-lock和--with-versioning虽然在帮助里列出,执行都会返回not implemented,所以走控制台建桶时勾选最稳。
给新对象上保留期,用rc object copy带上两个头,retain-until-date 必须是 RFC 3339 的 UTC 未来时间:
rc object copy /path/to/hello.txt rustfs/my-bucket/hello.txt\-H"x-amz-object-lock-mode:GOVERNANCE"\-H"x-amz-object-lock-retain-until-date:2027-01-01T00:00:00Z"上合法持有换一个头:
rc object copy /path/to/hello.txt rustfs/my-bucket/legal-hold.txt\-H"x-amz-object-lock-legal-hold:ON"列出版本、核对某个版本的保护状态:
rc bucket version list rustfs/my-bucket--jsonrc objectstatrustfs/my-bucket/hello.txt --version-id<id>--json注意rc0.1.29 目前没有"改保留期"或"切换合法持有 ON/OFF"的命令,这类变更得走控制台或 S3 SDK。桶级默认保留会在新对象版本或分段上传发起时结算,控制台开默认保留时初始显示 180 天,那是 UI 初值,按你的合规要求改成实际期限;按 S3 通用惯例,保留期上限约一百年(36,500 天,AWS 同为 1–36500 天)。
验证锁真的生效,别只信配置
配置写完最危险的一步是以为锁上了。稳妥的做法是用一个测试对象实打实验:上传一个带 GOVERNANCE 或合法持有的对象,记下它的版本 ID,然后用一个没有绕过权限的 S3 客户端去删这个确切版本,RustFS 必须返回AccessDenied;同时确认控制台和rc object stat --version-id仍能看到这个版本。GOVERNANCE 的绕过只在专门的管理身份上测,那个身份要有s3:BypassGovernanceRetention。COMPLIANCE 和合法持有则连治理绕过都挡得住。
锁的是 API 语义,不是物理介质
对象锁不是万能封条。它能护你到什么程度,取决于这两条边界。
最该防的能力幻觉:对象锁挡的是对已上锁历史版本的删除和覆盖,挡不住有人写入全新的恶意新版本。攻击者只要有写权限,照样能传一份新的加密版本进来——被锁的旧数据还在、能按版本 ID 找回,但「当前版本」可能已经被换成恶意内容。所以对象锁的真正价值是留出回滚窗口(出事能退回到已知完好版本),不是事前阻止写入。防御要成体系:IAM 最小权限收写入口子、审计日志及早发现异常写入;真要全桶强制上锁,靠桶策略在写入侧兜底(条件键的支持程度以实测为准)。
同样要认清:锁住的是 API 语义,不是物理介质。前文说的「删不掉」,指的是对象存储 API 层面——COMPLIANCE 档下连治理绕过权限都被拒。但能碰到宿主机的人,比如拿到节点 root、能读写底层数据目录或磁盘的人,可以直接删数据文件,或者换一套软件挂上同一块盘,对象锁完全无从约束;勒索软件走磁盘加密而不是 API 调用时同理。自建部署想补这一层,靠的是操作系统与存储介质的访问控制、离线或异地副本,以及锁、审计、备份的组合,而不是单指望对象锁。
还有三条容易踩的坑
保留期是按 UTC 比对 retain-until-date 的,跨时区部署先保证节点时间同步,否则该解锁了却删不掉、或提前被删都可能出现。
生命周期过期规则在保留期或合法持有还挡着的时候,删不掉那个版本,过期不会覆盖锁。
复制链路要小心:把锁住的对象复制到目标桶,目标桶自身得支持兼容的对象锁行为,而且复制不会把源桶的保留期和合法持有设置带过去,目标端要单独配。别假设主站锁了、备站自然也锁。
最后说合规依据。SEC Rule 17a-4(f)、FINRA Rule 4511、CFTC Regulation 1.31 这类监管,核心诉求是电子记录写入后不可改不可删、按期限留存且可访问。对象锁提供的正是这种机制:保留期内版本锁死,删除标记也动不了被锁版本。它给的是能力,过不过审取决于保留策略、时间同步和验证记录是否按监管口径配齐——具体年限与格式要求,以法规原文和你所在行业的细则为准。国内场景对应的是电子档案管理、等保、行业数据留存等另一套口径,落地前先对齐自己的合规要求,别直接套用美国法规的年限。
照这个顺序走一遍
- 建桶时在控制台开 Object Lock(顺带开版本控制),别用还没实现的 rc 命令。
- 写保留期用
rc object copy带x-amz-object-lock-mode与x-amz-object-lock-retain-until-date(RFC 3339 UTC)。 - 改保留期、切合法持有走控制台或 S3 SDK,
rc0.1.29 没有对应命令。 - 上线前用测试对象验证
AccessDenied,并核对版本仍可取。 - 跨站复制时目标桶单独配锁,且意识到复制不搬运保留与持有设置。
官方入口:对象锁文档 docs.rustfs.com/zh/administration/data/object/object-lock,源码在 GitHub。