Skip to content

Instantly share code, notes, and snippets.

@dwettstein
Last active March 17, 2024 06:26
Show Gist options
  • Save dwettstein/8e3ac6afd8925e1e4236ac71d68e137d to your computer and use it in GitHub Desktop.
Save dwettstein/8e3ac6afd8925e1e4236ac71d68e137d to your computer and use it in GitHub Desktop.

Guide Linux on LUKS and LVM

This guide describes how to prepare an USB stick or storage drive before installing Linux, including partitioning, creating LUKS and LVM, and configuring the OS after installation. Note that most commands need to be executed with sudo permissions.

Author: David Wettstein
Version: 1.1.1, 2022-07-28
License: Copyright (c) 2020-2022 David Wettstein, licensed under the Creative Commons Attribution-ShareAlike 4.0 International License.
Link: https://gist.github.com/dwettstein/8e3ac6afd8925e1e4236ac71d68e137d

Table of Contents

Create Partitions

Create a GPT partition table using fdisk (resp. gdisk), parted or GParted. Then create the partitions according to your requirements. If you need to be able to boot on legacy BIOS systems (not UEFI with CSM), the partition table needs to be in MBR format instead of GPT.

NOTE: Make sure you allocate at least 500 MB (I would even recommend 1 GB) for the /boot partition, otherwise you will have problems updating the Linux kernel.

Partitions 128 GB USB

No Name, Label Filesystem Size Flag
1 EFI System, ESP fat32 550 MiB boot, esp
2 GRUB cleared 100 MiB bios_grub
3 Data (optional) fat32 16 GiB msftdata
4 Boot ext4 1 GiB -
5 Linux encr. lvm ~102 GiB lvm

NOTE: The partition "Data" is optional and can be used to pretend an usual 16 GB USB stick.

Partitions 128 GB USB

Partitions 1000 GB Dual Boot

No Name, Label Filesystem Size Flag
1 EFI System, ESP fat32 550 MiB boot, esp
2 GRUB cleared 100 MiB bios_grub
3 Microsoft Reserved, MSR cleared 16 MiB msftres
4 Windows ntfs 500 GiB msftdata
5 Recovery (optional) or ntfs 1 GiB hidden, diag
Data (optional) ntfs 50 GiB msftdata
6 Boot ext4 1 GiB -
7 Linux encr. lvm ~402 GiB lvm

NOTE: The partitions "Recovery" or "Data" are optional. The latter can be used to transfer files from Windows to Linux and vice versa, when both OS are encrypted (make sure you use VeraCrypt or something similar).

Partitions 1000 GB Dual Boot

sudo -i  # If not already

# See `man parted` or `man gdisk` for documentation.

parted --list  # First, get an overview of the partition layout on all devices
# or
gdisk -l

# Don't forget to update these values!
export DEV="/dev/nvme0n1"

parted $DEV print  # Verify device, as all data on it will be lost

# When using the interactive mode by executing `parted`, the following options
# can be useful:
# parted unit MiB
# parted select $DEV

parted $DEV mktable gpt  # Or `msdos`, if you need a MBR partition table

# For MBR partition tables, add one of the following partition type after
# `mkpart`: primary, logical, extended
parted --script $DEV mkpart ESP fat32 '0%' 550MiB
parted --script $DEV set 1 esp on

parted --script $DEV mkpart GRUB 550MiB 650MiB
parted --script $DEV set 2 bios_grub on

parted --script $DEV mkpart MSR 650MiB 666MiB
parted --script $DEV set 3 msftres on

parted --script $DEV mkpart Windows ntfs 666MiB 512666MiB

parted --script $DEV mkpart Data ntfs 512666MiB 563866MiB

parted --script $DEV mkpart 'Linux Boot' ext4 563866MiB 564890MiB

parted --script $DEV mkpart Linux 564890MiB '100%'
parted --script $DEV set 7 lvm on

# Have a look at the created partitions
parted <<< "select $DEV unit MiB print"
# or
gdisk -l $DEV

Preparation

sudo -i  # If not already

# Don't forget to update these values!
export DEV="/dev/nvme0n1"
export DEVPNO="7"
export VG="vg01"

export DM="${DEV##*/}$( if [[ "$DEV" =~ "nvme" ]]; then echo "p"; fi )"
export DEVP="${DEV}$( if [[ "$DEV" =~ "nvme" ]]; then echo "p"; fi )"

printf "DM: $DM; DEVP: $DEVP; Partition Number: $DEVPNO\\n"

Create LUKS

sudo -i  # If not already

# First prepare device with random data
cryptsetup luksFormat --hash=sha512 --key-size=512 --verify-passphrase ${DEVP}${DEVPNO}
cryptsetup luksOpen ${DEVP}${DEVPNO} ${DM}${DEVPNO}_crypt
# Fill the device with 0s (will look like random data in the end, but is faster)
dd if=/dev/zero of=/dev/mapper/${DM}${DEVPNO}_crypt bs=1M
cryptsetup luksClose ${DM}${DEVPNO}_crypt
# Override the header, use /dev/urandom this time
dd if=/dev/urandom of=${DEVP}${DEVPNO} bs=512 count=20480

# Now repeat LUKS creation for real use
# Default hash and key size is only 256 bits
cryptsetup luksFormat --hash=sha512 --key-size=512 --verify-passphrase ${DEVP}${DEVPNO}
cryptsetup luksOpen ${DEVP}${DEVPNO} ${DM}${DEVPNO}_crypt

Create LVM

sudo -i  # If not already

pvcreate /dev/mapper/${DM}${DEVPNO}_crypt
vgcreate ${VG} /dev/mapper/${DM}${DEVPNO}_crypt

# Example sizes for ~100 GB in total
# Swap size up to equal size of RAM to allow hibernation
lvcreate -n home -L 32G ${VG}
lvcreate -n opt -L 16G ${VG}
lvcreate -n root -L 32G ${VG}
lvcreate -n swap -L 4G ${VG}
lvcreate -n var -L 16G ${VG}

Setup OS Post Installation

sudo -i  # If not already

# Don't forget to update these values!
export DEVPNO_ESP="1"
export DEVPNO_BOOT="6"
printf "ESP: ${DEVP}${DEVPNO_ESP}; Boot: ${DEVP}${DEVPNO_BOOT}\\n"

mount /dev/mapper/${VG}/root /mnt
# mount /dev/mapper/${VG}/var /mnt/var
mount ${DEVP}${DEVPNO_BOOT} /mnt/boot
mount ${DEVP}${DEVPNO_ESP} /mnt/boot/efi
for i in /dev /dev/pts /proc /sys /run; do mount -B $i /mnt$i; done

chroot /mnt

blkid

# Check if crypttab is OK
vim /etc/crypttab
# ${DM}${DEVPNO}_crypt UUID=... none luks,discard

# Check if fstab is OK
vim /etc/fstab
# UUID=... / ext4 errors=remount-ro 0 2
# UUID=... /boot ext4 defaults 0 2
# UUID=... /boot/efi vfat defaults 0 2
# UUID=... /home ext4 defaults 0 2
# UUID=... /opt ext4 defaults 0 2
# UUID=... /var ext4 defaults 0 2

# Install GRUB for BIOS boot:
apt install grub-pc
grub-install --target=i386-pc --boot-directory=/mnt/boot --recheck ${DEVP}  # --removable (if USB)

# Install GRUB for UEFI boot:
apt install grub-efi grub-efi-amd64-signed
grub-install --target=x86_64-efi --uefi-secure-boot --boot-directory=/mnt/boot --efi-directory=/mnt/boot/efi --recheck ${DEVP}  # --removable (if USB)

# If needed, edit custom GRUB config in /etc/grub.d/40_custom
# or create the file /mnt/boot/grub/custom.cfg.
# Furthermore, if you need additional Kernel parameters, add them to
# GRUB_CMDLINE_LINUX_DEFAULT in the file /etc/default/grub.
# These might be: i8042.nopnp=1 pci=nocrs iommu=soft
# resume=LABEL=swap or resume=UUID=...

# Create a new initramfs image and update GRUB
# To update existing initramfs images, replace -c with -u
update-initramfs -k all -c

update-grub
# or
grub-mkconfig -o /mnt/boot/grub/grub.cfg

# Exit chroot
exit

# Deactivate VG and close LUKS
vgchange -a n ${VG}
cryptsetup luksClose ${DM}${DEVPNO}_crypt

Change keyboard language

sudo dpkg-reconfigure keyboard-configuration
# Check if it was set properly
cat /etc/default/keyboard

Setup WiFi

# Either use nmtui or nmcli
read -ers -t 60 -p "Password: " pswd
sudo nmcli dev wifi connect "your-wifi-ssid" password "$pswd"

# Or edit the network interfaces directly
sudo vi /etc/network/interfaces
# Add following settings
# wpa-ssid "your-wifi-ssid"
# wpa-psk "your-wifi-password"

Update repositories and upgrade packages

sudo apt -y update
sudo apt -y upgrade

References

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