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.

UEFI MODE

You must boot your server in UEFI mode !!!

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.

debian advanced install

debian expert install

debian install choose language and more

Partition disks


We will create one EFI partition and one partition for encrypted root filesystem.

Partition disks - Basic setup


Choose your disk

partition-disks-choose-your-disk

Create Empty partition table

partition-disks-choose-your-disk

Create GPT table

create gpt table

Partition disks - Create one EFI partition


create efi partition 01

create efi partition 02

Partition disks - Configure Encrypted Volume


configure encrypted volumes

select device to be encrypted

encrypted disk settings

encrypted disk - finished

overwrite partition with random data

overwriting data progress

enter passphrase to encrypt data

re-enter passphrase to encrypt data

you can see encrypted partition sda2

Partition disks - Configure the Logical Volume manager


choose configure the logical volume manager

write to disk current partitioning scheme

create volume group

enter the name for new volume group - VG_01

select encrypted device for the new volume group

create logical volume

select volume group where the new logical volume should be created

enter the name for new logical volume - LV_01

select the size for new logical volume

finish LVM setup

Partition disks - Create root partition


for new root partition select previous created logical volume LV_01

select filesystem and / mount point for root filesystem

Partition disks - Finish partitioning and write changes to disk


this is our complete partition configuration for our disk

continue without swap space

write changes to disk

Continue in install process


continue in install progress up to install Grub

Install the GRUB boot loader on hard disk


debian grub error

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.

continue without boot loader

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
Share Comments
comments powered by Disqus