Skip to content

Instantly share code, notes, and snippets.

@broedli
Last active February 3, 2023 02:23
Show Gist options
  • Star 12 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save broedli/5604637d5855bef68f3e to your computer and use it in GitHub Desktop.
Save broedli/5604637d5855bef68f3e to your computer and use it in GitHub Desktop.
ARCH - install uefi on dm-crypt btrfs

Install Arch Linux in an encrypted BTRFS partition with GPT and UEFI support, GRUB2 with unencrypted SWAP

1. Set your environment

loadkeys de-latin1

For installation via SSH:

systemctl start ssh
passwd
pacman -Syy && pacman -S termite-terminfo

Check EFI:

modprobe efivars
stat /proc/efi/vars > /dev/null || systemctl reboot

2. Wipe your existing disk

Make sure you wipe the correct disk! Run lsblk and df -hT if you are not certain!

cryptsetup open --type plain /dev/sda container
dd if=/dev/zero of=/dev/mapper/container 
cryptsetup luksClose container

3. Create partition table

Assuming /dev/sda is the target disk

gdisk /dev/sda

Create your partition table with the following input:

3.1 Override partition table:

o

3.2 Create an EFI partition with the last possible ID (128):

Make this partition with the type EF00 (EFI System Partition). The minimum size for the EFI partition is 64M. This is sufficient for just the EFI bootloader */boot/efi/**.

n , 128 , [ENTER] , +64M , EF00

3.3 Create a SWAP partition:

n , 2 , [ENTER] , +8G , 8200

3.4 Create a ROOT partition:

n , [ENTER] , [ENTER] , [ENTER] , [ENTER]

4. Create filesystems

4.1 Create EFI (FAT32) filesystem:
mkfs.vfat -F32 -n "EFI" /dev/sda128
4.2 Create SWAP:
mkswap -L SWAP /dev/sda2
swapon /dev/sda2
4.3 Create encrypted (outer) volume:
cryptsetup --cipher aes-xts-plain64 --key-size 512 --hash sha512 --iter-time 5000 --use-random --verify-passphrase luksFormat /dev/sda1
4.3.1 Create KeyFile:
dd if=/dev/random of=/tmp/key bs=512 count=4
cryptsetup luksAddKey /dev/sda1 /tmp/key
cryptsetup luksOpen /dev/sda1 crypt -d /tmp/key
4.3.2 Create BTRFS (inner) volume:
mkfs.btrfs -KL "Arch Linux" /dev/mapper/crypt
4.3.3 Mount and the BTRFS volume && Create subvolumes:
mkdir -p /mnt/btrfs-root
mount -o ssd,discard,noatime,compress=lzo /dev/mapper/crypt /mnt/btrfs-root
mkdir -p /mnt/btrfs-root/__snapshot
cd /mnt/btrfs-root && btrfs subvolume create __active && cd __active
btrfs subvolume create system && btrfs subvolume create home
btrfs subvolume create system/rootvol && btrfs subvolume create system/var && btrfs subvolume create system/opt 

Check your work:

btrfs subvolume list .

5. Mount subvolumes (template for later fstab):

mkdir -p /mnt/btrfs-active && cd /mnt/btrfs-active
mount -o ssd,discard,noatime,compress=lzo,nodev,subvol=__active/system/rootvol /dev/mapper/crypt /mnt/btrfs-active
mkdir -p /mnt/btrfs-active/{home,opt,var,boot,boot/efi}
mount -o ssd,discard,noatime,compress=lzo,nosuid,nodev,subvol=__active/home /dev/mapper/crypt /mnt/btrfs-active/home
mount -o ssd,discard,noatime,compress=lzo,nosuid,nodev,subvol=__active/system/opt /dev/mapper/crypt /mnt/btrfs-active/opt
mount -o ssd,discard,noatime,compress=lzo,nosuid,nodev,noexec,subvol=__active/system/var /dev/mapper/crypt /mnt/btrfs-active/var

Check your mountpoints:

df -hT

6. Install BASE SYSTEM

pacstrap /mnt/btrfs-active base base-devel efibootmgr grub-efi-x86_64 cryptsetup btrfs-progs openssh rsync bash-completion curl termite-terminfo wget vim
6.1 Copy luks KeyFile to root:
mv /tmp/key /mnt/btrfs-active/root/luks-keyfile.bin
chmod 000 /mnt/btrfs-active/root/luks-keyfile.bin
6.2 Generate /etc/fstab:
genfstab -pU /mnt/btrfs-active >> /mnt/btrfs-active/etc/fstab
less /mnt/btrfs-active/etc/fstab

7. Chroot into installation

arch-chroot /mnt/btrfs-active /bin/bash
7.1 Set environment for installation:
ln -sf /usr/share/zoneinfo/Europe/Berlin /etc/localtime && tzselect
hwclock --systohc --utc --adjfile /etc/adjtime
loadkeys de-latin1
echo "KEYMAP=de-latin1" >> /etc/vconsole.conf
sed -i 's/#en_US.U/en_US.U/g' /etc/locale.gen && sed -i 's/#de_DE.UTF-8/de_DE.UTF-8/'g /etc/locale.gen && locale-gen
echo LANG=en_US.UTF-8 > /etc/locale.conf && export LANG=en_US.UTF-8
echo "HOSTNAME" > /etc/hostname
7.2 Bootloader (GRUB2) install

Enable HOOKS keymapping, encryption and btrfs; disable fsck:

sed -i 's/HOOKS="base udev autodetect modconf block filesystems keyboard fsck"/HOOKS="base udev autodetect modconf block keyboard keymap encrypt filesystems btrfs"/g' /etc/mkinitcpio.conf

Enable MODULES for keys on external FAT usb drives:

sed -i 's/MODULES=""/MODULES="vfat aes_x86_64 crc32c-intel"/g' /etc/mkinitcpio.conf

For troubleshooting add btrfsck to bootmenu:

sed -i 's,BINARIES="",BINARIES="/usr/bin/btrfsck",g' /etc/mkinitcpio.conf

Include KeyFile into initramfs (not recommendet). When doing this check that initramfs permission are set to 600, or users will be able to dump the keyfile!

sed -i 's,FILES="",FILES="/root/luks-keyfile.bin",g' /etc/mkinitcpio.conf
less /etc/mkinitcpio.conf

Create the initramfs:

mkinitcpio -p linux
chmod 600 /boot/initramfs-linux*

Mount your previously created EFI partition (NOTE: if you created a bigger partition to include kernel and initramfs change mountpoint to /boot):

mkdir -p /boot/efi && mount /dev/sda128 /boot/efi

Install GRUB2 on 64Bit UEFI system:

echo "GRUB_ENABLE_CRYPTODISK=y" >> /etc/default/grub
grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=arch_grub --recheck --debug
7.3 Edit persistent kernel settings:

Add something like cryptdevice=UUID=<UUID of /dev/sda1>:crypt cryptkey=UUID=<UUID of USBKEY>:<fstype>:<path> ... quiet to your GRUB_CMDLINE_LINUX_DEFAULT="" setting in /etc/default/grub:

ls -l /dev/disk/by-uuid | grep sda1
vim /etc/default/grub
7.4 Generate grub.cfg:
grub-mkconfig -o /boot/grub/grub.cfg

Check your work:

less /boot/grub/grub.cfg

8. Exit chroot unmount and reboot

exit
umount -R /mnt/btrfs-root && umount -R /mnt/btrfs-active
reboot
@sk0x1234
Copy link

can you do it with the systemd-boot without grub????

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