现有一块移动硬盘通过 USB 接入小主机。目标:实现这个盘自动加密挂载到 Ubuntu,供其他服务使用。
创建磁盘分区和格式化
工具有 fdisk
和 parted
,以往主要用 fdisk
,所以这次用 parted
,同时也尝试一下新的文件系统。
首先确定磁盘的信息。
parted -l
可以看到如下内容
1 | Model: WD My Passport 0748 (scsi) |
/dev/sda
这个设备就是我们的移动硬盘了。使用 parted
选择这个磁盘,开始操作。
parted /dev/sda
全新使用,磁盘上没有数据,可以随意修改。因为容量比较大,使用新的分区表类型,调整磁盘分区表到 gpt
。
(parted) mklabel gpt
个人习惯把整个磁盘作为一个分区。
(parted) mkpart primary 0% 100%
parted
的操作就完成了。退出前可以用如下命令检查效果。
(parted) print
这样就建立好了磁盘分区。
磁盘加密并自动挂载
加密部分主要参考Linux「磁盘加密」完全指南,依赖系统软件 cryptsetup。
操作系统启动时候涉及磁盘挂载的顺序为:
- 前置加载
- 基于
/etc/crypttab
解密被加密的设备 - 基于
/etc/fstab
挂载磁盘到目录 - 后续加载
所以要实现自动挂载加密盘的思路就是:
- 在
/etc/crypttab
自动解密加密磁盘 - 在
/etc/fstab
自动挂载解密盘
查找资料过程中发现前几年 Linux 创建加密盘还比较麻烦,好在现在有 cryptsetup,方便简单了很多。确定思路就开始做。
创建加密密钥
用密码不太友好,短了不安全,长了记忆成本高。使用密钥文件来进行加密解密,再妥善管理备份密钥文件。
通过 dd
命令使用随机数生成一个 4KB 的密钥文件,保存到 /etc
目录下:
dd if=/dev/urandom of=/etc/cryptfs.key bs=1k count=4
创建加密磁盘
使用这个密钥,加密磁盘:
cryptsetup luksFormat /dev/sda1 /etc/cryptfs.key
1 | WARNING! |
根据提示输入大写的 YES
确认操作。这里是空磁盘,创建非常快。创建完成之后,可以使用 cryptsetup open
打开加密磁盘,解密的设备位于 /dev/mapper
目录下。
cryptsetup open –key-file=/etc/cryptfs.key /dev/sda1 sda1
格式化加密分区
现在加密分区就被挂载到了 /dev/mapper/sda1
,使用 mkfs
格式化分区,通过补全发现 Ubuntu 现在支持的分区如下:
1 | mkfs mkfs.btrfs mkfs.ext2 mkfs.ext4 mkfs.minix mkfs.ntfs mkfs.xfs |
平时使用 ext4
,这次尝试以下 btrfs
。直接使用对应文件系统的命令,需要磁盘分区地址作为参数:
mkfs.btrfs /dev/mapper/sda1
自动解密并挂载
下面配置启动时候的默认解密,编辑 /etc/crypttab
,增加如下内容
1 | # <target name> <source device> <key file> <options> |
<target name>
的部分,会作为 /dev/mapper
目录下映射出来的设备名称。设置完解密部分后,再将解密设备进行挂载。
<source device>
是挂载的设备,简单的可以直接用 /dev/sda1
,但是这个在系统重启或者插入其他的磁盘的时候,可能发生变动。可以改成 uuid 的方式,更加保险。执行如下命令获取硬盘 uuid
sudo blkid
这个命令会显示当前全部的设备,找到我们这块磁盘的部分。
1 | /dev/sda1: UUID="89c83d74-6f09-4210-90a1-5718d680b9dd" TYPE="crypto_LUKS" PARTLABEL="primary" PARTUUID="718e439b-f52f-427c-9571-999784104ef6" |
然后就可以使用这个 UUID 来更新 /etc/crypttab
文件,下次就会基于 UUID 来处理设备,只要是这块硬盘,换 USB 插口也不会有问题。
1 | # <target name> <source device> <key file> <options> |
搞定了解密部分,剩下的就是编辑 /etc/fstab
自动把解密后的设备挂载到系统目录,供软件正常使用。增加如下内容
1 | # <file system> <mount point> <type> <options> <dump> <pass> |
完成这些操作,系统启动的时候可以自动解密,然后再将解密后的设备挂载到 /mnt/sda1
,任务完成。
一些额外的工作
Backup LUKS header and keyslot area
未加密的情况下,机械硬盘某些扇区损坏,只会丢失这部分数据。加密的情况下,如果某些损坏的扇区刚好是 LUKS header 的数据,那会因为 LUKS 损坏而无法解密,造成整块磁盘的数据都不可用。
所以这个唯一的入口数据,需要做好必要的备份。参考 How to backup and restore LUKS header on Linux,主要使用 luksHeaderBackup。设备使用 /dev/disk/by-uuid/
下拼接 UUID 的定位。
cryptsetup luksHeaderBackup /dev/disk/by-uuid/89c83d74-6f09-4210-90a1-5718d680b9dd –header-backup-file /mnt/backup.bin
这个文件备份到云上或者安全的位置,完成备份。