Skip to content

Instantly share code, notes, and snippets.

@ljfranklin
Last active November 16, 2021 18:38
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ljfranklin/97f37228c2d66accc52276ba3b0e5d86 to your computer and use it in GitHub Desktop.
Save ljfranklin/97f37228c2d66accc52276ba3b0e5d86 to your computer and use it in GitHub Desktop.
Bootstrapping an Arch Linux installation

Install Arch Linux

Create a bootable Arch Linux USB

  1. Download arch ISO from https://www.archlinux.org/download/
  2. Copy the ISO to the USB drive:
    • From a Linux machine:
    # replace sdX with usb drive listed by `fdisk -l`,
    # e.g. `/dev/sdb`, do NOT append a partition number
    sudo dd bs=4M if=/path/to/archlinux.iso of=/dev/sdX status=progress && sync
    
    • See windows or macOS instructions if you don't have access to a Linux machine.

Disable Secure Boot temporarily

To ensure we can boot off the USB, we're going to disable Secure Boot temporarily. We'll re-enable it after we create the partitions.

  1. Enter the BIOS, on my machine pressing F2 on boot.
  2. Set "Settings > Secure Boot > Secure Boot Enable" to "Disabled"

Create partitions

  1. Plug in USB drive, reboot, press F12 on boot and select USB drive from Boot list.
    • You should now see a terminal prompt and be logged in as root
  2. Run wifi-menu to connect to internet
    • Wait a couple seconds and run ping archlinux.org to verify connectivity
  3. Identify your root disk with fdisk -l, often /dev/sda or /dev/nvme0n1 on my laptop
  4. Optional: Delete existing partitions with wipefs -a /dev/sdX or securely wipe existing data
  5. See the Arch Wiki for a more in-depth guide to encrypting your partitions.
  6. Create EFI, Boot, and System partitions:
parted -s /dev/ROOT_DEVICE \
  mklabel gpt \
  mkpart ESP fat32 1MiB 550MiB \
  set 1 boot on \
  mkpart primary ext4 550MiB 806MiB \
  set 2 lvm on \
  mkpart primary ext4 806MiB 100%
  1. Create encrypted container on system partition: cryptsetup luksFormat /dev/SYSTEM_PARTITION.
  • Make sure you type YES not yes
  • You'll be prompted to enter your encryption password
  1. Format system partition: cryptsetup open /dev/SYSTEM_PARTITION system && mkfs.ext4 /dev/mapper/system
  2. Create encrypted container on boot partition: cryptsetup luksFormat /dev/BOOT_PARTITION
  3. Format boot partition: cryptsetup open /dev/BOOT_PARTITION cryptboot && mkfs.ext4 /dev/mapper/cryptboot

Perform initial Arch installation

  1. Install base package group: pacstrap /mnt base base-devel
  2. Mount the partitions:
    mount /dev/mapper/system /mnt
    mkdir /mnt/boot
    mount /dev/mapper/cryptboot /mnt/boot
    mkdir /mnt/boot/efi
    mount /dev/EFI_PARTITION /mnt/boot/efi
    
  3. Create swapfile:
    fallocate -l 4096 /mnt/swapfile
    chmod 600 /mnt/swapfile
    mkswap /mnt/swapfile
    
  4. Generate Filesystem table to ensure partitions are mounted at boot: genfstab -U /mnt >> /mnt/etc/fstab
  5. Add the swap entry: echo -e "\n/swapfile\tnone\tswap\tdefaults\t0 0" >> /mnt/etc/fstab
  6. Change root into /mnt: arch-chroot /mnt
  7. Set your timezone:
    ln -sf /usr/share/zoneinfo/REGION/CITY /etc/localtime
    # e.g. ln -sf /usr/share/zoneinfo/American/Los_Angeles /etc/localtime
    
  8. Sync time with hardware clock: hwclock --systohc
  9. Turn on NTP to ensure clock stays in sync: timedatectl set-ntp true
  10. Generate localizations:
    # uncomment 'en_US.UTF-8 UTF-8' and other other needed localizations
    vi /etc/locale.gen
    locale-gen
    echo "LANG=en_US.UTF-8" > /etc/locale.conf
    
  11. Set your hostname: echo YOUR_HOSTNAME > /etc/hostname
  12. Install wireless utilities: pacman -S wpa_supplicant wpa_actiond dialog wget
  13. Set root password: passwd
  14. Create a non-root user:
    useradd -m -G wheel -s /bin/bash YOUR_NAME
    passwd YOUR_NAME
    pacman -S sudo
    
    visudo
    # uncomment "%wheel ALL=(ALL) ALL"
    
  15. If you have an Intel CPU, enable microcode updates: pacman -S intel-ucode
  16. Install GRUB bootloader:
    pacman -S grub efibootmgr
    
  17. Configure GRUB to unlock encrypted root filesystem on boot:
    # get UUID for **root** partition (should say TYPE="crypto_LUKS")
    blkid
    # update grub config
    vi /etc/default/grub
    # add 'cryptdevice=UUID=<device-UUID>:lvm' to the 'GRUB_CMDLINE_LINUX' option list
    # uncomment 'GRUB_ENABLE_CRYPTODISK=y'
    
    # create keyfile to unlock root partition on boot (avoids a second password prompt)
    # the `/crypto_keyfile.bin` can be changed with the `cryptkey` GRUB option
    dd bs=512 count=4 if=/dev/urandom of=/crypto_keyfile.bin
    chmod 000 /crypto_keyfile.bin
    chmod 600 /boot/initramfs-linux* # ensure non-root users can't read keyfile
    cryptsetup luksAddKey /dev/ROOT_PARTITION /crypto_keyfile.bin
    
    vi /etc/mkinitcpio.conf
    # Replace 'FILES=()' with 'FILES=(/crypto_keyfile.bin)'
    # Add additional hooks to existing hooks array: 'HOOKS=(... keyboard keymap encrypt lvm2)'
    
    # regenerate initramfs
    mkinitcpio -p linux
    
    • Note: this setup prompts for a password at boot to unlock the encrypted root partition. Follow these directions to use a keyfile from a USB instead.
  18. Install GRUB:
    grub-mkconfig -o /boot/grub/grub.cfg
    grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=grub --recheck
    
  19. Configure crypttab and fstab to unlock /boot and /boot/efi at boot:
    # create randomtext keyfile
    dd bs=512 count=4 if=/dev/urandom of=/etc/boot-keyfile
    chmod 600 /etc/boot-keyfile
    cryptsetup luksAddKey /dev/BOOT_PARTITION /etc/boot-keyfile
    # get UUID for **boot** partition (should say TYPE="crypto_LUKS")
    blkid
    echo -e "\ncryptboot\tUUID=<device-UUID>\t/etc/boot-keyfile" >> /etc/crypttab
    
    • Note: Once the root filesystem is unlocked, the keyfile will be viewable in plain text if you have root access. Follow these directions for a more secure two-factor unlock method.
  20. Exit from chroot and reboot. You can now remove the USB drive.
  21. On boot, you should now be prompted to enter your encryption password to proceed.
  22. If successful, you should now see the GRUB menu. Select "Arch Linux" and hit enter.
  23. You should then see a login prompt. Enter root and the password you created in the previous passwd step.
  24. reboot again, we're going to go a step farther and encrypt our bootloader as well.
  25. Press F2 to go into BIOS setup:
    1. Set an Admin Password so someone can't just turn Secure Boot back off without a password
    • Note: you or an attacker can still reset the BIOS password and boot settings by opening the case and messing with some jumpers
    1. Re-enable Secure Boot
    2. Delete all pre-loaded keys, "Settings > Secure Boot > Expert Key Management > Enable Custom Mode + Delete All Keys" on my Dell XPS
    • We'll generate new keys in a subsequent step
  26. Exit BIOS, boot back into Arch as non-root user
  27. Download and install cryptboot utility
    # TODO: change this back after PR is merged
    # wget -O cryptboot.tgz https://github.com/xmikos/cryptboot/archive/v1.1.0.tar.gz
    wget -O cryptboot.tgz https://github.com/ljfranklin/cryptboot/archive/master.tar.gz
    tar xvf cryptboot.tgz
    cd ./cryptboot-*
    sudo pacman -S efitools sbsigntools
    sudo install -Dm755 cryptboot /usr/bin/cryptboot
    sudo install -Dm755 cryptboot-efikeys /usr/bin/cryptboot-efikeys
    sudo install -Dm755 cryptboot-grub-warning /etc/cryptboot-grub-warning
    sudo install -Dm644 cryptboot.conf /etc/cryptboot.conf
    
  28. Generate and install new UEFI Secure Boot keys:
    sudo su root
    cryptboot-efikeys create # enter any cosmetic ID when prompted for Common Name
    cryptboot-efikeys enroll
    cryptboot update-grub
    ln -s /etc/cryptboot-grub-warning /usr/local/bin/grub-install
    
    Important!!!: Going forward use cryptboot update-grub rather than grub-install. Failure to run cryptboot to re-sign your bootloader will cause subsequent Secure Boots to fail.
  29. reboot, login, and verify Secure Boot is shown as "enabled":
    bootctl status 2> /dev/null | grep "Secure Boot"
    
  30. Congrats! The current environment is not much to look at right now, but next we'll install a shiny graphical environment and a tiling window manager. Deeper down the Arch Linux rabbit hole we go...

TODO

  • Add instructions about reformatting root partition, but keeping boot partitions
  • How much of this can be scripted?
Copy link

ghost commented Nov 16, 2021

This was a brilliant tutorial.. I myself had been spinning cause no matter what I did.. from reading other tutorials and quite literally coming out like mince, trying to figure out why after every install.. and betterment of attempt after attempt.. why it wouldn't boot.. but its there.. if I put in the USB and boot.. access and all.. then read your system installation here and it made me go and double check some points.. and then I clicked it wasn't my way of installation.. but my poor way of assuming it was so easily accessible.. truly brilliant thanks a ton..

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