Skip to content

joan31/arch-fortress

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

36 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

๐Ÿฐ Arch Fortress โ€” Secure & Minimal Arch Linux Installer

Linux Arch Linux EFI UKI LUKS2 + TPM2 Secure Boot BTRFS Systemd Zswap Snapper License: MIT

Arch Fortress is a lightweight, secure, modern and efficient Arch Linux installation framework.

It aims to provide a solid base system for advanced users who want a clean, fully encrypted system using modern technologies โ€” without unnecessary components like GRUB or classic init hooks.

๐Ÿ›ก๏ธ Built on: EFI, UKI, LUKS2 + TPM2, Secure Boot, BTRFS, Systemd init, zswap, snapper


๐Ÿ“š Table of Contents


๐ŸŽฏ Overview

Arch Fortress is not a distribution or a preconfigured Arch setup โ€” itโ€™s a bare-metal bootstrapper that gives you a production-ready system. A fully modern, encrypted and bootloader-less Arch Linux installation with:

  • ๐ŸงŠ BTRFS root with subvolumes and snapper for snapshot management
  • ๐Ÿ” LUKS2 encryption for root with TPM2 auto-unlocking and passphrase fallback
  • ๐Ÿ’พ Encrypted swap file
  • ๐Ÿ” Direct EFI boot via a signed Unified Kernel Image (UKI) โ€” no bootloader (no GRUB, no systemd-boot)
  • ๐Ÿ’ฅ Full Secure Boot support
  • ๐Ÿง  Modern mkinitcpio using systemd init hooks
  • ๐Ÿงต zswap for compressed RAM swapping
  • ๐Ÿ›Ÿ Auto-backup of EFI partition in /.efibck

โš™๏ธ Features

๐Ÿ” Security

  • Full / system encryption with LUKS2 + TPM2
  • Fallback passphrase support
  • Secure Boot ready with signed kernels

๐ŸงŠ Filesystem

  • BTRFS with subvolumes:
    • @, @home, @snapshots, etc.
  • Snapshots for root only, managed by snapper
  • Encrypted swap file on BTRFS
  • zswap enabled for better memory performance

โš™๏ธ Boot Process

  • No bootloader (no GRUB, no systemd-boot)
  • EFI directly loads a signed Unified Kernel Image (UKI)
  • UKI built with mkinitcpio, containing:
    • Kernel
    • Initramfs
    • Kernel cmdline

๐Ÿง  Init System

  • mkinitcpio using:
    • systemd, sd-vconsole, sd-encrypt, sd-shutdown
  • No legacy hooks like udev, usr, resume, keymap, consolefont, encrypt
  • Faster, cleaner, future-proof boot

๐Ÿ›Ÿ Automatic EFI Backup

  • The /efi (ESP) is automatically backed up to /.efibck
  • Useful for system recovery

๐Ÿ“ฆ Structure

๐Ÿ“ arch-fortress/ (click to expand)
arch-fortress/
โ”œโ”€โ”€ etc/
โ”‚   โ””โ”€โ”€ pacman.d/
โ”‚       โ””โ”€โ”€ hooks/
โ”‚           โ””โ”€โ”€ 10-efi_backup.hook
โ”œโ”€โ”€ usr/
โ”‚   โ””โ”€โ”€ local/
โ”‚       โ””โ”€โ”€ sbin/
โ”‚           โ””โ”€โ”€ efi_backup.sh
โ”œโ”€โ”€ 01-arch_baseinstall.sh
โ”œโ”€โ”€ 02-arch_baseinstall_chroot.sh
โ”œโ”€โ”€ 03-install_hook_efibck.Sh
โ”œโ”€โ”€ LICENSE
โ””โ”€โ”€ README.md

๐Ÿ—‚๏ธ Disk Layout & Subvolume Architecture

This is the storage layout used by Arch Fortress, based on a secure and flexible setup combining LUKS2, BTRFS, and EFI boot with UKI.

๐Ÿ’ฝ Partition Table (GPT - /dev/nvme0n1)

Partition Type FS Mount Point Size Description
/dev/nvme0n1p1 EFI System (ef00) FAT32 /efi 500M EFI System Partition (boot via UKI)
/dev/nvme0n1p2 Linux LUKS (8309) LUKS2 (LUKS) ~2TB Encrypted root volume

๐Ÿ” Encrypted Volume

  • /dev/nvme0n1p2 is encrypted using LUKS2 + TPM2
  • Mapped as /dev/mapper/cryptarch
  • Inside: BTRFS filesystem with multiple subvolumes

๐ŸŒณ BTRFS Subvolume Layout

Subvolume Mount Point Description
@ / Root system
@home /home User data
@pkg /var/cache/pacman/pkg Pacman cache
@log /var/log System logs
@tmp /var/tmp Temporary files
@srv /srv Server data
@vms /var/lib/libvirt/images Virtual machines
@games /opt/games Optional game data
@swap /.swap Encrypted swapfile (e.g. 4GB)
@snapshots /.snapshots Snapper snapshots
@efibck /.efibackup EFI partition backups (automated)

๐Ÿง  This structure is designed for:

  • Granular snapshotting with snapper
  • Easy backup & restore
  • Separation of concerns (logs, cache, VMs, etc.)
  • Improved performance & maintenance

๐Ÿ–ผ๏ธ Layout Diagram

Disk: /dev/nvme0n1 (GPT)
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Partition Table                                  โ”‚
โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚
โ”‚ /dev/nvme0n1p1   โ†’ EFI System (FAT32, 500M)      โ”‚
โ”‚                  โ””โ”€โ”€ Mounted at /efi             โ”‚
โ”‚                                                  โ”‚
โ”‚ /dev/nvme0n1p2   โ†’ LUKS2 Encrypted Volume (~2TB) โ”‚
โ”‚                  โ””โ”€โ”€ mapper/cryptarch            โ”‚
โ”‚                      โ””โ”€โ”€ BTRFS filesystem        โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

BTRFS Subvolumes (inside /dev/mapper/cryptarch):

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ @           โ†’ /                                      โ† Root filesystem โ”‚
โ”‚ @home       โ†’ /home                                                    โ”‚
โ”‚ @log        โ†’ /var/log                                                 โ”‚
โ”‚ @tmp        โ†’ /var/tmp                                                 โ”‚
โ”‚ @srv        โ†’ /srv                                                     โ”‚
โ”‚ @pkg        โ†’ /var/cache/pacman/pkg                                    โ”‚
โ”‚ @vms        โ†’ /var/lib/libvirt/images                                  โ”‚
โ”‚ @games      โ†’ /opt/games                                               โ”‚
โ”‚ @snapshots  โ†’ /.snapshots                                โ† For Snapper โ”‚
โ”‚ @efibck     โ†’ /.efibackup                                โ† EFI backups โ”‚
โ”‚ @log        โ†’ /var/log                                                 โ”‚
โ”‚ @swap       โ†’ /.swap                    โ† Encrypted swapfile (e.g. 4G) โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Boot process:

[ EFI Firmware ]
    โ†“
[ UKI Image (.efi) in /efi ]
    โ†“
[ systemd (init) in initramfs ]
    โ†“
[ Unlock LUKS via TPM2 ]
    โ†“
[ Mount BTRFS subvolumes ]
    โ†“
[ Boot into secure, modern Arch Fortress ๐Ÿ”๐Ÿ›ก๏ธ ]

๐Ÿ”ง Mount Options Summary

๐Ÿ“‚ Mount Points and Options

๐Ÿ“ Mount Point ๐Ÿ’ฝ Device ๐Ÿ—‚๏ธ Subvolume โš™๏ธ Mount Options
/ /dev/mapper/cryptarch @ rw,noatime,nodiratime,compress=zstd:3,ssd,discard=async,space_cache=v2,commit=120
/efi /dev/nvme0n1p1 (N/A) rw,noatime,nodiratime,nodev,nosuid,noexec,fmask=0022,dmask=0022
/.swap /dev/mapper/cryptarch @swap rw,noatime,nodiratime,nodev,nosuid,noexec,compress=zstd:3,ssd,discard=async,space_cache=v2,commit=120
/.snapshots /dev/mapper/cryptarch @snapshots rw,noatime,nodiratime,nodev,nosuid,noexec,compress=zstd:3,ssd,discard=async,space_cache=v2,commit=120
/.efibackup /dev/mapper/cryptarch @efibck rw,noatime,nodiratime,nodev,nosuid,noexec,compress=zstd:3,ssd,discard=async,space_cache=v2,commit=120
/var/log /dev/mapper/cryptarch @log rw,noatime,nodiratime,nodev,nosuid,noexec,compress=zstd:3,ssd,discard=async,space_cache=v2,commit=120
/var/tmp /dev/mapper/cryptarch @tmp rw,noatime,nodiratime,nodev,nosuid,noexec,compress=zstd:3,ssd,discard=async,space_cache=v2,commit=120
/var/cache/pacman/pkg /dev/mapper/cryptarch @pkg rw,noatime,nodiratime,nodev,nosuid,noexec,compress=zstd:3,ssd,discard=async,space_cache=v2,commit=120
/var/lib/libvirt/images /dev/mapper/cryptarch @vms rw,noatime,nodiratime,nodev,nosuid,noexec,compress=zstd:3,ssd,discard=async,space_cache=v2,commit=120
/home /dev/mapper/cryptarch @home rw,noatime,nodiratime,nodev,nosuid,compress=zstd:3,ssd,discard=async,space_cache=v2,commit=120
/srv /dev/mapper/cryptarch @srv rw,noatime,nodiratime,nodev,nosuid,compress=zstd:3,ssd,discard=async,space_cache=v2,commit=120
/opt/games /dev/mapper/cryptarch @games rw,noatime,nodiratime,nodev,nosuid,compress=zstd:3,ssd,discard=async,space_cache=v2,commit=120

๐Ÿ“– Mount Options Explanation

โš™๏ธ Option ๐Ÿ”Ž Description ๐Ÿท๏ธ Category
rw Mount as read-write. ๐Ÿ”ง Default
noatime Do not update file access times (improves performance, reduces SSD writes). ๐Ÿš€ Performance
nodiratime Do not update directory access times (even more efficient than noatime). ๐Ÿš€ Performance
nodev Prevents character/block device files from being interpreted (security hardening). ๐Ÿ”’ Security
nosuid Disable set-user-ID and set-group-ID bits (security hardening). ๐Ÿ”’ Security
noexec Prevent execution of binaries on this mount (security hardening). ๐Ÿ”’ Security
fmask=0022 File mask for default file permissions on FAT32 (755 for files). ๐Ÿ”’ Security
dmask=0022 Directory mask for default directory permissions on FAT32 (755 for dirs). ๐Ÿ”’ Security
compress=zstd:3 Use Zstandard compression (level 3: good balance between speed and compression ratio). ๐Ÿ’พ Performance/Storage
ssd Optimize for SSD (disables unnecessary spinning disk optimizations). ๐Ÿš€ Performance
discard=async Asynchronous TRIM: notify SSD of free blocks asynchronously (less I/O overhead). ๐Ÿ’พ Performance
space_cache=v2 Improved Btrfs space cache version 2 (better mount speed, reliability). ๐Ÿš€ Performance
commit=120 Flush changes to disk every 120s (reduces write amplification). ๐Ÿ’พ Performance
subvol=@... Mount specific Btrfs subvolume. ๐Ÿ“‚ Btrfs Feature

๐Ÿ”Ž Why these mount options?

These options are carefully chosen for:

  • ๐Ÿš€ Performance: optimized for SSDs and minimizing unnecessary I/O.
  • ๐Ÿ”’ Security: limiting execution and device files where not needed.
  • ๐Ÿ’พ Reliability: with Btrfs improvements (space_cache=v2, commit=120).
  • ๐Ÿ“‚ Granular subvolume management: easy snapshot, rollback, backup management.

โœ… Quick Summary

๐ŸŽฏ Aspect โš™๏ธ Strategy
SSD optimization ssd, discard=async
Reduce writes noatime, nodiratime, commit=120
Compression compress=zstd:3
Security hardening nosuid, nodev, noexec
Faster mounts space_cache=v2
Granular control Subvolumes (@home, @swap, @log...)

โœ… READY FOR PRODUCTION ๐Ÿ–ฅ๏ธ


๐Ÿš€ Automatic Installation (WIP)

๐Ÿงช Coming soon: Full auto-install script with configuration prompts or flags.

โš ๏ธ Secure Boot must be set to "Setup Mode" in the BIOS/UEFI before installation.
This is required to enroll your own Secure Boot keys with sbctl.

Planned workflow:

  1. Boot from Arch ISO (UEFI)
  2. Download and run:
    curl -LO https://raw.githubusercontent.com/joan31/arch-fortress/main/install.sh
    chmod +x install.sh
    sudo ./install.sh
  3. The script will:
  • Partition the disk
  • Setup encryption, filesystems, mount points
  • Install base system
  • Chroot
  • Generate and sign UKI, configure EFI boot entries

๐Ÿ“– Manual Installation (Step-by-step)

๐Ÿง  For advanced users or educational purposes.

โš ๏ธ Secure Boot must be set to "Setup Mode" in the BIOS/UEFI before installation.
This is required to enroll your own Secure Boot keys with sbctl.

This section will provide all individual shell commands used in the installation, including:

  • ๐Ÿงฑ Partitioning & formatting
  • ๐Ÿ” LUKS2 setup with TPM2
  • ๐Ÿ—‚๏ธ Mounting and subvolume layout
  • ๐Ÿ“ฆ Base system installation
  • ๐Ÿงฐ Chroot configuration
  • ๐Ÿงฌ UKI creation and signing
  • โš™๏ธ EFI setup
  • ๐ŸงŠ Snapper configuration
  • ๐ŸŒ€ Swap and zswap activation

๐Ÿงฑ Step 1 โ€” Pre-Installation Setup

  • โŒจ๏ธ (Optional) Set keyboard layout to French
loadkeys fr
  • ๐Ÿงผ Clean existing EFI entries if needed (replace X with the entry number)
efibootmgr
efibootmgr -b X -B
  • ๐Ÿ” Update GPG keys from live environment (recommended before installing)
pacman -Sy archlinux-keyring

๐Ÿ’ฝ Step 2 โ€” Disk Partitioning (GPT)

  • โš™๏ธ Partition the disk: EFI (500MB) + LUKS root (rest of disk)
sgdisk --clear --align-end \
  --new=1:0:+500M --typecode=1:ef00 --change-name=1:"EFI system partition" \
  --new=2:0:0 --typecode=2:8309 --change-name=2:"Linux LUKS" \
  /dev/nvme0n1

๐Ÿงผ Step 3 โ€” Filesystem Creation

  • ๐Ÿงด Format EFI partition (optimized for NVMe 4K sector size)
mkfs.vfat -F 32 -n "SYSTEM" -S 4096 -s 1 /dev/nvme0n1p1
  • ๐Ÿ” Create LUKS2 encrypted container with strong encryption options
cryptsetup --type luks2 --cipher aes-xts-plain64 --hash sha512 \
  --iter-time 5000 --key-size 512 --pbkdf argon2id \
  --label "Linux LUKS" --sector-size 4096 --use-urandom \
  --verify-passphrase luksFormat /dev/nvme0n1p2
  • ๐Ÿ”“ Open the LUKS container as /dev/mapper/cryptarch
cryptsetup --allow-discards --persistent open --type luks2 \
  /dev/nvme0n1p2 cryptarch
  • ๐ŸงŠ Format the unlocked LUKS volume with BTRFS (4K sectors)
mkfs.btrfs -L "Arch Linux" -s 4096 /dev/mapper/cryptarch

๐ŸŒณ Step 4 โ€” BTRFS Subvolume Layout

  • ๐Ÿชต Mount the root BTRFS volume temporarily
mount -o rw,noatime,nodiratime,compress=zstd:3,ssd,discard=async,space_cache=v2,commit=120 \
  /dev/mapper/cryptarch /mnt
  • ๐Ÿ“‚ Create BTRFS subvolumes
btrfs subvolume create /mnt/@
btrfs subvolume create /mnt/@swap
btrfs subvolume create /mnt/@snapshots
btrfs subvolume create /mnt/@efibck
btrfs subvolume create /mnt/@log
btrfs subvolume create /mnt/@pkg
btrfs subvolume create /mnt/@tmp
btrfs subvolume create /mnt/@vms
btrfs subvolume create /mnt/@home
btrfs subvolume create /mnt/@srv
btrfs subvolume create /mnt/@games
  • ๐Ÿ”“ Unmount the volume before remounting subvolumes individually
umount /mnt

๐Ÿ› ๏ธ Step 5 โ€” Mount Subvolumes & Prepare System

  • ๐Ÿ”ง Mount root subvolume
mount -o rw,noatime,nodiratime,compress=zstd:3,ssd,discard=async,space_cache=v2,commit=120,subvol=@ \
  /dev/mapper/cryptarch /mnt
  • ๐Ÿ—‚๏ธ Create necessary mount points
mkdir -p /mnt/{efi,.swap,.snapshots,.efibackup,var/{log,tmp,cache/pacman/pkg,lib/libvirt/images},home,srv,opt/games}
  • ๐Ÿ–ฅ๏ธ Mount EFI system partition (read-only, noexec for safety)
mount -o rw,noatime,nodiratime,nodev,nosuid,noexec,fmask=0022,dmask=0022 \
  /dev/nvme0n1p1 /mnt/efi
  • ๐Ÿงท Mount other BTRFS subvolumes
mount -o rw,noatime,nodiratime,nodev,nosuid,noexec,compress=zstd:3,ssd,discard=async,space_cache=v2,commit=120,subvol=@swap /dev/mapper/cryptarch /mnt/.swap
mount -o rw,noatime,nodiratime,nodev,nosuid,noexec,compress=zstd:3,ssd,discard=async,space_cache=v2,commit=120,subvol=@snapshots /dev/mapper/cryptarch /mnt/.snapshots
mount -o rw,noatime,nodiratime,nodev,nosuid,noexec,compress=zstd:3,ssd,discard=async,space_cache=v2,commit=120,subvol=@efibck /dev/mapper/cryptarch /mnt/.efibackup
mount -o rw,noatime,nodiratime,nodev,nosuid,noexec,compress=zstd:3,ssd,discard=async,space_cache=v2,commit=120,subvol=@log /dev/mapper/cryptarch /mnt/var/log
mount -o rw,noatime,nodiratime,nodev,nosuid,noexec,compress=zstd:3,ssd,discard=async,space_cache=v2,commit=120,subvol=@tmp /dev/mapper/cryptarch /mnt/var/tmp
mount -o rw,noatime,nodiratime,nodev,nosuid,noexec,compress=zstd:3,ssd,discard=async,space_cache=v2,commit=120,subvol=@pkg /dev/mapper/cryptarch /mnt/var/cache/pacman/pkg
mount -o rw,noatime,nodiratime,nodev,nosuid,noexec,compress=zstd:3,ssd,discard=async,space_cache=v2,commit=120,subvol=@vms /dev/mapper/cryptarch /mnt/var/lib/libvirt/images
mount -o rw,noatime,nodiratime,nodev,nosuid,compress=zstd:3,ssd,discard=async,space_cache=v2,commit=120,subvol=@home /dev/mapper/cryptarch /mnt/home
mount -o rw,noatime,nodiratime,nodev,nosuid,noexec,compress=zstd:3,ssd,discard=async,space_cache=v2,commit=120,subvol=@srv /dev/mapper/cryptarch /mnt/srv
mount -o rw,noatime,nodiratime,nodev,nosuid,compress=zstd:3,ssd,discard=async,space_cache=v2,commit=120,subvol=@games /dev/mapper/cryptarch /mnt/opt/games

๐Ÿ’พ Step 6 โ€” Create Swap File

  • ๐Ÿ›๏ธ Create 4GB swap file on BTRFS subvolume
btrfs filesystem mkswapfile --size 4g /mnt/.swap/swapfile
chmod 600 /mnt/.swap/swapfile

๐Ÿ“ฆ Step 7 โ€” Install Base System

  • ๐Ÿงฑ Install base packages, kernel + firmwares, EFI tools, btrfs support, text editor, secure boot tools and splash screen
pacstrap /mnt \
  base base-devel linux linux-headers linux-firmware amd-ucode \
  neovim efibootmgr btrfs-progs sbctl plymouth

๐Ÿ—‚๏ธ Step 8 โ€” Generate fstab

  • ๐Ÿ“„ Generate fstab with UUIDs
genfstab -U /mnt >> /mnt/etc/fstab
  • ๐Ÿ” (Optional) Review fstab and check "0 1" to enable fsck on /
nvim /mnt/etc/fstab
  • Content:
UUID=<BTRFS-UUID-PARTITION>      /      btrfs      rw,noatime,nodiratime,compress=zstd:3,ssd,discard=async,space_cache=v2,commit=120,subvol=/@      0 1

๐Ÿšช Step 9 โ€” Enter Chroot

  • ๐ŸŒ€ Change root into new system
arch-chroot /mnt

๐ŸŒ Step 10 โ€” Keyboard & Locale Configuration

  • โŒจ๏ธ Set virtual console keyboard to French
nvim /etc/vconsole.conf
  • Content:
KEYMAP=fr
FONT=lat9w-16
  • ๐ŸŒ Set system-wide locale
nvim /etc/locale.conf
  • Content:
LANG=fr_FR.UTF-8
LC_COLLATE=C
LC_MESSAGES=en_US.UTF-8
  • ๐Ÿ”“ Enable required locales
nvim /etc/locale.gen
  • Uncomment:
en_US.UTF-8 UTF-8
fr_FR.UTF-8 UTF-8
  • โš™๏ธ Generate locale definitions
locale-gen

๐Ÿ”ข Step 11 โ€” TTY Behavior (Enable NumLock)

  • ๐Ÿงท Create drop-in to activate NumLock automatically on TTY login
mkdir /etc/systemd/system/[email protected]
nvim /etc/systemd/system/[email protected]/activate-numlock.conf
  • Content:
[Service]
ExecStartPre=/bin/sh -c 'setleds -D +num < /dev/%I'

๐Ÿ–ฅ๏ธ Step 12 โ€” Host Identity Configuration

  • ๐Ÿท๏ธ Set system hostname
nvim /etc/hostname
  • Content:
lianli-arch
  • ๐Ÿงญ Set hosts file entries for local networking
nvim /etc/hosts
  • Content:
127.0.0.1      localhost
::1            localhost
192.168.1.101  lianli-arch.zenitram lianli-arch

๐Ÿ•’ Step 13 โ€” Timezone & Clock Setup

  • ๐ŸŒ Set system timezone
ln -sf /usr/share/zoneinfo/Europe/Paris /etc/localtime
  • โฑ๏ธ Sync hardware clock with system time
hwclock --systohc

๐Ÿงฉ Step 14 โ€” Initramfs Configuration (AMDGPU Module, Systemd, LUKS, Keyboard)

  • โš™๏ธ Edit initramfs modules and hooks to include AMDGPU driver before anything, systemd & encryption
nvim /etc/mkinitcpio.conf
  • Content:
MODULES=(amdgpu)

HOOKS=(systemd plymouth autodetect microcode modconf kms keyboard sd-vconsole block sd-encrypt filesystems sd-shutdown)
  • ๐Ÿ” Setup encrypted volume for systemd to unlock via TPM2
nvim /etc/crypttab.initramfs
  • Content:
cryptarch UUID=<nvme-UUID> none tpm2-device=auto,password-echo=no,x-systemd.device-timeout=0,timeout=0,no-read-workqueue,no-write-workqueue,discard
  • Get <nvme-UUID> on neovim:
:read ! lsblk -dno UUID /dev/nvme0n1p2

๐Ÿงต Step 15 โ€” Kernel Command Line Configuration (UKI + zswap)

  • โš™๏ธ Root and logging options (read-only fs is handled by systemd and to fsck /)
nvim /etc/cmdline.d/01-root.conf
  • Content:
root=/dev/mapper/cryptarch rootfstype=btrfs rootflags=subvol=@ ro loglevel=3 quiet splash
  • ๐Ÿง  Configure zswap parameters for performance
nvim /etc/cmdline.d/02-zswap.conf
  • Content:
zswap.enabled=1 zswap.max_pool_percent=20 zswap.zpool=zsmalloc zswap.compressor=zstd zswap.accept_threshold_percent=90

๐Ÿงฌ Step 16 โ€” Initramfs Preset for Unified Kernel Image (UKI)

  • ๐Ÿ”ง Setup mkinitcpio preset to generate a UKI
nvim /etc/mkinitcpio.d/linux.preset
  • Content only:
ALL_kver="/boot/vmlinuz-linux"
PRESETS=('default')
default_uki="/efi/EFI/Linux/arch-linux.efi"
default_options="--splash=/usr/share/systemd/bootctl/splash-arch.bmp"

๐Ÿ” Step 17 โ€” Secure Boot with sbctl

  • ๐Ÿ”‘ Create Secure Boot keys
sbctl create-keys
  • ๐Ÿ“ฅ Enroll custom keys and micr0$0ft๐Ÿ’ฉ keys
sbctl enroll-keys -m
  • ๐Ÿ› ๏ธ Generate the Unified Kernel Image
mkdir -p /efi/EFI/Linux
mkinitcpio -p linux

๐Ÿ’ป Step 18 โ€” EFI Boot Entry

  • ๐Ÿงท Register UKI with UEFI firmware
efibootmgr --create --disk /dev/nvme0n1 --part 1 \
  --label "Arch Linux" --loader /EFI/Linux/arch-linux.efi --unicode

๐Ÿ›ก๏ธ Step 19 โ€” LUKS TPM2 Key Enrollment

  • ๐Ÿ”’ Enroll TPM2 key (PCR 0 = firmware, PCR 7 = Secure Boot state)
systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+7 /dev/nvme0n1p2

๐Ÿง  Step 20 โ€” Swappiness Tuning

  • ๐Ÿงฎ Lower swappiness to prefer RAM usage over swap
nvim /etc/sysctl.d/99-swappiness.conf
  • Content, 80% RAM usage before swapping:
vm.swappiness=20

๐Ÿ”„ Step 21 โ€” Encrypted Swap Setup

  • ๐Ÿ” Add encrypted swap entry using /dev/urandom
nvim /etc/crypttab
  • Content:
swap      /.swap/swapfile      /dev/urandom      swap,cipher=aes-xts-plain64,sector-size=4096
  • ๐Ÿ“„ Add swap to fstab
nvim /etc/fstab
  • Content:
#	/.swap/swapfile      CRYPTED SWAPFILE
/dev/mapper/swap      none      swap      defaults      0 0

๐Ÿ“ฆ Step 22 โ€” Pacman Configuration

  • ๐Ÿ“ฆ Enable multilib, candy theme, parallel downloads & ignore snapper cron jobs
nvim /etc/pacman.conf
  • Content:
NoExtract = etc/cron.daily/snapper etc/cron.hourly/snapper
Color
ParallelDownloads = 10
ILoveCandy

[multilib]
Include = /etc/pacman.d/mirrorlist

๐ŸŒ Step 23 โ€” Network Configuration

๐Ÿ”€ Choose one network management method depending on your setup

  • โš™๏ธ systemd-networkd โ†’ lightweight, minimal, server-friendly, wired only
  • ๐Ÿ–ฅ๏ธ NetworkManager โ†’ recommended for desktop environments (e.g. KDE Plasma, GNOME) with Wi-Fi support

โš™๏ธ Option A โ€” systemd-networkd (Only Wired, Minimal & Lightweight)

  • ๐Ÿ“ก Configure wired interface for DHCP, mDNS, and IPv6
nvim /etc/systemd/network/20-wired.network
  • Content:
๐Ÿ“„ 20-wired.network content (click to expand)
[Match]
Name=eno* ens* enp* eth*

[Link]
RequiredForOnline=routable

[Network]
DHCP=yes
IPv6PrivacyExtensions=yes
MulticastDNS=yes

[DHCPv4]
RouteMetric=100

[IPv6AcceptRA]
RouteMetric=100

โš™๏ธ Option B โ€” NetworkManager (Desktop-Friendly, Wi-Fi Ready)

๐Ÿ’ก Recommended if you plan to use KDE Plasma, GNOME, or need Wi-Fi support

  • ๐Ÿ“ฆ Install NetworkManager
pacman -Syy networkmanager

๐Ÿ”Œ Step 24 โ€” Basic Packages: Bluetooth, Snapper, Pacman Cache Service, Reflector

  • ๐Ÿ“ฆ Install essential tools
pacman -Syy bluez snapper pacman-contrib reflector

๐Ÿ•ฐ๏ธ Step 25 โ€” Time Sync with French NTP Servers

  • โฒ๏ธ Set systemd-timesyncd to use French pool servers with iburst
nvim /etc/systemd/timesyncd.conf
  • Content:
[Time]
NTP=0.fr.pool.ntp.org 1.fr.pool.ntp.org 2.fr.pool.ntp.org 3.fr.pool.ntp.org
FallbackNTP=0.arch.pool.ntp.org 1.arch.pool.ntp.org 2.arch.pool.ntp.org 3.arch.pool.ntp.org

๐Ÿš€ Step 26 โ€” I/O Scheduler Tuning for NVMe

  • ๐Ÿ“‰ Disable I/O scheduler on NVMe device to use none (for performance)
nvim /etc/udev/rules.d/60-schedulers.rules
  • Content:
ACTION=="add|change", KERNEL=="nvme0n1", ATTR{queue/scheduler}="none"

๐Ÿงญ Step 27 โ€” DNS Stub Resolver via systemd-resolved

โš ๏ธ Only apply this step if you are using systemd-networkd (from Step 23) โญ๏ธ Skip this step if you selected NetworkManager

  • ๐Ÿ” Link stub resolver to /etc/resolv.conf
ln -sf ../run/systemd/resolve/stub-resolv.conf /etc/resolv.conf

๐ŸŒ Step 28 โ€” Reflector Configuration (Update Mirrorlist)

  • ๐ŸŒ Optimize pacman mirrors by age, country, and protocol
nvim /etc/xdg/reflector/reflector.conf
  • Content:
--save /etc/pacman.d/mirrorlist
--country France,Germany,Netherlands
--protocol https
--latest 5
--sort age

โš™๏ธ Step 29 โ€” Enable Key Services (Networking, Bluetooth, Time, Maintenance)

  • ๐ŸŒ Enable network services (based on your previous choice)

  • โš™๏ธ If using systemd-networkd:

systemctl enable systemd-networkd.service
systemctl enable systemd-resolved.service
  • ๐Ÿ–ฅ๏ธ If using NetworkManager:
systemctl enable NetworkManager.service
  • ๐Ÿ”ง Enable essential system services
systemctl enable bluetooth.service
systemctl enable systemd-timesyncd.service
  • ๐Ÿงน Enable maintenance timers (package cache cleaner & mirrorlist updater)
systemctl enable paccache.timer
systemctl enable reflector.timer

๐Ÿ”‘ Step 30 โ€” Configure sudo

  • ๐Ÿ›ก๏ธ Grant sudo to wheel group
EDITOR=nvim visudo
  • Content:
%wheel ALL=(ALL:ALL) ALL

๐Ÿšง Step 31 โ€” Compilation Optimization (makepkg)

  • ๐Ÿงฐ Tune makepkg flags for native arch, use /tmp for build
nvim /etc/makepkg.conf
  • Content:
CFLAGS="-march=native -O2 -pipe ..."
MAKEFLAGS="-j$(nproc)"
BUILDDIR=/tmp/makepkg
  • ๐Ÿฆ€ Optimize Rust build flags
nvim /etc/makepkg.conf.d/rust.conf
  • Content:
RUSTFLAGS="-C opt-level=2 -C target-cpu=native"

๐Ÿ”‡ Step 32 โ€” Disable HDMI Audio

  • ๐Ÿ”• Blacklist HDMI audio module
nvim /etc/modprobe.d/blacklist.conf
  • Content:
blacklist snd_hda_intel

๐Ÿ”’ Step 33 โ€” Disable Webcam Microphone

  • ๐ŸŽ™๏ธ Block Logitech webcam microphone via udev rule
nvim /etc/udev/rules.d/90-blacklist-webcam-sound.rules
  • Content:
SUBSYSTEM=="usb", DRIVER=="snd-usb-audio", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="085c", ATTR{authorized}="0"

โšก Step 34 โ€” Allow games Group to Read CPU Power

  • ๐ŸŽฎ Grant members of the games group permission to read CPU power (via Intel RAPL interface).
nvim /etc/udev/rules.d/70-intel-rapl.rules
  • Content:
SUBSYSTEM=="powercap", KERNEL=="intel-rapl:0", RUN+="/usr/bin/chgrp games /sys/%p/energy_uj", RUN+="/usr/bin/chmod g+r /sys/%p/energy_uj"

โœ… This ensures users in the games group can access CPU energy readings without requiring root privileges โ€” useful for monitoring tools or performance overlays.

๐Ÿ” Step 35 โ€” Set Root Password

  • ๐Ÿ”‘ Set root password
passwd root

๐Ÿšช Step 36 โ€” Exit chroot, Unmount, Reboot into Firmware Setup

  • ๐Ÿ‘‹ Exit chroot, unmount and reboot into UEFI/BIOS to check if Secure Boot is enabled
exit
umount -R /mnt
systemctl reboot --firmware-setup

๐Ÿงฉ Step 37 โ€” Configure Snapper after Reboot

  • ๐Ÿ”Œ Unmount the default /.snapshots subvolume
umount /.snapshots
  • ๐Ÿ—‘๏ธ Delete it to avoid conflicts with our custom mount
rm -r /.snapshots
  • ๐Ÿ› ๏ธ Initialize Snapper for root filesystem
snapper -c root create-config /
  • โŒ Delete the subvolume Snapper just created (weโ€™ll remount it ourselves)
btrfs subvolume delete /.snapshots
  • ๐Ÿ“‚ Recreate the mount point and mount it
mkdir /.snapshots
mount /.snapshots
  • ๐Ÿ” Secure the directory
chmod 750 /.snapshots
  • ๐Ÿ“ Configure Snapper snapshot settings
nvim /etc/snapper/configs/root
  • Content:
TIMELINE_CREATE="yes"
TIMELINE_CLEANUP="yes"

NUMBER_MIN_AGE="1800"
NUMBER_LIMIT="10"
NUMBER_LIMIT_IMPORTANT="10"

TIMELINE_MIN_AGE="1800"
TIMELINE_LIMIT_HOURLY="5"
TIMELINE_LIMIT_DAILY="7"
TIMELINE_LIMIT_WEEKLY="0"
TIMELINE_LIMIT_MONTHLY="0"
TIMELINE_LIMIT_YEARLY="0"

๐Ÿ›ก๏ธ Step 38 โ€” Custom Pacman Hook to Backup /efi

  • ๐Ÿช Create a hook to automatically backup /efi before critical updates
nvim /etc/pacman.d/hooks/10-efi_backup.hook
  • Content:
๐Ÿ“„ 10-efi_backup.hook content (click to expand)
## PACMAN EFI BACKUP HOOK
## /etc/pacman.d/hooks/10-efi_backup.hook

[Trigger]
Type = Path
Operation = Install
Operation = Upgrade
Operation = Remove
Target = usr/lib/initcpio/*
Target = usr/lib/firmware/*
Target = usr/lib/modules/*/extramodules/
Target = usr/lib/modules/*/vmlinuz
Target = usr/src/*/dkms.conf

[Trigger]
Type = Package
Operation = Install
Operation = Upgrade
Operation = Remove
Target = mkinitcpio
Target = mkinitcpio-git

[Action]
Description = Backing up /efi...
When = PreTransaction
Exec = /usr/local/sbin/efi_backup.sh
  • โœ๏ธ Create the backup script
nvim /usr/local/sbin/efi_backup.sh
  • Content:
๐Ÿ“„ efi_backup.sh content (click to expand)
#!/bin/bash
## SCRIPT EFI BACKUP
## /usr/local/sbin/efi_backup.sh

tar -czf "/.efibackup/efi-$(date +%Y%m%d-%H%M%S).tar.gz" -C / efi
ls -1t /.efibackup/efi-*.tar.gz | tail -n +4 | xargs -r rm --
  • โœ… Make it executable
chmod +x /usr/local/sbin/efi_backup.sh

โœ‚๏ธ Step 39 โ€” Limit fstrim to FAT32 /efi Only

  • โš™๏ธ Override default fstrim behavior
systemctl edit fstrim.service
  • Content:
[Service]
ExecStart=
ExecStart=/usr/sbin/fstrim -v /efi

โฒ๏ธ Step 40 โ€” Enable Maintenance Timers

  • ๐Ÿ•’ Enable regular TRIM for /efi only
systemctl enable fstrim.timer
  • ๐Ÿ“ธ Enable automatic timeline snapshots
systemctl enable snapper-timeline.timer
  • ๐Ÿงผ Enable automatic snapshot cleanup
systemctl enable snapper-cleanup.timer

๐Ÿงท Step 41 โ€” Enable Pacman Transaction Snapshots

  • ๐Ÿงฉ Install snap-pac to snapshot before and after pacman operations
pacman -S snap-pac

๐Ÿ—‘๏ธ Step 42 โ€” Clean Snapper Initial Snapshots Manually

  • ๐Ÿ“‹ List snapshots (๐Ÿ”)
snapper -c root list
  • ๐Ÿงน Delete a range of snapshots (e.g., snapshots 1 to 2)
snapper -c root delete 1-2

๐Ÿ“ธ Step 43 โ€” Take Initial System Snapshot

  • ๐ŸงŠ Manually create the first system snapshot after full setup
snapper -c root create -d "init"

โ“ FAQ

โ“ Why no bootloader?

Because UKI allows booting the kernel directly from the EFI partition โ€” no need for GRUB or systemd-boot.

โ“ Can I use this on my laptop?

Yes โ€” it's ideal for modern laptops with TPM2 and Secure Boot enabled.


๐Ÿ›  Requirements

  • ๐Ÿ–ฅ๏ธ UEFI firmware
  • ๐Ÿงฉ TPM 2.0 module
  • ๐Ÿงท Secure Boot support
  • ๐Ÿ’ฟ Recent Arch Linux ISO
  • ๐ŸŒ Internet access
  • ๐Ÿงฎ NVMe drive with 4K physical block size

๐Ÿ“œ License

Licensed under the MIT License. Feel free to use, modify, and share!


๐Ÿ‘ค Author

Crafted with โค๏ธ by joan31

"Build it clean. Build it solid. Fortress-grade Arch Linux."

Releases

No releases published

Packages

 
 
 

Contributors

Languages