打开.sh

打开.sh

我有一个设置,我的可移动设备包含一个带有加密数据的分区,上面没有其他东西可以将其与随机数据区分开来。在物理上独立的设备上,我有一对使用 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 标头远离加密数据,使加密数据与随机数据无法区分。

为了实现这一目标,我使用了两卷:

  1. 一份文件标题.img(正好 2,139,648 字节)
  2. 物理设备/dev/sdx

设置说明

标题.img包含一个 GPT 分区,该分区托管一个足以容纳整个 LUKS 标头的 LVM PV。/dev/sdx包含一个 GPT 分区,该分区托管包含加密数据的 LVM PV。

它们是使用以下步骤创建的:

  1. fallocate -l 2139648 header.img创建一个图像来保存第一个 PV。
  2. 我装载该映像并在其中为 PV 创建一个 4,112 扇区的 GPT 分区(GUID:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)。
  3. sudo pvcreate --labelsector 0 --metadatatype 2 --pvmetadatacopies 1 --metadatasize 32768b --dataalignment 512b /dev/disk/by-partuuid/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx创建标头的物理卷。
  4. 对于设备(如/dev/sdx)在我想要存储加密数据的地方,我确定所需的分区对齐方式,并在 LVM 标头的开头添加一个扇区。如果 SSD 驱动器预格式化了一个从扇区 65536 开始的分区,请删除该分区并从扇区 65535 开始创建一个分区。这样,文件系统仍将保持最佳对齐。
  5. sudo pvcreate --labelsector 0 --pvmetadatacopies 0 --metadatasize 0b --dataalignment 512b '/dev/disk/by-partuuid/yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy'创建一个仅包含 LVM 标头但没有元数据的物理卷。
  6. vgcreate --metadatacopies unmanaged --physicalextentsize 512b Secrets '/dev/disk/by-partuuid/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' '/dev/disk/by-partuuid/yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy'在这两个物理卷之上创建一个卷组。
  7. lvcreate --contiguous n --extents 100%FREE Secrets --name Crypt创建一个占用卷组中所有可用空间的逻辑卷。
  8. 现在我遇到的一个特殊问题是,如果我将任何数据写入逻辑卷,则总是首先写入最大的物理卷。这很糟糕,因为我希望将 LUKS 标头写入 2 个物理卷中较小的一个。我通过将卷组的数据导出到文本文件来修复它,我可以在其中重新排序物理卷:vgcfgbackup -f metadata.txt Secrets
  9. 编辑生成的文本文件非常简单。在该logical_volumes部分下,应该有 2 个段,命名如下:segment1segment2。您需要编辑每个项下的start_extent和值。必须有和.并且必须等于较大的物理卷- 您可以在 参考资料 部分中找到该卷。你extent_countsegment1start_extent = 0extent_count = 4040segment2start_extent = 4040extent_countpe_countphysical_volumes可能需要交换pv0pv1周围,但请仔细检查卷定义以确保它们是合理的。
  10. vgcfgrestore -f metadata.txt Secrets会将您的更改应用到卷组。
  11. cryptsetup --verbose --cipher aes-xts-plain64 --key-size 512 --hash sha512 --align-payload 1 luksFormat /dev/Secrets/Crypt创建 LUKS 加密卷。
  12. 打开新的加密卷并执行需要执行的操作。
  13. 弹出:卸载加密卷上的任何文件系统,将其关闭,然后运行vgchange -an Secrets。然后,您可以分离和/或弹出物理卷。

什么时候/dev/sdx被插入并且标题.img使用磁盘工具安装时,启动器上会显示一个图标,单击该图标时会提示输入密码以解锁该卷;除逻辑卷未注册的随机情况外,任何步骤都不需要终端。然后运行vgscan --mknodesudevadm trigger似乎可以解决打嗝问题。

问题是,卸载卷时,在删除循环设备并弹出加密存储之前,我还必须使用终端停用 LVM 卷组 (VG)。物理移除存储介质似乎不会使卷组消失,并且会阻止循环设备被卸载。

我对解决设备删除问题感到满意,但我认为仅通过创建和维护这样的设置就使事情变得过于复杂。

目前是否有任何 Linux 发行版支持易于使用的多因素全磁盘加密?

相关内容