
用 LUKS 加密 VPS 磁盘
加密一块磁盘并不难。难的是在一台你无法亲手触碰的机器上做到这一点——让它在凌晨 4 点依然能在无人守着控制台的情况下重启——而这正是大多数指南略过的部分。同样被几乎所有指南略过的,是老老实实说清楚:在租来的硬件上,加密到底能为你换来什么。这篇指南把三件事都做了:从救援模式安装一个 LUKS2 根卷,通过 SSH 远程解锁,并如实交代它能挡住哪些威胁、挡不住哪些。
“我的数据加密了吗?”是我们被问到最多的问题,诚实的答案是:除非你自己加密,否则没有。我们不会替你加密磁盘,这是刻意为之——我们手上握有的密钥,就是我们可能被迫交出的密钥。我们的文档用一句话说明了这一点;这篇指南则是加长版,附带具体命令。
接下来是我们自己实际使用的流程:一个小小的未加密 /boot,其余一切都放进 LUKS2 容器,再加上运行在 initramfs 里的一个极小的 SSH 服务器,让密码短语可以在开机时从世界任何地方输入。这套流程在我们全部四个地区上运行方式完全相同——Paris、Reykjavík、Zürich 和 Bucharest——因为硬件完全一致。它同样适用于任何提供救援模式的其他服务商。最后一节会说明局限,因为一篇只讲加密能修复什么、却对局限只字不提的指南,多半是在推销什么。
VPS 磁盘加密到底保护什么
加密不是什么通用的隐私开关,它只回答一个问题:没有密钥的人能不能读到这些数据块?其余的一切——谁知道你租了这台服务器、流量能不能追溯到你、法院能不能强制要求什么——都不归它管。
在 VPS 上,LUKS 能切实防住以下几种情况:
- 报废和故障的硬件。NVMe 硬盘是会被更换的。故障设备上的安全擦除并非总能做到——有时它坏得连控制器都不再接受任何指令,却照样会被拆下机架、送出机房。
- 离线镜像。在服务器关机状态下被复制的卷——无论是因为查扣、迁移,还是操作失误——本身就是密文,而且会一直是密文。
- 外流的备份和快照。只要是从你可控范围之下的块层取出的数据,离开机器时就是加密的;如果是从块层之上取出的,就应该在客户端自行加密。
- 残留数据块。销毁一台服务器后,底层存储区最终会被重新分配使用。加密让这些残留内容变成噪声,而不是数据。
它不能防住正在运行的机器。服务器开着的时候,主密钥就驻留在内核内存里,任何能够转储该内存的人,都能不管密码短语是什么直接读出你的磁盘。在租用的基础设施上,这个人就是虚拟化平台的运营方。我们在隐私声明里说过这一点,这里再重申一次:没有任何提供商的磁盘加密功能能改变这一事实,包括我们自己在内;任何声称并非如此的提供商,讲的是营销话术,不是密码学。
三种方案,以及你到底需要哪一种
动手敲命令之前,先选好方案。三者所需的精力差别很大,多数人只需要第一种。
1. 加密数据卷。系统照常以未加密方式启动;只有一棵目录树——邮件目录、数据库、归档文件——放在一个 LUKS 容器里,每次启动后手动打开。只需十分钟,不用救援模式,也没有把自己锁在外面的风险。如果你在意的是某一份数据而不是整台机器,到这一步就可以停下:好处基本都拿到了,脆弱之处却几乎没有增加。这也是我们在匿名邮件服务器页面推荐的做法。
2. 加密根卷 + 远程解锁。除 /boot 之外的一切都被加密,每次启动都会在 initramfs 里暂停,直到你通过 SSH 连进去输入密码短语。本指南接下来搭建的就是这一种方案。第一次要花一个小时,之后每次重启只需一条 SSH 命令;它也是唯一一种连日志、软件包缓存、shell 历史和交换分区都覆盖到的方案——这些正是数据在没人特意决定的情况下悄悄泄露出去的地方。
3. 加密根卷 + 向你自己掌控的密钥服务器自动解锁。与方案 2 相同,只是由 Clevis 从位于另一司法辖区的 Tang 服务器获取解锁材料,因此重启无需人工值守。这里的取舍很明确,也值得弄清楚:只要你的密钥服务器点头,服务器现在就能自行解密——也就是说,你把秘密挪了个地方,而不是彻底去掉了它——但你也因此获得了一个远程“熔断开关”。后文会详细说明。
为什么我们不替你加密磁盘
不少主机商把“静态加密”当作一个可以打勾的卖点来宣传。这个说法背后其实藏着两种截然不同的东西,值得说清楚。
密钥由服务商掌握的加密,防的只是硬盘被偷,仅此而已。如果服务商不用问你就能启动你的服务器,那它不用问你也能解密你的服务器——能强制服务商这么做的任何一方,同样可以。这种加密对盗窃是真实有效的控制,对法律程序而言却纯属摆设。
密钥由你自己掌握的加密才是真正有意义的版本,而它从原理上就注定会让无人值守的重启无法进行。这不是一个需要被设计掉的缺陷,而正是这个方案起作用的地方。
我们只提供第二种选项,并且默认不启用,交由你自己决定。我们确实持有、且写在文档里的东西范围要小得多:服务器 root 密码以 AES-256-CBC 在行级别加密存储,我们不保留流量日志或数据包记录,并按计划发布经签名的预警声明(warrant canary)。这些都替代不了你自己的密钥——它们只是我们在此期间可以被追责的部分。
密码算法、密钥长度与 Argon2 内存陷阱
默认设置已经很好,其中有两项值得手动指定。
密码算法。默认值 aes-xts-plain64 配合 512 位密钥就是正确答案——这 512 位其实是两把 256 位密钥,所以本质上是 XTS 模式下的 AES-256,而我们运行的每一颗 CPU 都带有 AES-NI。在没有 AES 硬件加速的机器上,你会更想用 xchacha20,aes-adiantum-plain64,但那不是我们的硬件,大概率也不是你的。
密钥派生。LUKS2 默认使用 Argon2id,它刻意设计成对内存要求很高。cryptsetup 会在格式化时对你的机器做基准测试,并根据它看到的内存量选定一个内存开销——这正是绝大多数“加密服务器起不来”问题的陷阱所在:initramfs 可用的内存比正在运行的系统要少,如果你是在一个内存比目标套餐更大的救援环境里格式化的这个卷,解锁时就可能失败,或者在启动过程中被杀掉。所以要显式锁定这个值。1 GiB 的 Argon2 内存开销,对攻击者来说是相当高的代价,而一台 4 GB 内存的 S1 完全负担得起:
cryptsetup luksFormat --type luks2 \
--cipher aes-xts-plain64 --key-size 512 --hash sha256 \
--pbkdf argon2id --pbkdf-memory 1048576 --pbkdf-parallel 4 \
/dev/vda2--pbkdf-memory 的单位是 KiB,所以 1048576 就是 1 GiB。之后可以用 cryptsetup luksDump /dev/vda2 检查头部里实际写入的值——keyslot 部分会打印出将要使用的内存量和迭代次数,花一次时间看看,比启动失败要划算得多。
密码短语。Argon2 能为弱密码短语争取时间,却救不了它。请使用至少六个单词的 diceware 密码短语。它是整个系统里唯一的秘密,再好的密钥派生函数也弥补不了一个糟糕的密码短语。
远程解锁到底是怎么工作的
加密根卷的 Linux 启动过程存在一个先有鸡还是先有蛋的问题:内核和 initramfs 必须先加载,之后才能有东西来向你要密码短语,而它们恰恰就放在你想要解锁的那块磁盘上。标准做法是设置一个小的未加密 /boot 分区,存放内核、initramfs 和引导程序,其余一切都放进 LUKS 里。
随后 initramfs 会暂停下来,要求输入密码短语。在笔记本电脑上,你直接打字输入即可;而在三千公里外的一台服务器上,你需要下面两者之一:
- 控制台。面板里的每台服务器都有 noVNC 控制台,它确实管用——但按键会经过我们的基础设施,而这恰恰是你的密钥本该排除在外的一方。偶尔用来救急可以,当作日常手段就不对了。
- 装在 initramfs 里的 SSH 服务器。
dropbear-initramfs大约 200 KB,能拉起网络、监听你指定的端口、接受你的某个公钥,并直接把你带到解锁提示符前。密码短语从你的笔记本电脑到 initramfs 全程端到端加密。这才是正确答案。
有两个细节容易让人踩坑。initramfs 里的 Dropbear 有它自己的主机密钥,因此指纹和你平时用的 SSH 守护进程不一样——这是正常现象,不是中间人攻击,它值得拥有自己独立的 known_hosts 文件,而不是养成见到提示就敲 yes 的习惯。另外网卡接口名必须写对:Debian 13 上的 virtio 网卡通常显示为 ens3 或 enp1s0,而不是 eth0。写配置之前先用 ip -br link 确认一下,因为一旦写错,就意味着 initramfs 没有网络,只能跑一趟控制台。
用 Clevis 和 Tang 实现无人值守重启
如果机器必须能够自己恢复运行——比如内核更新之后、宿主机重启之后、遇到断电事件之后——那靠人手动输入密码短语就行不通了。Clevis 会把一个 LUKS 密钥槽绑定到一项外部策略上,而 Tang 就是实现了其中最简单、也最实用的那种策略的一个小型密钥交换服务器。
# on a small server you control, elsewhere
apt install -y tang
systemctl enable --now tangd.socket
# on the encrypted VPS
apt install -y clevis clevis-luks clevis-initramfs
clevis luks bind -d /dev/vda2 tang '{"url":"http://tang.internal:7500"}'
update-initramfs -u -k all启动时,initramfs 会与 Tang 完成一次 McCallum-Relyea 交换,从而恢复出密钥,而 Tang 服务器全程既不会得知这个密钥,也看不到密码短语。这里的几条性质值得说清楚:
- VPS 只有在能连通 Tang 的情况下才会自行解密。把 Tang 关掉,或者轮换它的密钥,下一次启动就会彻底卡住。这是一个真正意义上的远程“熔断开关”——不常见,但很有用。
- Tang 不应该暴露在公网上。请通过 WireGuard 或以 Tor 洋葱服务的方式访问它;隧道搭建部分我们在WireGuard 指南里有讲。
- 把 Tang 放在和数据所在地不同的司法辖区。我们的辖区页面存在的意义之一就是支持这种拆分。
- 在另一个密钥槽里保留一个密码短语。Clevis 只是一层便利手段,不该是你唯一的进入方式。
要清楚自己搭建的是什么:一台无人值守的机器,等于用代理的方式握着自己的密钥,因此不管是在它运行时查扣该 VPS 的对手,还是能够连到你 Tang 服务器的对手,都能拿到数据。相比一个只存在于你脑子里的密码短语,这是一种确确实实的削弱。只有当可用性比保密性的最后一点余量更重要时,才应该选择它,而不是把它当作默认项。
交换分区、临时文件,以及明文外泄的地方
加密根卷覆盖了大部分范围,但仍有几处会写到卷外,或者能在加密之外留存下来。
- 交换分区(swap)。内存里的任何东西都可能被换出到磁盘上——密钥、消息正文、已解密的缓冲区。如果交换空间是加密卷内的一个 swapfile,就在保护范围之内;单独的交换分区则不然,除非你把它加进
/etc/crypttab,用一个每次启动都会变化的随机密钥:cryptswap /dev/vda3 /dev/urandom swap,cipher=aes-xts-plain64,size=256。在 VPS 上用 swapfile 更简单,没有理由偏爱分区形式。 - /tmp。把它挂载成 tmpfs(
tmpfs /tmp tmpfs defaults,nosuid,nodev,size=512M 0 0),这样它就完全不会碰到磁盘,速度也更快。 - 休眠(hibernation)。会把整个内存内容——包括你的主密钥——写入交换设备。不要启用它。我们的镜像默认就是关闭的。
- 未加密的 /boot。内核、initramfs 镜像和 GRUB 配置对任何拥有磁盘离线访问权限的人来说都是可读的,更重要的是还可写。LUKS 给你的是机密性,不是启动完整性。如果你的威胁模型里包含有人篡改引导程序,光靠加密是抓不到的——在每次内核更新后记录
/boot的哈希值,并从外部进行核对,或者有意识地接受这个缺口。 - 已有的快照和旧卷。今天加密,对昨天拍下的镜像毫无帮助。如果服务器曾经以未加密状态运行过你在意的数据,就把那些数据当作已经暴露,并轮换所有由它派生出的凭据。
性能:代价是什么,该调什么
开销小到不应该成为决策依据,但它并不是零。先测量,再判断:
cryptsetup benchmark在我们的 EPYC 节点上,512 位密钥的 aes-xts 基准跑分能达到每核每秒几个 GB 的水平——远超一块 NVMe 卷的需求。真正会体现出来的代价,是小块随机写入时的延迟和 CPU 占用,而不是吞吐量。
在 NVMe 上,有两个 LUKS2 参数值得设置,因为内核 dm-crypt 的工作队列在这里增加的是延迟,而不是消除延迟。把它们设置好,并让它们写进头部持久保存:
cryptsetup refresh cryptroot \
--perf-no_read_workqueue --perf-no_write_workqueue --persistent第三个参数 --allow-discards 会把 TRIM 指令透传给底层设备。它能在整个卷的生命周期里降低写放大,代价是会暴露哪些块处于未使用状态——这会向任何能读取原始设备的人泄露你数据的大致大小和形状。通用型服务器可以启用它;如果一个卷只用了 3% 这件事本身就很敏感,那就关掉它。这里没有放之四海而皆准的答案,只有一个你应该主动做出的决定。
头部、密钥槽,以及出问题的那一天
LUKS 头部大约占分区最前面的 16 MB,里面保存着主密钥的加密副本。一旦损坏它——一次打错的 dd、一个“好心”重写设备起始部分的分区工具——它后面的每一个字节都没了。没有什么恢复服务可以找,我们自己也没有副本。
# back it up, off the server, before you put data on the volume
cryptsetup luksHeaderBackup /dev/vda2 \
--header-backup-file luks-header-$(date +%F).img
# add a second passphrase while you still have the first
cryptsetup luksAddKey /dev/vda2
# see what is in the header
cryptsetup luksDump /dev/vda2关于这份备份,有两点要说明。第一,它和磁盘本身一样敏感:因为里面包含密钥槽,一份旧头部在你改过密码短语之后被恢复回去,会照样欣然接受那个旧密码。请像保管密码短语一样保管它,轮换密钥时记得销毁过期的副本。第二,LUKS2 提供 32 个密钥槽——至少用上两个,备用的那个用一条保存在别处、与你日常密码短语不同地方的长随机密码短语。这样可以避免一种平淡却常见的故障:你轮换了密码短语,却两次都打错成同一个错误版本,直到下次重启才发现,而不是下次登录时。
也要给自己留一条退路。救援模式会用我们的 ISO 启动服务器,注入你的 SSH 密钥,且不触碰加密卷,这意味着你可以执行 cryptsetup open /dev/vda2 rescue && mount /dev/mapper/rescue /mnt,在不丢失数据的情况下修复损坏的 crypttab 或者出问题的 initramfs。请专门找个时间实际测试一次,趁一切都还正常的时候。
加密做不到什么:直说了吧
像这样一篇指南,能做的最有用的事,就是划清自己的边界。
- 它保护不了正在运行的服务器。从解锁到关机,主密钥始终待在内核内存里,虚拟化层的内存访问能力可以直接绕过它。内存加密——AMD SEV-SNP 及同类技术——是目前唯一能实质性改变这一点的技术,而我们目前并未提供它;任何在没有 SEV 的情况下,却声称你正在运行的虚拟机对其不可见的服务商,要么理解有误,要么在撒谎。
- 它不会让你变得匿名。一块位于 Zürich 的加密磁盘,照样有一个 IP、一条账单记录,以及一个总要从某处发起的 SSH 会话。那是另一个问题,我们在那些会让你现出原形的失误里写过它会以哪些方式出岔子。
- 它改变不了法院能下什么令。司法辖区决定谁能强制你做什么,加密决定数据能不能被读懂。在某些司法辖区,你可能被要求亲自交出密码短语。我们的法律程序指南说明了我们会采取行动、以及不会采取行动的部分。
- 它扛不过一个你弄丢的密码短语。这是设计使然,值得再说一遍:几乎每个月都会收到一张求助工单问这个问题,而答案永远一样。
- 它不会为启动链做身份验证。机密性不等于完整性。
/boot在离线状态下依然可读、可改。
它真正能做到的,是消除一整类暴露风险——也就是磁盘不运行时会发生的一切,而这恰恰是磁盘经历的大部分遭遇。这值得花一个小时去做。再配上一个无 KYC注册、用 Monero 付款,以及一个有意选定的司法辖区,每一层都能补上不同的漏洞。它们中没有哪一层能包办所有问题。
- 部署服务器,并启动进入救援模式
选择任意套餐和地区,用官方 Debian 13 镜像部署即可——反正装好的系统马上就要被替换掉,选哪个镜像都无所谓。然后前往 Server → Recovery → Boot into rescue。救援环境会自动注入你账户里已有的 SSH 密钥,且不会动磁盘,因此你得到的是一个 root shell,此时
/dev/vda处于未挂载、空闲状态。请注意,救援环境的主机密钥指纹和已安装系统的不同,这是正常现象。 - 分区:一个小的明文 /boot,加一个大的 LUKS 容器
分两个区。
/boot分配 1 GB——够放好几个内核版本——剩下的全部划给加密卷。sgdisk --zap-all /dev/vda sgdisk -n1:0:+1G -t1:8300 -c1:boot /dev/vda sgdisk -n2:0:0 -t2:8309 -c2:crypt /dev/vda partprobe /dev/vda && lsblk /dev/vda类型
8309把第二个分区标记为 Linux LUKS 卷。如果你的服务器以 UEFI 模式启动,就把第 1 个分区做成 ESP(-t1:ef00,格式化为 FAT32,挂载到/boot/efi),并另外加一个独立的 1 GB/boot;上面这种 BIOS 布局是我们镜像默认使用的方式。 - 创建 LUKS2 卷并打开它
显式锁定 Argon2 的内存开销,好让 initramfs 之后能负担得起。
cryptsetup luksFormat --type luks2 \ --cipher aes-xts-plain64 --key-size 512 --hash sha256 \ --pbkdf argon2id --pbkdf-memory 1048576 --pbkdf-parallel 4 \ /dev/vda2 cryptsetup open /dev/vda2 cryptroot mkfs.ext4 -L root /dev/mapper/cryptroot mkfs.ext2 -L boot /dev/vda1使用至少六个单词的 diceware 密码短语,并在继续之前把它写在纸上等实体介质上。没有人能替你找回它——这正是你在为之付费的那个特性。
- 把 Debian 安装进加密卷
挂载新的根分区,用 debootstrap 往里装一个基础系统,再绑定内核相关文件系统,让 chroot 能正常工作。
mount /dev/mapper/cryptroot /mnt mkdir -p /mnt/boot && mount /dev/vda1 /mnt/boot debootstrap --arch=amd64 trixie /mnt http://deb.debian.org/debian for d in dev dev/pts proc sys run; do mount --bind /$d /mnt/$d; done chroot /mnt /bin/bash在 chroot 里,安装能让加密根卷可启动、可访问所需的组件:
apt update && apt install -y linux-image-amd64 grub-pc \ cryptsetup cryptsetup-initramfs dropbear-initramfs \ openssh-server ifupdown ca-certificates locales - 写好 crypttab、fstab 和 initramfs 的网络配置
crypttab告诉 initramfs 要解锁哪个设备;initramfs.conf告诉它该怎么先把网络配起来。要用 LUKS 的 UUID,绝不要用/dev/vda2——设备名是会变的。echo "cryptroot UUID=$(blkid -s UUID -o value /dev/vda2) none luks,discard" \ > /etc/crypttab cat > /etc/fstab <<'EOF' /dev/mapper/cryptroot / ext4 defaults,noatime 0 1 LABEL=boot /boot ext2 defaults 0 2 tmpfs /tmp tmpfs defaults,nosuid,nodev,size=512M 0 0 EOF # DHCP on the virtio NIC. Confirm the name with `ip -br link` first. echo 'IP=:::::ens3:dhcp' >> /etc/initramfs-tools/initramfs.conf echo 'DEVICE=ens3' >> /etc/initramfs-tools/initramfs.conf如果你不想暴露哪些块处于未使用状态,就从 crypttab 那一行去掉
,discard。如果要用静态地址而不是 DHCP,字段顺序是IP=<ip>::<gateway>:<netmask>::<iface>:off。 - 把解锁密钥放进 initramfs,并把 Dropbear 锁紧
只有放在这里的密钥才能在启动时解锁机器。让它和你日常使用的 SSH 密钥分开存放,这样丢一个也不会两个一起丢。
install -d -m 0755 /etc/dropbear/initramfs cat > /etc/dropbear/initramfs/authorized_keys <<'EOF' ssh-ed25519 AAAAC3Nza... unlock@laptop EOF chmod 0600 /etc/dropbear/initramfs/authorized_keys cat > /etc/dropbear/initramfs/dropbear.conf <<'EOF' DROPBEAR_OPTIONS="-p 2222 -s -j -k -I 180 -c cryptroot-unlock" EOF update-initramfs -u -k all dropbearkey -y -f /etc/dropbear/initramfs/dropbear_ed25519_host_key | grep -i fingerprint-p 2222让解锁服务不占用 22 端口,这样就不会和运行中系统的 sshd 冲突;-s禁止密码登录,-j和-k禁用端口转发,-I 180会断开空闲会话,-c cryptroot-unlock则让任何成功的登录都直接进入密码短语提示符。现在就把这个指纹记下来——这是你确认自己正在跟自己的 initramfs 通信的依据。在 Debian 11 及更早版本上,这些文件改放在/etc/dropbear-initramfs/里。 - 安装引导程序、设置 root 密码、重启
GRUB 要装在整块磁盘上,而不是某个分区上。因为
/boot是未加密的,所以不需要GRUB_ENABLE_CRYPTODISK。grub-install /dev/vda update-grub passwd root echo 'cryptovps' > /etc/hostname exit # leave the chroot umount -R /mnt cryptsetup close cryptroot reboot然后在面板里把服务器切出救援模式,让它从磁盘启动。这第一次启动时把 noVNC 控制台开着——如果 initramfs 起来后没有网络,你能在那里直接看到,从而去修正接口名,而不是靠猜。
- 远程解锁,并确认这个卷确实是加密的
等大约三十秒,然后连到 initramfs 的 2222 端口。把它的主机密钥单独固定在一个文件里,不要和你平时用的 known_hosts 混在一起。
ssh -p 2222 -o UserKnownHostsFile=~/.ssh/known_hosts.initramfs \ -i ~/.ssh/id_ed25519_unlock root@<server-ip> # the passphrase prompt appears immediately; type it, the session closes, # and the machine finishes booting into the decrypted root. # once you are in the running system: lsblk -o NAME,FSTYPE,MOUNTPOINT cryptsetup status cryptroot cryptsetup luksDump /dev/vda2 | head -20cryptsetup status应该会报告type: LUKS2、cipher: aes-xts-plain64和keysize: 512 bits。现在去做那两件所有人都会拖延的事:把 LUKS 头部备份到服务器之外,并添加第二个密钥槽。然后特意再重启一次,证明在你不指望它出错的时候,这条解锁路径确实能用。
三种加密方式,各自要付出什么代价
| 方案 | 加密范围 | 下一次重启时 | 搭建成本 | 适合场景 |
|---|---|---|---|---|
| 加密数据卷 | LUKS 容器内的一棵目录树 | 服务器正常启动;手动打开容器 | 约 10 分钟,无需救援模式 | 单个敏感数据集——邮件目录、数据库、归档文件 |
| 加密根卷 + 通过 SSH 远程解锁 | 除 /boot 外的一切——日志、交换分区、缓存、历史记录 | 启动会在 initramfs 中暂停,直到你通过 SSH 登录并输入密码短语 | 约 1 小时,需从救援模式安装 | 整机状态都敏感、且你能守着重启的机器 |
| 加密根卷 + Clevis/Tang | 除 /boot 外的一切 | 只要能连上你的 Tang 服务器就会自动解锁;连不上就彻底卡住 | 约 1 小时,外加一台你自己掌控的服务器 | 可用性比最后一点保密性更重要的无人值守机器 |
常见问题解答
CryptoVpsHost 能读到我服务器上的数据吗?
在服务器运行期间,原则上可以——任何虚拟化基础设施的提供商都可以,包括那些嘴上说不能的。已解锁的 LUKS 卷的主密钥驻留在内核内存里,而内存归虚拟化平台所有。LUKS 能排除掉的是其余的一切:关机状态的卷、报废的硬盘、被复制的镜像、备份。我们不替你加密磁盘,正是因为我们手上握着的密钥,就是我们可能被迫交出的密钥,我们宁愿把这一点说清楚,也不想卖一个勾选框给你。如果你的威胁模型里包含正在运行的机器的运营方,那不管是谁家的磁盘加密功能,都解决不了这个问题。
全盘加密会拖慢 VPS 的速度吗?
在带有 AES-NI 的硬件上几乎感觉不到——而我们所有机器都是这样。跑一下 cryptsetup benchmark,你会看到 aes-xts 每核每秒能到几个 GB,远高于一块 NVMe 卷的需求。真正能测出来的代价,是小块随机写入时多一点延迟和 CPU 占用,而不是吞吐量。在 NVMe 上,设置 --perf-no_read_workqueue 和 --perf-no_write_workqueue,再配合 --persistent,能去掉剩下的大部分开销。
如果我把密码短语弄丢了会怎样?
数据就没了。没有恢复手段,没有托管在别处的主密钥,也没有哪张工单能改变这一点——我们从来就没留过副本。这正是你在为之付费的特性,也是为什么本指南两次提到:在往卷里放真正的数据之前,先把 LUKS 头部备份到服务器之外,再用一条不同的长密码短语添加第二个密钥槽。一个只存在于一个地方——哪怕只是存在你自己脑子里——的密码短语,就是一个单点故障。
/boot 也会被加密吗?
不会,这是正常的。内核和 initramfs 必须先能被读取,之后才谈得上向你要密码短语,所以它们放在一个小的明文分区里。GRUB 可以借助 GRUB_ENABLE_CRYPTODISK 读取加密的 /boot,但这只是把问题挪了个位置——它之前的引导阶段仍然是明文的。诚实的说法是:LUKS 给你的是静态数据的机密性,不是启动链的完整性。如果离线篡改 /boot 也在你的威胁模型之内,就在每次内核更新后给它算一次哈希,并从机器外部进行核验。
服务器能不能在我什么都不输入的情况下重启?
只有在你给它一种获取密钥的途径时才行,而这必然会削弱原本的保证。比较干净的做法,是用 Clevis 绑定到你在另一个司法辖区自行掌控的一台机器上的 Tang 服务器:只要能连上 Tang,VPS 就会自动解锁;连不上就彻底卡住——这同时也充当了一个远程“熔断开关”。请通过 WireGuard 或 Tor 洋葱服务访问 Tang,而不是走公网,并且在第二个密钥槽里保留一个密码短语,这样 Clevis 就不会是你唯一的进入方式。
这套方法只能用在 Debian 上,还是任何操作系统镜像都行?
任何带救援模式的 Linux 镜像都能用;这里的命令是 Debian 13 的,可以直接照搬到 Ubuntu 24.04 上。在 Rocky、Alma 和 Fedora 上,工具链是 dracut 而不是 initramfs-tools,所以远程解锁用的是 dracut-crypt-ssh 模块,或者一个启用了网络功能的 dracut initramfs,而不是 dropbear-initramfs——LUKS 那一侧的做法是一样的。如果你完全不想从救援 shell 里手动搭建,也可以上传一个最大 4 GiB 的自定义 ISO,用你所选发行版自带的安装程序,它会把加密 LVM 作为标准选项提供给你;之后你再补上远程解锁即可。