Ubuntu多硬盘luks全盘加密自动解锁(硬件变更后失效)的方法

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

简介

大家都知道Linux现在用Luks全盘加密一直有一个痛点就是每次开机都需要输入解密硬盘的密码之后又要输入用户密码非常的麻烦本文正是为了解决这个问题诞生的

本文多硬盘加密带来的效果是当你的硬盘被拔出其他人试图拿到数据时必须需要密码。而硬盘如果一直留在原来的主机中且硬件没有发生大的变化则不需要密码即可自动解密硬盘开机。

密钥验证逻辑链路如下

使用TPM芯片验证当前环境是否可行如果可信的话则释放密钥给系统硬盘。系统启动后会释放其他硬盘的密钥来进行解锁。

其中任何一个链路被破坏都将无法再自动解锁必须输入密码。其实这里有个可改进的地方如果System Storage不是通过TPM解锁的则销毁解密其他存储器的密钥

    • 在安装Ubuntu的时候进行仅对根目录进行加密

    • 设置根目录在开机时通过tpm 2.0硬件自动解密

安装所需工具

sudo apt install clevis clevis-tpm2 clevis-luks clevis-udisks2 clevis-systemd clevis-initramfs 

更新tpm权限

sudo udevadm trigger

查看tpm可用的槽位

sudo tpm2_pcrread

PCR

Use

0

Core System Firmware executable code (aka Firmware)

1

Core System Firmware data (aka UEFI settings)

2

Extended or pluggable executable code

3

Extended or pluggable firmware data

4

Boot Manager

5

GPT/Partition Table

6

Resume from S4 and S5 Power State Events

7

Secure Boot State

8

Hash of the kernel command line

9-10

Reserved for Future Use

11

BitLocker Access Control

12

Data events and highly volatile events

13

Boot Module Details

14

Boot Authorities

15-23

Reserved for Future Use

上面的表格中说明了TPM芯片各槽位的作用。

根据槽位的作用我们最好选择PCR7作为密钥存储的位置。对于PC来说我们也可以选择0和1作为存储位置UEFI相关的用途。我们选择安全性更高的SHA256作为启动密钥。

将TPM密钥与LUKS分区关联

首先执行lsblk查看当前根目录所在分区

此处可以发现是nvme0n1p3

将密钥用于根luks分区解密执行下面这个指令后需要输入挂在nvme0n1p3 luks分区所需密码之后会自动进行配置

sudo clevis luks bind -d /dev/nvme0n1p3 tpm2 '{"pcr_bank":"sha256","pcr_ids":"0,1,7"}'

需要注意的是TPM只能和一个系统分区关联和Windows的Bitloader一样所以别想着所有硬盘都通过这种方式来自动解密了其他硬盘我们将会通过其他方式来自动解密

更新initramfs

sudo update-initramfs -u -k 'all'

然后就结束了重启测试一下是否还需要输入密码解锁加密硬盘吧

    • 处理其他硬盘设置加密并且打开格式化

查看还未处理的硬盘

可以看到sda和sdb还没有处理之后我们就会对它们进行处理

创建加密分区

sudo cryptsetup luksFormat /dev/sda
sudo cryptsetup luksFormat /dev/sdb

是否覆盖那里需要输入大写的YES然后就是输入密码。

处理后执行lsblk看看

打开加密分区打开后映射出的虚拟设备会放在/dev/mapper/[映射名称]

# sudo cryptsetup luksOpen [加密的part path] [映射名称]
sudo cryptsetup --allow-discards luksOpen /dev/sda AndroidCodes
sudo cryptsetup --allow-discards luksOpen /dev/sdb Store
--allow-discards是为luks的打开参数允许trim

执行完成后lsblk看看打开的状态

格式化加密分区映射出的虚拟设备为Ext4

也可以是其他文件系统按照大家的喜好来
# sudo mkfs.ext4 /dev/mapper/[映射名称]
sudo mkfs.ext4 /dev/mapper/Store
sudo mkfs.ext4 /dev/mapper/AndroidCodes

创建挂载点并挂载

sudo mkdir /AndroidCodes
sudo mkdir /Store
sudo mount /dev/mapper/Store /Store
sudo mount /dev/mapper/AndroidCodes /AndroidCodes

修改挂载点权限

sudo chown miovea /Store
sudo chown miovea /AndroidCodes
sudo chgrp miovea /Store
sudo chgrp miovea /AndroidCodes

到这里就完成了但是每次开机都需要手动打开加密分区再挂载非常麻烦所以我们打算开机自动运行挂载脚本。

    • 编写开机自动解密脚本

sudo apt install vim
sudo passwd
su
vim /mountall.sh
chmod +x /mountall.sh

mountall.sh内容如下

echo [加密密码] | cryptsetup --allow-discards luksOpen /dev/sda AndroidCodes
echo [加密密码] | cryptsetup --allow-discards luksOpen /dev/sdb Store
mount /dev/mapper/Store /Store
mount /dev/mapper/AndroidCodes /AndroidCodes

    • 设定开机自动运行脚本

su
crontab -e
第一次使用会让你选择一个合适的编辑器
@reboot 在crontab的功能是在启动时执行的
后面的两行是为了在每天凌晨3点自动对存储器发送trim指令因为自带的fstrim.service仅能对fstab或crypttab中带有discard的存储器自动发trim指令毕竟我们不是立即挂载所以没有把其他的存储器信息写在fstab或crypttab中这个服务也不知道它们也需要

记录内容为

@reboot /mountall.sh
0 3 * * * /usr/sbin/fstrim /AndroidCodes
0 3 * * * /usr/sbin/fstrim /Store
关于trim

由于叠瓦式机械硬盘和SSD都带有FTL层来存储逻辑数据位置实际存储位置和逻辑位置并不相同当我们格式化分区或者删除文件的时候只是修改了元数据而已而这些数据占一个分区或者一个文件大小来说是微乎其微的其他数据虽然已经都不需要了可是由于FTL层的存在存储器只能认为刚才所谓的格式化或删除操作只是在某个逻辑地址写了了一些数据其他逻辑地址的数据都还需要所以存储器并不会清空FTL层数据和实际的存储空间。

当操作系统写入数据到已经使用过的逻辑地址上时存储器则需要临时去清除这块逻辑地址的空间然后再存放数据这样需要花费很长的时间等到FTL的逻辑地址几乎消耗殆尽后操作系统有更大的概率将数据写入到已经使用过的逻辑地址上这也是存储器开始掉速的原因

trim指令则是通过一种方式告知存储器现在哪些逻辑地址还在使用哪些不再使用了这样存储器就会清除FTL表相关的逻辑地址它们对应的存储空间也会立刻被混淆处理防止数据泄露空闲时再回收下次存储器就可以直接使用了而无需再临时清除数据后再写入数据。

然后重启看看吧之后如果需要在这些加密分区进行操作(比如挂载swap)都在mountall.sh中追加指令即可

End of Document

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: Ubuntu