There are a number of existing guides online that already cover how to reencrypt a disk, such as maxschelpzig's response here and the documentation in the Arch wiki. However, the Arch wiki focuses more on systems that use mkinitcpio as opposed to dracut, and the existing StackExchange answer assumes an ext4 filesystem.
Asked
Active
Viewed 4,294 times
5
cam-rod
- 165
1 Answers
11
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 --kver <kernel version> --force - 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. On March 16th 2023 a typo was corrected where --reduce-device-size incorrectly contained a space.