During a periodic review of my machine’s security posture, I realized my Linux installation was running without full disk encryption. Reinstalling to add encryption wasn’t an option: I needed a way to encrypt in place, while continuing to use the machine normally.
Here’s the approach: use LVM’s pvmove to migrate data to an external disk, encrypt the internal partition, then migrate the data back. The machine stays usable throughout the entire process.
Requirements
- Your Linux installation already uses LVM on an unencrypted partition
- An external disk or partition with at least as much capacity as the LVM partition you’re encrypting
- A verified backup: use Clonezilla or your preferred tool. Test the backup before you start.
Starting point
The goal is to convert this:

The root LV (red) is unencrypted. Windows on the other partition is already encrypted with BitLocker and should not be touched.
…into an LVM on LUKS layout, where the LVM physical volume lives inside a LUKS encrypted container.
/boot remains a separate unencrypted partition for now; the optional final section covers full disk encryption.
Install the required tools
Install cryptsetup from your distribution’s repositories if it’s not already present.
Step-by-step process
1. Add the external disk to the volume group
Create a physical volume on the external disk and extend the volume group to include it:
pvcreate /dev/sdb1
vgextend system /dev/sdb1
The external disk is now part of the VG. Data is still on /dev/sda5.
2. Move all physical extents to the external disk
This is the time-consuming step. Speed depends on disk throughput and data size:
pvmove /dev/sda5 /dev/sdb1The command prints progress periodically. Your system remains fully usable throughout.
3. Remove the internal disk physical volume from the VG
The internal PV is now empty; remove it:
vgreduce system /dev/sda5
pvremove /dev/sda5
All data is now on the external disk PV.
4. Create a LUKS container on the internal partition
Wipe the internal partition:
cryptsetup open --type plain /dev/sda5 container --key-file /dev/urandomCreate the LUKS container. Choose your parameters based on your cryptsetup version and bootloader; see the Arch Wiki options. I used:
- XTS cipher
- 512-bit key size
- LUKS1 (required if you want to optionally encrypt
/bootwith GRUB later; LUKS2 requires cryptsetup ≥ 2.1.0)
cryptsetup -v --verify-passphrase -s 512 luksFormat /dev/sda5This passphrase will be required on every boot. Choose carefully and store it safely.
Open the container and add it to the VG:
cryptsetup luksOpen /dev/sda5 dm_crypt-1
pvcreate /dev/mapper/dm_crypt-1
vgextend system /dev/mapper/dm_crypt-15. Move data back to the encrypted internal disk
pvmove /dev/sdb1 /dev/mapper/dm_crypt-1Again, this takes time. The system remains usable.
6. Remove the external disk physical volume
vgreduce system /dev/sdb1
pvremove /dev/sdb1
Data is now encrypted on the internal disk. Wipe /dev/sdb1: it still contains a plaintext copy.
Wipe the external disk now: it still holds the unencrypted data from step 2.
7. Configure the bootloader
Tell the bootloader that the root filesystem is on an encrypted partition.
Find the UUID of the internal partition:
ls -l /dev/disk/by-uuid/ | grep sda5Create /etc/crypttab:
echo "dm_crypt-1 UUID=45a4cbf0-da55-443f-9f2d-70752b16de8d" > /etc/crypttabRegenerate initrd (openSUSE):
mkinitrdReinstall GRUB:
grub2-mkconfig -o /boot/grub2/grub.cfg && grub2-install /dev/sda
/boot is still unencrypted at this point.
On every boot, initrd will prompt for the LUKS passphrase before mounting the root filesystem.
Optional: full disk encryption (encrypt /boot too)
Leaving /boot unencrypted enables convenient features like:
- Unattended LUKS unlock via a USB key containing a keyfile
- Remote LUKS unlock via SSH at boot (e.g., using dropbear-initramfs)
The trade-off is the evil maid attack: someone with physical access could tamper with your bootloader.
If your threat model requires full disk encryption, here’s how to move /boot inside the encrypted volume:
Copy /boot into the LVM root, unmount the separate partition, and replace it:
cp -rav /boot /boot-new
umount /boot
mv /boot /boot.old
mv /boot-new /bootRemove the /boot entry from /etc/fstab:
grep -v /boot /etc/fstab > /etc/fstab.new && mv /etc/fstab.new /etc/fstabEnable GRUB crypto support:
echo "GRUB_ENABLE_CRYPTODISK=y" >> /etc/default/grubTo avoid entering the passphrase twice (once for GRUB, once for initrd), configure a keyfile. Follow the openSUSE Wiki guide on avoiding the passphrase twice with FDE.
Reinstall GRUB:
grub2-mkconfig -o /boot/grub2/grub.cfg && grub2-install /dev/sda
Full disk encryption: mission accomplished.
Everything on disk is now encrypted at rest. GRUB prompts for the LUKS passphrase at boot; initrd uses the keyfile and doesn’t prompt again.