Install Fedora 35 with LUKS Full Disk Encryption Feature Image

Install Fedora 35 with LUKS Full Disk Encryption (FDE)

You can protect the data on your laptop or computer by encrypting its drive with LUKS full disk encryption. This safeguards the disk contents even if your disk is physically removed from the system. To access the decrypted content on the device, you need to provide a passphrase or key file.

In this guide, I’ll show you how to install Fedora 35 Workstation with LUKS full disk encryption for UEFI systems.

Note: This guide is applicable for Fedora 36 Workstation as well.

Below is a brief outline of what to expect.

  • Install the Fedora 35 Workstation with an encrypted root filesystem using Btrfs in a LUKS2 container.
  • Within the Btrfs volume, create three subvolumes: roothome and var.
  • Later, encrypt the boot partition using the LUKS1 container.
  • And finally, configure the system to ask for the passphrase only once by auto mounting the encrypted partitions using the key file.

Here is what the final layout of the disk looks like.


So let’s get started.

Table of Contents

1. Install Fedora 35 Workstation with LUKS2 encryption

Boot your computer using the Fedora 35 Installer media in UEFI mode. On the Welcome to Fedora screen, select the Install to Hard Drive option. Next, select your Language. Following that, in the INSTALLATION SUMMARY screen, configure your KeyboardTime & Date, and then click the Installation Destination option.

You should now be on the INSTALLATION DESTINATION screen. To proceed, pick the Advanced Custom (Blivet-GUI) radio button and then hit the Done button.

Install Fedora 35 with LUKS Full Disk Encryption Select Blivet

You will see the BLIVET GUI PARTITIONING screen. Here you will create partitions, file systems, and Btrfs subvolumes necessary to install Fedora 35 Workstation.

Install Fedora 35 with LUKS Full Disk Encryption Partitioning

First, you need to create and mount the EFI partition. Select the free space and click the + sign to create a partition.

Set the partition Size to 512 MiB, the Filesystem to EFI System Partition, and the Mountpoint to /boot/efi.

Install Fedora 35 with LUKS Full Disk Encryption EFI Partition

Next, you need to create and mount the /boot partition. Select the free space again and click on the + sign. Set the partition Size to 1 GiB, the Filesystem to ext4, and the Mountpoint to /boot.

Install Fedora 35 with LUKS Full Disk Encryption boot Partition

Don’t check the Encrypt box here. This isn’t going to work. The Anaconda installer does not allow you to encrypt the /boot partition.

Finally, create a LUKS2 encrypted Btrfs volume on which you will create the necessary subvolumes and install Fedora Linux.

Select the free space one more time and click on the + sign. (1) Set the Device Type to Btrfs Volume. (2) Set the Size of the Btrfs volume. (3) Set the volume name for Btrfs. I named the Btrfs volume FEDORA, but you can name it whatever you like. (4) Set the Encryption type to luks2 and (5) provide a strong password (password entropy > 60 bits is suggested). Do not set any Mountpoint here. Leave it blank and click on the OK button.

Install Fedora 35 with LUKS Full Disk Encryption BTRFS Volume

Next, I’ll create three subvolumes: roothome, and var. The root subvolume will be mounted at /, the home subvolume will be mounted at /home, and the var subvolume will be mounted at /var.

You don’t need to create a separate var subvolume if you don’t intend to install a web server, KVM virtualization, or anything else that uses the /var directory. I’m making a separate var subvolume because I don’t want the /var directory to be included when I take a snapshot of the root (/) subvolume.

Select the Btrfs Volume from the left panel, and click on the + sign on the right panel.

Install Fedora 35 with LUKS Full Disk Encryption Blivet

For some reason, the Btrfs subvolumes are created in reverse order in the Anaconda installer. This means that the first specified subvolume is created last, and the last specified subvolume is created first. So I’m going to specify subvolumes in reverse order.

Create var subvolume. Enter the Name as var and Mountpoint as /var. Click OK to finish.

Install Fedora 35 with LUKS Full Disk Encryption var Subvolume

Click again on the + symbol to create the home subvolume. Enter the Name as home and Mountpoint as /home. Click OK to finish.

Install Fedora 35 with LUKS Full Disk Encryption home Subvolume

Repeat the same process for the root subvolume as well. Enter the Name as root and Mountpoint as /. Click OK to finish.

Install Fedora 35 with LUKS Full Disk Encryption root Subvolume

When completed, the subvolumes must look something like this. Click Done to create subvolumes.

Install Fedora 35 with LUKS Full Disk Encryption Blivet GUI BTRFS

As with the swap partition, Fedora generates a SwapOnZRAM upon startup, so no separate swap partition is needed.

Verify that the partitions and subvolumes are properly defined on the SUMMARY OF CHANGES screen. To finalize the changes, click the Accept Changes button.

Install Fedora 35 with LUKS Full Disk Encryption Summary of Changes

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.

Install Fedora 35 with LUKS Full Disk Encryption Installation Process

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

Install Fedora 35 with LUKS Full Disk Encryption LUKS2 Passphrase

Enter the LUKS2 passphrase that you previously specified. 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 all-new Gnome 41 desktop interface.

Install Fedora 35 with LUKS Full Disk Encryption Gnome 41

Open the Gnome terminal and check your current setup.

[madhu@fedora ~]$ lsblk -pf
NAME                                                      FSTYPE      FSVER LABEL  UUID                                 FSAVAIL FSUSE% MOUNTPOINTS
/dev/zram0                                                                                                                             [SWAP]
├─/dev/vda1                                               vfat        FAT32 EFI    C840-B103                             497.1M     3% /boot/efi
├─/dev/vda2                                               ext4        1.0   BOOT   4710c00d-ade5-4c87-8175-70555ecef209  756.8M    15% /boot
└─/dev/vda3                                               crypto_LUKS 2            ba088b73-808f-4082-81bc-714828c5669b                
  └─/dev/mapper/luks-ba088b73-808f-4082-81bc-714828c5669b btrfs             FEDORA 2dbcf976-0658-43e7-9edd-f99fec1d9a0f   74.7G     4% /home
[madhu@fedora ~]$ sudo btrfs filesystem show /
Label: 'FEDORA'  uuid: 2dbcf976-0658-43e7-9edd-f99fec1d9a0f
	Total devices 1 FS bytes used 2.93GiB
	devid    1 size 78.48GiB used 4.02GiB path /dev/mapper/luks-ba088b73-808f-4082-81bc-714828c5669b
[madhu@fedora ~]$ sudo btrfs subvolume list /
ID 256 gen 71 top level 5 path root
ID 257 gen 74 top level 5 path home
ID 258 gen 74 top level 5 path var
ID 263 gen 70 top level 258 path var/lib/machines

Review the device encryption details.

[madhu@fedora ~]$ sudo cryptsetup luksDump /dev/vda3
LUKS header information
Version:       	2
Epoch:         	3
Metadata area: 	16384 [bytes]
Keyslots area: 	16744448 [bytes]
UUID:          	ba088b73-808f-4082-81bc-714828c5669b
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]

  0: luks2
	Key:        512 bits
	Priority:   normal
	Cipher:     aes-xts-plain64
	Cipher key: 512 bits
	PBKDF:      argon2id
	Time cost:  4
	Memory:     674863
	Threads:    2
	Salt:       33 4a 18 46 e3 58 37 70 9e 7d e5 08 93 b4 e4 de 
	            7a 14 ee 8b d2 96 69 8c c5 c9 72 67 98 2e a8 83 
	AF stripes: 4000
	AF hash:    sha256
	Area offset:32768 [bytes]
	Area length:258048 [bytes]
	Digest ID:  0
  0: pbkdf2
	Hash:       sha256
	Iterations: 108323
	Salt:       44 71 a2 e7 82 c0 37 ae af dd 08 15 d4 b5 11 cb 
	            df e0 a0 fc 91 0c ce 20 fb f1 ed e2 b2 5f 0e f7 
	Digest:     90 ed 23 47 89 03 5d 8c 13 52 63 20 0f ff 23 be 
	            3d 76 90 65 6d 60 53 73 e6 37 c5 d1 19 00 0d cf

The Fedora 35 Workstation installation with the LUKS2 encrypted root file system is now complete.

2. Encrypt the /boot partition with LUKS1

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

Since support for LUKS2 in GRUB 2.0.6 is limited (Argon2i and Argon2id are not supported), it is recommended to use LUKS1 to encrypt the /boot partition.

2.1 Backup the /boot partition

A backup of the /boot partition is required since it must be re-formatted as LUKS1. You’ll need to restore it later.

However, before performing the backup, you must first unmount the EFI partition (/dev/vda1), which is mounted on top of the /boot partition (/boot/efi).

Log in as root, unmount the EFI partition, backup the /boot partition, and then unmount it.

[madhu@fedora ~]$ sudo -i
[root@fedora ~]# umount -v /boot/efi
[root@fedora ~]# rsync -avAXP /boot/ /boot-backup
[root@fedora ~]# umount -v /boot

2.2 Format the partition to LUKS1

Format the /dev/vda2 partition to LUKS1. But before you format the /dev/vda2 partition, consider the following two things.

  1. Set the same passphrase. Because the / partition is already encrypted with LUKS2, it is recommended that you use the same passphrase for the /boot partition (LUKS1) as well. This reduces the number of times a passphrase is asked at boot time (from three to two). You can further reduce the required engagement to just one time after creating a key file for filesystem root.
  2. Reduce the amount of time spent on passphrase processing. The default time to process PBKDF passphrase for LUKS1 is 2000 milliseconds (cryptsetup --help | tail). The passphrase iteration count is based on time and hence the security level depends on CPU power of the system the LUKS container is created on. In my tests, after entering the LUKS1 passphrase, the GRUB menu appeared after around 30 seconds. The GRUB menu displayed in 15 seconds when the iteration time was set to 1000 ms (--iter-time 1000). With an iteration time of 500 ms (--iter-time 500), the duration was further reduced to 8 seconds.

I will stick to the default iteration time of 2000 ms though, as I do not wish to compromise security. I have no problem waiting 30 seconds. For the passphrase, I will be using the same passphrase I used for LUKS2.

[root@fedora ~]# cryptsetup luksFormat /dev/vda2 --type luks1
WARNING: Device /dev/vda2 already contains a 'ext4' superblock signature.

This will overwrite data on /dev/vda2 irrevocably.

Are you sure? (Type 'yes' in capital letters): YES
Enter passphrase for /dev/vda2: 
Verify passphrase:
[root@fedora ~]# cryptsetup luksDump /dev/vda2
LUKS header information for /dev/vda2

Version:       	1
Cipher name:   	aes
Cipher mode:   	xts-plain64
Hash spec:     	sha256
Payload offset:	4096
MK bits:       	512
MK digest:     	27 7d c8 9b 7b 56 53 d5 e4 4a 74 71 15 13 a7 36 88 18 80 d2 
MK salt:       	0f 3d ba d7 4a e7 b4 d0 ef 36 4f f6 df a9 a4 29 
               	0d 22 e9 a4 ce e3 1e f4 c3 78 3b da fe ac 88 90 
MK iterations: 	109226
UUID:          	70cf78f4-108f-4f8b-9e12-f08b8b897d3e

Key Slot 0: ENABLED
	Iterations:         	1768256
	Salt:               	42 1e e2 12 13 db 2e a8 16 63 84 21 80 d4 8c 1b 
	                      	26 96 64 ba 54 63 2a c5 05 3f 4e 45 58 8c 10 5a 
	Key material offset:	8
	AF stripes:            	4000
Key Slot 1: DISABLED
Key Slot 2: DISABLED
Key Slot 3: DISABLED
Key Slot 4: DISABLED
Key Slot 5: DISABLED
Key Slot 6: DISABLED
Key Slot 7: DISABLED

2.3 Create a Ext4 filesystem

Map the encrypted partition with a device name in the luks-UUID format. The UUID here is of the /dev/vda2 partition.

[root@fedora ~]# lsblk -dno uuid /dev/vda2

[root@fedora ~]# cryptsetup open /dev/vda2 luks-70cf78f4-108f-4f8b-9e12-f08b8b897d3e
Enter passphrase for /dev/vda2: 

Now create an Ext4 filesystem on the mapped device with the same UUID that was originally used by the /boot partition. This avoids the need to change the /etc/fstab file or any other file that has the old UUID.

[root@fedora ~]# grep 'boot.*ext4' /etc/fstab
UUID=4710c00d-ade5-4c87-8175-70555ecef209  /boot  ext4  defaults  1 2

[root@fedora ~]# mkfs.ext4 \
  -U 4710c00d-ade5-4c87-8175-70555ecef209 \
  -L BOOT \

Mount the mapped device back to /boot directory.

[root@fedora ~]# mount -v /dev/mapper/luks-70cf78f4-108f-4f8b-9e12-f08b8b897d3e /boot

You may receive an SELinux warning. Ignore that for the time being. After the backup is restored, I’ll relabel the /boot folder.

2.4 Restore the backup

Restore the backup back to /boot partition.

[root@fedora ~]# rsync -avAXP /boot-backup/ /boot/

Mount the EFI partition (/dev/vda1) back to /boot/efi.

[root@fedora ~]# mount -v /dev/vda1 /boot/efi/

Restore the SELinux labels.

[root@fedora ~]# restorecon -RFv /boot

Remove the temporary backup folder.

[root@fedora ~]# rm -rvf /boot-backup/

Verify your new setup.

[root@fedora ~]# lsblk -pf
NAME                                                      FSTYPE      FSVER LABEL  UUID                                 FSAVAIL FSUSE% MOUNTPOINTS
/dev/zram0                                                                                                                             [SWAP]
├─/dev/vda1                                               vfat        FAT32 EFI    C840-B103                             497.1M     3% /boot/efi
├─/dev/vda2                                               crypto_LUKS 1            70cf78f4-108f-4f8b-9e12-f08b8b897d3e                
│ └─/dev/mapper/luks-70cf78f4-108f-4f8b-9e12-f08b8b897d3e ext4        1.0   BOOT   4710c00d-ade5-4c87-8175-70555ecef209    771M    15% /boot
└─/dev/vda3                                               crypto_LUKS 2            ba088b73-808f-4082-81bc-714828c5669b                
  └─/dev/mapper/luks-ba088b73-808f-4082-81bc-714828c5669b btrfs             FEDORA 2dbcf976-0658-43e7-9edd-f99fec1d9a0f   74.7G     4% /home

2.5 Enable the cryptodisk in GRUB

Next, 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.

[root@fedora ~]# echo "GRUB_ENABLE_CRYPTODISK=y" >> /etc/default/grub

2.6 Add an entry in the /etc/crypttab file

Create a permanent entry into the /etc/crypttab file for the newly created encrypted block device. It should be in the following format.

luks-<your luks UUID> UUID=<your luks UUID> none discard
[root@fedora ~]# echo "luks-70cf78f4-108f-4f8b-9e12-f08b8b897d3e UUID=70cf78f4-108f-4f8b-9e12-f08b8b897d3e none discard" >> /etc/crypttab

[root@fedora ~]# cat /etc/crypttab
luks-ba088b73-808f-4082-81bc-714828c5669b UUID=ba088b73-808f-4082-81bc-714828c5669b none discard
luks-70cf78f4-108f-4f8b-9e12-f08b8b897d3e UUID=70cf78f4-108f-4f8b-9e12-f08b8b897d3e none discard

2.7 Update the GRUB conf

Update the grub.conf file.

[root@fedora ~]# grub2-mkconfig -o /boot/grub2/grub.cfg

DO NOT use the previous style to update the grub file: grub2-mkconfig -o /boot/efi/EFI/fedora/grub.cfg. You will break the system once the kernel is updated. Thanks to Jeff for reporting this problem.

Because the /boot file system has been encrypted now, you must add/modify the following lines in the /boot/efi/EFI/fedora/grub.cfg file.

From this:

search --no-floppy --fs-uuid --set=dev 4710c00d-ade5-4c87-8175-70555ecef209
set prefix=($dev)/grub2

export $prefix
configfile $prefix/grub.cfg

To this:

cryptomount -u 70cf78f4108f4f8b9e12f08b8b897d3e
search --no-floppy --fs-uuid --set=dev --hint='cryptouuid/70cf78f4108f4f8b9e12f08b8b897d3e' 4710c00d-ade5-4c87-8175-70555ecef209
set prefix=($dev)/grub2

export $prefix
configfile $prefix/grub.cfg

Changes are in orange color. It’s the UUID of the mapped device to the LUKS1 encrypted /boot partition without dashes.

2.8 And finally, reboot your computer

[root@fedora ~]# reboot

Reboot the computer and verify if it worked. You will be prompted for the password twice. The first time is to decrypt the /boot partition (LUKS1), and the second time is to decrypt the / partition (LUKS2).

Depending on your computer’s CPU, the GRUB may take 30 seconds or more to display the menu after you enter the first LUKS1 passphrase. So please be patient.

3. Bypass the additional passphrase prompt

While GRUB asks for a passphrase to unlock the LUKS1 encrypted /boot partition, this information is not passed on to initramfs. As a result, the root (/) partition must be unlocked once again during the initramfs stage. This implies that either the user has to enter his passphrase twice, or the initramfs image itself has to contain a file with the passphrase of the root partition.

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. When the data is online, however, it must be protected by making it read-only by the root user.

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

[root@fedora ~]# 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.

[root@fedora ~]# dd if=/dev/random \
  of=/etc/cryptsetup-keys.d/luks-$(cryptsetup luksUUID /dev/vda2).key \
  bs=512 count=8

[root@fedora ~]# dd if=/dev/random \
  of=/etc/cryptsetup-keys.d/luks-$(cryptsetup luksUUID /dev/vda3).key \
  bs=512 count=8

Ensure the key files are read-only by the root user.

[root@fedora ~]# chmod 0400 /etc/cryptsetup-keys.d/*.key

[root@fedora ~]# ls -l /etc/cryptsetup-keys.d/
-r--------. 1 root root 4096 Oct 13 22:33 luks-70cf78f4-108f-4f8b-9e12-f08b8b897d3e.key
-r--------. 1 root root 4096 Oct 13 22:34 luks-ba088b73-808f-4082-81bc-714828c5669b.key

Attach the generated key to the available key slot on the encrypted device. When asked for a passphrase, enter the regular LUKS passphrase.

# /boot partition:
[root@fedora ~]# cryptsetup luksAddKey /dev/vda2 \
Enter any existing passphrase: 

# root (/) partition:
[root@fedora ~]# cryptsetup luksAddKey /dev/vda3 \
Enter any existing passphrase:

Also, include the keys in the initramfs image. To do so, open (or create) the cryptodisk.conf file in the /etc/dracut.conf.d/ directory.

[root@fedora ~]# vi /etc/dracut.conf.d/cryptodisk.conf

And add the following line.

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

Finally, rebuild the initramfs image.

[root@fedora ~]# dracut -vf

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

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

4. Conclusion

Congrats! You have now secured your Fedora 35 Workstation Linux distribution with LUKS full disk encryption. Going from here, check out my other blog about how you can make your computer's pre-boot environment even more secure against Evil Maid attacks by using UEFI Secure Boot custom key enrollment and a self-signed kernel and bootloader.

Watch on YouTube