Install Fedora 37 with LUKS Full Disk Encryption - Feature Image

How to Install Fedora 37 with LUKS Full Disk Encryption (FDE)

In this blog, I will show you how to install Fedora 37 with LUKS Full Disk Encryption (FDE) for the default partition layout.

LUKS encryption protects the data on a block device while it is offline (Data at rest). This is especially important for mobile devices like laptops because your hard drive may be easily accessed if it is left in the wrong places or, worse, stolen. To access the decrypted content on the device, you need to provide a passphrase or key file. The LUKS Full Disk Encryption (FDE) will take care of this.

For the demonstration, I will use the default 'Automatic' partition setup, which includes a vfat EFI partition, an ext4 boot partition, and a btrfs partition with root and home subvolumes. I will use a 100 GiB hard disk for this.

This is how your setup will look once everything is completed.

/boot/efi/boot//home
roothome
vfatext4btrfs
/dev/mapper/luks-xxxx
(luks2: pbkdf2)
/dev/mapper/luks-yyyy
(luks2: argon2id)
/dev/vda1/dev/vda2/dev/vda3
ESP PARTITION
(600 MiB)
BOOT PARTITION
(1 GiB)
BTRFS PARTITION
(98.4 GiB)

If you prefer to install Fedora 37 with LUKS Full Disk Encryption and Full System Rollback feature, please visit my other article ‘How to Install Fedora 37 with LUKS Full Disk Encryption, Snapper, and Grub-Btrfs for Full System Rollback

So let’s get started.

Table of Contents

1. Install Fedora 37 Workstation with LUKS Encryption

In this section, I'll show you how to install a new copy of Fedora 37 Workstation with a LUKS encrypted btrfs partition.

Boot your system using the Fedora 37 Workstation installer in UEFI mode. On the welcome screen, select the Install to Hard Drive option. Next, select your LanguageKeyboard, and configure Time & Date. Following that, from the INSTALLATION SUMMARY screen, select Installation Destination.

You should now be on the INSTALLATION DESTINATION screen. (1) Select the Automatic partition, (2) check the Encrypt my data box, and (3) click the Done button to continue.

How to Install Fedora 37 with LUKS Full Disk Encryption (FDE) - Encrypt LUKS

A new window will open in which you must enter your LUKS passphrase. Provide a strong passphrase with entropy greater than 60 bits.

How to Install Fedora 37 with LUKS Full Disk Encryption (FDE) - Set LUKS Passphrase

You will be returned to the INSTALLATION SUMMARY screen. Press the Begin Installation button to start the installation process. The installation process will start. Just sit back and relax.

How to Install Fedora 37 with LUKS Full Disk Encryption (FDE) - Installation

When the installation is finished, click the Finish installation button and restart the system. After the computer restarts, you will be prompted for the LUKS passphrase.

How to Install Fedora 37 with LUKS Full Disk Encryption (FDE) - LUKS Passphrase

Enter the LUKS passphrase that you provided. The last phase of the installation procedure will start. Click the Start Setup button to complete the remaining customization steps, such as setting a new login, password, and so on.

You will then be logged into the Fedora 37 Workstation with the all-new Gnome 43 desktop interface.

How to Install Fedora 37 with LUKS Full Disk Encryption (FDE) - GNOME 43

Open the Gnome terminal and check your current setup.

$ lsblk -po name,size,fstype,mountpoints /dev/vda
NAME                                                       SIZE FSTYPE      MOUNTPOINTS
/dev/vda                                                   100G             
├─/dev/vda1                                                600M vfat        /boot/efi
├─/dev/vda2                                                  1G ext4        /boot
└─/dev/vda3                                               98.4G crypto_LUKS 
  └─/dev/mapper/luks-f5237975-7889-4a54-9861-d9961d21ccef 98.4G btrfs       /home
                                                                            /

List the subvolumes.

$ sudo btrfs subvolume list /
ID 256 gen 83 top level 5 path home
ID 257 gen 83 top level 5 path root
ID 258 gen 80 top level 257 path var/lib/machines

The var/lib/machines subvolume is created by systemd implicitly in Fedora 37 Workstation for systemd-nspawn containers.

Review the device encryption details.

$ sudo cryptsetup luksDump /dev/vda3
LUKS header information
Version:       	2
Epoch:         	3
Metadata area: 	16384 [bytes]
Keyslots area: 	16744448 [bytes]
UUID:          	f5237975-7889-4a54-9861-d9961d21ccef
Label:         	(no label)
Subsystem:     	(no subsystem)
Flags:       	(no flags)
Data segments:
  0: crypt
	offset: 16777216 [bytes]
	length: (whole device)
	cipher: aes-xts-plain64
	sector: 512 [bytes]
Keyslots:
  0: luks2
	Key:        512 bits
	Priority:   normal
	Cipher:     aes-xts-plain64
	Cipher key: 512 bits
	PBKDF:      argon2id
	Time cost:  4
	Memory:     796652
	Threads:    2
	Salt:       6a a9 2b 08 ad 35 04 5b d4 dd 7d 3e 69 17 e8 2e 
	            6f 5f f7 16 9f 9c d0 e0 82 6e 36 4d 0c e6 cb 3a 
	AF stripes: 4000
	AF hash:    sha256
	Area offset:32768 [bytes]
	Area length:258048 [bytes]
	Digest ID:  0
Tokens:
Digests:
  0: pbkdf2
	Hash:       sha256
	Iterations: 91530
	Salt:       59 c2 e1 93 3a eb 28 6a 23 1c 45 6e a8 d6 cf 23 
	            99 e1 e2 39 51 50 57 2d 4a 02 ff 1c a7 bc c7 f4 
	Digest:     48 fc 15 f7 08 d0 1d aa b6 b3 6f 33 9c 10 d1 d0 
	            70 75 4a bb aa e5 c3 69 be 6b 2d 19 f2 fa 4d 72

The Fedora 37 Workstation installation with the LUKS2 encrypted btrfs / file system is now complete.

2. Encrypt the /boot Partition with LUKS

GRUB has a feature to unlock a LUKS encrypted /boot partition to read its configuration and load the initramfs and kernel from it.

When you encrypt a partition with LUKS, a 16 MiB LUKS header is created by default at the beginning of the encrypted block device. However, because the /dev/vda2 partition is already formatted with an ext4 file system with no encryption, you must shrink the ext4 file system to allow for the LUKS header to be written at the end of the block device. The minimum size recommended by Cryptsetup is twice the default LUKS2 header size, i.e. 32 MiB.

So, first, unmount the /boot partition.

$ sudo umount -vR /boot

Examine the ext4 file system for any issues.

$ sudo e2fsck -f /dev/vda2

Shrink the ext4 file system to make some room for the LUKS header. Please keep in mind that you only need to shrink the ext4 file system, not the partition.

As the /dev/vda2 partition is set to 1 GiB, I'm going to reduce the ext4 file system to 992 MiB (1024-32).

$ sudo resize2fs -p /dev/vda2 992M

Then, encrypt the partition with LUKS. Currently, GRUB only supports LUKS with the pbkdf2 algorithm. When prompted for a passphrase, enter the same one you set for the Btrfs volume (/dev/vda3).

$ sudo cryptsetup reencrypt \
    --encrypt \
    --verbose \
    --type luks2 \
    --pbkdf pbkdf2 \
    --pbkdf-force-iterations 500000 \
    --reduce-device-size 32m \
    /dev/vda2
WARNING!
========
This will overwrite data on LUKS2-temp-16a8a876-a238-4cc0-a4a1-469275476cce.new irrevocably.
Are you sure? (Type 'yes' in capital letters): YES
Enter passphrase for LUKS2-temp-16a8a876-a238-4cc0-a4a1-469275476cce.new: 
Verify passphrase: 
Key slot 0 created.
Finished, time 00m37s, 1008 MiB written, speed  26.7 MiB/s
Command successful.

For pbkdf2, the minimum iteration count is 1000 and the maximum is 4294967295. I will set the iteration count to 500000. The lower the iterations, the faster the GRUB boots, but it also reduces the security.

Review the /dev/vda2 device LUKS encryption details.

$ sudo cryptsetup luksDump /dev/vda2
LUKS header information
Version:       	2
Epoch:         	129
Metadata area: 	16384 [bytes]
Keyslots area: 	16744448 [bytes]
UUID:          	16a8a876-a238-4cc0-a4a1-469275476cce
Label:         	(no label)
Subsystem:     	(no subsystem)
Flags:       	(no flags)
Data segments:
  0: crypt
	offset: 16777216 [bytes]
	length: (whole device)
	cipher: aes-xts-plain64
	sector: 512 [bytes]
Keyslots:
  0: luks2
	Key:        512 bits
	Priority:   normal
	Cipher:     aes-xts-plain64
	Cipher key: 512 bits
	PBKDF:      pbkdf2
	Hash:       sha256
	Iterations: 500000
	Salt:       3b 1f 80 b2 ba aa 84 c8 e7 ce 3c 9b 0d dc 5b 5a 
	            da 52 e5 d1 7f 48 2f aa 03 42 75 13 43 4c c2 d7 
	AF stripes: 4000
	AF hash:    sha256
	Area offset:32768 [bytes]
	Area length:258048 [bytes]
	Digest ID:  0
Tokens:
Digests:
  0: pbkdf2
	Hash:       sha256
	Iterations: 1000
	Salt:       0e 1f 3b e9 7a 07 82 d4 13 8a d1 66 e6 fa 61 99 
	            7e 43 19 45 a5 5d d8 95 10 17 7e 02 02 1d c3 52 
	Digest:     47 d1 c0 92 83 b3 ac 39 cd 69 7f 92 6c 7d eb 87 
	            d9 a8 ac 08 c4 36 e8 9a 8c d4 c1 f4 12 7b a0 dc

Open the LUKS device.

$ VDA2UUID="$(sudo cryptsetup luksUUID /dev/vda2)"
$ sudo cryptsetup open /dev/vda2 luks-"${VDA2UUID}"
$ sudo mount -va

Restore the SELinux labels to the /boot directory.

$ sudo restorecon -RFv /boot

Create a permanent entry into the /etc/crypttab file for the newly created encrypted block device.

$ echo "luks-${VDA2UUID} UUID=${VDA2UUID} none discard" \
    | sudo tee -a /etc/crypttab
$ sudo cat /etc/crypttab
luks-f5237975-7889-4a54-9861-d9961d21ccef UUID=f5237975-7889-4a54-9861-d9961d21ccef none discard
luks-16a8a876-a238-4cc0-a4a1-469275476cce UUID=16a8a876-a238-4cc0-a4a1-469275476cce none discard

Enable the CRYPTODISK option in GRUB. When enabled, it will check the encrypted disks and generate the additional commands needed to access them during boot.

$ echo 'GRUB_ENABLE_CRYPTODISK=y' | sudo tee -a /etc/default/grub
$ sudo grub2-mkconfig -o /boot/grub2/grub.cfg

Set up access to the encrypted boot device by adding the cryptomount command.

$ CRYPTOUUID="$(echo ${VDA2UUID} | tr -d -)"
$ sudo sed -i.backup "1i cryptomount -u ${CRYPTOUUID}" \
    /boot/efi/EFI/fedora/grub.cfg
$ sudo cat /boot/efi/EFI/fedora/grub.cfg
cryptomount -u 16a8a876a2384cc0a4a1469275476cce
search --no-floppy --fs-uuid --set=dev 1f962d1c-8dfd-4351-aea0-f022dbebebad
set prefix=($dev)/grub2
export $prefix
configfile $prefix/grub.cfg

Reboot the computer now to ensure that everything is working correctly. You will be prompted for the passphrase twice. The first time is before loading GRUB, and the second time is before mounting the root file system.

Depending on your computer's CPU, it may take up to 15 seconds for the GRUB to display the second passphrase prompt. So please be patient.

When you input your passphrase in the first LUKS prompt, no "*" cursor indication appears. So you should assume you have entered your passphrase correctly. Simply enter your LUKS passphrase blindly and hit the [ENTER] key.

3. Bypass the Additional Passphrase Prompt

While GRUB asks for a passphrase to unlock the encrypted /boot files, this information is not passed on to initramfs. As a result, during the initramfs stage, the root (/) must be unlocked once again. This means that either the user must input his passphrase twice, or the initramfs image itself must include a file with the root partition’s passphrase.

The latter method is more commonly used. Because the initramfs image now sits on an encrypted /boot partition, the root (/) partition’s passphrase is secured when data is at rest. However, when the data is online, it must be protected by making it read-only by the root user.

So let’s create key files so that the passphrase is only asked once.

Create /etc/cryptsetup-keys.d directory if it is not already there.

$ sudo mkdir /etc/cryptsetup-keys.d

Create key files for both encrypted partitions with 4KiB of random data each. The key file has to be in volume.key format. For more info, see the man page man 8 systemd-cryptsetup.

$ sudo dd if=/dev/random \
  of=/etc/cryptsetup-keys.d/luks-$(sudo cryptsetup luksUUID /dev/vda2).key \
  bs=512 count=8
$ sudo dd if=/dev/random \
  of=/etc/cryptsetup-keys.d/luks-$(sudo cryptsetup luksUUID /dev/vda3).key \
  bs=512 count=8

Ensure that only the root user has read access to the key file.

$ sudo chmod 0400 /etc/cryptsetup-keys.d/*.key

Attach the created keys to the encrypted device’s available key slot. When prompted for a passphrase, enter the same LUKS passphrase.

#### /boot partition:
$ sudo cryptsetup luksAddKey \
    --pbkdf pbkdf2 \
    --pbkdf-force-iterations 500000 \
    /dev/vda2 \
    /etc/cryptsetup-keys.d/luks-$(sudo cryptsetup luksUUID /dev/vda2).key

#### / partition (btrfs volume):
$ sudo cryptsetup luksAddKey \
    /dev/vda3 \
    /etc/cryptsetup-keys.d/luks-$(sudo cryptsetup luksUUID /dev/vda3).key

Open (or create) the /etc/dracut.conf.d/cryptodisk.conf file.

$ sudo vi /etc/dracut.conf.d/cryptodisk.conf

And add the following line to include both the keys in the initramfs image.

install_items+=" /etc/cryptsetup-keys.d/* "

Finally, rebuild the initramfs image.

$ sudo dracut -vf

Reboot the computer and verify that everything is operating correctly. The LUKS passphrase should only be asked once.

The configuration to bypass the additional passphrase prompt and automatically mount the encrypted partitions is now complete.

4. Conclusion

You have now protected your Fedora 37 Workstation Linux distribution with LUKS Full Disc Encryption. Continue on to my other blog to learn how to use UEFI Secure Boot custom key enrollment and a self-signed kernel and bootloader to make your computer's pre-boot environment even more secure against Evil Maid attacks.

Watch on YouTube