Skip to content

Instantly share code, notes, and snippets.

@jeffersfp
Last active May 30, 2024 23:19
Show Gist options
  • Save jeffersfp/57235176d0ba71ee40316cf183969dd8 to your computer and use it in GitHub Desktop.
Save jeffersfp/57235176d0ba71ee40316cf183969dd8 to your computer and use it in GitHub Desktop.
Arch Linux install: gpt + luks + btrfs + systemd-boot

Arch Linux Install

  • GUID Partition Table
  • Encrypted root and swap partitions with dm-crypt
  • Btrfs filesystem with support to snapshots
  • bspwm + polybar

Download the install ISO image at https://archlinux.org/download/

Burn the ISO to a USB drive and boot from it.

At the arch iso root shell, set a passwd and enable ssh daemon:

passwd
systemctl start sshd

Find the ip address of the ethernet interface:

ip addr

Once logged in via ssh, list the hard drives:

fdisk -l

Set the hard drive you want to format:

export DRIVE=/dev/sdX

Format the drive. Partition layout for this guide:

  • 1st partition: EFI - 550MiB
  • 2nd partition: SWAP - 4GiB
  • 3rd partition: System - all left space
    • btrfs subvolumes
      • root
      • home
      • snapshots
sgdisk --clear \
  --new=1:0:+550MiB --typecode=1:ef00 --change-name=1:EFI \
  --new=2:0:+4GiB   --typecode=2:8200 --change-name=2:cryptswap \
  --new=3:0:0       --typecode=3:8300 --change-name=3:cryptsystem \
  $DRIVE

Encrypt the system partition:

cryptsetup luksFormat --align-payload=8192 -s 256 -c aes-xts-plain64 /dev/disk/by-partlabel/cryptsystem
cryptsetup open /dev/disk/by-partlabel/cryptsystem system

Enable encrypted swap partition:

cryptsetup open --type plain --key-file /dev/urandom /dev/disk/by-partlabel/cryptswap swap
mkswap -L swap /dev/mapper/swap
swapon -L swap

Format the partitions:

mkfs.fat -F32 -n EFI /dev/disk/by-partlabel/EFI
mkfs.btrfs --force --label system /dev/mapper/system

Create btrfs subvolumes:

mount -t btrfs LABEL=system /mnt
btrfs subvolume create /mnt/root
btrfs subvolume create /mnt/home
btrfs subvolume create /mnt/snapshots

Mount partitions:

o=defaults,x-mount.mkdir
o_btrfs=$o,compress=lzo,ssd,noatime
umount -R /mnt
mount -t btrfs -o subvol=root,$o_btrfs LABEL=system /mnt
mount -t btrfs -o subvol=home,$o_btrfs LABEL=system /mnt/home
mount -t btrfs -o subvol=snapshots,$o_btrfs LABEL=system /mnt/.snapshots
mkdir /mnt/boot
mount /dev/sda1 /mnt/boot

Discover the best mirros to download packages:

reflector --verbose --country 'United States' --latest 5 --sort rate --save /etc/pacman.d/mirrorlist
sed -i "/\[multilib\]/,/Include/"'s/^#//' /etc/pacman.conf
sed -i "s/#Color/Color/g" /etc/pacman.conf
sed -i "s/#UseSyslog/UseSyslog/g" /etc/pacman.conf
sed -i "s/#VerbosePkgLists/VerbosePkgLists/g" /etc/pacman.conf
sed -i "s/#ParallelDownloads = 5/ParallelDownloads = 50/g" /etc/pacman.conf

Install base system and some basic tools:

pacstrap /mnt base base-devel

Generate fstab entries:

genfstab -L -p /mnt >> /mnt/etc/fstab
sed -i "s+LABEL=swap+/dev/mapper/swap+" /mnt/etc/fstab

Add cryptab entry:

echo "swap /dev/disk/by-partlabel/cryptswap /dev/urandom swap,offset=2048,cipher=aes-xts-plain64,size=256" >> /mnt/etc/crypttab

Chroot into the new system:

arch-chroot /mnt

Setup locale

echo "en_US.UTF-8 UTF-8" > /etc/locale.gen
locale-gen
localectl set-locale LANG=en_US.UTF-8

Enable clock sync and set the timezone

timedatectl set-ntp 1
timedatectl set-timezone America/Sao_Paulo

Setup up the hostname and /etc/hosts entries:

export SYS_NAME=mars
hostnamectl set-hostname ${SYS_NAME}
cat > /etc/hosts <<EOF
127.0.0.1 localhost.localdomain localhost
::1 localhost.localdomain localhost
127.0.1.1 ${SYS_NAME}.localdomain ${SYS_NAME}
EOF

Install reflector:

pacman -Sy reflector

Discover the best mirros to download packages:

reflector --verbose --country 'United States' --latest 5 --sort rate --save /etc/pacman.d/mirrorlist
sed -i "/\[multilib\]/,/Include/"'s/^#//' /etc/pacman.conf
sed -i "s/#Color/Color/g" /etc/pacman.conf
sed -i "s/#UseSyslog/UseSyslog/g" /etc/pacman.conf
sed -i "s/#VerbosePkgLists/VerbosePkgLists/g" /etc/pacman.conf
sed -i "s/#ParallelDownloads = 5/ParallelDownloads = 50/g" /etc/pacman.conf

Install some packages:

PACKAGES=(
  "zsh"
  "git"
  "vim"
  "curl"
  "wget"
  "htop"
  "tree"
  "byobu"
  "intel-ucode"
  "efibootmgr"
  "efitools"
  "mkinitcpio"
  "base-devel"
  "btrfs-progs"
  "gptfdisk"
  "linux"
  "linux-headers"
  "networkmanager"
)
pacman -Sy ${PACKAGES[@]}

Enable NetworkManager:

systemctl enable NetworkManager.service

Set the keyboard map:

echo 'KEYMAP=us' > /etc/vconsole.conf

Generate the initramfs:

sed -i 's/BINARIES=()/BINARIES=(btrfs)/' /etc/mkinitcpio.conf
sed -i 's/^HOOKS=.*/HOOKS=(base\ systemd\ autodetect\ keyboard\ sd-vconsole\ modconf\ block\ sd-encrypt\ filesystems\ fsck)/' /etc/mkinitcpio.conf
mkinitcpio -P

Setup the bootloader:

# get the device uuid
DRIVE_UUID=$(blkid $DRIVE | awk -F '"' '{print $2}')

# install bootloader
bootctl --path=/boot install

# generate the arch linux entry config
cat > /boot/loader/entries/arch.conf <<EOF
title   Arch Linux
linux   /vmlinuz-linux
initrd  /intel-ucode.img
initrd  /initramfs-linux.img
options rd.luks.name=${DRIVE_UUID}=system root=/dev/mapper/system rootflags=subvol=root rd.luks.options=discard rw
EOF

# generate the loader config
cat > /boot/loader/loader.conf <<EOF
default  arch.conf
timeout  4
console-mode max
editor   no
EOF

Set the root password and reboot into the new system:

passwd
exit
reboot

Log in with root user.

Issues?

Reboot the USB image and then mount the filesystem easily with:

cryptsetup open /dev/disk/by-partlabel/cryptsystem system

cryptsetup open --type plain --key-file /dev/urandom /dev/disk/by-partlabel/cryptswap swap
mkswap -L swap /dev/mapper/swap
swapon -L swap

o=defaults,x-mount.mkdir
o_btrfs=$o,compress=lzo,ssd,noatime
mount -t btrfs -o subvol=root,$o_btrfs LABEL=system /mnt
mount -t btrfs -o subvol=home,$o_btrfs LABEL=system /mnt/home
mount -t btrfs -o subvol=snapshots,$o_btrfs LABEL=system /mnt/.snapshots
mount -t vfat ${DRIVE}1 /mnt/boot

Install WM and stuff

Install xserver:

pacman -S xorg-server xorg-init

Install bspwm + sxhkd + alacritty + rofi

pacman -S bspwm sxhkd alacritty rofi

Create config dirs

mkdir -p ~/.config/{bspwm,sxhkd,rofi,polybar}

Copy config files

cp /usr/share/doc/bspwm/examples/bspwmrc ~/.config/bspwm/bspwmrc
cp /usr/share/doc/bspwm/examples/sxhkdrc ~/.config/sxhkd/sxhkdrc

Edit sxhkd config ~/.config/sxhkd/sxhkdrc to use alacritty as the terminal and rofi as the menu:

# terminal emulator
super + Return
        alacritty

# program launcher
super + Space
        rofi -show drun

Install lightdm

sudo pacman -S lightdm lightdm-gtk-greeter
sudo systemctl enable lightdm.service

Instal yay:

git clone https://aur.archlinux.org/yay.git
cd yay
makepkg -si

Install polybar:

yay -Sy polybar

TODO: custom configs

@eualexandrerrr
Copy link

Isso me parece muito bom, estou comentando em português pois vi que é brasileiro. Vou adaptar agora para o meu uso. Obrigado!

@eualexandrerrr
Copy link

Esqueci, uma observação, em Add cryptab entry, não deveria ter /mnt/ no path?

@jeffersfp
Copy link
Author

Esqueci, uma observação, em Add cryptab entry, não deveria ter /mnt/ no path?

Deveria sim, ontem mesmo estava fazendo uma nova instalação e me deparei com esse problema, mas não havia investigado a causa. Atualizei o caminho adicionando o mnt no path do arquivo. Obrigado! :)

@eualexandrerrr
Copy link

Outra questão, dessa maneira não é necessário grub?

@jeffersfp
Copy link
Author

Outra questão, dessa maneira não é necessário grub?

Dessa maneira não... O systemd-boot faz o papel de boot loader nesse setup.

@eualexandrerrr
Copy link

Boa noite, por um acaso você já tentou usar outro modo de compressão?

@Syphdias
Copy link

Hi, thanks for the write-up. I discovered a few issues with it though:

  • mounting of /mnt/boot should use ${DISK}1 or mount by label
  • some systemd related commands fail: timedatectl and hostnamectl set-hostname did not work for me. My solution was to do it manually or do it after the reboot
  • Set the keyboard map uses one backtick ` instead of two single quotes '
  • The modifications in /etc/mkinitcpio.conf did not work since the line is different (this took me the longest to figure out). I'd recommend to only search for the line starting with HOOK= in the sed command like this:
    sed -i 's/^HOOKS=.*/HOOKS=(base\ systemd\ autodetect\ keyboard\ sd-vconsole\ modconf\ block\ sd-encrypt\ filesystems\ fsck)/' /etc/mkinitcpio.conf
  • Also the DRIVE_UUID seems to be wrong I had to get the UUID of the encrypted partition – makes sense: Use ${DRIVE}3

HTH

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