这一篇我们造的不是代码,是一个盒子。
盒子不大,能塞下五六个蓝光光盘盒。里面装三到四张刻好的 M-Disc,一袋变色硅胶,一层自己裁的 PE 泡棉;盖好,扣上卡扣,穿一根带序列号和条码的一次性塑料封条,贴上标签,拍照。然后把盒子交给一个朋友,放在离你家几十公里外的柜子里。过一到三年,你带一个新盒子去找他,先看旧盒子的封条是不是还完整,再交换。
原型是 hukl 这个月初发在他博客 SMYCK 上的那篇《Holocron: The Backup of Last Resort》。名字取自星战里绝地和西斯用的那种全息存储装置;盘是光学介质,名字确实贴切。他做这件事的动机一句话就能说完:如果你的备份硬盘和你的电脑在同一个房间,火灾来的时候你其实没有备份,你有两份同归于尽的拷贝。
这个动机朴素到不像一个技术项目。但我越想越觉得,它是整个备份话题里唯一真正难的部分;剩下的事,比如选什么盘、用什么加密、买哪个箱子,都是往下推导就能得出的。
先说清楚这一篇要交付什么。这里不写“你应该备份”那种劝告。我们要造的是一个具体的东西:一个数据子集、一套加密和校验流程、一个物理容器、一根不能被无损拆开的封条、一个轮换周期,以及至少一个知道这盒东西存在的活人。这一篇结束时这六样应该都在;少一样,这个盒子就只是个装盘的铁皮箱。
先把架子搭起来:三层,不是一层
不先把这个东西拆开摆出来,很容易一开始就陷进“买哪个盘”里出不来。它分三层:
- 数据层:装什么、怎么打包、怎么加密、怎么校验。
- 物理层:盘、箱子、泡棉、封条、标签、干燥剂。
- 社会层:交给谁、多久换一次、怎么换、对方怎么知道这玩意儿重要。
绝大多数备份教程只写第一层,而且写得很细:AES 多少位、什么模式、密钥怎么派生。你照着做完,得到一个躺抽屉里的加密压缩包。第二层和第三层是零。这就是为什么那么多人“做了备份”,硬盘一挂还是什么都没剩下。
三层里最便宜的是第二层,最难的是第三层。这个顺序和直觉是反的:大家本能地觉得密码学最难,其实密码学在这里是最不需要你操心的部分,因为现成的工具已经足够好,好到你只要不自己发明算法就不会出错。真正会失败的是另外两件事:你朋友把盒子塞进了储物间最里面然后忘了;或者三年后你打开盒子,发现里面那张盘读不出来。
所以先把骨架立一个最小可跑版:三张盘,一个盒子,一个朋友,一年半换一次。这个版本不需要你搞懂 M-Disc 的记录层是什么材料,也不需要你先去买封条枪。先把这条线走通,再往里填肉。
骨架立住了。我们一层一层往下拆。
数据层:最后手段必须小到不讲理
hukl 列的核心数据是这几样:用 paperless-ngx 数字化整理的全部文档,不愿意失去的音乐收藏,精选过的旅行和事件相册,以及从零重建数字生活所需的关键资料。加起来能全部塞进三张蓝光 M-Disc。
这个体量不是巧合。我把这个约束单独拎出来说,因为它其实是整个方案里最硬的一条设计决策:一个“最后手段”备份如果装不进三张盘,它就不叫最后手段,叫第二份主存储。
这两者的区别是预算区别。第二份主存储必须覆盖你所有会变的东西,所以它必然要增量、要同步、要版本、要能自动跑;最后手段只覆盖“如果这些没了,我这辈子会真的难受”的那一小块,它不需要增量,不需要同步,一年到三年才更新一次。你一旦让它长大,它就会开始需要上面那些东西,然后它就变成了一个你要维护的系统,然后它就会在某一天停止工作而你不知道。
所以第一步是把“最后手段”的子集从“全部数据”里切出来。切的时候我给一个偏方:不看大小,问自己“如果明天全没了,我愿意花多少钱把它买回来”。愿意花五位数买回来的进盒子,其余的不进。这个标准很粗暴,但它比“重要、比较重要、一般重要”这种分级好用得多,因为人对抽象等级没有感觉,对钱有。
分盘我建议按主题切,不按大小切。hukl 就是这么干的——他按主题分盘,其中“Documents”那张单独做了加密。为什么按主题:恢复的时候,你是按“我要什么”去找盘的,不是按“第几张 25GB”去找。一盒四张盘,贴纸上写的是“文档”“照片”“音乐”“重建”,这比写“1/4、2/4”有用一个量级。
还有一件事容易被跳过,我不跳:每张盘的根目录放一份纯文本 README。
不是放在你电脑里,是刻在盘上。里面写四件事:这是什么;按什么顺序读;缺了哪张盘还能不能恢复出有用的东西;解密的口令在哪(或者写“口令不在本盘上,请联系某人”)。这份 README 比你的加密算法重要得多,因为加密算法不会因为你不在了而出问题,README 会。
我见过太多人把恢复步骤存在脑子里,把口令存在密码管理器里,把密码管理器的主密码也存在密码管理器里。这不是备份,这是许愿。
加密:能在一台陌生机器上打开的,才叫加密
hukl 的加密方案简单到有点反潮流:把 Documents 那张盘的内容打包成 tar,再用 openssl 的分组密码加密。理由他自己说了,看重的是 openssl 的通用性和对旧系统的兼容。
我完全同意,而且愿意把这个理由说得更狠一点。
你现在用 VeraCrypt 建一个加密卷,五年后你朋友坐在一台不知道什么系统、不知道有没有管理员权限的机器前面,他需要先下载、安装、可能还要编译,才能到“输入密码”这一步。这条路每一步都能断。而 openssl 大概率已经在那台机器上了——没有的话,包管理器里一行就有。
具体怎么做,我把它摆出来:
tar -cf - Documents \
| openssl enc -aes-256-cbc -pbkdf2 -iter 200000 -salt \
-out Documents.tar.enc
解密就是把管道反过来:
openssl enc -d -aes-256-cbc -pbkdf2 -iter 200000 \
-in Documents.tar.enc | tar -xf -
有一个兼容性的坑要提一句:-pbkdf2 不是所有老版本的 openssl 都认。如果你真的打算让这个盒子在十年后的机器上被打开,那你该做的是把这条命令本身写进盘上的 README,连同“如果你的 openssl 报错不认识 -pbkdf2,那就说明它太老了,你需要先升级,或者用这台机器上能用的参数重新试”这句话一起写进去。这一步换来的东西很实在:把“我朋友得会一点密码学”换成“我朋友得会照着纸敲一行命令”。
我再加一条自己的偏好:别用 zip 的加密。zip 的加密实现历史上版本繁杂,跨平台工具对它的支持常常停在“能打开就行”的水平,而你需要的恰好是“十年后在陌生机器上能打开”。tar 加 openssl 的好处是格式简单到你可以用一句话向别人解释清楚。
然后是密码放不放进去的问题。hukl 说这由个人决定,放进去的话,盒子在你去世之后还能当数字遗产用——亲属可以拿它去处理订阅和账号。这是个开关,不是一个对错。
我的倾向是放,但我不会假装这是唯一答案。放进去意味着你放弃了“即使朋友叛变也读不出来”这个性质;不放意味着你一旦出事,这盒东西就变成一块很贵的镇纸。你得先想清楚你更怕哪一个,再动手。这个决定必须在你封箱之前做完,封完再改就得破坏封条,那就难看了。
介质:写到这儿我改主意了
我一开始以为这一篇的重心会是介质——M-Disc 到底能存多久、蓝光会不会比硬盘靠谱、要不要上磁带。写到这儿我发现不是,介质是这个方案里最不重要的一环,而且它不重要的原因恰好是它不可控。
先把争议摆出来。评论区有个叫 D 的人说,今天的 M-Disc 只是个营销噱头,还援引 heise.de 的报道,说 Verbatim 在 2022 年把这个产品的记录层调整成了和普通蓝光一致。hukl 的回应很克制:他见过类似说法但缺来源,目前当成“有可能但未证实”,并且——这句话是关键——他并不指望光盘保存 25 年,只需要撑到一到三年的更换周期。
我想在这个回应上加一句:就算 M-Disc 完全退化成普通蓝光,这个方案依然成立;反过来,任何一个依赖“25 年寿命”的方案本来就不成立,因为你没有任何手段去验证第 24 年那张盘还能不能读。
这是两种完全不同的可靠性来源。前一种把可靠性寄托在介质上,后一种把可靠性寄托在流程上。介质可靠性你既测不了也控不了——你没有加速老化试验台,你也无法知道厂商这一批的染料和上一批是不是同一家供货。流程可靠性你能控:盒子在哪、多久换一次、上一次换是什么时候、封条编号对不对得上,全是你能看见的东西。
评论区还有个叫 Andrew Poulos 的人给了反面数据:他把 CD-R 放在塑料盒里、装纸箱、存在地下车库,五年后检测发现很多已经读不出来。而 hukl 说自己的经验相反,手头十年以上的 CD-R 大多还能读。
这两条个体经验都不能外推,而这正是问题所在。你永远不知道自己手里这一批属于哪一类,所以正确的做法不是去赌,是设计一个“不需要赌”的方案。一年到三年换一次,这个周期保守到过分——一张普通蓝光在三年内失效的概率极低。但这个数字本来就不是为了赌概率,它是为了让你每十八个月必须去朋友家一趟,顺便验证三件事:他还在,盒子还在,封条还在。
这一步换来的东西:把一个你控制不了也测不了的变量,换成了一个你能控制的变量。这在工程上叫降低方差,在备份这件事上叫常识。
顺便说一句,hukl 在不同地方说过 1 到 3 年,也说过在 1 到 5 年的区间里轮换。这个不一致我觉得一点都不重要。重要的是它是个有限数,不是“永久保存”。凡是把周期写成“永久”的方案,实际执行周期都等于“直到我想起来”,而人不会想起来。
容器:箱子、泡棉、硅胶
物理层便宜,但便宜不等于随便。
箱子他选的是 B&W 的 Outdoor Case Type 500,买的时候 33.74 欧元。这个尺寸能装五到六个蓝光光盘盒——注意,是盘盒,不是盘,盘盒本身提供了第一层缓冲,这是别把它扔了的原因。箱子有坚固的卡扣、两个可以穿扎带或封条的孔、一个提手。他对这箱子唯一的不满,是厂商在箱体上印了太多标识。
这个不满我也有,而且我觉得它比“不好看”严重一点。一个印满户外战术风格的箱子放在别人家柜子里,等于在说“这里面有值得拿走的东西”。你可以用贴纸盖掉,或者买素面的。三十几欧的箱子,不值得为 logo 妥协。
防晃动用的是普通的 PE 泡棉。这里有个小取舍值得停一下:工具抽屉常用的那种植绒泡棉看着高级,但植绒面会吸潮,背胶会老化发粘,十年之后你会得到一层黏在盘盒上的东西。PE 便宜、化学性质稳定、不发粘,买 1 厘米厚的卷材,按箱内尺寸裁,不够厚就叠两层。他买的具体型号是 Adam Hall 019310 B Plastazote LD29,10 毫米厚。
别用气泡膜。气泡膜会缓慢漏气,一年之后它就变成一层塑料薄膜,缓冲性能掉光,而你不会知道它是什么时候掉的。
箱子里还放了一袋硅胶干燥剂,干燥时是橙色,受潮变绿。hukl 自己说这东西并非必需,我同意,但我会放:它便宜,而且那个变色是个免费的状态指示器——你每次开箱换盘,看一眼颜色就知道这几年箱内湿度大致什么水平。但别指望它替代密封,它只是缓冲,不是屏障。
标签是个小坑。厂商不提供和箱体标签区匹配的贴纸,所以他自己设计了标签,交给 stickma.de 印。标签上该写什么,我列一下:盒子编号、封箱日期、内容摘要、以及一句“如本人长期失联,请联系 X”。最后那句最重要,也最容易被省略。
封条:防的不是贼
这一节是全文我最想写好的,因为它是这个方案里唯一一个真正的“设计”。
他没用普通扎带。理由非常干脆:扎带用一把螺丝刀就能顶开,然后还能复原到你看不出区别。所以扎带提供的是“看起来封上了”,不是“没被打开过”。
他用的是一次性的塑料封条,带序列号和条码,来自 plomben.de,必须破坏才能打开。
流程是这样的:封箱,贴标,拍照——重点是拍清楚封条上的条码和编号。然后存档。每次更新备份时把这些照片调出来对照。
我想把这件事的意义讲透一点。封条防的不是技术高超的攻击者——hukl 自己也承认,技术高超的人可以仿制封条,所以他没有公开完整的安全设计。这一点我特别欣赏:写 howto 的时候知道在哪里停,是一种纪律,很多人没有。
那封条防什么?防两件事,都很现实。
第一,防“无声的被动过”。你的盒子在别人家里放了两年,你没有任何手段知道这期间有没有人打开过它,包括你朋友自己出于好奇。封条把这个可能性从“不可知”变成“可知”:封条完整,就是没开过;封条断了,你就知道该问一句。它不提供绝对安全,它提供一个可观测的信号,而在备份这件事上,可观测比安全有用得多。
第二,防你自己记不清。人对自己做过的事的记忆衰减得比想象中快。三年后你打开柜子,看见一个箱子,你会不确定这是哪一版、上次换是什么时候、里面那几张盘是旧的还是新的。序列号加照片把这件事变成一次查表。
顺便,他刻意没有公开完整的安全设计。这个决定在写作上是不讨喜的——读者想要完整的方案,你给了个八成的。但这是对的:一篇公开的教程如果把某套物理封条方案的弱点全写出来,那这套方案对所有人就同时失效了。留白在这里不是偷懒,是负责。
跑一下看看:不演练的备份不算备份
到这里数据层和物理层都齐了,可以封箱了。但先别封。
我要在这一节插一条自己的硬规矩,比上面所有内容都硬:没有演练过的备份,等于没有备份。
这句话不是修辞。备份系统最常见的失效模式不是介质坏了,是恢复的时候发现:tar 包里少了一层目录、加密时用了一个已经忘了的参数、某张盘刻录时其实报过错但被 2>/dev/null 吃掉了、或者最经典的——一切正常,但你不知道口令。
所以我们跑一遍。顺序是这样的:先在源机器上生成校验清单,然后刻盘,然后换一台机器恢复。
生成清单:
cd /path/to/staging
find . -type f -print0 | sort -z | xargs -0 sha256sum > MANIFEST.sha256
刻完盘,换一台不是源机器的机器,用一个干净用户,最好断网,把盘挂上去,跑:
sha256sum -c MANIFEST.sha256
输出应该是一整屏 OK,最后没有 FAILED。有一个 FAILED 就重刻,不要自我安慰说“可能就这一个文件不重要”。
这里有三个坑,都是我自己踩过或者看别人踩过的:
第一,macOS 上没有 sha256sum,得用 shasum -a 256。所以你的恢复 README 里不能只写一条命令,得写两条,并且写清楚哪条给哪种系统用。
第二,MANIFEST.sha256 本身也要防篡改。如果校验清单只存在于盘上,那盘上的内容被改了,清单也会跟着被改,你就查不出来了。所以清单的 sha256 要单独抄一份在你手上——打印出来夹在钱包里、或者存在密码管理器里都行。这一步很土,但它把“校验”从一个仪式变成了一个真的检查。
第三,也是最重要的:校验通过不等于能恢复。 校验只证明比特没变,不证明你能读懂它。所以还要真的恢复一次:解开 tar,打开一份 PDF 看到第一页,听一首歌听到副歌,看一张照片看到人脸。
跑一下看看的结果大概是这样:
$ sha256sum -c MANIFEST.sha256
./Documents/2024/steuerbescheid.pdf: OK
./Documents/2024/mietvertrag.pdf: OK
./Documents/2025/arztbrief.pdf: OK
...
$ tar -tf Documents.tar | wc -l
14823
$ openssl enc -d -aes-256-cbc -pbkdf2 -iter 200000 -in Documents.tar.enc | tar -xf -
$ ls Documents/2025 | head
arztbrief.pdf gehaltsabrechnung.pdf ...
全部 OK,tar 里一万四千多个文件,解密解出来了,随手打开一个能看到内容。到这一步,这盒东西才算真的“能跑”。
然后才封箱。封箱之前最后确认一遍:README 在每张盘上;口令至少有一个活人知道或者有一个你能找到的地方存着;标签贴好了;封条穿好了;照片拍了,条码清楚。
交接:把仪式当接口
现在到了三层里最难的那一层。
hukl 的做法是:做两到三个小盒子,每个盒子里放三到四张盘,分别交给几位可靠的朋友,形成异地分散。每隔一到三年换一次盒子,换的时候先检查旧盒封条是否完好,只有旧盒没被破坏才交付新盒,并且把这件事办成一个小小的交接仪式。
我知道“仪式”这个词会让一些人觉得矫情。但它不是浪漫,它是接口设计。
你的朋友不是运维。他不会主动去检查那个盒子,他没有理由关心,他甚至可能在两年后搬家时把它塞进某个纸箱然后忘了。所以你需要一个机制,让这件事在他脑子里保持一个最低限度的存在感。
交接仪式干三件事。
一,明确责任边界。你要当面说清楚:你不需要打开它,你不需要知道里面是什么,你只需要在我不在的时候把它交给某人,或者在我问起的时候告诉我它还在。这个话说出口和不说出口,效果差很远。
二,制造一个固定触点。一年到三年一次,你出现,你们喝点东西,交换盒子。这个触点同时完成了三件事:验证封条、验证朋友还在、验证你自己还在做这件事。任何依赖“我会记得”的流程都会死,任何嵌进社交关系的流程都能活很久。
三,传递信号。你郑重其事地交给他一个封好的、贴了标签的、有编号的箱子,这个动作本身在说“这不是垃圾,别扔”。人对物品的处置方式很大程度上取决于别人交给他的方式。
还有一层,hukl 提到了,我觉得值得单独说:如果解密口令也放进了盒子,那这个盒子在你去世之后就变成了数字遗产——亲属可以拿它去处理订阅和账号。他说他已经让至少一位朋友掌握了解密口令。
这件事我建议你在封箱那天就做完,别拖。因为“等我哪天整理一份口令清单”是一个永远不会被执行的待办事项,而“现在把这句话告诉这个人”只需要三十秒。
三种别人家的盒子
评论区里有几个人的做法值得摆出来对照,因为它们在解不同的题。
一个叫 SP 的人把 2.5 英寸 USB 3.0 硬盘装进钢制的 .50 口径弹药箱,内衬两层用防火密封胶粘合的石膏板,再用泡棉缓冲,箱外贴白色反光胶带。整箱 8 到 10 磅,靠橡胶密封条防水,金属外壳兼作法拉第笼。他的目标是抗火灾、抗龙卷风、抗跌落,并且在灾后容易定位。
这个方案很硬核,但它在解另一个题:盒子留在灾难现场,怎么让它活下来。我解的是:让盒子根本不在现场。两种都对,但我的是更省事的那一种——异地本身就是最强的防火措施,你不需要石膏板,你只需要几十公里的距离。
至于法拉第笼,我得说一句不太好听的:它防的是电磁脉冲。你的威胁列表里有电磁脉冲吗?如果没有,那 8 到 10 磅的重量是白背的。威胁建模这件事的价值不在于把所有威胁都防住,在于把不防的威胁明确划掉,不然你会为了一个不存在的敌人付出真实的成本。
另一个人叫 Mikael,走的是完全不同的方向:早年用 TrueCrypt(现在是 VeraCrypt)建和 DVD 容量匹配的加密卷做长期备份,现在把一个 5 GB 的 VeraCrypt 容器(里面是源代码、日记之类)放在 Dropbox 里;主力是一块 5 TB 的 VeraCrypt 加密硬盘,交给朋友保管。他的 VeraCrypt 卷用了 128 位字符的密码,密码存在同样放在 Dropbox 的 KeePassXC 数据库里。
这条经验里有一个地方我要挑出来,因为我见过太多人栽在这里:密码和容器放在同一个 Dropbox 账户下,等于把锁和钥匙挂在同一个钩子上。这套方案成立的唯一前提是 KeePassXC 的主密码只在他脑子里,从来没落在任何存储上。如果这个前提成立,他很安全;如果不成立,那么 Dropbox 账号被破的那一天,5 GB 和那把 128 位的密码会一起被拿走。
这不是技术问题,是“你要不要留遗产”的问题,和前面那个“密码放不放盒子里”是同一个开关的两端。他选了不留,我尊重,但我会在 README 里写清楚这件事,别让后来的人猜。
还有 Andrew Poulos 那个 CD-R 在地下车库五年读不出来的例子。这条我前面拿来论证介质不可靠,但它其实还说明另一件事:地下车库不是异地备份,那只是把东西放在你看不见的地方。 高湿、温差、无人看管、可能还漏过水,这是最差的环境之一。异地必须配一个可控的环境——朋友家的衣柜里,比你自己家的地下车库强。
边界:这个盒子没有的东西
到这里该交代边界了。不交代的话,你会以为手里捧的是个万无一失的方案。
这个盒子不含:高频变更数据。它是最后手段,不是工作备份。你的日常备份还得另外做,按 3-2-1 那份来,这个盒子只是那份方案里最远的那一份。
它不防:你自己忘了口令。这条没有技术解,只有流程解,就是把口令托付给一个活人。
它不防:朋友搬家、去世、失联、或者单纯把箱子塞进储物间最里面。所以 hukl 做两到三个盒子,分别给不同的人。这不是冗余,这是社会层的容错。
它不防:格式淘汰。这是我认为整个方案里最大的单点风险,比介质寿命大得多——十年后你朋友家里可能已经没有能读蓝光的机器了。这一条我没有什么好办法,只能说别把轮换周期拉到五年以上,并且在 README 里写清楚需要什么设备。光盘这个介质本身正在退出消费市场,这是你没法用工艺解决的问题。
它不防:技术高超者仿制封条。这一点他在文章里明说了。
还有两条属于“我知道但我选择不管”的:一是他没做前向纠错编码,D 在评论里提到了这个,说认真做备份的人应该遵循 3-2-1 原则并使用 FEC。3-2-1 我完全同意;FEC 我觉得对这个威胁模型收益不高——光盘读出失败通常是整段物理层失效,纠错码救不回来多少,那笔钱不如花在多做一个盒子上。二是干燥剂不是必需的,我放了,但我不打算论证它必需。
交付
到这里,这个东西已经能用了。
盘点一下这一篇造出来的:一个切到极小的数据子集,按主题分盘,每张盘带一份纯文本 README;一套 tar 加 openssl 的加密流程,参数写在盘上;一次真的恢复演练,含一份独立保存的校验值;一个 B&W Type 500 的箱子,PE 泡棉,变色硅胶,自制标签;一根带序列号的一次性封条和一张封箱照片;一个一到三年的轮换日程,以及至少一个知道这盒东西存在的活人。从零到封箱,一个下午加一趟打印店。
下一步往哪走,我给两个方向,都比再加一层加密有价值。
一是把首次轮换真的做完,然后记录结果。hukl 自己在评论里承诺了完成首次轮换之后汇报。这个承诺听起来平淡,但它是整个方案里唯一能产生真实数据的动作——所有关于“光盘能存多久”的讨论,只有在你自己的盒子上真的过了三年之后才有意义。
二是把 3-2-1 里的另外两份补齐。这个盒子只解决了那个“1”。你还有一份在主力机器上,一份在本地另一块盘上,那两块才是你日常真正会用到的东西。别因为做了这个仪式感很强的盒子,就觉得自己已经备份完了——这是这类方案最常见的副作用,做了最远的那一步,然后松了最近的那一步。
到这一步,我们不跳。
