Skip to content

Instantly share code, notes, and snippets.

@mipimipi
Last active February 9, 2022 14:27
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mipimipi/78359ce1347f044888e9f2a1f809f2ff to your computer and use it in GitHub Desktop.
Save mipimipi/78359ce1347f044888e9f2a1f809f2ff to your computer and use it in GitHub Desktop.
Installing Arch Linux on an USB stick with encryted file system

Installing Arch Linux on an USB stick with encryted file system

Objective

Goal is to have an USB stick that ...

  • has a persistent Linux installed
  • can be connected and booted on different computers
  • has an encrypted file system

Approach

  • Install Arch Linux on an USB stick, that has sufficient capacity (64+ GB) and supports USB 3.0 (which is important to have a quick r/w access). Arch Linux has been chosen because is has a well-documented installation procedure which give the user a lot of freedom and flexibility
  • Use GPT and UEFI
  • Encrypt the root partition with LUKS

Partition scheme

The stick will consist of 2 partitions:

  1. An unencrypted boot partion of size 512 MB
  2. The remaining part of the stick will be used for an encyryptec partition that contains the root file system (containing also /home). We will use EXT4 for this partition.
  3. There will be no SWAP partition.

Encryption

We will use LUKS / cryptsetup to create an encrypted container for the root partition. The partition will be secured by a passphrase. This passphrase needs to be entered during the boot process. Without the passphrase, the content of the root partition cannot be read.

Installation

This installation procedure is inspired by the references [1] - [5]. It assumes that you have a 2nd USB stick (not the one that you want to use for the new installation) with the Arch Linux installer. Since I would like to have a German system, the language and keyboard layout will be configured during the installation accordingly. If you want to have a different language, you have to adjust the corresponding steps.

Start installation

Connect the 2nd USB stick to your computer and boot from it.

Configure German keyboard layout (take into account, that by default the US layout is used):

$ loadkeys de
$ loadkeys de-latin1

Partitioning

Get the of the id (dev/sdX) USB stick (the "target" stick)

$ lsblk

For the rest of this gist we assuem that it's /dev/sdb.

We partion the stick with gdisk:

$ gdisk /dev/sdb 
GPT fdisk (gdisk) version 1.0.3

Partition table scan:
  MBR: protective
  BSD: not present
  APM: not present
  GPT: present

Found valid GPT with protective MBR; using GPT.

Command (? for help): o
This option deletes all partitions and creates a new protective MBR.
Proceed? (Y/N): Y

Command (? for help): n
Partition number (1-128, default 1): 1
First sector (34-123731934, default = 2048) or {+-}size{KMGTP}: 
Last sector (2048-123731934, default = 123731934) or {+-}size{KMGTP}: +512m
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300): ef00
Changed type of partition to 'EFI System'

Command (? for help): n
Partition number (2-128, default 2): 2
First sector (34-123731934, default = 1050624) or {+-}size{KMGTP}: 
Last sector (1050624-123731934, default = 123731934) or {+-}size{KMGTP}: 
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300): 
Changed type of partition to 'Linux filesystem'

Command (? for help): w

Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
PARTITIONS!!

Do you want to proceed? (Y/N): Y
OK; writing new GUID partition table (GPT) to /dev/sdb.
Warning: The kernel is still using the old partition table.
The new table will be used at the next reboot or after you
run partprobe(8) or kpartx(8)
The operation has completed successfully.

Encryption and file systems

Create encrypted container:

$ cryptsetup luksFormat -c aes-xts-plain64 -s 512 /dev/sdb2

Open encrypted container and map it to sticky-luks (you can chose whatever name you prefer):

$ cryptsetup open --type luks /dev/sdb2 sticky-luks

Create file system in boot partition:

$ mkfs.vfat -F 32 /dev/sdb1

Create EXT4 file system in root partition:

$ mkfs.ext4 -O "^has_journal" /dev/mapper/sticky-luks

The option "^has_journal" disables journaling, which reduces the number of r/w operations (see reference [4])

Mount the new file systems:

$ mount /dev/mapper/sticky-luks /mnt
$ mkdir /mnt/boot
$ mount /dev/sdb1 /mnt/boot

Installation of Arch Linux

Select the mirrors as described here.

Install Arch Linux:

$ pacstrap /mnt base base-devel grub-efi-x86_64 efibootmgr dialog wpa_supplicant

In case your computer has a Intel CPU, install the support for Intel micorcode:

$ pacstrap /mnt intel-ucode

To make sure your new installation runs on many different computers, install additional input and output drivers (see [4]):

$ pacstrap /mnt xf86-input-synaptics xf86-video-vesa xf86-video-ati xf86-video-intel xf86-video-amdgpu xf86-video-nouveau

System Configuration

fstab

Generate fstab. Use option -U to define by UUID. That's necessary to make sure that the partitions of the USB stick can be identified clearly also on other computers.

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

Check the fstab:

(a) Determine UUID's:

$ blkid

(b) Edit fstab:

$ nano /mnt/etc/fstab

Replace the option relatime by noatime for both mounts. Also this reduces the number of r/w operations.

chroot

Enter the newly installed environment:

$ arch-chroot /mnt

Hostname

Set the hostname (in the example myhost)

$ echo myhost > /etc/hostname

Adjust /etc/hosts:

$ nano /etc/hosts
127.0.0.1   localhost
::1         localhost
127.0.1.1	myhost.localdomain	myhost

Locale

Set language (LOCALE) to German:

$ echo LANG=de_DE.UTF-8 > /etc/locale.conf

Create /etc/locale.gen:

$ nano /etc/locale.gen

Search for the following rows and remove the # at the beginning:

#de_DE.UTF-8 UTF-8
#de_DE ISO-8859-1
#de_DE@euro ISO-8859-15
#en_US.UTF-8

Generate locale

$ locale-gen

Keyboard

Set keyboard layout and font:

$ echo KEYMAP=de-latin1 > /etc/vconsole.conf
$ echo FONT=lat9w-16 >> /etc/vconsole.conf

Time zone

Set time zone to Berlin:

$ ln -sf /usr/share/zoneinfo/Europe/Berlin /etc/localtime

Initramfs

Adjust hooks in /etc/mkinitcpio.conf:

$ nano /etc/mkinitcpio.conf

Adjust the corresponding row. It should look like this:

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

It's important to move the keyboard hook before autodetect since otherwise you might have problems with the keyboard in case you to this installation on a desktop with USB keyboard and you want to use the USB stick with a laptop with the build-in keyboard.

Create initramfs:

$ mkinitcpio -p linux

Root

Set password for user root:

$ passwd

Bootloader

Install grub. You can use any id, Sticky is just an example:

$ grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=Sticky --removable --recheck

Configure grub:

$ nano /etc/default/grub

Change the corresponding row to

GRUB_CMDLINE_LINUX="cryptdevice=UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx:sticky-luks root=/dev/mapper/sticky-luks"

Here, we used sticky-luks to provide consistency to the LUKS configuration (see above), but you can use any other id instead. Please use the UUID of the root partition of your USB stick instead of xxxxxxxx-... - use the command blkid to determine this UUID.

Generate grub.cfg:

$ grub-mkconfig -o /boot/grub/grub.cfg

Finalization

Exit chroot environment:

$ exit

Unmount all partitions:

$ umount -R /mnt

Reboot and enjoy your new USB stick installation:

$ reboot

References

[1] Arch Linux Installation Guide

[2] Arch Linux - Anleitung für Einsteiger (German)

[3] Arch Linux – UEFI Boot mit Grub und verschlüsseltem LVM (German)

[4] Installing Arch Linux on a USB key

[5] Efficient Encrypted UEFI-Booting Arch Installation

@wearepixelated
Copy link

I had a few issues with the HOOKS section for mkinitcpio.conf, moving "block" to before "autodetect" fixed the issue.

But, great write up thanks. Loving my new Arch USB.

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