How to encrypt an existing archlinux LVM installation [LVM on LUKS]
Tags: archlinux, luks, lvm, linux
Published: 2020-08-15 03:05:36

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

![specific-case](https://dev-to-uploads.s3.amazonaws.com/i/ttjdbkn671fep98ug1lv.png)

## 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
```

![benchmark](https://dev-to-uploads.s3.amazonaws.com/i/klp9q8kpmn3252l0s2gb.png)

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

![result](https://dev-to-uploads.s3.amazonaws.com/i/htt4g39yk56j6rsta3se.jpeg)

Finally I recommend to wipe the temporally drive to prevent unwanted data recovery.