BitVPS
VPS 全盘加密:LUKS、远程解锁,以及查封到底能恢复出什么
加固操作演示

VPS 全盘加密:LUKS、远程解锁,以及查封到底能恢复出什么

"加密磁盘,服务器就安全了",这几乎是这个话题下所有回答的通用套路,而它错得很关键。租用机器上的全盘加密只防御一件具体的事——机器关机时有人读取存储介质。对一台正在运行的机器,它几乎起不到作用,因为解锁卷所用的密钥自开机起就一直待在 RAM 里。本文要讲清楚的是:那条界线到底画在哪里、加密该怎么正确配置,以及被镜像取走的磁盘究竟能恢复出什么。

永不核查 KYC 忽略 DMCA 无流量日志 60 秒上线

给租来的磁盘加密,到底换来了什么

服务器只有两种状态,而磁盘加密只对其中一种有意见。关机时,卷是密文:存储介质里的字节在没有密钥的情况下与噪声无异。运行时,卷已挂载,这意味着主密钥已经被派生出来,加载进内核内存,并且只要机器在运行就一直留在那里。操作系统能读到的每一个文件,之所以能读到,正是因为那把密钥常驻内存。加密并没有失效——它只是恰好在做被要求做的事。

那是一份比宣传语暗示的更窄的保证,但依然值得拥有,因为它覆盖的正是真实会发生的事件。硬盘被淘汰后转卖。出故障的 NVMe 带着你的数据以 RMA 名义寄回厂商。节点关机,磁盘被镜像。备份归档在没人加密的介质上离开了机房。有人能接触到机柜,顺手把不该拿的东西带回了家。这些事一点都不戏剧化,却构成了现实世界中绝大多数的数据外泄——远比人人想象的"对运行中机器的突袭"要常见得多。

场景机器状态LUKS 有帮助吗?暴露的内容
硬盘淘汰、转卖或 RMA 寄回关机是,完全有效密文与 LUKS 头
节点关机,磁盘被镜像关机密文、分区布局、明文 /boot
备份归档被拷贝到站外不适用只有归档本身被加密时才有效归档中的一切内容,明文可见
对运行中实例的实时取证运行中基本无效全部——密钥就在 RAM 中
运行中系统被攻破运行中无效已挂载卷所暴露的一切

虚拟化层本身就在你的威胁模型之内,加密并不能把它排除出去

在 VPS 上,你的内核是一台客户机。运营虚拟化层的一方持有这台客户机的内存,就像你持有一份文件的内容一样,中间没有任何加密步骤。virsh dump 把一个运行中域的 RAM 写入文件,这是常规操作;实时迁移会把同一份内存按设计拷贝到网络上,因为迁移本来就是这么回事。存在于客户机内存中的 LUKS 主密钥,也在这一切之内。

所以诚实的说法是这样的:VPS 上的全盘加密能防住除了运营虚拟化层那一方之外的所有人——也能防住那一方,但仅限于机器关机的时候。任何声称"给客户机磁盘加密,就能让运行中的实例对我们不可读"的主机商,描述的都是一台不存在的机器。我们宁可把这句话写清楚,也不让你自己脑补出更舒服的版本。

如果服务商真的在你的威胁模型之内,答案不是换一种更强的密码算法,而是把虚拟化层整个拿掉:独立服务器让你的内核直接跑在裸机上,要读取它的内存就得实际拿到这台机器,再对 RAM 发起 DMA 或冷启动式攻击——缓慢、动静大,需要的访问权限远超一次常规请求所能给到的。VPS 与独立服务器对比指南还讲了这次切换在其他方面同样划算的原因。AMD SEV-SNP、Intel TDX 这类机密计算扩展正是瞄准这个缺口而生,但它们在今天的租用 VPS 上还不是标配,而且只是把信任转移给了 CPU 厂商,并没有消除信任本身。

三种落地方式,各自要付出什么代价

实践中主要有三种形态,它们在安全性和重启的痛苦程度之间做取舍。从控制台解锁的加密根分区最强也最烦人:没有人工介入,什么都撑不过一次重启。initramfs 中带 SSH 服务的加密根分区安全性相同,却能远程解锁,是大多数人应该搭建的方案。明文根分区上的加密数据卷是最省事的选项,也是那个会悄悄让你失望的选项。

它让人失望,是因为明文根分区无论你是否愿意,都会把你的秘密收集起来。systemd 日志写在那里。shell 历史、软件包缓存、core dump、/tmp、Docker 的默认数据根目录也是如此——而几乎每个人都会中招的那一个,是 swap:机器承压时,进程的内存就是往那里去的。给 /var/lib/mysql 加密,却让旁边的 swap 保持明文,这不是打了个折扣的防御,而是一份中间挖了个洞的完整防御。

配置方案解锁方式能否扛过无人值守的重启诚实评价
加密根分区,控制台解锁KVM-over-VNC 或 IPMI不能——在有人解锁前一直停机最强;适合很少重启的机器
加密根分区,initramfs 中带 dropbearSSH 到解锁端口不能——但可以随时随地解锁明智的默认选择
加密数据卷,明文根分区启动后脚本或手动执行除非把 swap、日志和临时目录都处理好,否则很弱
加密根分区,密钥文件放在明文 /boot 中自动只能防住转卖的硬盘,别的都防不住

分步安装加密根分区

1. 启动安装程序,而不是套用模板。预制镜像给不了你加密根分区,因为磁盘在你成为客户之前就已经写好了。每个 BitVPS 套餐都支持从 ISO 重装、上传自定义 ISO 和 netboot,也都自带 KVM-over-VNC 应急控制台——这一点很关键,因为你需要盯着安装程序、回答它提出的问题。独立服务器通过一个由 VPN 网关保护的 IPMI 端点提供同样的能力,支持 ISO 挂载和 BIOS 访问。

2. 划分一个小的明文引导区。/boot 或 EFI 系统分区留一个小分区,其余全部空间划给一个 LUKS 容器。引导程序和 initramfs 必须在任何密钥存在之前就可读,所以这个分区对任何镜像了磁盘的人来说都是可读的。围绕这一点做设计,而不是假装它不存在。

3. 创建容器。cryptsetup luksFormat --type luks2 --pbkdf argon2id /dev/vda2。LUKS2 搭配 argon2id 正是重点所在:argon2id 是内存困难型算法,规范见 RFC 9106,它让离线猜测攻击在硬件层面变得昂贵,而不只是在软件层面变慢——这就是"GPU 农场吭哧吭哧啃你的口令"和"GPU 农场根本不值得对准你"之间的差别。把内存开销控制在机器早期启动阶段能分配到的范围之内;在 4 GB 的实例上,用你 64 GB 笔记本电脑调出来的开销参数,只会导致解锁失败。

4. 打开容器并安装系统。cryptsetup open /dev/vda2 cryptroot,接着在 /dev/mapper/cryptroot 上直接建 LVM 或文件系统,然后让发行版的安装程序对着它安装,/boot 放在明文分区上。Debian、Ubuntu、Alpine、Arch、Rocky、Fedora 和 FreeBSD 都能这么处理;不管你实际用的是哪个发行版,Arch wiki 的 dm-crypt 页面都是最完整的参考资料。

5. 在 initramfs 里放一个 SSH 服务。安装 dropbear-initramfs,把你的公钥放进 /etc/dropbear/initramfs/authorized_keys,再给内核命令行加一个 ip= 参数,让网络接口在口令提示之前就起来。漏掉这个参数,你造出来的就是一台启动到提示符、却没人能连上的机器。

6. 重建并重启。update-initramfs -u 会把 SSH 服务、你的密钥和网络设置一并打进引导程序加载的镜像里。然后开着控制台重启,因为第一次尝试最容易出岔子。

7. 解锁并确认交接完成。SSH 到解锁端口,运行 cryptroot-unlock。initramfs 出示的主机密钥和已安装系统的不一样,所以你的客户端首次连接时会大声警告——这是正确行为,是一个有用的信号,不是障碍:把这个指纹单独固定为一条 known_hosts 记录,而不是干脆关掉主机密钥校验。会话断开,正是真正的系统已经接管的信号。

远程解锁,以及那个没人先问的 04:00 问题

让 initramfs 里的 SSH 服务用自己独立的端口——约定俗成用 2222——这样两把主机密钥就不会撞进同一条 known_hosts 记录里。优先用静态 ip= 而不是 DHCP:initramfs 是一个极简环境,一次失败的 DHCP 交互会留给你一台开着机、连不上、卡在提示符上的机器。如果你依赖 IPv6,要确认你的 initramfs 真的配置了它;有几个发行版在这个阶段还是只启用 v4。

即便 SSH 解锁跑通了,也要把控制台留作后备手段。你最终会撞上的失败不是密码学层面的,而是一次内核更新重建了 initramfs、却没带上你的密钥,或者网络参数在你不知情的情况下变了——那一刻,唯一的入口就是套餐自带的 KVM-over-VNC 控制台。两手都留着不是冗余,而是"小麻烦"和"推倒重装"之间的差别。

然后是那个运营层面的问题,也是在动手搭建这一切之前就该想清楚的问题:加密根分区意味着无人值守的重启会让你的服务保持宕机,直到有人手动解锁。节点维护、内核 panic、断电事件——机器重新出现时停在提示符上,而不是你的应用上。如果这个后果对你的业务来说无法接受,不要用一份放在明文引导分区里的密钥文件来敷衍过去。那就是把钥匙用胶带粘在门上的锁,只能防住转卖的硬盘,别的什么都防不住。如果你愿意,也可以刻意选它,但要在自己的运维手册里写清楚:这是你有意做出的选择。

加密卷周围会泄漏的一切

出问题的地方很少是卷本身。出问题的是那些根本没被放进卷里的东西。

泄漏点为什么会发生解决办法
Swap进程内存(含密钥在内)在系统承压时溢写到磁盘把 swap 放进容器内,或使用随机密钥的 swap 设备,或干脆不用 swap
休眠镜像按设计把完整的 RAM 转储写入磁盘在服务器上禁用它;它本就不该出现在服务器上
明文的 /boot 和 initramfs必须在任何密钥存在之前就可读接受这一点,把它遭到修改视为入侵——加以校验,或在可用时启用 Secure Boot
挂载之前写入的日志早期启动日志落在明文分区上确认你的日志在卷打开之前实际存放在哪里
Docker 数据根目录默认是 /var/lib/docker,在外挂的数据卷之外把它挪进卷内,或者干脆加密根分区
盒外监控与日志代理把文件内容以明文形式发往第三方在信任这个卷之前,先审计代理都发送了什么

有一个特性必须说清楚,因为它经常被过度宣传:LUKS 头会主动暴露自己的存在。任何镜像了这块磁盘的人都能看到有一个加密容器存在、用的是哪种密码算法、KDF 参数是什么,以及占用了多少个密钥槽。LUKS 给你的是机密性,不是可否认性,任何指望"没人会注意到这个容器"的计划,都是建在沙子上的。

口令、密钥文件与分离头

口令就是整套系统。Argon2id 让每一次猜测都变得昂贵,但"昂贵"乘以一个很小的密钥空间,结果依然便宜:从 diceware 词表里选五六个单词,胜过一个带替换字符的十一位密码,而且差距不小。用 --iter-time 针对真正会执行解锁的那台机器来调开销,而不是你正在打字的这台,并且绝不要复用任何靠近过 KYC 账户的口令。

密钥文件省去了打字,却把问题挪到了别处:cryptsetup luksAddKey 把一个密钥加进空闲槽位,而唯一值得拥有的版本,是那种从不留在服务器上的——放在你自己的机器或硬件令牌上,在 SSH 会话中喂给解锁过程。分离头(--header)更进一步:由于元数据存放在别处,数据设备本身与随机字节再无区别。代价是毫无余地。丢了这个头,卷就永久没了,没有任何补救办法——所以要认真对待 cryptsetup luksHeaderBackup,并把这份备份存放在另一处同样加密的地方。上游的 cryptsetup FAQ 和内核的 dm-crypt 文档,是你敲定方案之前值得读的两份参考资料。

还有一条没有例外的规矩:口令永远不进工单。不进我们的工单,也不进任何人的工单。我们做的任何事都不需要它,我们能替你执行的任何操作都用不上它,而工单是数据库里一条写死的记录。如果哪家主机商问你要口令,这段对话到此就该结束了。

被镜像取走的磁盘,究竟会交出什么

把关机场景说具体一点,因为在这件事上含糊其辞对谁都没好处。手里有你磁盘镜像的调查者,能拿到的是:密文、带着密码算法和 KDF 参数以及槽位数量的 LUKS 头、分区表、所有东西的大小,以及整个明文引导分区——你的内核、你的 initramfs,以及其中每个文件的修改时间戳。最后这一项透露的信息比人们以为的要多。软件包的安装时间能勾勒出一条时间线,而一个包含 dropbear 密钥的 initramfs,也能说明这台机器是怎么被管理的。

他们拿不到的是内容本身。面对一个用 argon2id、配了真正强口令的现代 LUKS2 容器,离线攻击不是"再多等一会儿"的问题——它根本不在选项之内。这就是整份价值主张,而且是一份实实在在的价值。

运行中的情形正好相反,而且很简短:一切都能拿到。不是因为加密失效了,而是因为密钥常驻内存——这正是一个已挂载文件系统能正常工作所必须具备的条件。

快照处在两者之间,常常让人意外。我们提供每小时快照、保留 7 天,是块级别的,所以加密卷做出来的快照同样是密文——这是好事,而它的推论也很扎实:没有口令,你同样读不了那份快照。丢了密钥,快照和原卷一样彻底无法恢复。恢复方案里必须包含口令的保管办法,否则你搭建出来的只是七天非常可靠的噪声。我们在卷之外持有关于你的哪些信息,写在 隐私政策 里,我们每周发布一份 PGP 签名的预警金丝雀,作为长期存在的证据,而不是一句承诺。

决定最终结果的部分,从来不是密码学

没有人是因为 AES-256-XTS 顶不住而丢了数据的。他们丢数据,是因为口令是从存过护照的交易所账户上复用来的,是因为为了让重启安静一点,把密钥文件留在了明文引导分区上,是因为站外备份就是一个普通的 tarball,是因为口令留在了笔记本电脑的 shell 历史里,或者是因为某个监控代理一直在把文件内容发送给某个 SaaS。

还有一个容易被忽视的:一台从不关机的服务器,整段生命周期都处于"这一切都帮不上忙"的状态。一个正常运行了 400 天的实例,已经解密了 400 天。如果数据真的是冷数据——归档、密钥备份、一年也就查两次的记录——就把它放进一个容器里,需要时才打开,用完就 cryptsetup close。十秒钟的打字操作,能把一次永久性的暴露变成一次瞬时的暴露,而这个转换比你能传给 luksFormat 的任何参数都更有价值。

顺带把管辖地也纳入同一套推理。加密决定的是什么内容可读;机器坐落在哪个法域决定的是谁有资格来问,以及请求会经过哪些情报联盟。这两者不能互相替代,而真正做对这件事的人,会把它们当成同一个决策来对待。

我们能提供什么,又不能提供什么

从 $8.50 的 Starter 套餐往上,每个套餐都提供了加密根分区真正需要的东西:拥有完整 root 权限的 KVM 虚拟化、启动自定义 ISO 与 netboot 的能力、面板上的从 ISO 重装、内核模块加载,以及在 initramfs 不肯回应时用得上的 KVM-over-VNC 应急控制台。独立服务器档位额外提供一个由 VPN 网关保护的 IPMI 端点,带控制台、断电重启、ISO 挂载和 BIOS 访问。加密这件事上,没有任何一部分是我们卖给你的产品——它是你自己搭建的东西,我们的工作是不挡你的路。

说清楚我们不能做什么,反而更有用。在一台运行中的 VPS 上,虚拟化层能读取客户机内存;这是架构决定的,不是策略开关,你在客户机内部装再多加密都改变不了它。针对这一点,我们提供的不是数学证明,而是态度和证据:不留 netflow、不留 PCAP、不做网卡镜像、面板会话 IP 在 24 小时内清除、注册不做 KYC 所以账户本身不构成筹码、只收加密货币所以账单流水同样不构成筹码,外加一份你自己可以核验的、每周 PGP 签名的预警金丝雀。只有独立硬件能把虚拟化层从整个局面里拿掉,也只有断电能把 RAM 里的内容清掉。

如果这段话读起来像是在某些威胁模型下反对我们自家的 VPS,那确实就是。我们宁可把对的东西卖给你两次,也不愿把错的东西卖给你一次。用一份 ISO 部署一个实例,在 Starter 套餐上试装一个月;如果答案最终指向裸机,独立服务器档位从 $39.50 起,开通需要两到四小时,而不是 41 秒。

快速解答

常见问题

如果数据中心被突袭,全盘加密能保护我吗?
这完全取决于事发时机器是否在运行,而通常情况下它就是在运行的。关机的加密卷是密文,而且会一直是密文。运行中的实例把主密钥放在 RAM 里,而在 VPS 上虚拟化层能读取那块内存——所以对大多数人脑子里想象的那个场景,诚实的答案是不能。对离开机房的磁盘,加密是强防御;对被现场查封的运行中机器,加密是弱防御。
BitVPS 能读取我加密卷里的内容吗?
在实例运行期间,主密钥在客户机内存里,而虚拟化层能读取客户机内存——所以从技术上说,能。任何在这一点上就运行中的 VPS 告诉你相反答案的服务商,说的都是错的。我们不这么做,我们不保留 netflow、PCAP 或网卡镜像,并且每周发布一份 PGP 签名的预警金丝雀,而不是要求你单凭信任接受这句话。但这些是政策和证据,不是数学证明。如果你需要的是数学证明,那就必须关闭这个卷,或者让虚拟化层根本不存在——也就是用独立硬件。
没有控制台的情况下,重启后怎么解锁磁盘?
在 initramfs 里放一个 SSH 服务。dropbear-initramfs 配上放在 /etc/dropbear/initramfs/authorized_keys 里的公钥,以及内核命令行上的 ip= 参数,就能给你一个随时随地可以连上的提示符;cryptroot-unlock 负责打开卷并把控制权交给真正的系统。让它跑在独立的端口上,并且预期首次连接时会收到主机密钥警告,因为 initramfs 有自己的一把密钥。把 KVM-over-VNC 控制台留作后备,以应对某次更新重建 initramfs 却没带上你密钥的那一天。
LUKS 会拖慢服务器吗?
在我们所用的硬件上,慢到不会被人察觉。我们全部机队的每一颗 CPU 都带 AES-NI,硬件加速下的 dm-crypt 对典型的 Web、邮件、数据库和节点负载来说,开销只是个位数百分比的低端。真正能测出差别的地方,是快速 NVMe 上持续的高 IOPS 工作负载,每次请求的加密会在尾延迟而不是平均延迟上体现出来。如果你跑的东西能把一块 Gen4 NVMe 跑满,去做个基准测试;其余情况下,这点开销就是噪声。
我应该加密整个根分区,还是只加密一个数据卷?
加密根分区,除非你有明确的理由不这么做。只加密数据卷的方案看起来整洁,却会从 swap、systemd 日志、/tmp、软件包缓存、core dump 和 Docker 的默认数据根目录泄漏——真正有价值的材料,是意外落在明文一侧的,而不是被有意安排在那里的。加密根分区之后,每装一个新服务,这个问题就不用再重新回答一次。
如果卷是加密的,我的每小时快照会怎么样?
快照是在块级别打出来的,所以捕获到的是密文——这正是你想要的,而它是一把双刃剑:没有口令,谁都读不了这份快照,包括你自己。恢复意味着先恢复出加密卷,再像解锁原卷一样把它解锁一遍,所以口令必须挺过那次让你不得不动用快照的事件。一把只存在于你刚刚丢掉的那台服务器上的密钥,根本不算一把密钥。
我可以使用分离的 LUKS 头,或者把密钥放在服务器之外吗?
两者都可以,而且都是好主意。cryptsetup luksAddKey 把一个密钥文件加进空闲槽位,这样你就能把它留在自己的机器或硬件令牌上,在解锁会话中喂给它。通过 --header 使用分离头则更进一步,让数据设备看起来就是一堆随机字节。代价是丢了这个头就会永久摧毁整个卷——在需要之前就先做好 luksHeaderBackup,并把这份备份存放在另一处同样加密的地方。
就这件事而言,独立服务器真的比 VPS 好很多吗?
是的,而且这是唯一一次能改变答案本身、而不只是改变胜算的升级。在独立硬件上,你的内核和 CPU 之间没有虚拟化层,所以读取你的内存需要实际拿到这台机器,再发起 DMA 或冷启动式攻击——缓慢、动静大,门槛比一次常规操作高得多。其余的搭建过程完全一样,而且带 ISO 挂载的 IPMI 让安装比在 VPS 上还更省事。档位从 $39.50 起。
应用指南

本指南适用的工作负载

每张卡片打开包含规格建议和系统管理员 FAQ 的工作负载专属页面。

读够了吗? 60 秒内部署

无需邮箱验证,无需身份证,无需账户。选择套餐,以任意加密货币支付,获得 root 权限。