我有一个设置,我的可移动设备包含一个带有加密数据的分区,上面没有其他东西可以将其与随机数据区分开来。在物理上独立的设备上,我有一对使用 GPG 加密密钥打开/关闭设备的脚本:
打开.sh
#!/bin/bash
# The crypt UUID is hard-coded. That way it will not try to decrypt the wrong
# device.
cryptuuid='xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
# The UUID of the decrypted device is hard-coded. This is currently how the
# script knows what to mount after decrypting.
deviceuuid='yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy'
# The encrypted key bits are fed to cryptsetup with specific parameters to
# decrypt the crypt.
gpg2 --decrypt <<- END | sudo cryptsetup --offset 0 --cipher aes-xts-plain64 --key-size 256 --hash sha256 --key-file - open --type plain "/dev/disk/by-partuuid/$cryptuuid" Secrets
-----BEGIN PGP MESSAGE-----
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
zzzzz
-----END PGP MESSAGE-----
END
# A small delay is necessary to give time for the decrypted device to show up.
sleep 1
# Mount the decrypted device as if the user did it using the GUI.
gvfs-mount -d $(readlink -f $(blkid -U "$deviceuuid"))
关闭.sh
#!/bin/bash
# The UUID of the decrypted device is hard-coded. This is currently how the
# script knows what unmount.
deviceuuid='yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy'
# Find all processes using the decrypted device and issue a “friendly” kill
# signal.
sudo lsof -t $(findmnt -rn -S UUID="$deviceuuid" -o TARGET) | while read process; do kill -HUP $process; done
# Try to unmount the decrypted device and then close it with cryptsetup. findmnt
# identifies the path which the device is mounted. lsblk finds the decrypted
# device (minus “/dev/” from the UUID). dmsetup finds the decrypted device name
# given the block device name from before.
gvfs-mount -u $(findmnt -rn -S UUID="$deviceuuid" -o TARGET) && sudo cryptsetup close $(sudo dmsetup info --columns --noheadings --options Name --select BlkDevName=$(lsblk --raw --noheadings --output KNAME,UUID | awk '{if ($2=="'"$deviceuuid"'") { print $1}}'))
这些脚本有效,但理想情况下,我希望尽可能多地利用对加密分区的内置 GUI 支持,从而减少终端的使用。
为了更接近这一目标,我研究了逻辑卷管理器 (LVM) 的 JBOD 功能。我们的想法是拥有一个显示在文件管理器中的 LUKS 分区,但同时也要使 LUKS 标头远离加密数据,使加密数据与随机数据无法区分。
为了实现这一目标,我使用了两卷:
- 一份文件标题.img(正好 2,139,648 字节)
- 物理设备/dev/sdx
标题.img包含一个 GPT 分区,该分区托管一个足以容纳整个 LUKS 标头的 LVM PV。/dev/sdx包含一个 GPT 分区,该分区托管包含加密数据的 LVM PV。
它们是使用以下步骤创建的:
fallocate -l 2139648 header.img
创建一个图像来保存第一个 PV。- 我装载该映像并在其中为 PV 创建一个 4,112 扇区的 GPT 分区(GUID:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)。
sudo pvcreate --labelsector 0 --metadatatype 2 --pvmetadatacopies 1 --metadatasize 32768b --dataalignment 512b /dev/disk/by-partuuid/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
创建标头的物理卷。- 对于设备(如/dev/sdx)在我想要存储加密数据的地方,我确定所需的分区对齐方式,并在 LVM 标头的开头添加一个扇区。如果 SSD 驱动器预格式化了一个从扇区 65536 开始的分区,请删除该分区并从扇区 65535 开始创建一个分区。这样,文件系统仍将保持最佳对齐。
sudo pvcreate --labelsector 0 --pvmetadatacopies 0 --metadatasize 0b --dataalignment 512b '/dev/disk/by-partuuid/yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy'
创建一个仅包含 LVM 标头但没有元数据的物理卷。vgcreate --metadatacopies unmanaged --physicalextentsize 512b Secrets '/dev/disk/by-partuuid/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' '/dev/disk/by-partuuid/yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy'
在这两个物理卷之上创建一个卷组。lvcreate --contiguous n --extents 100%FREE Secrets --name Crypt
创建一个占用卷组中所有可用空间的逻辑卷。- 现在我遇到的一个特殊问题是,如果我将任何数据写入逻辑卷,则总是首先写入最大的物理卷。这很糟糕,因为我希望将 LUKS 标头写入 2 个物理卷中较小的一个。我通过将卷组的数据导出到文本文件来修复它,我可以在其中重新排序物理卷:
vgcfgbackup -f metadata.txt Secrets
。 - 编辑生成的文本文件非常简单。在该
logical_volumes
部分下,应该有 2 个段,命名如下:segment1
和segment2
。您需要编辑每个项下的start_extent
和值。必须有和.并且必须等于较大的物理卷- 您可以在 参考资料 部分中找到该卷。你extent_count
segment1
start_extent = 0
extent_count = 4040
segment2
start_extent = 4040
extent_count
pe_count
physical_volumes
可能需要交换pv0
和pv1
周围,但请仔细检查卷定义以确保它们是合理的。 vgcfgrestore -f metadata.txt Secrets
会将您的更改应用到卷组。cryptsetup --verbose --cipher aes-xts-plain64 --key-size 512 --hash sha512 --align-payload 1 luksFormat /dev/Secrets/Crypt
创建 LUKS 加密卷。- 打开新的加密卷并执行需要执行的操作。
- 弹出:卸载加密卷上的任何文件系统,将其关闭,然后运行
vgchange -an Secrets
。然后,您可以分离和/或弹出物理卷。
什么时候/dev/sdx被插入并且标题.img使用磁盘工具安装时,启动器上会显示一个图标,单击该图标时会提示输入密码以解锁该卷;除逻辑卷未注册的随机情况外,任何步骤都不需要终端。然后运行vgscan --mknodes
和udevadm trigger
似乎可以解决打嗝问题。
问题是,卸载卷时,在删除循环设备并弹出加密存储之前,我还必须使用终端停用 LVM 卷组 (VG)。物理移除存储介质似乎不会使卷组消失,并且会阻止循环设备被卸载。
我对解决设备删除问题感到满意,但我认为仅通过创建和维护这样的设置就使事情变得过于复杂。
目前是否有任何 Linux 发行版支持易于使用的多因素全磁盘加密?