HOWTO - GPT/UEFI install with full disk encryption: LVMonLUKS with a separate home partition and working hibernation with a swapfile

+----------------+-----------------------------------------------------------------------+
| Boot partition | Logical volume 1      | Logical volume 2      | Optional free space   |
|                |                       |                       |                       |
| /boot/efi      | /    (with swapfile)  | /home                 | for snapshots         |
|                |                       |                       |  or                   |
|                | /dev/MyVolGroup/root  | /dev/MyVolGroup/home  | to grow other lv's    |
|                |_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _|
|                |                                                                       |
|                |                         LUKS encrypted partition                      |
| /dev/sda1      |                           /dev/sda2                                   |
+----------------+-----------------------------------------------------------------------+

.
e. g. end result with a 500GB SSD

+--------------+------------------------------------------------+
| Boot  512MiB | LV 1      40GiB | LV 2     430GiB | free 30GiB |
| /boot/efi    | /   (+swapfile) | /home           |            |
|              | /dev/vg0/lvroot | /dev/vg0/lvhome |            |
|              |_ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _|_ _ _ _ _ _ |
| /dev/sda1    |                 LUKS  /dev/sda2                |
+--------------+------------------------------------------------+

For now (endeavouros-2019.07.15-x86_64.iso) the only installer shipped with EndeavourOS, the Calamares Installer, doesn’t cope with anything other than the simplest of partitioning schemes.

I personally can’t live with an unencrypted system and this being Arch, it’s just a matter of time (when, not if!) before your system breaks after an update. That’s where snapshots of the root volume come in handy. No matter how bad the system breaks, I’m always able to revert to a snapshot in under five minutes. This is why I need a LVMonLUKS installation with a separate home volume; I wouldn’t want to reset my personal files residing in /home, just everything in root.

Below is a quite lengthy manual method to achieve my desired installation. I do hope that EndeavourOS will eventually ship with an installer that supports this, like Manjaro-Architect does or the now dysfunctional Cnchi did; but I wouldn’t place any bet on calamares getting it done anytime soon.

+++ Howto: LVMonLUKS (with separate /home volume) ++++++++++++++++++++++++++++++++
(Disclaimer: only tested in VirtualBox for now)


#01 - Boot into Live-CD environment
With the help of GParted, assuming you have an empty disk

  • create a GPT partition table
  • create sda1 with 512MiB, format fat32 and set boot & esp flag
  • create sda2 with xGiB unformatted
  • leave a rest of 6GiB unallocated
+------------+-------------+-------------+
|     512MiB |     restGiB |        6GiB |
| boot & esp | unformatted | unallocated |
| flag set   |             |             |
| /dev/sda1  | /dev/sda2   |             |
+------------+-------------+-------------+

The minimum of 6GB space will hold a temporary installation. We will later reclaim this space by adding it to the LUKS partition on /dev/sda2. For this to work the LUKS partition must reside to the left of the temporary partition. Growing a LUKS partition on the right is easy to achieve.


#02 - Install temporary system with calamares
Set up calamares like you usually would (Location, Keyboard, Users, …) but
choose Manual partioning and edit (double-click) …

  1. sda1
  • Mount point -> /boot/efi
  • set boot flag
  • keep fat32
  1. free space
  • Mount point -> /
  • File system -> ext4
  • Encrypt (choose easy password as this is only temporary)

Let Calamares finish the installation. If you get a warning about missing esp or boot flag(s) on /dev/sda1 just add them with GParted and continue with the install.


#03 - Reboot & test; reboot into live-cd
After the install finishes reboot and check if you can access the encrypted system.
You should now have a LUKS encrypted system (without the fun stuff like logical volumes).
Reboot into the Live-Cd environment.


#04 - Open (unencrypt) and mount temporary system
Open a Terminal and type (or mark and copy line with ctrl-c and paste in terminal with shift-ctrl-v) …

sudo cryptsetup luksOpen /dev/sda3 crypttemp
sudo mkdir -p /media/crypttemp
sudo mount /dev/mapper/crypttemp /media/crypttemp

Our temporary installation data is now accessible under /media/crypttemp and can be copied to the new system we will be setting up in the next steps.


#05 - Set up new LVMonLUKS system

sudo su
cryptsetup luksFormat --type luks1 /dev/sda2

The --type luks1 is crucial because GRUB does not support LUKS2 yet. If your /boot directory is on a LUKS-encrypted device and you use GRUB as your bootloader, it won’t work.
Choose a secure password (https://xkcd.com/936/)!

cryptsetup luksOpen /dev/sda2 crypt
pvcreate /dev/mapper/crypt
vgcreate vg0 /dev/mapper/crypt

.
A good starting size for the root volume (lvroot) is about 30GiB. If you’re planning on using a swapfile residing on root later on, you should factor that in.
Resizing the volumes later on is quite easy, so don’t give this too much thought.
You could assign all the free space left to the home volume with
lvcreate --extents 100%FREE vg0 -n lvhome
but for growing the volumes later on and for snapshots one needs empty space inside the volume group, so I usually choose a size for lvhome that leaves about 30GiB overall unused space in the volume group (assuming a 500GB drive e. g. 500 - 0.512 - 40 - 430 = 29.488)

lvcreate -L 40G vg0 -n lvroot
lvcreate -L 430G vg0 -n lvhome

.
Create a ext4 filesystem on the logical volumes.

mkfs.ext4 -L root /dev/mapper/vg0-lvroot
mkfs.ext4 -L home /dev/mapper/vg0-lvhome
exit


#06 - Mount new system to /mnt

sudo mount /dev/mapper/vg0-lvroot /mnt
sudo mkdir -p /mnt/boot/efi
sudo mount /dev/sda1 /mnt/boot/efi
sudo mkdir -p /mnt/home
sudo mount /dev/mapper/vg0-lvhome /mnt/home

.

lsblk

should now provide a similar output to the following (ignore the sizes, these come from a test install)

NAME             MAJ:MIN RM  SIZE RO TYPE  MOUNTPOINT
loop0              7:0    0  1.2G  1 loop  /run/archiso/sfs/airootfs
sda                8:0    0   20G  0 disk  
├─sda1             8:1    0  512M  0 part  /mnt/boot/efi
├─sda2             8:2    0 13.7G  0 part  
│ └─crypt        254:1    0 13.7G  0 crypt 
│   ├─vg0-lvroot 254:2    0    8G  0 lvm   /mnt
│   └─vg0-lvhome 254:3    0    2G  0 lvm   /mnt/home
└─sda3             8:3    0  5.9G  0 part  
  └─crypttemp    254:0    0  5.9G  0 crypt /media/crypttemp
sr0               11:0    1  1.3G  0 rom   /run/archiso/bootmnt

#07 - Copy temporary system to empty new mount points

sudo rsync -avA /media/crypttemp/ /mnt


#08 - Unmount temporary system

sudo umount /media/crypttemp
sudo cryptsetup luksClose crypttemp


#09 - Add existing keyfile to Slot 1 of our LUKS-partition

sudo cryptsetup luksDump /dev/sda2

A LUKS-partition can store and be opened by up to eight different passwords. Right now only Slot 0 contains a key (your chosen password) to decrypt. We will now add a second key which was generated by the temporary install. We will reference this key in step 11.

sudo cryptsetup luksAddKey /dev/sda2 /mnt/crypto_keyfile.bin


#10 - OPTIONAL: Install gedit in live-cd environment
The following step isn’t actually necessary. I’m just so used to gedit. If you don’t want to or can’t install to your live-environment just substitute gedit with mousepad from here on forward.

sudo pacman -S gedit


#11 - Set up /etc/crypttab

sudo cryptsetup luksUUID /dev/sda2

for example returns 384fb0a7-101a-4c58-8ed7-4ea177a761e0. Your UUID will be different, so make sure you use your UUID in the next step!

sudo gedit /mnt/etc/crypttab

contains an uncommented line starting with luks-
Change this line to the following; remebmer to use your UUID.

cryptlvm UUID=384fb0a7-101a-4c58-8ed7-4ea177a761e0 /crypto_keyfile.bin luks

Save and exit.


#12 - Set up /etc/mkinitcpio.conf

sudo gedit /mnt/etc/mkinitcpio.conf

Change the HOOKS=… line by adding lvm2 and resume.

HOOKS="base udev autodetect modconf block keyboard keymap encrypt lvm2 resume filesystems fsck"

Save and exit.


#13 - Set up /etc/fstab

sudo blkid -s UUID -o value /dev/mapper/vg0-lvroot

returns the UUID of the root volume. For example 5bd28f54-6804-423c-a8c5-f13913793b9a.

sudo blkid -s UUID -o value /dev/mapper/vg0-lvhome

returns the UUID of the home volume. For example de5f20c7-6d53-4f0b-a2c4-8cd8a64eb454.

sudo gedit /mnt/etc/fstab

contains a line starting with /dev/mapper/luks-
Remove this line and add the following; remember to use your UUIDs.

UUID=5bd28f54-6804-423c-a8c5-f13913793b9a / ext4 defaults,acl,noatime,discard 0 0

UUID=de5f20c7-6d53-4f0b-a2c4-8cd8a64eb454 /home ext4 defaults,acl,noatime,discard 0 0

Save and exit.


#14 - Set up /etc/default/grub

sudo cryptsetup luksUUID /dev/sda2

returns the UUID of the ‘cryptdevice’. For example 384fb0a7-101a-4c58-8ed7-4ea177a761e0.

sudo gedit /mnt/etc/default/grub

Change to the following; remember to use your UUID after cryptdevice=/dev/disk/by-uuid/....

GRUB_CMDLINE_LINUX_DEFAULT="audit=0 loglevel=3"

GRUB_CMDLINE_LINUX="cryptdevice=/dev/disk/by-uuid/384fb0a7-101a-4c58-8ed7-4ea177a761e0:cryptlvm:allow-discards rd.luks.options=discard"

GRUB_ENABLE_CRYPTODISK=y

Save and exit.


#15 - Repair GRUB UEFI system

sudo su

arch-chroot /mnt

mkinitcpio -p linux

grub-mkconfig -o /boot/grub/grub.cfg

grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=EndeavourOS-grub

rm -rf /boot/efi/EFI/EndeavourOS

cp /boot/efi/EFI/EndeavourOS-grub/grubx64.efi /boot/efi/EFI/boot/bootx64.efi

exit

#16 - Reboot & test new encrypted LVMonLUKS system

sudo umount -R /mnt
sudo reboot

FINISHED! You should now have a functioning LVMonLUKS system with a separate logical volume for /home.


+++ OPTIONAL Howto: Add space of temporary partition to LUKS-partition +++++++++++++++++
You could reformat /dev/sda3 and use it as unencrypted storage, but here we will reclaim the space and assign it to e. g. our home volume.


#17 - Reboot into the Live-Cd environment.


#18 - Delete sda3 (temporary EndeavourOS Install)

sudo fdisk -l

displays some information regarding our disks and partitions.

.
We will now delete /dev/sda3. Just enter the letters below in this order.

sudo fdisk /dev/sda

> p
> d
> 3 (delete partition 3)
> w (write changes to disk)

#19 - Extend /dev/sda2 (LUKS-partition) and the volume group

sudo fdisk /dev/sda

> d
> 2 (delete partition 2)
> n
> 2 (recreate partition 2)
>   (first sector is 'default'; press enter)
>   (last sector is 'default'; press enter)
> n (keep existing filesystem signature)
> w (write changes to disk)

sudo cryptsetup luksOpen /dev/sda2 crypt
sudo cryptsetup resize crypt -v

sudo e2fsck -f /dev/mapper/vg0-lvroot
sudo e2fsck -f /dev/mapper/vg0-lvhome

sudo pvresize /dev/mapper/crypt

.
The volume group vg0 now contains the space we freed up by deleting /dev/sda3. It was added as free space one could use for snapshots or future assigning to the root or home volume.


#20 - Grow home volume
Theoretically you should be able to resize logical volumes with KDE Partition Manager. I’ve actually never tried this and will stick to the cli.

Some information on how to convert/calculate sectors, MB, PE’s:

  • sectors / 2048 / 4 = PE
  • PE *4 = MiB *2048 = sectors
    If your calculations return a non-integer of PE’s, you have to round it down!

sudo fdisk -l
sudo vgdisplay
sudo lvdisplay
will provide information regarding used (allocated) and free space.

Examples for different growing possibilities:

  • grow lvroot by 32326 PE
    sudo lvextend -l+32326 /dev/mapper/vg0-lvroot

  • extend the volume to 150GB
    sudo lvextend -L150G /dev/mapper/vg0-lvroot

  • extend the volume by 10GB
    sudo lvextend -L+10G /dev/mapper/vg0-lvroot

  • fill all of the unallocated space in the volume group
    sudo lvextend -l +100%FREE /dev/vg0-lvroot

.
But we will now add the formerly freed up space (6GB) to the home volume.

sudo lvextend -L+6G /dev/mapper/vg0-lvhome

adds 6GB to the logical home volume.

The filesystem residing in our logical volume needs to be adjusted as well. We will grow the filesystem to the maximum size to add the 6GB.

sudo resize2fs -p /dev/mapper/vg0-lvhome

Let’s check the resized logical volumes filesystem …

sudo e2fsck -f /dev/mapper/vg0-lvhome

DONE! You can leave the live-cd environment and reboot into your LVMonLUKS-system.


+++ OPTIONAL Howto: Get autologin working in XFCE +++++++++++++++++++++++++++++++
If you by any chance opted for the autologin option in the calamares installer you may have noticed that this doesn’t work. Yes, calamares can’t even get this right. Luckily there is an easy fix.


#21 - Get autologin working in XFCE …

yay -S lightdm-settings

Run the app Login Window. This can now also be opened from Settings Manager.

Under the ‘Users’ tab, you can enter the user that will get logged in automatically.


+++ OPTIONAL Howto: Make a swapfile (with working hibernation) +++++++++++++++++++++++


#22 - Make a swapfile

If you want to use hibernation, then you must add swap because the content of the RAM will be written to the swap partition/file. This also means that the swap size should be at least the size of RAM.

.
The following commands will produce a swapfile the size of 8GB.

sudo fallocate -l 8G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

To check …

swapon --show


#23 - Edit /etc/fstab to enable the swapfile after reboot

sudo gedit /etc/fstab

Add the following line …

/swapfile none swap defaults,pri=-2 0 0

Save and exit.


#24 - Activate hibernation

sudo blkid -s UUID -o value /dev/mapper/vg0-lvroot

returns the UUID of the root volume. For example 53d2a76e-13b8-4a29-affc-197b33a706c1.

sudo filefrag -v /swapfile | awk '{if($1=="0:"){print $4}}'

returns the swapfile offset. For example 997376.., which means 997376.

sudo gedit /etc/default/grub

Change to the following; remember to use your UUID and offset.

GRUB_CMDLINE_LINUX_DEFAULT="audit=0 loglevel=3 resume=UUID=53d2a76e-13b8-4a29-affc-197b33a706c1 resume_offset=997376"

Save and exit.

.
If you didn’t already follow step #12 and add resume to /etc/mkinitcpio.conf, do this now …

sudo gedit /etc/mkinitcpio.conf

Change the HOOKS=… line by adding resume.

HOOKS="base udev autodetect modconf block keyboard keymap encrypt lvm2 resume filesystems fsck"

Save and exit.

.
Let the system know that some things have changed …

sudo mkinitcpio -p linux

sudo grub-mkconfig -o /boot/grub/grub.cfg

sudo grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=EndeavourOS-grub

DONE! You should now have a swapfile and be able to hibernate.


7 Likes

Bloody exelent tutorial!

applauding like a circus seal on chrystal meth

1 Like