Many users need to secure their laptop, workstation or regular PC, this users want to protect their information. In Linux exist many cryptographic techniques to protect a hard disk, directory and partition, one of this techniques is Linux Unified Key Setup (LUKS) which uses the kernel device mapper subsystem via the dm-crypt module which make the encrypted device transparent to the user.
Assumptions
This tutorial only encrypt an existing LVM installation, the EFI and boot partitions are in a non-encrypted partition. In order to encrypt an existing LVM installation we need to have root permissions and an external temporally drive to allocate the entire volume group.
In this tutorial the system drive is called rootDrive
and temporally drive is called tmpDrive
, the LVM root partition (partition to encrypt) is called rootDriveXY
, the temporally partition is called tmpDriveXY
both are formatted as Linux LVM.
The entire system are installed in a single volume group, in this tutorial is called “vg-sys”.
You can realize the entire process without umount any partition because of flexibility of LVM, in summary this process can be do on-the-fly.
Warning
Only realize the process if you know what are you doing a bad execution can result in a system damage and data-loss. I recommend to realize a backup before starting this tutorial.
The specific case
I have an existing archlinux installation on LVM volumes, the entire system is in a single volume group “arch”, I have 5 logical volumes (swap, root, var, home and data) in a single physical volume, the entire disk have 3 partitions EFI (/dev/sdb1), boot (/dev/sdb2) and LVM (/dev/sdb3). In order to encrypt an existing LVM installation (/dev/sdb3) I have an empty temporally hard drive (/dev/sda1) with the minimum size of volume group allocated size, in my case the allocated size is 208 GiB (arch volume group), the temporally drive have 465 GiB (/dev/sda1), the temporally drive is formatted as Linux LVM, this setup is showing in the next image
Steps
The first step is to create a physical volume in temporally drive, extend the “vg-sys” volume group to temporally drive and move volume group to temporally drive.
Create physical volume
$ pvcreate /dev/tmpDriveXY
Extend "vg-sys" to temporally drive
$ vgextend vg-sys /dev/tmpDriveXY
Move volume group to temporally drive
$ pvmove /dev/rootDriveXY /dev/tmpDriveXY
Once the volume group is moved, reduce the rootDriveXY
from volume group “vg-sys” and remove the physical drive to be encrypted /dev/rootDriveXY
Remove physical drive from volume group
$ vgreduce vg-sys /dev/rootDriveXY
Remove physical drive
$ pvremove /dev/rootDriveXY
Change the partition type of root drive, on GPT the code is 8309
for Linux LUKS
$ gdisk /dev/rootDrive
Change type with t, choose partition number
Set type 8309 for Linux LUKS
See changes whit p and write with w
$ gdisk -l /dev/rootDrive
Wipe the partition to prevent cryptographic attacks or unwanted file recovery
Create a temporary encrypted container
$ cryptsetup open --type plain -d /dev/urandom /dev/rootDeviceXY to_be_wiped
Verify
$ lsblk
Wipe with zeros, wait til "No space left on device" be patient, this step takes a long time
$ dd if=/dev/zero of=/dev/mapper/to_be_wiped bs=1M status=progress
Close wiped device
$ cryptsetup close to_be_wiped
A this point probably you want to check performance of encrypt algorithms, use the next command to run a benchmark
$ cryptsetup benchmark
I choose an aes-xts-plain64
cipher with a key size of 256
and sha256
hash. To encrypt the rootDriveXY
use the next command
Encrypt device and set passphrase
$ cryptsetup -v --type luks --cipher aes-xts-plain64 --key-size 256 --hash sha256 --iter-time 2000 --use-urandom --verify-passphrase luksFormat /dev/rootDriveXY
Open encrypted device with passphrase, create a LVM physical volume, extend the “vg-sys” volume to encrypted physical volume and move the temporally drive to encrypted
Open encrypted volume
$ cryptsetup open /dev/rootDriveXY cryptarch
Create a physical LVM device
$ pvcreate /dev/mapper/cryptarch
Extend the "vg-sys" group
$ vgextend vg-sys /dev/mapper/cryptarch
Move volume group to encrypted drive
$ pvmove /dev/tmpDriveXY /dev/mapper/cryptarch
Now remove the temporally drive from LVM
$ vgreduce vg-sys /dev/tmpDriveXY
Remove physical volume from temporally drive
$ pvremove /dev/tmpDriveXY
Configure mkinitcpio, first edit /etc/mkinitcpio.conf
file and change hooks like this
HOOKS=(base udev autodetect keyboard keymap consolefont modconf block encrypt lvm2 filesystems fsck)
Then recreate the initramfs image for linux-lts
kernel
$ mkinitcpio -P linux-lts
Configuring the boot loader to unlock the encrypted root partition at boot, the following kernel parameter needs to be set by the boot loader, this can be set in /etc/default/grub
Get UUID of encrypted drive, in this case /dev/rootDriveXY
NOT /dev/mapper/cryptarch
$ blkid
Add this line in GRUB_CMDLINE_LINUX
option, in /etc/default/grub
file
cryptdevice=UUID=rootDriveXY-UUID:cryptarch root=/dev/vg-sys/root
Uncoment GRUB_ENABLE_CRYPTODISK="y"
Regenerate /boot/grub/grub.cfg
file
$ grub-mkconfig -o /boot/grub/grub.cfg
If everything goes fine reboot the system and in boot time the system should ask a password to open the encrypted rootDriveXY
as shown in the next image
Finally I recommend to wipe the temporally drive to prevent unwanted data recovery.
Top comments (1)
Great guide! I did it all without restarting my system once! Linux is so awesome! Although lvm was badly fragmented afterwards but I just defragmented it with this ruby script: git.slxh.eu/silex/lvm-defrag/