How to Enable Full Disk Encryption with encrypted boot, root partition and ramdisk in Debian - Ubuntu Linux
How to Enable Full Disk Encryption with encrypted boot, root partition and ramdisk in Debian - Ubuntu Linux
Today's distributions usually offer the ability to encrypt an operating system and data disc at installation. Unfortunately, there is often an unencrypted linux kernel
and an initialization ramdisk - initrd
in the open /boot
directory. With modern boot loader like Grub
it is possible to solve this as well, because the bootloader
can read files from the encrypted disk. So, when booting, you can ask for a password, load both files (kernel and ramdisk) and then run them. The system base is then able to crack the encrypted disk and the system normally boots.
The advantage of this procedure is that the disk remains pure Grub boot loader on the EFI partition . The rest of the system is protected by encryption, so any thief can not read anything from the disk - data, metadata, partitioning, nothing.
Used Software and Hardware
We'll use one laptop with one SSD unit that we boot in UEFI mode. We will install Debian Stretch on it so that two partitions will be visible on the drive: EFI with the boot loader and then the second completely encrypted using standard LUKS Linux encryption . Inside, we will have the LVM and the partitions in the ext4 and swap filesystems .
We also avoid double type passwords. For the first time, the user has to write password to the Grub boot loader, but he has no way to pass it on to the started kernel, so we would have to write it again. It is very uncomfortable. Because the initramdisk is retrieved from the encrypted storage, we can safely store another encryption key in open form. He then uses it to decrypt the disk during the boot without further delay.
Installer
For most things, we use a standard installer of debian-9.6.0-amd64-xfce-CD-1.iso
iso image, which contains just the most necessary. First we will take standard steps in a wizard asking us for a time zone, language, keyboard, and so on. Then there is a question about partitioning disks.
Partition disks
We will create one EFI partition and one partition for encrypted root filesystem.
Partition disks - Basic setup
Choose your disk
Create Empty partition table
Create GPT table
Partition disks - Create one EFI partition
Partition disks - Configure Encrypted Volume
Partition disks - Configure the Logical Volume manager
Partition disks - Create root partition
Partition disks - Finish partitioning and write changes to disk
Continue in install process
Install the GRUB boot loader on hard disk
GRUB Install
The installer then expects that he did not install Grub in this configuration and will not boot your system. It does not matter, it's time for manual work. Switch over with Alt-F2 to the second console and get the rest.Preparing the boot loader
Mount sysfs filesystem
~] mount -t sysfs sys /target/sys
Switching to the newly installed system that the installer has connected to /target directory. Then we generate a random key to access the encrypted disk.
root@debian:/ ~] mkdir /etc/keys
root@debian:/ ~] cd /etc/kyes
root@debian:/etc/kyes ~] dd if=/dev/urandom of=disk_crypto.key count=4096
4096+0 records in
4096+0 records out
2097152 bytes (2.1 MB, 2.0 MiB) copied, 0.0227492 s, 92.2 MB/s
root@debian:/etc/kyes ~] chmod 400 disk_crypto.key
Fresh debian system is installe to /target mountpoint.
We chrooted to the /target filesystem and created /etc/keys directory. Then we created file disk_crypto.key
with random content.
For the key file, we have removed the file permissions to regular users so that they can not detect the key at runtime and then exploit it in the future. The unique owner of key is the root user. Now we'll add it to LUKS keychains.
root@debian:/etc/kyes ~] cryptsetup luksAddKey /dev/sda2 disk_crypto.key
Enter any existing passphrase:
Check the our partitions:
root@debian:/etc/kyes ~] lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 4G 0 disk
├─sda1 8:1 0 487M 0 part /boot/efi
└─sda2 8:2 0 3.5G 0 part
└─sda2_crypt 253:0 0 3.5G 0 crypt
└─VG_01-LV_01 253:1 0 3.5G 0 lvm /
sr0 11:0 1 1024M 0 rom
We want use sda2 partition, so we check the UUID
root@debian:/etc/kyes ~] blkid /dev/sda2
/dev/sda2: UUID="117222cd-83cc-4fd8-9c04-14fae6c45a1d" TYPE="crypto_LUKS" PARTUUID="df5599df-5e41-4002-9d9c-745d75accd37"
Now we need to explain to the system that we want to use a secondary key when connecting a disk. We will modify /etc/crypttab
file by adding a path to the key file. Optionally, we can assign a parameter that allows the disk to report empty blocks using the TRIM command. The result will look like this:
root@debian:/etc/kyes ~] vi /etc/crypttab
sda2_crypt UUID=117222cd-83cc-4fd8-9c04-14fae6c45a1d /etc/keys/disk_crypto.key luks,discard
In the next step, we set scripts generating initramfs to add a key file to it:
root@debian:/etc/kyes ~] vi /etc/cryptsetup-initramfs/conf-hook
KEYFILE_PATTERN=/etc/keys/disk_crypto.key
In order for no one to read the key from initramfs , it is necessary to set users rights so that for the users in the system is initramfs unreadable. If you do not, the ramdisk generator will protested loudly.
root@debian:/etc/kyes ~] vi /etc/initramfs-tools/initramfs.conf
UMASK=0077
Finally, let's create the initramfs itself with all hooks and the generated key:
root@debian:/etc/kyes ~] update-initramfs -u
update-initramfs: Generating /boot/initrd.img-4.9.0-8-amd64
cryptsetup: WARNING: Invalid source device UUID=117222cd-83cc-4fd8-9c04-14fae6c45a1d
We have a finished initramfs and go to the boot loader itself. First, we enable Grub's module to retrieve content from encrypted block devices:
root@debian:/etc/kyes ~] nano /etc/default/grub
GRUB_ENABLE_CRYPTODISK=y
Then we generate the configuration file loaded by the grub boot loader:
root@debian:/etc/kyes ~] grub-mkconfig -o /boot/grub/grub.cfg
Generating grub configuration file ...
WARNING: Failed to connect to lvmetad. Falling back to device scanning.
WARNING: Failed to connect to lvmetad. Falling back to device scanning.
WARNING: Failed to connect to lvmetad. Falling back to device scanning.
WARNING: Failed to connect to lvmetad. Falling back to device scanning.
WARNING: Failed to connect to lvmetad. Falling back to device scanning.
WARNING: Failed to connect to lvmetad. Falling back to device scanning.
WARNING: Failed to connect to lvmetad. Falling back to device scanning.
WARNING: Failed to connect to lvmetad. Falling back to device scanning.
WARNING: Failed to connect to lvmetad. Falling back to device scanning.
WARNING: Failed to connect to lvmetad. Falling back to device scanning.
Found linux image: /boot/vmlinuz-4.9.0-8-amd64
Found initrd image: /boot/initrd.img-4.9.0-8-amd64
WARNING: Failed to connect to lvmetad. Falling back to device scanning.
WARNING: Failed to connect to lvmetad. Falling back to device scanning.
WARNING: Failed to connect to lvmetad. Falling back to device scanning.
WARNING: Failed to connect to lvmetad. Falling back to device scanning.
WARNING: Failed to connect to lvmetad. Falling back to device scanning.
WARNING: Failed to connect to lvmetad. Falling back to device scanning.
WARNING: Failed to connect to lvmetad. Falling back to device scanning.
WARNING: Failed to connect to lvmetad. Falling back to device scanning.
WARNING: Failed to connect to lvmetad. Falling back to device scanning.
WARNING: Failed to connect to lvmetad. Falling back to device scanning.
Adding boot menu entry for EFI firmware configuration
done
The final step is to install the boot loader into EFI:
root@debian:/etc/kyes ~] grub-install
Installing for x86_64-efi platform.
File descriptor 4 (/dev/sda1) leaked on vgs invocation. Parent PID 12168: grub-install
WARNING: Failed to connect to lvmetad. Falling back to device scanning.
File descriptor 4 (/dev/sda1) leaked on vgs invocation. Parent PID 12168: grub-install
WARNING: Failed to connect to lvmetad. Falling back to device scanning.
Installation finished. No error reported.
Continue in install and reboot fresh debian system
That's all, now, using Alt + F1, we get back to the installation terminal and finish the installation exactly from where it was done. The installer will no longer scream that the loader is not in place because we put him there. There are a couple of post-installation steps and the system is ready to reboot.
At startup, a simple text query prompts you to enter the password that Grub displays. If the password is entered correctly, the kernel and initramfs will load and run, join the system disk, and the boot will run as usual. All data is always encrypted.
It remains to show how the block topology looks at the output of the useful lsblk utility:
root@crypto-debian: ~] lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 4G 0 disk
├─sda1 8:1 0 487M 0 part /boot/efi
└─sda2 8:2 0 3.5G 0 part
└─sda2_crypt 254:0 0 3.5G 0 crypt
└─VG_01-LV_01 254:1 0 3.5G 0 lvm /
sr0
root@crypto-debian: ~] blkid
/dev/mapper/sda2_crypt: UUID="eddS8g-amVL-1MmW-9bVB-05Fg-PQVr-dVfFXF" TYPE="LVM2_member"
/dev/mapper/VG_01-LV_01: UUID="33925f15-f26e-4840-b3c1-20788a03b19f" TYPE="ext4"
/dev/sda2: UUID="117222cd-83cc-4fd8-9c04-14fae6c45a1d" TYPE="crypto_LUKS" PARTUUID="df5599df-5e41-4002-9d9c-745d75accd37"
/dev/sda1: UUID="FBA8-AE32" TYPE="vfat" PARTUUID="8b5d335b-a87f-4a9d-93ca-162a78244752"
root@crypto-debian: ~] fdisk -l
Disk /dev/sda: 4 GiB, 4294967296 bytes, 8388608 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 1C003178-F091-453B-932D-3F80FFD7465D
Device Start End Sectors Size Type
/dev/sda1 2048 999423 997376 487M EFI System
/dev/sda2 999424 8386559 7387136 3.5G Linux filesystem
Disk /dev/mapper/sda2_crypt: 3.5 GiB, 3780116480 bytes, 7383040 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk /dev/mapper/VG_01-LV_01: 3.5 GiB, 3779067904 bytes, 7380992 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes