在 VPS 上使用全盘加密(LUKS)时,安装 Dropbear 是唯一的“救命稻草”。它会在系统内核启动、但尚未挂载加密根分区时,先运行一个微型 SSH 服务,让你远程输入解锁密码。
以下是在 Debian 13 上配置 Dropbear 远程解锁的完整手册:
1. 安装 Dropbear 核心组件
在已经安装好加密 Debian 系统的环境下,执行:
apt update
apt install dropbear-initramfs -y
2. 配置 SSH 密钥 (关键)
由于这个环境非常早,Dropbear 默认禁用了密码登录(为了安全且简化配置)。你需要将你本地电脑的 SSH 公钥放入其配置文件中。
- 复制你的公钥:通常位于你本地电脑的
~/.ssh/id_rsa.pub。 写入 Dropbear 配置:
# 编辑 Dropbear 的授权密钥文件 nano /etc/dropbear/initramfs/authorized_keys
将你的公钥内容(以 ssh-rsa 或 ssh-ed25519 开头的一长串)粘贴进去并保存。
3. 设置网络与端口配置
因为 Dropbear 运行在系统完全启动之前,它可能需要手动指定 IP 地址(如果你的 VPS 不支持 DHCP)。
编辑配置文件:
nano /etc/dropbear/initramfs/dropbear.conf
- 修改端口(建议改为 2222,避免与系统正式的端口冲突):
DROPBEAR_OPTIONS="-p 2222" - 配置静态 IP(如果 VPS 重启后没网):
编辑/etc/initramfs-tools/initramfs.conf,找到IP=这一行,按以下格式填写:IP=DEVICE_IP::GATEWAY_IP:NETMASK:HOSTNAME:INTERFACE:off
*例如:IP=1.2.3.4::1.2.3.1:255.255.255.0:pve:eth0:off*
4. 更新 Initramfs
所有的更改都必须重新打包进引导镜像才能生效:
update-initramfs -u
5. 远程解锁流程
当你重启 VPS 后,系统会停在要求输入加密密码的界面。此时,你在本地电脑操作:
连接 Dropbear:
ssh root@你的VPS-IP -p 2222输入解锁命令:
登录成功后,你会看到一个简单的 Shell。输入以下命令:cryptroot-unlock- 输入密码:此时输入你安装系统时设置的 LUKS 密码。
- 自动断开:密码正确后,Dropbear 会自动关闭并断开连接,VPS 将继续完成正常的系统启动流程。
💡 避坑指南
- Host Key 冲突:当你连接端口 2222 时,SSH 可能会提示“Host identification has changed”,因为 Dropbear 的密钥和系统正式 SSH 的密钥不同。建议在本地连接时使用:
ssh -o "UserKnownHostsFile=/dev/null" -o "StrictHostKeyChecking=no" root@IP -p 2222 - 网卡名称:Debian 13 默认网卡名通常是
enp0s3或eth0,请通过ip link确认后再填入配置。
多次输入密码错误后
会进入 initramfs ,系统实际上是停留在了一个极其简化的内存操作系统中。因为 LUKS 解密失败(密码错误),内核无法挂载真正的根分区,所以才把你丢进了这个 Shell。
要手动解密并继续启动,请按照以下步骤操作:
1. 确认加密分区路径
首先,你需要知道哪个分区是被加密的。输入以下命令查看:
Bash
ls /dev/sd*
# 或者如果是 NVMe 硬盘
ls /dev/nvme*通常,加密分区会是类似 /dev/sda3 或 /dev/nvme0n1p3 这种较大的分区。
2. 手动解密 LUKS 分区
使用 cryptsetup 命令手动打开分区。你需要给解密后的设备取个名字(通常建议用 root 或系统默认的映射名):
Bash
cryptsetup open /dev/sdaX root注意:将 /dev/sdaX 替换为你上一步找到的分区。执行后,系统会再次提示你输入 LUKS 密码。3. 处理 LVM (如果使用了 LVM)
大部分 Linux 发行版(如 Debian, Ubuntu, Proxmox, Manjaro)在加密分区内会使用 LVM。如果解密成功后依然没有自动继续,你需要激活逻辑卷:
Bash
lvm vgscan
lvm vgchange -ay这会扫描并激活解密后的卷组(如 pve 或 vg0)。
4. 退出 initramfs 并继续引导
一旦分区解密且映射成功(你可以检查 /dev/mapper/ 目录下是否存在解密后的设备),只需退出当前的 Shell,内核就会尝试重新挂载根目录并继续启动过程:
Bash
exit或者按下 Ctrl + D。
常见故障排查
- 找不到 cryptsetup 命令:如果
initramfs里没有这个命令,说明你的initramfs镜像可能损坏或构建不全。这种情况通常需要通过 Live CD(如 Ubuntu 安装盘或 SystemRescue)挂载并修复。 - 映射名称错误:如果你的
/etc/fstab指向的是/dev/mapper/sda3_crypt而你手动映射成了root,可能会导致启动脚本找不到设备。你可以尝试重启再次进入initramfs,观察报错信息中提到的设备名称,并在cryptsetup open时使用该名称。
启动成功后,建议运行 update-initramfs -u(Debian/Proxmox)或 mkinitcpio -P(Manjaro/Arch)来更新你的引导镜像,防止配置不匹配。
在没有物理内网、所有机器都直接暴露在公网的情况下,远程解锁 LUKS 面临着极大的安全风险(无论是暴露 Dropbear 的 SSH 端口,还是暴露 Tang 服务器的 HTTP 端口)。
为了确保只有受信任的节点才能进行干预,你可以采用以下几种维度的防御策略,将风险降到最低:
方法一:最轻量——SSH 密钥的 from 限制 (针对 Dropbear)
如果你继续使用 Dropbear,最快、最简单的防护是在 authorized_keys 层面做文章。OpenSSH 和 Dropbear 都支持在公钥前添加限制参数。
打开 /etc/dropbear/initramfs/authorized_keys,在你的公钥最前面加上 from="允许的IP" 限制:
Plaintext
from="212.60.X.X,198.51.X.X",no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1...- 原理: 即使攻击者(或者未授权的服务器)拿到了你的私钥,只要它的出口 IP 不在
from列表里,Dropbear 也会直接拒绝连接。 - 局限: 端口依然对公网敞开(容易被扫描器打满连接数),且要求你的主控机拥有固定的公网 IP。
方法二:最安全——在 initramfs 中打通虚拟内网 (Overlay Network)
既然没有物理内网,最好的办法是自己造一个安全的虚拟内网。在服务器进入 initramfs 阶段时,不直接绑定公网 IP 等待连接,而是主动向外拨号,建立一条加密隧道(例如 WireGuard Site-to-Site 隧道)。
- 通过安装特定的钩子(如
wireguard-initramfs相关的包或自定义脚本),把 WireGuard 客户端打包进引导镜像。 - 在 GRUB 阶段完成基本的公网联网后,initramfs 脚本立即启动 WireGuard 接口(例如
wg0),并分配一个内网 IP(如10.0.0.2)。 - 配置 Dropbear 仅仅监听这个内网 IP:
DROPBEAR_OPTIONS="-p 10.0.0.2:2222"。
- 优势: 你的服务器在未解锁前,对公网是绝对“隐身”的(没有任何端口对外开放)。只有已经在这个 WireGuard 隧道网络内的节点,才能通过
10.0.x.x连入 Dropbear 或访问 Tang 服务器。 - 架构契合度: 这种方案非常适合跨多个 VPS 提供商的分布式集群,能把所有分散的公网节点统一到一个安全的逻辑内网中。
方法三:企业级改造——Tang + mTLS 双向认证 (针对自动化解锁)
如果你决定抛弃手动 SSH,改用 Clevis + Tang 的自动化方案,由于标准的 Tang 是基于明文 HTTP 的,直接放公网无异于“裸奔”。
在公网环境部署 Tang,必须加一层反向代理(如 Nginx/HAProxy)并强制开启 mTLS(双向 TLS 认证):
- Tang 服务器本身只监听
127.0.0.1。 - 前端 Nginx 配置 HTTPS,并要求客户端(等待解锁的服务器)提供有效的客户端证书。
- 在需要解锁的服务器上,将客户端证书打包进 initramfs。当 Clevis 发起 HTTP 请求去拿密钥时,Nginx 会先验证证书。
- 如果没有合法的客户端证书,任何人访问这个 URL 都会直接收到
403 Forbidden。
方法四:硬核网络拦截——initramfs 注入防火墙规则
默认情况下,initramfs 环境里是没有完整 iptables 或 nftables 的,所以很多公网机器在引导阶段处于不设防状态。如果你不想搞复杂的虚拟内网,可以手动把网络过滤工具塞进去。
可以在 /etc/initramfs-tools/scripts/init-premount/ 目录下写一个脚本:
- 将静态编译的
iptables或busybox路由规则打包进去。 - 在脚本中写入规则,直接在内核层丢弃所有目标端口为 2222 的包,除非源 IP 是你指定的跳板机。
核心建议:
如果你仅仅是为了偶尔的故障排查,方法一(authorized_keys 限制)+ 更改 Dropbear 默认端口(避开 22 端口扫描)已经能挡住绝大多数盲目攻击。
这个方案需要配合上面的防御/防火墙操作
每次服务器重启或者更新内核后,都要手动 SSH 连进去敲一遍 LUKS 密码,确实非常繁琐。
如果你希望实现自动化解锁,有两条完全不同的技术路线:一条是继续利用你现有的 Dropbear 环境进行“外部注入”,另一条是引入更现代的密钥绑定机制(完全替代手动输入)。
以下是三种最主流的自动化方案,你可以根据你的安全需求和服务器架构来选择:
方案一:主控机脚本自动注入 (保留 Dropbear 的最快方法)
既然你的 Dropbear 已经配置好了公钥登录,你可以利用另一台 24 小时开机的机器(比如你的跳板机、软路由或集群中的其他节点),写一个脚本定时探测目标机器是否处于 initramfs 状态,如果是,则自动通过 SSH 管道注入密码。
在 Debian/Ubuntu 的 initramfs 环境中,cryptroot-unlock 实际上是从一个名为 passfifo 的命名管道读取密码的。你可以直接把密码 echo 进这个管道,不需要任何交互。
自动化脚本示例 (运行在主控机上):
Bash
#!/bin/bash
TARGET_IP="212.60.X.X"
PORT="22" # 你的 Dropbear 端口
LUKS_PASS="你的超复杂LUKS密码"
# 检查目标是否开放了 SSH 端口 (使用 nc)
if nc -z -w 2 $TARGET_IP $PORT; then
# 尝试连进去看看是不是在 initramfs 阶段 (比如检查是否有 cryptroot 提示)
IS_INITRAMFS=$(ssh -o StrictHostKeyChecking=no -p $PORT root@$TARGET_IP "test -e /lib/cryptsetup/passfifo && echo YES || echo NO")
if [ "$IS_INITRAMFS" == "YES" ]; then
echo "检测到目标处于 LUKS 锁定状态,正在自动解锁..."
# 将密码直接写入目标机的 passfifo 管道
echo -n "$LUKS_PASS" | ssh -o StrictHostKeyChecking=no -p $PORT root@$TARGET_IP "cat > /lib/cryptsetup/passfifo"
echo "解锁指令已发送。"
fi
fi- 优点: 不需要修改目标机的现有配置,立刻就能用。
- 缺点: 你的 LUKS 明文密码需要以某种形式(哪怕是加密文件)存在于另一台主控机上。
方案二:Clevis + Tang (NBDE 网络绑定磁盘加密 - 企业级推荐)
如果你管理着多个节点,最推荐的做法是抛弃 Dropbear 手动输入,改用 NBDE 架构。
它的原理是:你在内网(或安全通道)部署一个非常轻量级的 Tang 服务器。目标机在 initramfs 阶段启动时,Clevis 客户端会自动联网,向 Tang 服务器请求解密密钥。
- 如果机器在你的机房/内网里: 它可以连上 Tang 服务器,自动获取密钥,无感启动。
- 如果机器被拔盘或整机被盗走: 离开你的网络环境后,它连不上 Tang,LUKS 将保持死锁状态。
实施思路:
- 找一台安全的机器安装并启动
tang。 - 在目标机上安装
clevis、clevis-luks和clevis-initramfs。 - 将 LUKS 的一个新 Slot 绑定到 Tang 服务器:
Bash
clevis luks bind -d /dev/sdaX tang '{"url":"http://<tang-server-ip>"}'- 更新 initramfs。下次重启时,它会自动联网解锁(此时你可以将 Dropbear 作为 Tang 服务器宕机时的紧急后备入口)。
方案三:TPM 2.0 自动解锁 (最省事,但改变了威胁模型)
如果你的服务器有 TPM 2.0 芯片,你可以直接将 LUKS 的解密密钥封存到 TPM 硬件中。
启动时,内核会检查硬件环境(如 Secure Boot 状态、BIOS 设置等 PCR 寄存器)。如果硬件环境未被篡改,TPM 会自动释放密码解密磁盘。
实施思路:
Bash
# 假设你的根分区是 /dev/sda2
systemd-cryptenroll --wipe-slot=tpm2 --tpm2-device=auto --tpm2-pcrs=7 /dev/sda2然后在 /etc/crypttab 中添加 tpm2-device=auto 参数并更新 initramfs。
- 注意其安全边界: 这种方案防的是“硬盘被拔走插到别的机器上”。如果你防范的威胁是“别人把你整台服务器连带主板一起抱走”,TPM 会在你不知道的情况下自动解锁进入系统。因此,这种方案通常用于对物理安全性有一定保障的机房服务器,仅仅是为了免去重启敲密码的麻烦。
总结建议:
如果你只想要个快速的“补丁”方案,用方案一写个看门狗脚本是最快的。如果你希望从架构上解决这个问题,让多台服务器实现优雅的无人值守重启,方案二 (Clevis+Tang) 是 Linux 圈目前最成熟的最佳实践。
附注(Ray): https://ytai.de/t/topic/95