我的公司正在为一些新的测试工作实施一些 Ubuntu 系统,我被委托为他们提供加密解决方案。作为一个主要使用 Windows 的用户,我对 Ubuntu 和 Linux/Unix 有一些基本的了解,这有点挑战性,但也很有趣。我知道许多现有的加密服务适用于 Windows,但我发现 Ubuntu 缺少这些服务,在阅读了 20 多篇关于它的帖子后,我决定全新安装并进行全盘加密是唯一现实的选择。话虽如此,有些系统已经在使用中,不能只是擦除并全新安装并进行加密。我需要复制/备份所有设置和更改以及现有文件。因此,这并不像复制 /home 那么简单。我很好奇对我来说最好的行动方案是什么,我有一份完整的分区副本(使用 gparted 快速复制到外部)用于我的测试机器,并全新安装了带有 LUKS 的 Ubuntu。我熟悉 clonezilla 的基础知识,但从我所收集的信息来看,我认为这对我不会有帮助。
tldr:我需要将 Ubuntu 16.04 的完整安装移至加密磁盘。有些机器会启用 TPM,有些则不会,我需要知道每种机器的最佳操作方案。感谢您帮助新管理员。
如果您能描述一种不需要外部网络访问但不是必需的方法,那就更好了。也就是说,如果它需要一个包,我可以在测试电脑上将其下载到 USB/CD/DVD 上,然后离线安装该包。
答案1
下面描述的是我多次成功使用的过程。它适用于 Ubuntu 16.04 和 18.04。与 @Arno 在其答案中提出的解决方案不同,它不需要手动编辑内核启动选项。相反,它依赖于update-grub
基于/etc/crypttab
- 更规范(无意双关)的解决方案生成正确的配置,Ubuntu 在使用其默认的基于 LVM 的加密进行安装时也使用该解决方案。(此解决方案不使用 LVM 也不加密/boot
)
我对按照本指南操作导致的任何数据丢失或其他潜在不良后果概不负责。在执行任何操作之前,请确保您有可靠的备份。
我在写这篇文章时并没有测试本指南。它基于(经过测试的)我自己写的博客文章关于有些类似的情况和我记得的一些细节。
本指南假设:
- Ubuntu 已安装
- 系统使用 (U)EFI 启动,而不是 BIOS/CSM
/boot
位于单独的分区1- 你可以启动 Ubuntu 16.04/18.04 或 Pop!_OS 18.04 的实时媒体(从 USB、PXE、DVD 等)2
如果您/boot
不在单独的分区上,则提取它非常简单:在任何地方创建一个 200-500 MB 的分区,将其格式化为 ext4,复制当前/boot
内容,添加/etc/fstab
条目,update-grub
然后重新启动。
1. 备份
您必须备份当前系统分区。最简单的方法是使用 Clonezilla。它是用户友好的,无需手册 - 只需按照说明操作即可。
2. 缩小分区
LUKS 标头占用了分区上的部分空间。Clonezilla/partclone 无法将映像恢复到比源设备小的设备,因此您无法将未加密分区的映像恢复到加密容器,因为它要小一点。
然后我们必须稍微缩小要加密的分区。为了安全起见,将它们缩小 10 MB 或更多。最简单的方法是使用 GParted。它在 Ubuntu Live 媒体上可用。
3. 制作缩小分区的镜像
要么再次使用 Clonezilla 执行此操作,要么已经熟悉部分克隆,这是 Clonezilla 默认使用的。稍后我们将使用 partclone 手动恢复映像。
使用 partclone 克隆到图像:
sudo partclone.ext4 -c -s /dev/sda2 | pigz -0 > /mnt/backup/sda2.ext4.ptcl.gz
partclone.ext4
是 partclone 的二进制文件之一,专用于与 ext4 配合使用。每个受支持的文件系统都有自己的 partclone 二进制文件。/dev/sda2
显然是您要克隆的分区。我更喜欢通过分区的 partlabel 来引用分区,例如/dev/disk/by-partlabel/os
- 在我看来更简洁。/dev/sda2
不过更容易识别。猪是多核 gzip。
-0
告诉它优先考虑速度而不是有效压缩。/mnt/backup
这里代表您想要存储图像的某个外部位置。如果您以前使用过 Clonezilla,它仍然可以安装在 下/home/partimag
。如果您想安装 SMB 共享:(sudo mount -t cifs -o username=gronostaj //192.168.1.90/Backup /mnt/backup
以交互方式询问密码)
4. 将分区扩大至原始大小
我们想为 LUKS 标头保留额外的空间,不是吗?将分区调整回其原始大小。
5. 格式化为 LUKS
此时,您就会丢失原始数据。请确保您的备份完好无损。
将系统分区(除)格式化/boot
为 LUKS:
sudo cryptsetup luksFormat --type luks2 /dev/sda2
打开创建的容器:
sudo cryptsetup open /dev/sda2 os
确保整个加密容器看起来像随机垃圾,并且旧数据仍然不可读:
sudo dd if=/dev/zero of=/dev/mapper/os bs=1M
(这将用零覆盖容器的解密内容,但加密内容看起来像随机垃圾)
6. 恢复图像
手动运行 partclone 来恢复图像:
cat /mnt/backup/sda2.ext4.ptcl.gz | pigz -d | sudo partclone.ext4 -r -o /dev/mapper/os
如果您选择了简单的方法,并使用 Clonezilla 制作了“缩小”备份,请查看其输出文件,您将轻松找出哪些是部分克隆源。除非您设置了巨大的块大小,否则它们将被分割成碎片,您必须将cat
它们放在一起,然后再传输到 pigz。
您还应该调整文件系统几何以适合整个分区:
sudo resize2fs /dev/mapper/os
7. 启用加密支持
首先,chroot 到刚刚恢复的操作系统:
mkdir /mnt/os
sudo mount /dev/mapper/os /mnt/os
cd /mnt/os
mount --bind /etc/resolv.conf etc/resolv.conf
mount --bind /dev dev
mount -t tmpfs tmpfs tmp
mount -t sysfs sys sys
mount -t proc proc proc
sudo chroot .
mount -a
此终端现在正在您安装的 Ubuntu 实例上运行,而不是实时实例。
安装密码设置:
apt update
apt install cryptsetup -y
它应该会创建一个文件/etc/crypttab
。如果没有,不用担心,请手动创建。编辑此文件并添加分区条目:
os /dev/sda2 none luks
保存并退出编辑器。重建 initramfs:
update-initramfs -u -k all
更新 GRUB 条目:
update-grub
8. 删除多余的密码提示
如果您有多个加密分区,则必须在启动时输入每个分区的密码。但是,LUKS 允许您添加可用于解锁分区的额外密钥文件,而不是密码。您可以将这些密钥文件存储在加密/
分区上,并使用它来解锁后续分区。
创建随机密钥文件:
dd if=/dev/urandom of=/luks.key bs=4096 count=1
将其添加到非根分区:
cryptsetup luksAddKey /dev/sda3 /luks.key
添加crypttab
条目:
home /dev/sda3 /luks.key luks
重建 initramfs:
update-initramfs -u -k all
1我为什么使用单独的/boot
:
- 这样比较简单 ;)
- GRUB 尚不支持 LUKS2,因此
/boot
不能位于 LUKS2 加密分区上 - 如果你想要 LUKS 加密
/boot
和 LUKS2 加密/
,那么你必须输入两次密码或在 initramfs 中嵌入密钥文件- 在我看来太麻烦了,因为...... - 加密
/boot
本身并不能降低你的攻击风险,因为即使你的/boot
EFI 系统分区是加密的,你的 EFI 系统分区也不能加密,所以攻击者可以篡改它,例如使用他们自定义的恶意内核/initramfs 来代替你的/boot
。(要解决这个问题,你必须构建一个自容器 GRUB 二进制文件并使用你的私钥对其进行签名,然后使用 UEFI 安全启动来验证)
定义您自己的威胁模型并决定您需要什么级别的安全性(以及针对什么)。
2你可以尝试使用其他 Ubuntu 版本或救援 CD,例如几何模型,但您的情况可能会有所不同。我曾遇到过此过程失败的情况,只是因为实时媒体与系统不匹配。
答案2
您可以对根分区进行映像处理,使用 LUKS 对其进行格式化,然后将其挂载并用映像覆盖。然后需要对 GRUB 进行一些更改,以便它在启动时对其进行解密。我还没有测试过以下步骤,它们只是一条线索。
我假设是/boot
打开的sdb1
,根分区已打开sdb2
并且/media/hdd
是外部驱动器。我们在管理员提示符下使用 Live USB。
加密根分区
dd if=/dev/sdb2 of=/media/hdd/diskimg bs=1M
cryptsetup luksFormat /dev/sdb2
cryptsetup luksOpen /dev/sdb2 enc_root
dd if=/media/hdd/diskimg of=/dev/mapper/enc_root
挂载分区
mount /dev/sdb2 /mnt
mount /dev/sdb1 /mnt/boot
配置 GRUB
通过运行以下命令记下分区的 UUID:
blkid /dev/sdb2
编辑/mnt/etc/default/grub
,找到显示 的行GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
。将其更改为以下内容,替换device-UUID
为您在上一步中记下的 UUID。
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash cryptdevice=UUID=device-UUID:enc_root root=/dev/mapper/enc_root"
然后更新 GRUB 配置:
mount --bind /dev /mnt/dev
mount --bind /sys /mnt/sys
mount --bind /proc /mnt/proc
chroot /mnt
update-grub
exit
卸载所有东西:
umount /mnt/dev
umount /mnt/sys
umount /mnt/proc
umount /mnt/boot
umount /mnt
然后重启。有几个陷阱:
- 我还没有测试过这些,而且已经有一段时间没有使用 Linux 分区了,所以我几乎可以肯定我忘记了或者搞砸了一些东西。等待人们校对并修复它。
- 这假设它
/boot
是在一个单独的分区上,如果所有内容都在同一个分区上,它将无法工作。 - 在 UEFI 系统上,不要忘记将 EFI 分区挂载到其所属的位置。
dd
将复制一切包括可用空间,更快捷的方法是仅复制分区中的文件。
祝你好运!