How to encrypt an existing disk on Fedora without formatting
This is a mirror of an existing answer that I posted on the Unix & Linux Stack Exchange. I’m bringing it to my personal blog for preservation purposes (and honestly, so I can refer back to it when I inevitably need to set up a new laptop). This post by Jessica Rodriguez is licensed under CC BY-SA 4.0.
I originally wrote this guide for Fedora 36, but there haven’t been any significant changes between then and now (Fedora 42).
Assumptions
This assumes a default Fedora installation, with the following Btrfs-based partitions:
- Root partition (Btrfs subvolumes “root” [mounted at
/] and “home” [mounted at/home]) - Boot partition (mounted at
/boot) - EFI partition (UEFI systems only, mounted at
/boot/efi)
Requirements
- A full-disk backup
- cryptsetup (should be included, otherwise install with
dnf install cryptsetup) - At least 100 MiB of free space
- A rescue system that can unmount the root filesystem (ex. Fedora live USB)
- NOTE: The encryption screen will use the keyboard layout defined in
/etc/vconsole.conf(set withlocalectl). The layout cannot be changed at boot time.
Instructions
- Identify the root filesystem with
lsblk -f. Store the UUID (formatXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX) for later use. - Identify your current kernel version with
uname -r, and save this value for later. - Reboot into the rescue system. Locate the root filesystem with
blkid --uuid <UUID>, and run a check on the filesystem withbtrfs check <device> - Mount the filesystem with
mount /dev/<device> /mnt - Shrink the filesystem to make room for the LUKS header. At least 32 MiB is recommended, use
btrfs filesystem resize -32M /mnt - Unmount the filesystem:
umount /mnt - Encrypt the partition with
cryptsetup reencrypt --encrypt --reduce-device size 32M /dev/<device>, providing a passphrase when prompted. - Identify the encrypted LUKS partition with
lsblk -f(note that the UUID has changed). Save this LUKS partition UUID for later use. - Open the partition, providing your passphrase when prompted:
cryptsetup open /dev/<device> system - Mount the mapped filesystem with
mount /dev/mapper/system /mnt - Resize the filesystem to use all the space:
btrfs filesystem resize max /mnt, then unmount the filesystem withumount /mnt - Mount the root subvolume (the Linux filesystem root) with
mount -t btrfs -o "noatime,subvol=root,compress=zstd:1" /dev/mapper/system /mnt - Identify the devices for the boot and EFI partitions with
lsblk. Mount the boot filesystem (mount /dev/<boot device> /mnt/boot), followed by the EFI filesystem for UEFI systems (mount /dev/<EFI device /mnt/boot/efi). - Bind-mount the pseudo filesystems
/dev,/dev/pts,/proc,/run, and/sys, in the format ofmount --bind /sys /mnt/sys - Open a shell within the filesystem:
chroot /mnt /bin/bash - Open
/etc/default/grubwith a text editor, and modify the kernel parameters to identify the LUKS partition, and temporarily disable SELinux enforcing. Add these parameters, then save the changes and close the file:GRUB_CMDLINE_LINUX="[other params] rd.luks.uuid=<LUKS partition UUID> enforcing=0" - Configure a relabelling of SELinux with
touch /.autorelabel - Regenerate the GRUB config:
grub2-mkconfig -o /boot/grub2/grub.cfg(also generate for/etc/grub2.cfg, and on UEFI systems/etc/grub2-efi.cfg) - Regenerate initramfs to ensure cryptsetup is enabled:
dracut -f /boot/initramfs-<kernel version>.img <kernel version> - Exit the chroot
- Unmount all filesystems in reverse order. (For filesystems mounted with
--bind, the option-lcan be used.) Close the LUKS partition withcryptsetup close system - Reboot and log into the regular system. You’ll be asked for your passphrase to decrypt the system during boot.
- Open
/etc/default/grubin a text editor, and reenable SELinux enforcing by removingenforcing=0fromGRUB_CMDLINE_LINUX. Save and exit. - Relabel SELinux again with
touch /.autorelabel. - Repeat step 18 to regenerate the GRUB config.
- Reboot and log into the system.
This answer heavily derives from maxschelpzig’s answer and the Arch wiki. It also pulls from ceremcem’s answer.