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: root, home 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.
ESP PARTITION | BOOT PARTITION | ROOT BTRFS VOLUME | ||
---|---|---|---|---|
/boot/efi | /boot | / | /home | /var |
root | home | var | ||
/dev/mapper/luks-YYYY | /dev/mapper/luks-XXXX | |||
/dev/vda1 | /dev/vda2 | /dev/vda3 | ||
UEFI SECURE BOOT | LUKS1 ENCRYPTED | LUKS2 ENCRYPTED |
So let’s get started.
Table of Contents
- 1. Install Fedora 35 Workstation with LUKS2 encryption
- 2. Encrypt the /boot partition with LUKS1
- 3. Bypass the additional passphrase prompt
- 4. Conclusion
- Watch on YouTube
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 Keyboard, Time & 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.
You will see the BLIVET GUI PARTITIONING screen. Here you will create partitions, file systems, and Btrfs subvolumes necessary to install Fedora 35 Workstation.
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.
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.
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.
Next, I’ll create three subvolumes: root, home, 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.
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.
Click again on the + symbol to create the home subvolume. Enter the Name as home and Mountpoint as /home. Click OK to finish.
Repeat the same process for the root subvolume as well. Enter the Name as root and Mountpoint as /. Click OK to finish.
When completed, the subvolumes must look something like this. Click Done to create subvolumes.
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.
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.
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.
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.
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/vda
├─/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
/var
/
[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]
Keyslots:
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
Tokens:
Digests:
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.
- 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.
- 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.
WARNING!
========
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
70cf78f4-108f-4f8b-9e12-f08b8b897d3e
[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 \
/dev/mapper/luks-70cf78f4-108f-4f8b-9e12-f08b8b897d3e
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/vda
├─/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
/var
/
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 \
/etc/cryptsetup-keys.d/luks-70cf78f4-108f-4f8b-9e12-f08b8b897d3e.key
Enter any existing passphrase:
# root (/) partition:
[root@fedora ~]# cryptsetup luksAddKey /dev/vda3 \
/etc/cryptsetup-keys.d/luks-ba088b73-808f-4082-81bc-714828c5669b.key
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.