使用 USB 密钥对 Debian 8 上的 Linux 根分区进行无密码加密
存储设备(硬盘、便携式记忆棒)上的关键数据的安全性是必要的,这样入侵者就无法窃取敏感信息。在本教程中,我们的重点是 Linux 根文件系统和交换区域的安全性。将使用默认的 Linux 加密功能“LUKS”,这需要在启动时输入密码。因此,我们的下一个目标是在启动时自动向加密卷提供密码。对于旧版本的 Debian 发行版,已经有几篇关于同一主题的文章可用。但是,在本教程中,Debain 8 (Jessie) 版本安装在 VirtualBox VM 上。
Debian 操作系统安装
在本教程中,Debian Jessie 安装在虚拟机上,详细信息如下图所示。同样的过程也适用于“真实”服务器或桌面。
在虚拟机中添加Debian net installer iso文件,启动虚拟机,会出现安装提示。选择“安装”选项开始安装过程。

以下几个屏幕将提示您进行 Debian 的基本设置。从给定列表中选择所需的语言选项。

选择国家或地区,如下图所示。

配置键盘的语言。

基本设置后,安装程序会加载更多组件进行配置。

同样,在安装过程中将配置更多基本设置。
1.设置主机名

2.配置域名

3. 为“root”用户设置密码。


4. 创建除 root 以外的新用户。




5.设置时区

6. 最后,最重要的部分是磁盘的分区。

本文需要对硬盘进行手动分区。因此,在上述提示中选择“手动”选项,并选择所需的硬盘即可启动该过程。

如上图所示,Debian将安装在VM中。按回车键开始对选定的硬盘进行分区,如下图所示。

接受上述消息后将出现以下屏幕。如下截图所示,当前硬盘上没有分区。

按 \enter\ 在虚拟硬盘上创建第一个分区。

我们在硬盘上创建的第一个分区是“/dev/sda1”,用于“/boot”挂载点。

为分区选择主要或逻辑类型。

选择新分区的位置。

挂载点 \/boot\ 如下图所示。

第一个分区已经在硬盘上成功创建。 Linux 内核后来放在\/boot\ 分区中。

在 VM 硬盘上创建的第二个分区是交换分区,交换分区的大小应该是 RAM 大小的两倍。如以下屏幕截图所示,选择剩余的可用空间进行交换。

设置交换分区的大小。

以下屏幕截图显示该分区被选为交换区。

还会在 VM 上创建另一个分区。

Linux 平台的核心分区是在 /(“根”挂载点)的剩余空间上创建的。以下快照显示了“根”分区的大小。

为硬盘上的新分区选择“物理加密卷”选项。

在 Linux 平台上加密分区需要以下屏幕截图中突出显示的选项。

选择“加密物理卷”后的分区设置如下图所示。默认加密方法是 device-mapper (dm-crypt),加密算法是 AES,密钥大小为 256。

在虚拟硬盘上成功创建分区如下图所示。

下面是在 Debian 上选择的加密卷的高级配置。

以下提示说明当前分区方案需要先写入硬盘,然后才能开始配置加密卷。

以下提示显示了在 Debian 平台上创建加密卷。

选择加密卷的设备。不要为加密卷选择引导设备\/dev/sda1\,因为它不允许加密引导分区。
如下图所示,加密卷只选择了“/dev/sda3”,这是磁盘的根分区。

配置加密卷后,选择完成以应用更改。

但是,如果没有为加密卷选择交换分区,则会提示以下错误。

因此,我们为加密卷选择两个分区。

交换加密卷的分区设置如下所示。

以下提示表示将在“sda2”(swap)上擦除数据。

擦除 \sda2\ 和 \sda3\ 上的数据如下所示。


该过程完成后,为两个加密分区输入密码。

重新输入相同的密码。

磁盘加密卷配置成功后的分区表如下图所示。

完成分区过程以开始安装 Debian 操作系统。但是会出现如下错误提示,因为还没有为任何分区选择挂载点\/\。

出现上述错误提示后,重新配置加密卷设置挂载点。在本文中,“sda3_crypt”是根文件系统,“sda2_crypt”是交换区。

为加密卷选择安装点 \/\。

选择 \sda2_crypt\ 加密卷作为交换区。

以下屏幕截图显示了加密卷的最终分区表。

分区的格式化如下所示。

格式化过程完成后,将安装基本系统。

以下屏幕截图显示了为 Debian 软件包选择存档镜像。

包管理器配置如下所示。

仅安装了基本或核心系统,可以从显示的列表中安装其他软件包。

从列表中选择桌面环境和其他包。

所选软件包的安装如下所示。

下面的屏幕截图显示了 Linux 引导加载程序“GRUB”的安装。

选择设备 (sda) 进行引导加载程序安装。

最后,安装过程完成。

重启后,输入密码解密sda3盘。

输入密码解密作为交换区的 sda2 磁盘。

成功登录已安装的系统。

无密码根文件系统的配置
在启动时输入密码的过程现在将使用 USB 记忆棒自动进行。而不是使用
密码,USB 上的密钥将解密加密的卷。将 U 盘连接到虚拟机并使用“dmesg”命令找到它。它在我的 VM 中被检测为 \/dev/sdb\。

使用 dd 命令从 U 盘中提取 8192 随机字节的密钥。
dd if=/dev/sdb of=/root/secret.key bs=512 skip=4 count=16

使用“cryptsetup”命令将上面生成的密钥添加到加密卷中。默认情况下,密码短语保存在插槽 0 中。因此,插槽 1 将用于第二个密钥。
运行 \blkid\ 命令以获取磁盘上卷的详细信息。
blkid

在本教程中,用于解密卷的密钥仅添加到 /dev/sda3 中。但是,它也可以添加到“/dev/sda2”(交换)分区。
cryptsetup luksAddKey /dev/sda3 /root/secret.key --key-slot 1

在文件 /etc/udev/rules.d/99-custom-usb.rules 中为 USB 设备创建了一个简单的 udev 规则,我们将使用的符号链接是 /dev/usbdevice。
SUBSYSTEMS=="usb", DRIVERS=="usb",SYMLINK+="usbdevice%n"

使用以下命令重新加载规则。
udevadm control --reload-rules

插入 USB 设备以验证自定义规则。

需要一个 shell 脚本来从 USB 设备读取密钥并在启动时将其提供给 cryptsetup。该脚本创建为 \/usr/local/sbin/openluksdevices.sh\ 并取自 http://www.oxygenimpaired.com/ 站点。
#!/bin/sh
############taken from following link#########
###http://www.oxygenimpaired.com/debian-lenny-luks-encrypted-root-hidden-usb-keyfile
TRUE=0
FALSE=1
# flag tracking key-file availability
OPENED=$FALSE
if [ -b /dev/usbdevice ]; then
# if device exists then output the keyfile from the usb key
dd if=/dev/usbdevice bs=512 skip=4 count=16 | cat
OPENED=$TRUE
fi
if [ $OPENED -ne $TRUE ]; then
echo "FAILED to get USB key file ..." >&2
/lib/cryptsetup/askpass "Try LUKS password: "
else
echo "Success loading key file for Root . Moving on." >&2
fi
sleep 2
设置脚本的权限,使其可以执行。
chmod a+x /usr/local/sbin/openluksdevices.sh

类似于 fstab 配置文件,crypttab 文件包含有关 Linux 平台上加密卷的信息。为 sda3_crypt 加密分区添加 shell 脚本。加密卷的配置文件“/etc/crypttab”的内容如下。
sda3_crypt /dev/disk/by-uuid/c37a8128-5ea9-45c6-8890-d52f3d452ccc none luks,keyscript=/usr/local/sbin/openluksdevices.sh

在 \/etc/initramfs-tools/conf.d/cryptroot\ 文件中添加以下行。
CRYPTROOT=target=sda3_crypt,source=/dev/disk/by-uuid/c37a8128-5ea9-45c6-8890-d52f3d452ccc

确保将 \usb_storage\ 添加到 \/etc/initramfs-tools/modules\ 文件中。

以下 shell 脚本 (/etc/initramfs-tools/hooks/udevusbkey.sh) 也取自外部来源。它用于在临时文件系统“initrd”中添加一个自定义的 udev 规则。
#!/bin/sh
# udev-usbkey script
###taken from
###http://www.oxygenimpaired.com/ubuntu-with-grub2-luks-encrypted-lvm-root-hidden-usb-keyfile
PREREQ="udev"
prereqs()
{
echo "$PREREQ"
}
case $1 in
prereqs)
prereqs
exit 0
;;
esac
. /usr/share/initramfs-tools/hook-functions
# Copy across relevant rules
cp /etc/udev/rules.d/99-custom-usb.rules ${DESTDIR}/lib/udev/rules.d/
exit 0

更改脚本的权限。
chmod a+x /etc/initramfs-tools/hooks/udevusbkey.sh

GRUB2 引导加载程序配置需要进行一些更改。但是,不允许直接更改配置文件\/boot/grub/grub.cfg\。因此,更改“/etc/default/grub”配置文件中的“GRUB_CMDLINE_LINUX_DEFAULT”参数。如下所示,\rootdelay\ 和 \cryptopts\ 包含在 \GRUB_CMDLINE_LINUX_DEFAULT\ 参数中。
GRUB_CMDLINE_LINUX_DEFAULT="rootdelay=20 cryptopts=target=sda3_crypt,source=/dev/disk/by-uuid/c37a8128-5ea9-45c6-8890-d52f3d452ccc,keyscript=/lib/cryptsetup/scripts/openluksdevices.sh"
GRUB_CMDLINE_LINUX=""
# Uncomment to enable BadRAM filtering, modify to suit your needs
# This works with Linux (no patch required) and with any kernel that obtainsConclusion

运行 \update-grub\ 命令以在 \/boot/grub/grub.cfg\ 配置文件中应用上述更改。

执行上述命令后,\/boot/grub/grub.cfg\ 配置文件中应用了以下更改。
echo 'Loading Linux 3.16.0-4-686-pae ...'
linux /vmlinuz-3.16.0-4-686-pae root=UUID=b30cdb22-8e3c-4ffd-a0c7-af96b90ba016 ro rootdelay=20 cryptopts=target=sda3_crypt,source=/dev/disk/by-uuid/c37a8128-5ea9-45c6-8890-d52f3d452ccc,keyscript=/lib/cryptsetup/scripts/openluksdevices.sh
echo 'Loading initial ramdisk ...'
initrd /initrd.img-3.16.0-4-686-pae
运行 \update-initramfs -u\ 以更新所有内核的临时文件系统文件。<br>

在重新启动之前,解压 newley 生成的 \initrd.img\ 并验证密钥脚本是否已复制到 \lib/cryptsetup/scripts\ 目录和自定义 udev 规则到 \lib/udev/rules.d/ \“ 目录。
cd /tmp/
zcat /boot/initrd.img-3.16.0-4-686-pae | cpio -iv

Keyscript 已成功包含在 initramfs 脚本中。

自定义 USB 规则也包含在 udev 规则中。

在测试整个设置之前,在 VM 设置中添加 USB 设备。

最后,成功为加密卷加载密钥。

结论
在本文中,使用保存在 USB 存储设备中的密钥打开加密分区。自动 shell 脚本用于在启动时为加密卷提供密钥。