Skip to content

Instantly share code, notes, and snippets.

@superjamie
Last active November 8, 2024 18:28
Show Gist options
  • Save superjamie/d56d8bc3c9261ad603194726e3fef50f to your computer and use it in GitHub Desktop.
Save superjamie/d56d8bc3c9261ad603194726e3fef50f to your computer and use it in GitHub Desktop.
How to install Ubuntu with LUKS Encryption on LVM

How to install Ubuntu with LUKS Encryption on LVM

My work requires us to have full-disk encryption, so these are the steps I use.

The basic idea is to create a LUKS-encrypted partition which is used as an LVM Physical Volume.

The GRUB boot partition isn't encrypted, but everything else is.

These steps tested and working on 22.04 (jammy) and 20.04 (focal).

Steps

Boot from the Ubuntu LiveUSB. I am actually using Ubuntu MATE.

Open the terminal application and become root:

sudo -s

If you're using storage which had something on it before, you might want to ATA Secure Erase and reboot again.

If using BIOS Legacy Boot, use fdisk /dev/sda to create partitions like:

  • sda1 - at least 512M - type 83 Linux
  • sda2 - rest of disk - type 8e LVM seems fine, or type e8 LUKS

If using UEFI, use gdisk /dev/sda to create partitions like:

  • sda1 - at least 512M - type EF00 EFI System Partition
  • sda2 - at least 512M - type 8300 Linux
  • sda3 - rest of disk - type 8309 LUKS

If using UEFI, format the EFI System Partition as FAT32:

mkfs.vfat -F 32 /dev/sda1

For the rest of this tutorial, I will refer to the LUKS partition as sdaX. Select sda2 or sda3 as appropriate for your system.

Encrypt the LUKS partition with a passphrase:

cryptsetup luksFormat /dev/sdaX

Mount the encrypted partition with your passphrase:

cryptsetup open /dev/sdaX luks1

The encrypted partition is now mounted at /dev/mapper/luks1.

Treat /dev/mapper/luks1 as an LVM PV and create your volumes. Mine are like:

  • Volume Group vg_hostname
    • Logical Volume lv_root - Probably at least 20G, maybe 30 or 40
    • Logical Volume lv_swap - Optional, maybe not desirable if you have an SSD
    • Logical Volume lv_home - Rest of the space

Commands to do this are:

pvcreate /dev/mapper/luks1
vgcreate vg_hostname /dev/mapper/luks1
lvcreate -L 30G -n lv_root vg_hostname
lvcreate -L 512M -n lv_swap vg_hostname
lvcreate -l100%FREE -n lv_home vg_hostname

Run the regular installer, choose custom partitioning.

If using BIOS Legacy Boot, set it up like:

  • /dev/sda1 - ext4 or XFS at /boot
  • /dev/mapper/vg_hostname-lv_root - ext4 or XFS at / (root)
  • /dev/mapper/vg_hostname-lv_home - ext4 or XFS at /home
  • Add swap if you created it
  • Install bootloader into /dev/sda

If using UEFI, set it up like:

  • /dev/sda1 - EFI System Partition
  • /dev/sda2 - ext4 or XFS at /boot
  • /dev/mapper/vg_hostname-lv_root - ext4 or XFS at / (root)
  • /dev/mapper/vg_hostname-lv_home - ext4 or XFS at /home
  • Add swap if you created it

When the installer finishes, don't reboot.

The system currently won't boot from disk, so stay in the LiveUSB environent.

(If you accidentally do reboot, that's fine, just get back into the LiveUSB and cryptsetup open again then pvscan; vgscan; lvscan to find the LVM volumes)

Open the terminal application and become root:

sudo -s

We'll now create a chroot and enter the installed system:

## /target will already exist in the live environment post-install
mkdir -p /target
## mount the root filesystem at /target
mount /dev/mapper/vg_hostname-lv_root /target
## mount some extra stuff so the chroot works
for DIR in proc sys dev /etc/resolv.conf; do mount --rbind /$DIR /target/$DIR; done
## enter the chroot
chroot /target
## we are now inside the installed system, not the live environment
## the following command mounts /boot (and /boot/efi if present) so initramfs/GRUB updates work
mount -a

Get the UUID of the encrypted outer partition sdaX with:

blkid
/dev/sdaX: UUID="abcdef-abcd-abcd-abcd-abcd-abcd-abcdef" TYPE="crypto_LUKS"

Using the above UUID, create the file /etc/crypttab with the contents:

luks1 UUID="abcdef-abcd-abcd-abcd-abcd-abcd-abcdef" none luks

The none parameter makes the system ask for passphrase on boot.

Edit /etc/default/grub and set:

GRUB_ENABLE_CRYPTODISK=y

As of kernel 5.11.0-40-generic there's a ~45-second pause at boot while the system tries to find a non-existent resume device, so we'll disable resume.

Create the file /etc/initramfs-tools/conf.d/noresume.conf with contents:

RESUME=none

If you want to mount /tmp as tmpfs (ramdisk) then:

sudo ln -s /usr/share/systemd/tmp.mount /etc/systemd/system/ 
sudo systemctl enable tmp.mount

Update the initramfs for all installed kernels:

update-initramfs -u -k all

Update the GRUB bootloader config:

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

Exit the chroot with Ctrl+d and turn the system off gracefully with poweroff.

Remove the LiveUSB, boot normally.

You will be asked for your encryption passphrase before boot proceeds.

References

Author and License

History

  • 2021-11 - First publish
  • 2022-01 - Add UEFI steps, remove mid-install reboot, add license, tidy here and there
  • 2022-04 - Works on 22.04 as well
  • 2022-11 - Fix a typo, remove my old Asus-laptop-specific microcode workaround from a general guide
@mauriciogracia
Copy link

Are there any considerations to keep in mind, If my hard drive is SSD with Windows 10 and I dont want to lose my data (besides a backup) - I want dual boot with LVM and LUKS enabled

@superjamie
Copy link
Author

I don't know sorry, I haven't used Windows since XP and don't know how it handles UEFI at all. There was a change in Ubuntu 22.04 to disable GRUB's os-prober so it won't look for existing Windows installs. You have some research and testing to do.

@mauriciogracia
Copy link

mauriciogracia commented Jun 2, 2022

I has able to follow the above instructions while keeping Windows intact (backup your data as usual when dealing with partition changes)

There are the steps/notes about it

  1. In Windows I used a free tool called IM-Magic Partition Resizer to shrink my C: partition beyond what the "windows shrink partition" optioned allowed me - https://www.resize-c.com/howto/freeware-to-resize-partition-in-windows-10.html
  2. There is no need to create or format the EFI System Partition since Windows has already created
  3. The sda2 partition only needs to be 512M - type 8300 Linux because it will be the /boot and nothing else (rest of Linux will be inside the LVM partitions using the rest of the available space)
  4. the command lvcreate -l100%FREE is lower-caseL-no-space-100%FREE
  5. When installing Ubuntu you need to select each of the NEW partitions, select the file system, select the option to format it and select the mount point
  6. After powering off and powering up, you might need to press a F-key in order to bring the EFI options to boot, in my case it was F9 but you need to check your bios. (this is probably because I did not format/touch my EFI system partition and in this way avoided misconfiguring windows boot process)

@superjamie
Copy link
Author

Cool, good work! With /boot at 512M make sure you delete old kernels so the filesystem doesn't fill. At most you can keep 3 old kernels installed. The configuration of apt package manager for this is discussed at https://askubuntu.com/questions/563483/why-doesnt-apt-get-autoremove-remove-my-old-kernels

@vijay-at-work
Copy link

This is a great writeup and exactly what I was looking for! Thanks superjamie for putting it out.
I did it a bit differently, instead of /dev/sdaX being a container partition hosting all the logical volumes, I used existing logical volumes as follows -

/dev/sdaY fat32 --- UEFI partition
/dev/mapper/vg_ubuntu-boot ext2 /boot boot partition
/dev/mapper/vg_ubuntu-luks LUKS --- encrypted outer block device
|---> /dev/mapper/root ext4 / ubuntu root partition

The above logical volumes could be created from any existing PVs as follows -

sudo lvcreate vg_ubuntu -n luks -L 25G
sudo lvcreate vg_ubuntu -n boot -L 1G
sudo cryptsetup luksFormat /dev/mapper/vg_ubuntu-luks
sudo cryptsetup open /dev/mapper/vg_ubuntu-luks root
sudo mkfs.ext4 -j /dev/mapper/root

In the Ubuntu installer, use /dev/mapper/root for the root partition and /dev/mapper/vg_ubuntu-boot for the boot partition.
For rest of the setup follow superjamie's instructions.
The /etc/crypttab and GRUB_ENABLE_CRYPTODISK=y were the important parts of the encrypted lvm based installation.

@superjamie
Copy link
Author

Yes, though keep in mind only your root filesystem will be encrypted that way. By encrypting the whole LVM PV, I also encrypt my home filesystem and swap area so they are secure at rest.

@vijay-at-work
Copy link

Totally agree.
For me everything was under / including /home and I did this way because I primarily use logical volumes for everything. In fact I have chunked my hard disk into fixed size partitions that serve as LVM PVs. That way I am able to resize the volumes at will without having to move around partitions just because I need more space.

@szocsbarni
Copy link

such a great article, thx, helped me a lot. why is it required to have the /boot as a separate partition, in an EFI scenario? I have tried to encrypt the /boot too, but grub fails to load then.

@devniel
Copy link

devniel commented Sep 17, 2022

thanks for the guide!! I agree with @mauriciogracia, EFI partition is not necessary (I unmounted it with gpart after the installation) if Windows one is already there; the only thing that needs to be done is to add Windows to grub via update-grub using:

sudo echo GRUB_DISABLE_OS_PROBER=false >> /etc/default/grub && sudo update-grub

On my case, I have now Ubuntu encrypted (LUKS) + Windows encrypted (bitlocker) in dual boot 😁

@superjamie
Copy link
Author

Yes, an EFI system just needs an EFI System Partition. In my case I'm not using Windows at all so I created one. If an ESP already exists because of some other OS, then there's no need to create another one (it would probably be wrong to have two ESPs).

@rebeldevop I find the unencrypted /boot a simpler setup. Apparently GRUB's EFI loader can read /boot from a LUKS-encrypted LVM root (see https://outflux.net/blog/archives/2017/08/30/grub-and-luks/) but I've never done it myself and it seems very fiddly.

@wurzelsand
Copy link

Great article! Helped me a lot to install Xubuntu alongside Windows over an existing encrypted Linux installation whose home partition I wanted to keep. 👍

@radekcrlik
Copy link

I thank you. I thank you dearly. I wish luck to you, your family, and your children for 100 generations!
This was exactly what I was looking for. I spent 3 days unable to make Ubuntu work with this disc layout. I really don't know why it's that complicated.

@tux2bsd
Copy link

tux2bsd commented Dec 7, 2023

cryptsetup open /dev/sdaX luks1

suggested tweak:

cryptsetup luksOpen /dev/sdaX luks1

A little clearer to about the "luks"-ness in is occuring, since cryptsetup covers range of things.

@fuckFH
Copy link

fuckFH commented Apr 28, 2024

It looks like the "new" installer (Subiquity) in Ubuntu 24.04 works in another way. The installer doesn't detect the LVM partitions. It would be nice if you can update your tutorial.

@superjamie
Copy link
Author

I no longer use Ubuntu sorry.

@doman18
Copy link

doman18 commented May 29, 2024

Tried this with Kubuntu 22.04 in in virtualbox. I had no issues with any of steps - disk setup, mounting in installer, chrooting, crypttab, initramfs conf, initramfs update and grub.cfg creation. But after restart Im getting Kernel panic - not syncing: VFS: Unable to mount root fs on uknown-block(0,0). I tried twice with the same result.

~~Previously i tried to install it with installers encryption (full disk encryption option) and it worked. ~~

Ok the problem was trivial - too small root volume (10GB). Weirdly enough installer did not complain about it. After making larger (12GB) all went smoothly

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment