Skip to content

Instantly share code, notes, and snippets.

@OdinsPlasmaRifle
Last active March 29, 2024 14:12
Show Gist options
  • Star 80 You must be signed in to star a gist
  • Fork 15 You must be signed in to fork a gist
  • Save OdinsPlasmaRifle/e16700b83624ff44316f87d9cdbb5c94 to your computer and use it in GitHub Desktop.
Save OdinsPlasmaRifle/e16700b83624ff44316f87d9cdbb5c94 to your computer and use it in GitHub Desktop.
LVM on LUKS Arch installation with systemd-boot

Arch Linux Installation

LVM on LUKS Arch installation with systemd-boot

Sources:

Note: If you want a simpler encryption setup (with LUKS only), you can instead use the archinstall "guided" installer included with Arch since April 2021.

USB

Download Arch Linux. Prepare an installtion medium (A USB drive is used as an example below).

If you downloaded Arch Linux from a mirror, ensure you verify the file's checksum:

sha1sum file_name.iso
md5sum file_name.iso

The above should yield checksums that you can compare to the official Arch Linux checksums for the file.

Find out the name of your USB drive with lsblk. Make sure that it is not mounted.

To mount the Arch ISO run the following command, replacing /dev/sdx with your drive, e.g. /dev/sdb. (do not append a partition number, so do not use something like /dev/sdb1):

dd bs=4M if=path/to/archlinux-version-x86_64.iso of=/dev/sdx conv=fsync oflag=direct status=progress

Preparation

Boot from the USB drive (ensure Secure Boot is turned off in the BIOS if booting from the USB is failing).

If the current font is unreadable or too small, change it:

setfont sun12x22

Check if you are running in UEFI mode:

ls /sys/firmware/efi/efivars

If no errors are ouputted and the directory exists then the system is booted in UEFI. Otherwise reboot in UEFI.

Check that there is an internet connection:

ping archlinux.org

If you need to connect via Wi-Fi, use iwctl (the interactive prompt for iwd):

$ iwctl
[iwd]# device list
[iwd]# station DEVICE_NAME scan
[iwd]# station DEVICE_NAME get-networks
[iwd]# station DEVICE_NAME connect SSID

Update the system clock:

timedatectl set-ntp true

Lastly, you can modify /etc/pacman.d/mirrorlist if you wish to change the list of mirrors (and order of priority) used when installing packages. It may be worthwhile moving the geogrpahically closest mirrors to the top of the file. This file will be copied to your final system once the installation is complete.

Partitioning

Get the name of the disk to format/partition:

lsblk

The name should be something like /dev/sda

First shred the disk using the shred tool:

shred -v -n1 /dev/sdX

Now partition the disk using gdisk:

gdisk /dev/sda

Partition 1 should be an EFI boot partition (code: ef00) of 512MB. Partition 2 should be a Linux LVM partition (8e00). The 2nd partition can take up the full disk or only a part of it (this is up to you). Remember to write the partition table changes to the disk on configuration completion.

Once partitioned you can format the boot partition (the LVM partition needs to be encrypted before it gets formatted)

mkfs.fat -F32 /dev/sda1

Encryption

First modprobe for dm-crypt

modprobe dm-crypt

Now, encrypt the disk:

cryptsetup luksFormat /dev/sda2

Open the disk with the password set above:

cryptsetup open --type luks /dev/sda2 cryptlvm

Check the lvm disk exists:

ls /dev/mapper/cryptlvm

Create a physical volume:

pvcreate /dev/mapper/cryptlvm

Create a volume group:

vgcreate volume /dev/mapper/cryptlvm

Create logical partitions:

lvcreate -L20G volume -n swap
lvcreate -L40G volume -n root
lvcreate -l 100%FREE volume -n home

Format file system on logical partitions:

mkfs.ext4 /dev/volume/root
mkfs.ext4 /dev/volume/home
mkswap /dev/volume/swap

Mount the volumes and file systems:

mount /dev/volume/root /mnt
mkdir /mnt/home
mkdir /mnt/boot
mount /dev/volume/home /mnt/home
mount /dev/sda1 /mnt/boot
swapon /dev/volume/swap

Installation

Install base package, linux, firmware, lvm2 and utilities:

pacstrap /mnt base base-devel linux linux-firmware lvm2 vim

Generate fstab:

genfstab -U /mnt >> /mnt/etc/fstab

chroot into system:

arch-chroot /mnt

Set time locale (choose a relevant locale):

ln -sf /usr/share/zoneinfo/Africa/Johannesburg /etc/localtime

Set clock:

hwclock --systohc

Uncomment en_US.UTF-8 UTF-8 en_US ISO-8859-1 or whatever localizations you need in /etc/locale.gen. Now run:

locale-gen

Create locale config file:

locale > /etc/locale.conf

Set the lang variable in the above file (Choose the language code that is relevant to you):

LANG=en_US.UTF-8

Add an hostname (any hostname of your choice as one line in the file. eg. myhostname):

vim /etc/hostname

Update /etc/hosts to contain (replace myhostname with the host name you used above):

127.0.1.1   myhostname.localdomain  myhostname

Because our filesystem is on LVM we will need to enable the correct mkinitcpio hooks.

Edit the /etc/mkinitcpio.conf. Look for the HOOKS variable and update it to look like:

HOOKS=(base udev autodetect keyboard keymap modconf block encrypt lvm2 filesystems fsck)

Regenerate the initramfs:

mkinitcpio -p linux

Install a bootloader:

bootctl --path=/boot/ install

Create bootloader. Edit /boot/loader/loader.conf. Replace the file's contents with:

default arch
timeout 3
editor 0

The editor 0 ensures the configuration can't be changed on boot.

Next create a bootloader entry in /boot/loader/entries/arch.conf

title Arch Linux
linux /vmlinuz-linux
initrd /initramfs-linux.img
options cryptdevice=UUID={UUID}:cryptlvm root=/dev/volume/root quiet rw

Replace {UUID} with the UUID of /dev/sda2. In order to get the UUID run the following command:

blkid

Or, while stil in vim, run the following command (replacing /dev/sda2 with the relevant partition):

:read ! blkid /dev/sda2

Complete

Before completeing the final installation steps, you may want to install some additional packages for user and network management (these are included in the installer but are normally not included in the installation itself):

sudo pacman -Syu sudo iw iwd dhcpcd

Set a password for your root user:

passwd

exit chroot:

exit

unmount everything:

umount -R /mnt

and reboot

reboot
@lambroisie
Copy link

Hey @OdinsPlasmaRifle thanks for this guide. I used it recently to install Arch on my desktop. Just a tiny suggestion - were the two mkfs.ext4 /dev/mapper/volume-root statements intentional? I think it makes more sense if one is mkfs.ext4 /dev/mapper/volume-home.

Thanks again for making my recent install as seamless as possible!

@OdinsPlasmaRifle
Copy link
Author

OdinsPlasmaRifle commented Apr 11, 2020

Hey @OdinsPlasmaRifle thanks for this guide. I used it recently to install Arch on my desktop. Just a tiny suggestion - were the two mkfs.ext4 /dev/mapper/volume-root statements intentional? I think it makes more sense if one is mkfs.ext4 /dev/mapper/volume-home.

Thanks again for making my recent install as seamless as possible!

@lambroisie Sorry for the delayed response but I only saw this comment recently when looking through my older gists. I have updated the gist to match your suggestion as you are correct.

I wrote this guide while setting up Linux on a new laptop. Basically, I realized I needed a reference I could look back on if I broke anything too badly! So I didn't really expect others to end up using it .... but I am glad the effort proved useful to others!

@OdinsPlasmaRifle
Copy link
Author

Hi, Thanks for the guide. Just installed it :)
I noticed a mistake where it says mount /mnt/boot - I think you meant mkdir instead of mount

@WithoutCaps thanks for the input (and sorry for the slow reply), you are correct and I have updated the gist accordingly. Hopefully this reduces any future confusion!

@BobCollins42
Copy link

BobCollins42 commented May 7, 2020

Great template for my install!
Comment: I think you need to install the lvm2 package in the arch-chroot enviornment to use the lvm2 HOOK. My mkinitcpio failed because this was missing. It is covered in "Install Arch Linux on LVM" wiki page as:

Tip:
The lvm2 and sd-lvm2 hooks are installed by lvm2, not mkinitcpio. If you are running mkinitcpio in an arch-chroot for a new installation, lvm2 must be installed inside the arch-chroot for mkinitcpio to find the lvm2 or sd-lvm2 hook. If lvm2 only exists outside the arch-chroot, mkinitcpio will output Error: Hook 'lvm2' cannot be found.

Edit: Another issue:
In the arch.conf bootloader file, the last field of the cryptdevice option is :dmname. With you example, this should be "lvm", not the VG name "volume".
The line would be: options cryptdevice=UUID={UUID}:lvm root=...

@Link512
Copy link

Link512 commented Jan 28, 2021

Hi,

Thanks for the guide. Two small observations though:

  • in the arch.conf kernel boot options, root should be root=/dev/volume/root. From the docs: If the root file system is contained in a logical volume of a fully encrypted LVM, the device mapper for it will be in the general form of root=/dev/volumegroup/logicalvolume
  • when you do pacstrap you don't install any linux kernel

@OdinsPlasmaRifle
Copy link
Author

Hi,

Thanks for the guide. Two small observations though:

* in the `arch.conf` kernel boot options, root should be `root=/dev/volume/root`. From the [docs](https://wiki.archlinux.org/index.php/Dm-crypt/System_configuration): `If the root file system is contained in a logical volume of a fully encrypted LVM, the device mapper for it will be in the general form of root=/dev/volumegroup/logicalvolume`

* when you do `pacstrap` you don't install any linux kernel

Hey @Link512, thanks for the feedback!

I quickly ran through the Arch docs and then made changes to the gist wherever it no longer matched the official guides. It seems like several things were out of date and I have updated these wherever I noticed them. Unfortunately I don't have the time right now to run through the whole process again to check whether everything is working still.

Updated the following:

  • Changed the pacstrap command to pacstrap /mnt base base-devel linux linux-fimware lvm2 vim. Seems like the previous pacstrap command was taken from an old revision of the Arch docs. Probably back when I first wrote this guide: https://wiki.archlinux.org/index.php?title=Installation_Guide&diff=253744&oldid=250715
  • Switched the LVM physical volume name to cryptlvm to match the current dm-crypt docs.
  • Updated the genfstab command to the latest recommended format in the docs: genfstab -U /mnt >> /mnt/etc/fstab.
  • Updated the logical partition usage to /dev/volume/{name} (eg. /dev/volume/root, /dev/volume/home and /dev/volume/swap).
  • Updated the arch.conf to match the changes above and use the physical volume cryptlvm instead of the volume group @BobCollins42 for this as well.

@GrumpyChunks
Copy link

GrumpyChunks commented Mar 30, 2021

There's a minor typo in the installation section. The pacstrap command should include 'linux-firmware' not 'linux-fimware'

@OdinsPlasmaRifle
Copy link
Author

@GrumpyChunks thanks for spotting that, updated now.

@cihatertem
Copy link

Hi,
Firstly thanks nice and clean tutorial. I want to learn about combining your set up with systemd-homed too. You know systemd-homed gives us a encrypted home folder and unloads the home while suspend. This security feature does not providing with full disc enc. Is there a way combine both option for better security? Or do we have to choose onlyone of them?

@OdinsPlasmaRifle
Copy link
Author

Hey @Fincan, unfortunately I am not that familiar with systemd-homed... I suspect they can probably work together but I can't say for certain without doing some research, which I don't have a lot of time for at the moment.

@i2
Copy link

i2 commented May 19, 2022

Regarding your note:

I believe this tutorial (because it covers LVM+LUKS) is still relevant because archinstall doesn't support LVM yet, correct?

@OdinsPlasmaRifle
Copy link
Author

Regarding your note:

I believe this tutorial (because it covers LVM+LUKS) is still relevant because archinstall doesn't support LVM yet, correct?

Hey, @i2 I have not tried the archinstall helper myself. But according to the Arch docs it should include a step for configuring disk encryption:

image

However, I am unsure what disk encryption setup it uses and archinstall is experimental software so it may have some issues I am not aware of. In which case, following a guided installation (like this one) might yield more predictable results. Unfortunately, I cannot really give a more definite answer until I try out archinstall myself.

I will continue to maintain this Guide though, as it remains useful for those who want to go through the process manually (and potentially customize individual steps).

@i2
Copy link

i2 commented May 19, 2022

@OdinsPlasmaRifle I am interested in LVM2 and not just LUKS.

@tomjtoth
Copy link

tomjtoth commented Sep 2, 2022

hello, good write-up, please update HOOKS="..." to HOOKS=( ... ), it might break functionality, explanation here.

@OdinsPlasmaRifle
Copy link
Author

Thanks for spotting this @tomjtoth. I have updated to the new HOOKS format.

@zestygrass
Copy link

Hi, thanks to this tutorial, I have working system with LVM on LUKS. Tried with Arch wiki alone twice but I could not get the system to boot afterwards. This helped keeping things clear. Thanks alot.

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