Inatall Arch Linux with secure boot + encrypt (luks2 cryptlvm) partition + unlock lvm encrypt with TPM2 + Dualboot with windows
Arch Linux Install – Introduction
This guide will tell you how to install fully encrypted Arch base system with SecureBoot enabled . This specific guide uses Unified Boot Image for booting and therefore there is no need for software like GRUB.
Check this list before starting!
Your computer supports SecureBoot/UEFI
Your computer allows for enrollment of your own secureboot keys
Your computer does not have manufacturer’s backdoors
You DO NOT need dualboot with windows You can choose whether you want Microsoft CA when enrolling keys
If you are not interested in SecureBoot, you can just skip last section of this document.
Preparing USB and booting the installer
Download the latest Archlinux ISO and copy it to your USB:
sudo dd if=/path/to/file.iso of=/dev/sdX status=progress
sync
or if you are using windows can download rufus and create a bootable usb (GPT bootable) or BalenaEtcher
Reboot your machine (if enabled => disable secureboot in BIOS) and boot ArchLinux USB.
When your installer has booted, especially on laptop, you may want to enable WiFi connection:
iwctl
station list
station wlan0 connect SSID (or station wlan0 connect-hidden SSID)
<password prompt>
exit
then if not get ip, run:
Run this command for get ip
dhcpcd
check net
ping -c3 archlinux.org
Disk partitioning
See your disk status:
to get list of partition and structure of it
lsblk
Following example assumes you have a nvme drive (/dev/nvme0nX). Your drive may as well report as (/dev/sdX).
You can use your favoruite tool, that supports creating the GPT partiton, for example cfdisk:
change nvme0nX with your disk data (get from lsblk)
cfdisk /dev/nvme0nX
and then choose gpt partiton table and create something like this:
+----------------------+----------------------+----------------------+
| /dev/nvme0n1p1 | /dev/nvme0n1p2 (encrypted using LUKS2) |
| 1024 MB | 68 GB |
+----------------------+---------------------------------------------+
| EFI Boot Partition | LVM | LVM |
| | | |
| /boot/efi | / | [Swap] |
| | | |
| | /dev/vg/root | /dev/vg/swap |
| | | |
| 1024 MB | 60 GB | 8 GB |
+----------------------+----------------------+----------------------+
So we need to EFI partitions (if already installed windows or etc… – or you have efi partiton befor it => dont need to recreate or format it just mount it)
for root partiton Create ext4 partiton
and creat a SWAP pariton
at the end => choose Write from bottom menu to save your change (Carefull !!!)
Format:
EFI -> (if already installed windows or etc... - or you have efi partiton befor it => dont need to recreate or format it just mount it)
mkfs.fat -F32 /dev/nvme0n1p1
Encrypted DISK for (root and swap)
cryptsetup luksFormat --type luks2 /dev/nvme0n1p2
Now we can create encrypted volume and open it (–perf options are optional and recommended for SSD):
cryptsetup open --perf-noreadworkqueue --perf-nowriteworkqueue --persistent /dev/nvme0n1p2 cryptlvm
Configuring LVM and formatting root partition:
pvcreate /dev/mapper/cryptlvm
vgcreate vg /dev/mapper/cryptlvm
Create 60 GB space for root
lvcreate -L 60G vg -n root
Use another space for SWAP (68 - 60 = 8 GB)
lvcreate -l 100%FREE vg -n swap
format root
mkfs.ext4 /dev/vg/root
Create swap
mkswap /dev/vg/swap
After all is done we need to mount our drives:
root
mount /dev/vg/root /mnt
swap
swapon /dev/vg/swap
boot
mkdir -p /mnt/boot/efi
mount /dev/nvme0n1p1 /mnt/boot/efi
Now for see result
Run:
lsblk
For best performance in download speed from arch repo
go to mirror list file and set best arch repo at first – example:
add : Best Repo for IRAN – copy one of them and set it in the first repo in this file
nano /etc/pacman.d/mirrorlist
System bootstraping
In the next step it is recommended to install CPU microcode package. Depending on whether you have intel of amd you should apend intel-ucode or amd-ucode to your pacstrap
My pacstrap presents as follows:
pacstrap -K /mnt base linux linux-firmware YOURUCODEPACKAGE sudo nano lvm2 dracut sbsigntools iwd git efibootmgr binutils dhcpcd
Generate fstab:
genfstab -U /mnt >> /mnt/etc/fstab
Optional Step
For esay-write script in arch (In real installation we not have option for copy paste script so copy all script file to a usb flash drive and mount it after generate fstab)
Create this files in usb flash drive
usb2
|
├── cmdline.conf
├── flags.conf
├── secureboot.conf
├── dracut-install.sh
├── dracut-remove.sh
├── 60-dracut-remove.hook
├── 90-dracut-install.hook
└── zz-sbctl.hook
!!!(files content is in the bellow)!!!
Connect the usb flash drive to computer and run:
Check place of usb => SdaX or SdbX etc ...
lsblk
mount usb2 to /usb2 folder
mount /dev/sdbX /mnt/usb2 --mkdir
Now you can chroot to your system and perform some basic configuration:
arch-chroot /mnt
Set the root password:
passwd
My Optional suggestion is to also install man for additional help you may require:
manual for package Ex. -> man ls
pacman -Syu man-db
Set timezone and generate /etc/adjtime:
ln -sf /usr/share/zoneinfo/<Region>/<city> /etc/localtime
hwclock --systohc
Set your desired locale:
at /etc/locale.gen -> uncomment locales you want
with ctrl+w search for locales ex. enUS and remove -> sign at first it's line
nano /etc/locale.gen
Configure your keyboard (Optional) layout (mine is adapted to polish-programmer keyboard):
nano /etc/vconsole.conf
KEYMAP=pl
FONT=Lat2-Terminus16
FONTMAP=8859-2
Run locale-gen for generate locales
Set your hostname:
nano /etc/hostname
Write a name for your computer at this file and close it
Create your user:
useradd --create-home YOURNAME
passwd YOURNAME
Add your user to sudo:
add to sudo user
usermod --append --groups wheel YOURNAME
Config sudo
EDITOR=nano visudo
%wheel ALL=(ALL) ALL Uncomment this line
Enable some systemd units:
if you want system auto connect to wireless network at startup
systemctl enable iwd
if you want system auto get ip at startup
systemctl enable dhcpcd
Creating Unified Kernel Image and configuring boot entry
Create dracut scripts that will hook into pacman:
nano /usr/local/bin/dracut-install.sh copy this file to usb2
Write:
!/usr/bin/env bash
mkdir -p /boot/efi/EFI/Linux
while read -r line; do
if [[ "$line" == 'usr/lib/modules/'+([^/])'/pkgbase' ]]; then
kver="${line'usr/lib/modules/'}"
kver="${kver%'/pkgbase'}"
dracut --force --uefi --kver "$kver" /boot/efi/EFI/Linux/bootx64.efi
fi
done
And the removal script:
nano /usr/local/bin/dracut-remove.sh copy this file to usb2
!/usr/bin/env bash
rm -f /boot/efi/EFI/Linux/bootx64.efi
Make those scripts executable and create pacman’s hook directory:
chmod +x /usr/local/bin/dracut-
mkdir /etc/pacman.d/hooks
Now the actual hooks, first for the install and upgrade:
nano /etc/pacman.d/hooks/90-dracut-install.hook copy this file to usb2
[Trigger]
Type = Path
Operation = Install
Operation = Upgrade
Target = usr/lib/modules//pkgbase
[Action]
Description = Updating linux EFI image
When = PostTransaction
Exec = /usr/local/bin/dracut-install.sh
Depends = dracut
NeedsTargets
And for removal:
nano /etc/pacman.d/hooks/60-dracut-remove.hook copy this file to usb2
[Trigger]
Type = Path
Operation = Remove
Target = usr/lib/modules//pkgbase
[Action]
Description = Removing linux EFI image
When = PreTransaction
Exec = /usr/local/bin/dracut-remove.sh
NeedsTargets
Check UUID of your encrypted volume and write it to file you will edit next:
if you wnat copy this file from usb => first copy it and then run this command:
blkid -s UUID -o value /dev/nvme0n1p2 >> /etc/dracut.conf.d/cmdline.conf
and replace YOURUUID in this file with end line at this file (contain a code)
Edit the file and fill with with kernel arguments:
nano /etc/dracut.conf.d/cmdline.conf copy this file to usb2
kernelcmdline="rd.luks.uuid=luks-YOURUUID rd.lvm.lv=vg/root rd.lvm.lv=vg/swap resume=/dev/mapper/vg-swap root=/dev/mapper/vg-root rootfstype=ext4 rootflags=rw,relatime"
Create file with flags:
nano /etc/dracut.conf.d/flags.conf copy this file to usb2
compress="zstd"
hostonly="no"
Generate your image by re-installing linux package and making sure the hooks work properly:
pacman -S linux
You should have bootx64.efi within your /boot/efi/EFI/Linux/
Now you only have to add UEFI boot entry and create an order of booting:
efibootmgr to see your status of boot
Create boot entry for arch
efibootmgr --create --disk /dev/nvme0n1 --label "Linux Boot Manager" --loader 'EFI\Linux\bootx64.efi' --unicode
efibootmgr Check if you have left over UEFI entries, remove them with efibootmgr -b INDEX -B and note down Arch index
efibootmgr -o ARCHINDEXFROMPREVIOUSCOMMAND 0 or whatever number your Arch entry shows as
Now you can reboot and log into your system. (if not boot to arch you can boot from usb againg and just open encrypted device and mount your created partiton and run arch-chroot for troubleshooting and check files and scripts)
:exclamation: :exclamation: :exclamation: Compatilibity thing I noticed :exclamation: :exclamation: :exclamation:
Some (older?) platforms can ignore entries by efibootmgr all together and just look for EFI\BOOT\bootx64.efi, in that case you may generate your UKI directly to that directory and under that name. It’s very important that the name is also bootx64.efi.
SecureBoot
At this point you should enable Setup Mode for SecureBoot in your BIOS, and erase your existing keys (it may spare you setting attributes for efi vars in OS). If your system does not offer reverting to default keys (useful if you want to install windows later), you should backup them, though this will not be described here.
Configuring SecureBoot is easy with sbctl:
pacman -S sbctl
Check your status, setup mode should be enabled (You can do that in BIOS):
sbctl status
Installed: ✘ Sbctl is not installed
Setup Mode: ✘ Enabled
Secure Boot: ✘ Disabled
Create keys and sign binaries:
sbctl create-keys
sbctl sign -s /boot/efi/EFI/Linux/bootx64.efi it should be single file with name verying from kernel version
Configure dracut to know where are signing keys:
nano /etc/dracut.conf.d/secureboot.conf copy this file to usb2
uefisecurebootcert="/var/lib/sbctl/keys/db/db.pem"
uefisecurebootkey="/var/lib/sbctl/keys/db/db.key"
We also need to fix sbctl’s pacman hook. Creating the following file will overshadow the real one:
nano /etc/pacman.d/hooks/zz-sbctl.hook copy this file to usb2
[Trigger]
Type = Path
Operation = Install
Operation = Upgrade
Operation = Remove
Target = boot/
Target = efi/
Target = usr/lib/modules//vmlinuz
Target = usr/lib/initcpio/
Target = usr/lib//efi/.efi
[Action]
Description = Signing EFI binaries...
When = PostTransaction
Exec = /usr/bin/sbctl sign /boot/efi/EFI/Linux/bootx64.efi
Enroll previously generated keys (drop microsoft option if you don’t want their keys – Ex. Usage: dual booting):
sbctl enroll-keys --microsoft
or use it's(without microsoft config secureboot):
sbctl enroll-keys
Reboot the system. Enable only UEFI boot and Secure boot in BIOS and set BIOS password so anyone won’t simply turn off the setting. If everything went fine you should first of all, boot into your system, and then verify with sbctl or bootctl:
sbctl status
Installed: ✓ sbctl is installed
Owner GUID: YOURGUID
Setup Mode: ✓ Disabled
Secure Boot: ✓ Enabled
Enroll LUKS key in TPM 🤩 – Optional but fascination
if you wnat your computer boot without password (just with your config) do:
Install tpm2-tools:
pacman -S tpm2-tools
Enroll your LUKS volume to tpm, simply run the following command as root:
Select 0 or 1 or 2 or ... - My suggestin 1 < YOURREGNUMBER
systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/nvme0n1p2
or if you wnat remove your key, run this command:
systemd-cryptenroll --wipe-slot=tpm2 /dev/nvme0n1p2
You will need to add a kernel argument for enable the TPM2 bits
open:
nano /etc/dracut.conf.d/cmdline.conf
and change to:
kernelcmdline="rd.luks.options=YOURUUID=tpm2-device=auto rd.luks.uuid=luks-YOURUUID rd.lvm.lv=vg/root rd.lvm.lv=vg/swap resume=/dev/mapper/vg-swap root=/dev/mapper/vg-root rootfstype=ext4 rootflags=rw,relatime"
Ensure that dracut builds in the TPM2 libraries. Create:
nano /etc/dracut.conf.d/tpm2-tss.conf
write:
adddracutmodules+=" tpm2-tss "
Finally, rebuild your unified kernel image:
Run for auto
pacman -S linux
Mybe not neeed bellow command (Because this create a other xxxx.efi boot file) - Manually create
ls /lib/modules for check kver
dracut --force --uefi --kver "YOURKEYVER" /boot/efi/EFI/Linux/bootx64.efi
Additionally, A useful script to have handy for when you change UEFI settings to reenroll your LUKS key under the different PCR values is as follows:
nano /bin/luksreenrolltpm
write:
systemd-cryptenroll --wipe-slot=tpm2 /dev/disk/by-uuid/UUIDHERE
Select 0 or 1 or 2 or ... - My suggestin 1 < YOURREGNUMBER
systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/disk/by-uuid/UUIDHERE
At the end – you have a Compter with enabled Secure boot and encrypted drive
When need passphrase at boot
The goal here is to only require the passphrase when something spooky happens in your boot path.
UEFI settings change? Request password.
Some weird swap of some module of UEFI code that lives on your motherboard somewhere? Request password.
Unified Kernel Image changes? Don’t even boot.
Drive in another computer? Request password.
The only time the drive should unlock is when it’s in the right computer with the right configuration and the right signed unified kernel image with the right kernel arguments. If your Xorg server just auto logs in and opens a terminal well…don’t do that.
Thanks from
Ataraxxia for secure-arch
Krin for TPM2 unlocking
this gist just a fork (copy this file from github to gist) wtih some additonal setting and edit and … for my usage
if you want continue and install sway UI and some app and customaization go to secure-arch
Thank you for reading this gist and i’m sorry about my english grammer (if it’s)