https://wiki.archlinux.org/api.php?action=feedcontributions&user=Krin&feedformat=atomArchWiki - User contributions [en]2024-03-29T07:05:11ZUser contributionsMediaWiki 1.41.0https://wiki.archlinux.org/index.php?title=User:Krin/Secure_Boot,_full_disk_encryption,_and_TPM2_unlocking_install&diff=701616User:Krin/Secure Boot, full disk encryption, and TPM2 unlocking install2021-11-11T16:12:50Z<p>Krin: /* Booting only Linux */ Update instructions for post enroll-keys reboot.</p>
<hr />
<div>{{Unsupported|1 October 2021}}<br />
<br />
== Introduction ==<br />
<br />
This installation is based on my installing Arch on an Asus ROG Strix G G531 I got second hand and a desktop computer made of second hand parts that had to share space with Windows. The primary goals were to replace Windows 10 Pro with Bitlocker encryption and maintain the convenience and security balance of that original operating system.<br />
<br />
My requirements boiled down to:<br />
<br />
* A fully encrypted disk<br />
* Full Secure Boot validation of all UEFI components.<br />
* Use of the TPM to facilitate unlocking of the disk.<br />
* Hibernate/Suspend working.<br />
<br />
My primary use case here is to make it difficult enough for a baggage handler with sticky hands to get at my data that they just wipe the drive. A state level actor with the expertise and equipment to hot swap my ram in my hotel room is not something that I'm defending this ''particular'' laptop against. This is more for gaming and web browsing and uploading photos while traveling.<br />
<br />
I'll continue to update these notes as I develop further solutions.<br />
<br />
== Disclaimers ==<br />
<br />
This article is primarily for the author's own notes. It is assumed that the reader is familiar with the [[Installation guide]] and will refer to it often. Reading linked articles is recommended.<br />
<br />
== Dual Booting Modifications ==<br />
<br />
{{warning|If you use BitLocker on your Windows drive, ensure you have your recovery key handy. The installation process will change your TPM measurements causing Windows to require you enter the key manually the next time you boot it.}}<br />
<br />
For computers that will have to dual boot with windows, the easiest solution is to use two different physical drives and utilize your motherboard's UEFI boot menu to select which one to boot. This guide will follow that assumption. You can also attempt to have everything live on one EFI partition. Windows's 100 MiB EFI partition is especially problematic to this approach for secure boot, as Unified Kernel Images can approach 80 MiB and Windows 10 regularly uses up to 30 MiB. An alternative is to copy the Microsoft bootloader into your Linux EFI bootloader and then prioritize the Linux EFI disk over your Windows disk. You will want to copy the directory {{ic|WINDOWS_EFI_PARITION/EFI/Microsoft}} to the same location on your Linux EFI partition. Anytime Microsoft updates the bootloader, you will need to copy the Microsoft EFI folder again.<br />
<br />
There are two changes that will be made and will be noted in the relevant sections:<br />
<br />
* Do not clear your Secure Boot keys. Merely disable Secure Boot for the installation.<br />
* Use {{ic|shim}} to boot systemd-bootloader<br />
* Load your db.cer file into the MOKManager application.<br />
<br />
All remaining steps should remain the same, except your system will still be dependent on the factory provided Microsoft Certificates. But you can boot Windows 10 in Secure Boot, which will be important for Windows 11.<br />
<br />
== Initial setup ==<br />
<br />
=== Pre-installation ===<br />
<br />
If you will only boot linux, reset your Secure Boot settings in BIOS to enable setup mode. Usually this means you set Secure Boot to Enabled and then select the option to wipe out the keys.<br />
<br />
If you will be dual booting Windows, disable secure boot.<br />
<br />
Follow the [[Installation_guide#Pre-installation]] up to Paritioning the Disks.<br />
<br />
=== Disk preparation ===<br />
<br />
If you have data on your disks you want to overwrite, utilize [[Dm-crypt/Drive_preparation#dm-crypt_wipe_on_an_empty_disk_or_partition]] to wipe it. If this disk was previously encrypted, utilize [[Dm-crypt/Drive_preparation#Wipe_LUKS_header]] instead for a much faster disposal. Finally, use [[Dm-crypt/Encrypting_an_entire_system#LVM_on_LUKS]] to parition your drive with two differences.<br />
<br />
{{tip|Using a memorable LUKS passphrase until you've completed the install process can be helpful. It will take several reboots to finish setup.}}<br />
<br />
First, the partition layout will be similar to here. You may wish to break out the /home directory into it's own partition. The primary requirement is that only your EFI partition be unencrypted.<br />
<br />
{{hc|Partiton Layout|<br />
┌────────────────────┬─────────────────────────┬──────────────────────────┬───────────────────────────┐<br />
│ │ │ │ │<br />
│ EFI Boot Partition │ Logical Volume 1 │ Logical Volume 2 │ Logical Volume 3 │<br />
│ /efi │ [Swap] │ / │ /home │<br />
│ /dev/nvme0n1p1 │ /dev/CryptRootVG/swap │ /dev/CryptRootVG/root │ /dev/CryptRootVG/home │<br />
│ 512 MB │ 16GB (Or RAM Size) │ 50 GB │ Remaining Space │<br />
│ │ │ │ │<br />
│ ├─────────────────────────┴──────────────────────────┴───────────────────────────┤<br />
│ │ LUKS and LVM Physical Volume │<br />
│ │ /dev/nvme0n1p2 │<br />
│ │ │<br />
│ │ │<br />
│ │ │<br />
│ │ │<br />
└────────────────────┴────────────────────────────────────────────────────────────────────────────────┘<br />
}}<br />
<br />
Second, if your hard drive is an SSD, use the following command to open your LUKS volume.<br />
<br />
# cryptsetup open --perf-no_read_workqueue --perf-no_write_workqueue --persistent /dev/nvme0n1p2 cryptroot<br />
<br />
After completing your LUKS on LVM setup, format your EFI partition per [[EFI system partition]].<br />
<br />
# mkfs.fat -F32 /dev/nvme0n1p1<br />
<br />
Mount this partition at {{ic|/mnt/efi}}. It is very important to leave {{ic|/boot}} on your encrypted root partition.<br />
<br />
== Installation ==<br />
<br />
Continue with [[Installation_guide#Installation]]. Be sure to flesh out your {{man|8|pacstrap}} with the following list of packages:<br />
<br />
* {{Pkg|dracut}}<br />
* {{Pkg|sbsigntools}}<br />
* {{Pkg|intel-ucode}}<br />
* {{Pkg|lvm2}}<br />
* {{Pkg|openssh}}<br />
* {{Pkg|ansible}}<br />
* {{Pkg|git}}<br />
* {{Pkg|iwd}}<br />
* {{Pkg|efibootmgr}}<br />
<br />
<br />
We are going to leave off the installation guide at the initramfs section, so go ahead and reset your root password. <br />
<br />
# passwd<br />
<br />
=== Bootloader ===<br />
<br />
First, install {{ic|systemd-boot}} by following [[Systemd-boot#Installing_the_EFI_boot_manager]]. Next, install {{aur|dracut-hook-uefi}}.<br />
<br />
Ensure you drop in a systemd-boot hook to update your bootctl any time it's updated.<br />
<br />
{{hc|/etc/pacman.d/hooks/998-systemd-boot.hook|2=<br />
[Trigger]<br />
Type = Package<br />
Operation = Install<br />
Operation = Upgrade<br />
Target = systemd<br />
<br />
[Action]<br />
Description = Updating systemd-boot<br />
When = PostTransaction<br />
Exec = /usr/bin/bootctl update; <br />
}}<br />
<br />
Obtain the UUID of your LUKS drive via the following command:<br />
<br />
{{bc|<br />
blkid -s UUID -o value /dev/nvme0n1p2<br />
}}<br />
<br />
Create the following files with the listed content. Be sure to replace UUIDs with what you actually need. See {{man|5|dracut.conf}} for more information on what these commands do.<br />
<br />
This is just an example command line, you may need to rework this based on your partitions and UUIDs.<br />
<br />
{{hc|/etc/dracut.conf.d/cmdline.conf|2=<br />
kernel_cmdline="rd.luks.uuid=luks-17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02 rd.lvm.lv=CryptRoot/root rd.lvm.lv=CryptRoot/swap resume=/dev/mapper/CryptRoot-swap root=/dev/mapper/CryptRoot-root rootfstype=ext4 rootflags=rw,relatime"<br />
}}<br />
<br />
{{hc|/etc/dracut.conf.d/flags.conf|2=<br />
compress="zstd"<br />
hostonly="no"<br />
}}<br />
<br />
Run the following command to generate your EFI stub kernels.<br />
<br />
dracut --uefi<br />
<br />
{{Warning|If the archiso kernel version (or type) differs from what is installed in your chroot, find the appropriate name in {{ic|/lib/modules}} and add it as the value of the {{ic|--kver}} argument to all dracut commands. For example, {{ic| dracut --uefi --kver 5.14.16-zen1-1-zen}}.}}<br />
<br />
=== Secure boot ===<br />
<br />
==== Dual Booting Windows ====<br />
<br />
Review [[Unified Extensible Firmware Interface/Secure Boot#shim]] to get a rough understanding of how it's going to work. Install {{aur|shim-signed}}. Perform the following commands to place files where both the UEFI boot entry and shim will load them.<br />
<br />
# mv /efi/EFI/BOOT/BOOTx64.EFI /efi/EFI/BOOT/grubx64.efi<br />
# cp /usr/share/shim-signed/shimx64.efi esp/EFI/BOOT/BOOTx64.EFI<br />
# cp /usr/share/shim-signed/mmx64.efi esp/EFI/BOOT/<br />
<br />
Install {{Pkg|sbctl}}. Use the following command to check that secure boot is in the right status. Your output should be similar.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✘ Sbctl is not installed<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/BOOT/grubx64.efi is not signed<br />
<br />
✘ /efi/EFI/BOOT/mmx64.efi is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
}}<br />
<br />
Note that shim and MOKManager (mmx) is included in this list, even though we will not be signing it.<br />
<br />
{{bc|<br />
# sbctl sign -s /efi/EFI/BOOT/ grubx64.efi <br />
<br />
✔ Signed /efi/EFI/BOOT/grubx64.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi <br />
<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi <br />
<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi<br />
# sbctl verify<br />
<br />
Verifying file database and EFI images in /efi...<br />
✔� /efi/EFI/BOOT/grubx64.efi is signed<br />
✔ /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi is signed<br />
✔ /efi/EFI/systemd/systemd-bootx64.efi is signed<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/BOOT/mmx64.efi is not signed<br />
}}<br />
<br />
You can validate that {{ic|BOOTx64.EFI}} and {{ic|mmx64.efi}} have signatures with {{man|1|sbverify}} from the {{Pkg|sbsigntools}} package.<br />
<br />
Next, we need to create the DER format certificate to load into ''MokManager''.<br />
<br />
# openssl x509 -outform DER -in /usr/share/secureboot/keys/db/db.pem -out /efi/signing.cer<br />
<br />
Use {{Pkg|efibootmgr}} ({{man|8|efibootmgr}}) to adjust your boot entries. Primarily, you will want to remove the {{ic|Linux Boot Manager}} entry.<br />
<br />
{{bc|<br />
# efibootmgr<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0001,0000,0002,0003,0004<br />
Boot0000* Windows Boot Manager<br />
Boot0001* Linux Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
}}<br />
<br />
In this example, we see that {{ic|0000}} is the Windows boot manager. {{ic|0001}} is the Linux Boot Manager and also the first in line to boot. {{ic|0001}} needs to be deleted and optionally the boot order modified so {{ic|0004}} is the default boot entry.<br />
<br />
{{bc|<br />
# efibootmgr --bootnum 0001 --delete-bootnum<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0000,0002,0003,0004<br />
Boot0000* Windows Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
<br />
# efibootmgr --bootorder 0004,0000,0002,0003<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0004,0000,0002,0003<br />
Boot0000* Windows Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Now reboot. You should get an error from your motherboard's UEFI BIOS that secure boot checks failed. Your computer should restart directly into ''MokManager'', if you rearranged the boot order. If not, you will need to select {{ic|UEFI OS}} from your UEFI boot menu. Navigate to the {{ic|signing.cer}} file we placed on the EFI partition and enroll the key. Select reboot, and the system should boot directly into linux with no problem.<br />
<br />
==== Booting only Linux ====<br />
<br />
{{note|Credit to this [https://lunaryorn.com/secure-boot-on-arch-linux-with-sbctl-and-dracut blog post by lunaryorn] for the inspiration.}}<br />
<br />
Install {{Pkg|sbctl}}. At this point you will likely need to reboot and adjust your secure boot settings. You want secure boot in '''setup mode'''. <br />
<br />
{{bc|<br />
$ sbctl status<br />
Installed: X Sbctl is not installed<br />
Setup Mode: X Enabled<br />
Secure Boot: X Disabled<br />
}}<br />
<br />
Run the following commands as root. See {{man|8|sbctl}} for more information on their function. Of particular note is the {{ic|-s}} flag which indicates {{ic|sbctl}} should remember the file for future verification and signing.<br />
<br />
Note your Linux EFI binary name may be slightly different.<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
<br />
# sbctl sign -s /efi/EFI/BOOT/BOOTx64.EFI<br />
✔ Signed /efi/EFI/BOOT/BOOTx64.EFI<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Finally, enroll the Secure Boot keys.<br />
<br />
{{bc|<br />
# sbctl enroll-keys<br />
Enrolling keys to EFI variables...✔<br />
Enrolled keys to the EFI variables!<br />
}}<br />
<br />
Verify that secure boot now has an owner GUID and setup mode is disabled.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✔ Sbctl is installed<br />
Owner GUID: a2ee3d08-725a-408b-9d95-28026a44611c<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
Now reboot and enable secure boot in your firmware.<br />
<br />
=== Enroll LUKS key in TPM ===<br />
{{warning|Yes, this will cause a system to automatically unlock it's encrypted root volume without any interaction from a human. Yes, this exposes it to any sufficently advanced Evil Maid attacks. If sealed against the appropriate registers (especially register 8 with the kernel arguments), the TPM measurements should force systemd to ask for your LUKS passphrase in almost any attempt to access the encrypted volume from outside your normal boot process.}}<br />
<br />
We are fortunate that in our shift to dracut includes utilizing systemd and sd-encrypt, as we can use systemd's native support for enrolling LUKS keys. A review of [[Trusted Platform Module#Using TPM 2.0]] is recommended but not very clear.<br />
<br />
==== Avoid dracut bugs ====<br />
<br />
Subtitle: The Case of the Missing {{ic|d}}<br />
<br />
Two bugs, one in systemd 249.4-1-arch [https://github.com/systemd/systemd/issues/19177] and one in dracut 055 [https://github.com/dracutdevs/dracut/pull/1526][https://github.com/dracutdevs/dracut/issues/1542] will combine to prevent your system from being able to boot. The dracut issue causes the '''tpm2-tss''' module to not be included in your image. The systemd issue causes systemd to go into an emergency when it can't locate the TPM2 libraries, instead of falling back to asking for your passcode.<br />
<br />
The systemd bug isn't a problem so long as you always have TPM2 libraries present.<br />
<br />
To resolve this, first check your version of dracut.<br />
<br />
{{bc|<br />
$ dracut --version<br />
dracut 055<br />
}}<br />
<br />
Since the next release of dracut should have this fixed, we can simply fix the script locally until the next release.<br />
<br />
{{warning|These steps are only necessary for dracut 055}}<br />
<br />
Find the following lines in {{ic|/usr/lib/dracut/modules.d/91tpm2-tss/module-setup.sh}}:<br />
<br />
{{bc|1=<br />
# Module dependency requirements.<br />
depends() {<br />
<br />
# This module has external dependency on other module(s).<br />
echo systemd-sysusers systemd-udev<br />
# Return 0 to include the dependent module(s) in the initramfs.<br />
return 0<br />
<br />
}<br />
}}<br />
<br />
Change the dependency {{ic|systemd-udev}} to <code>systemd-udev<b>d</b></code>.<br />
<br />
Continue with the remaining steps in this section.<br />
<br />
==== Enrollment ====<br />
<br />
First, be sure to install {{Pkg|tpm2-tools}}. Alternatively {{aur|ibm-tss}} can be used per [[Trusted Platform Module]], however this guide is not tested against those.<br />
<br />
{{note|A reboot may be required to convince {{ic|systemd-cryptenroll}} that TPM 2.0 devices now exist on the machine.}}<br />
<br />
There are several decisions to be made here. The table at [[Trusted Platform Module#Accessing PCR registers]] is accurate as of October 2021. Essentially, once you seal your LUKS key, if any of the registers you've sealed against change, then you will be asked for your LUKS passphrase. This is equivalent to when Windows 10 makes you enter your BitLocker recovery key after a hardware change or changing BIOS settings.<br />
<br />
Your mileage may vary, based on UEFI vendors. For my laptop, I went with 0+1+2+3+4+5+7+8 and have been able to invalidate my TPM. Unfortunately, if you change your system BACK the volume will unlock. I'm investigating how to disable that.<br />
<br />
Other options on {{man|1|systemd-cryptenroll}} will reveal that several hardware tokens can also be enrolled to allow unlocking the root LUKS volume automatically, but only if a key is present. Further testing is requried.<br />
<br />
To enroll your LUKS volume, simply run the following command as root<br />
<br />
# systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/nvme0n1p2<br />
<br />
To remove your key, run this command:<br />
<br />
# systemd-cryptenroll --wipe-slot=tpm2 /dev/nvme0n1p2<br />
<br />
You will need to add a kernel argument like below to enable the TPM2 bits. If following this guide, this should be located in {{ic|/etc/dracut.conf.d/cmdline.conf}}<br />
<br />
rd.luks.options={UUID}=tpm2-device=auto<br />
<br />
Ensure that dracut builds in the TPM2 libraries. Create the following file.<br />
<br />
{{hc|/etc/dracut.conf.d/tpm2-tss.conf|2=<br />
add_dracutmodules+=" tpm2-tss "<br />
}}<br />
<br />
Finally, rebuild your unified kernel image.<br />
<br />
# dracut --force --uefi<br />
<br />
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:<br />
<br />
{{hc|~/bin/luks_reenroll_tpm|2=<br />
sudo systemd-cryptenroll --wipe-slot=tpm2 /dev/disk/by-uuid/{UUID_HERE}<br />
systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/disk/by-uuid/{UUID_HERE}<br />
}}<br />
<br />
=== Wrapping up ===<br />
<br />
Set your UEFI password. <br />
<br />
Change your LUKS passphrase from something easily memorable to a good long recovery key.<br />
<br />
Keep both of these pieces of info somewhere safe. This varies depending on your threat model. If we're just talking about Stolen Laptops and Nosy Maids, a hard copy in your safe should be sufficient. If it's the NSA, I'm not sure this setup is appropriate for that model.<br />
<br />
This is an excellent base to handle stolen laptop and even some lower grade Evil Maids. From here, you should head into [[Security]]. Consider learning a framework to help you manage your system state such as [[Ansible]] or headless [[Puppet]].<br />
<br />
== Justifications ==<br />
<br />
=== LVM on LUKS vs other dm-crypt approaches ===<br />
<br />
LVM on LUKS was selected becasue it is simply the easiest to manage while conferring both encrypted swap and disk. The other approaches required much more tooling and manual fussing to utilize. This selection also gives room change freely between {{ic|busybox}} and {{ic|systemd}} initrds.<br />
<br />
=== Using dracut ===<br />
<br />
{{Pkg|dracut}} just makes it easier to build full unified kernels that {{man|7|systemd-boot}} can launch as EFI binaries. There is also available tooling in the [[AUR]] for automating the creation of these binaries. Finally, {{ic|dracut}} will sign the binaries it creates automatically when configured to do so.<br />
<br />
=== Unified kernel images ===<br />
<br />
While UKI's could be problematic on other distributions, they fit right in with an Arch Linux install. The automation is there through pacman hooks and {{Pkg|sbctl}} to sign our UKIs as they're created. Furthermore, you can only sign and create a new signed UKI while booted into a properly signed UKI. It creates a chain of trust, which means it's important to never disable Secure Boot once you've set it up.<br />
<br />
The UKI encompasses all of the following items inside the signature, which means you can't change any of them without invalidating the signature.<br />
<br />
* Kernel arguments<br />
* Initrd/Initramfs<br />
* Kernel<br />
<br />
In particular, all other flavors of secureboot do not sign or validate the initramfs. This is a big attack area and can be relatively trivialized that a semi-decent pawn shop owner with Google could likely find an image that would grant him access and make the TPM none the wiser the system has changed. One can prevent this with encrypted /boot, but that would limit you to GRUB2 and LUKS version 1 devices only. This also doesn't include the work to keep GRUB2's files signed with a PGP key by root.<br />
<br />
=== LUKS enrolled in TPM ===<br />
<br />
The goal here is to only require the passphrase when something spooky happens in your boot path.<br />
<br />
UEFI settings change? Request password.<br />
<br />
Some weird swap of some module of UEFI code that lives on your motherboard somewhere? Request password.<br />
<br />
Unified Kernel Image changes? Don't even boot.<br />
<br />
Drive in another computer? Request password.<br />
<br />
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.<br />
<br />
== Miscellaneous discussions ==<br />
<br />
=== Filesystem Selection ===<br />
<br />
Most examples on Arch utilize {{ic|ext4}}, but other file systems such as {{ic|brtfs}} can work equally well. As for performance or issues with being inside LVM, [https://btrfs.wiki.kernel.org/index.php/FAQ#Btrfs_has_subvolumes.2C_does_this_mean_I_don.27t_need_a_logical_volume_manager_and_I_can_create_a_big_Btrfs_filesystem_on_a_raw_partition.3F this question in the brtfs FAQ] implies that there is some performance loss but no other issues.<br />
<br />
=== LUKS TPM enrollment and managing luks keys ===<br />
<br />
Note that using {{man|1|systemd-cryptenroll}} will add a key to your LUKS volume. It's not clear how exactly the option {{ic|1=--wipe-slot=tpm2}} is able to identify which slot it needs to wipe, but it does. This even works if your TPM has changed.<br />
<br />
You can see the effects by comparing the output of {{ic|cryptsetup luksDump /dev/nvme0n1p2}} before and after you enroll or wipe a TPM based key. You can identify what slot your own passphrase is in with {{ic|cryptsetup --verbose open --test-passphrase /dev/nvme0n1p2}} and entering your passphrase. The output will inform you which key slot was unlocked.<br />
<br />
Finally, your passphrase may be changed with {{ic|cryptsetup luksChangeKey /dev/nvme0n1p2 -S 0}}.<br />
<br />
== Planned TODOs ==<br />
A panic command that can dump the TPM and shutdown the computer (without requiring the time of entering a password in sudo) forcing an adversary to resort to [https://en.wikipedia.org/wiki/Rubber-hose_cryptanalysis rubber-hose cryptanalysis] to get to the encrypted data.</div>Krinhttps://wiki.archlinux.org/index.php?title=User:Krin/Secure_Boot,_full_disk_encryption,_and_TPM2_unlocking_install&diff=701615User:Krin/Secure Boot, full disk encryption, and TPM2 unlocking install2021-11-11T16:11:24Z<p>Krin: /* Bootloader */ Add warning for when booted kernel and the kernel we're building differ.</p>
<hr />
<div>{{Unsupported|1 October 2021}}<br />
<br />
== Introduction ==<br />
<br />
This installation is based on my installing Arch on an Asus ROG Strix G G531 I got second hand and a desktop computer made of second hand parts that had to share space with Windows. The primary goals were to replace Windows 10 Pro with Bitlocker encryption and maintain the convenience and security balance of that original operating system.<br />
<br />
My requirements boiled down to:<br />
<br />
* A fully encrypted disk<br />
* Full Secure Boot validation of all UEFI components.<br />
* Use of the TPM to facilitate unlocking of the disk.<br />
* Hibernate/Suspend working.<br />
<br />
My primary use case here is to make it difficult enough for a baggage handler with sticky hands to get at my data that they just wipe the drive. A state level actor with the expertise and equipment to hot swap my ram in my hotel room is not something that I'm defending this ''particular'' laptop against. This is more for gaming and web browsing and uploading photos while traveling.<br />
<br />
I'll continue to update these notes as I develop further solutions.<br />
<br />
== Disclaimers ==<br />
<br />
This article is primarily for the author's own notes. It is assumed that the reader is familiar with the [[Installation guide]] and will refer to it often. Reading linked articles is recommended.<br />
<br />
== Dual Booting Modifications ==<br />
<br />
{{warning|If you use BitLocker on your Windows drive, ensure you have your recovery key handy. The installation process will change your TPM measurements causing Windows to require you enter the key manually the next time you boot it.}}<br />
<br />
For computers that will have to dual boot with windows, the easiest solution is to use two different physical drives and utilize your motherboard's UEFI boot menu to select which one to boot. This guide will follow that assumption. You can also attempt to have everything live on one EFI partition. Windows's 100 MiB EFI partition is especially problematic to this approach for secure boot, as Unified Kernel Images can approach 80 MiB and Windows 10 regularly uses up to 30 MiB. An alternative is to copy the Microsoft bootloader into your Linux EFI bootloader and then prioritize the Linux EFI disk over your Windows disk. You will want to copy the directory {{ic|WINDOWS_EFI_PARITION/EFI/Microsoft}} to the same location on your Linux EFI partition. Anytime Microsoft updates the bootloader, you will need to copy the Microsoft EFI folder again.<br />
<br />
There are two changes that will be made and will be noted in the relevant sections:<br />
<br />
* Do not clear your Secure Boot keys. Merely disable Secure Boot for the installation.<br />
* Use {{ic|shim}} to boot systemd-bootloader<br />
* Load your db.cer file into the MOKManager application.<br />
<br />
All remaining steps should remain the same, except your system will still be dependent on the factory provided Microsoft Certificates. But you can boot Windows 10 in Secure Boot, which will be important for Windows 11.<br />
<br />
== Initial setup ==<br />
<br />
=== Pre-installation ===<br />
<br />
If you will only boot linux, reset your Secure Boot settings in BIOS to enable setup mode. Usually this means you set Secure Boot to Enabled and then select the option to wipe out the keys.<br />
<br />
If you will be dual booting Windows, disable secure boot.<br />
<br />
Follow the [[Installation_guide#Pre-installation]] up to Paritioning the Disks.<br />
<br />
=== Disk preparation ===<br />
<br />
If you have data on your disks you want to overwrite, utilize [[Dm-crypt/Drive_preparation#dm-crypt_wipe_on_an_empty_disk_or_partition]] to wipe it. If this disk was previously encrypted, utilize [[Dm-crypt/Drive_preparation#Wipe_LUKS_header]] instead for a much faster disposal. Finally, use [[Dm-crypt/Encrypting_an_entire_system#LVM_on_LUKS]] to parition your drive with two differences.<br />
<br />
{{tip|Using a memorable LUKS passphrase until you've completed the install process can be helpful. It will take several reboots to finish setup.}}<br />
<br />
First, the partition layout will be similar to here. You may wish to break out the /home directory into it's own partition. The primary requirement is that only your EFI partition be unencrypted.<br />
<br />
{{hc|Partiton Layout|<br />
┌────────────────────┬─────────────────────────┬──────────────────────────┬───────────────────────────┐<br />
│ │ │ │ │<br />
│ EFI Boot Partition │ Logical Volume 1 │ Logical Volume 2 │ Logical Volume 3 │<br />
│ /efi │ [Swap] │ / │ /home │<br />
│ /dev/nvme0n1p1 │ /dev/CryptRootVG/swap │ /dev/CryptRootVG/root │ /dev/CryptRootVG/home │<br />
│ 512 MB │ 16GB (Or RAM Size) │ 50 GB │ Remaining Space │<br />
│ │ │ │ │<br />
│ ├─────────────────────────┴──────────────────────────┴───────────────────────────┤<br />
│ │ LUKS and LVM Physical Volume │<br />
│ │ /dev/nvme0n1p2 │<br />
│ │ │<br />
│ │ │<br />
│ │ │<br />
│ │ │<br />
└────────────────────┴────────────────────────────────────────────────────────────────────────────────┘<br />
}}<br />
<br />
Second, if your hard drive is an SSD, use the following command to open your LUKS volume.<br />
<br />
# cryptsetup open --perf-no_read_workqueue --perf-no_write_workqueue --persistent /dev/nvme0n1p2 cryptroot<br />
<br />
After completing your LUKS on LVM setup, format your EFI partition per [[EFI system partition]].<br />
<br />
# mkfs.fat -F32 /dev/nvme0n1p1<br />
<br />
Mount this partition at {{ic|/mnt/efi}}. It is very important to leave {{ic|/boot}} on your encrypted root partition.<br />
<br />
== Installation ==<br />
<br />
Continue with [[Installation_guide#Installation]]. Be sure to flesh out your {{man|8|pacstrap}} with the following list of packages:<br />
<br />
* {{Pkg|dracut}}<br />
* {{Pkg|sbsigntools}}<br />
* {{Pkg|intel-ucode}}<br />
* {{Pkg|lvm2}}<br />
* {{Pkg|openssh}}<br />
* {{Pkg|ansible}}<br />
* {{Pkg|git}}<br />
* {{Pkg|iwd}}<br />
* {{Pkg|efibootmgr}}<br />
<br />
<br />
We are going to leave off the installation guide at the initramfs section, so go ahead and reset your root password. <br />
<br />
# passwd<br />
<br />
=== Bootloader ===<br />
<br />
First, install {{ic|systemd-boot}} by following [[Systemd-boot#Installing_the_EFI_boot_manager]]. Next, install {{aur|dracut-hook-uefi}}.<br />
<br />
Ensure you drop in a systemd-boot hook to update your bootctl any time it's updated.<br />
<br />
{{hc|/etc/pacman.d/hooks/998-systemd-boot.hook|2=<br />
[Trigger]<br />
Type = Package<br />
Operation = Install<br />
Operation = Upgrade<br />
Target = systemd<br />
<br />
[Action]<br />
Description = Updating systemd-boot<br />
When = PostTransaction<br />
Exec = /usr/bin/bootctl update; <br />
}}<br />
<br />
Obtain the UUID of your LUKS drive via the following command:<br />
<br />
{{bc|<br />
blkid -s UUID -o value /dev/nvme0n1p2<br />
}}<br />
<br />
Create the following files with the listed content. Be sure to replace UUIDs with what you actually need. See {{man|5|dracut.conf}} for more information on what these commands do.<br />
<br />
This is just an example command line, you may need to rework this based on your partitions and UUIDs.<br />
<br />
{{hc|/etc/dracut.conf.d/cmdline.conf|2=<br />
kernel_cmdline="rd.luks.uuid=luks-17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02 rd.lvm.lv=CryptRoot/root rd.lvm.lv=CryptRoot/swap resume=/dev/mapper/CryptRoot-swap root=/dev/mapper/CryptRoot-root rootfstype=ext4 rootflags=rw,relatime"<br />
}}<br />
<br />
{{hc|/etc/dracut.conf.d/flags.conf|2=<br />
compress="zstd"<br />
hostonly="no"<br />
}}<br />
<br />
Run the following command to generate your EFI stub kernels.<br />
<br />
dracut --uefi<br />
<br />
{{Warning|If the archiso kernel version (or type) differs from what is installed in your chroot, find the appropriate name in {{ic|/lib/modules}} and add it as the value of the {{ic|--kver}} argument to all dracut commands. For example, {{ic| dracut --uefi --kver 5.14.16-zen1-1-zen}}.}}<br />
<br />
=== Secure boot ===<br />
<br />
==== Dual Booting Windows ====<br />
<br />
Review [[Unified Extensible Firmware Interface/Secure Boot#shim]] to get a rough understanding of how it's going to work. Install {{aur|shim-signed}}. Perform the following commands to place files where both the UEFI boot entry and shim will load them.<br />
<br />
# mv /efi/EFI/BOOT/BOOTx64.EFI /efi/EFI/BOOT/grubx64.efi<br />
# cp /usr/share/shim-signed/shimx64.efi esp/EFI/BOOT/BOOTx64.EFI<br />
# cp /usr/share/shim-signed/mmx64.efi esp/EFI/BOOT/<br />
<br />
Install {{Pkg|sbctl}}. Use the following command to check that secure boot is in the right status. Your output should be similar.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✘ Sbctl is not installed<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/BOOT/grubx64.efi is not signed<br />
<br />
✘ /efi/EFI/BOOT/mmx64.efi is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
}}<br />
<br />
Note that shim and MOKManager (mmx) is included in this list, even though we will not be signing it.<br />
<br />
{{bc|<br />
# sbctl sign -s /efi/EFI/BOOT/ grubx64.efi <br />
<br />
✔ Signed /efi/EFI/BOOT/grubx64.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi <br />
<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi <br />
<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi<br />
# sbctl verify<br />
<br />
Verifying file database and EFI images in /efi...<br />
✔� /efi/EFI/BOOT/grubx64.efi is signed<br />
✔ /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi is signed<br />
✔ /efi/EFI/systemd/systemd-bootx64.efi is signed<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/BOOT/mmx64.efi is not signed<br />
}}<br />
<br />
You can validate that {{ic|BOOTx64.EFI}} and {{ic|mmx64.efi}} have signatures with {{man|1|sbverify}} from the {{Pkg|sbsigntools}} package.<br />
<br />
Next, we need to create the DER format certificate to load into ''MokManager''.<br />
<br />
# openssl x509 -outform DER -in /usr/share/secureboot/keys/db/db.pem -out /efi/signing.cer<br />
<br />
Use {{Pkg|efibootmgr}} ({{man|8|efibootmgr}}) to adjust your boot entries. Primarily, you will want to remove the {{ic|Linux Boot Manager}} entry.<br />
<br />
{{bc|<br />
# efibootmgr<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0001,0000,0002,0003,0004<br />
Boot0000* Windows Boot Manager<br />
Boot0001* Linux Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
}}<br />
<br />
In this example, we see that {{ic|0000}} is the Windows boot manager. {{ic|0001}} is the Linux Boot Manager and also the first in line to boot. {{ic|0001}} needs to be deleted and optionally the boot order modified so {{ic|0004}} is the default boot entry.<br />
<br />
{{bc|<br />
# efibootmgr --bootnum 0001 --delete-bootnum<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0000,0002,0003,0004<br />
Boot0000* Windows Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
<br />
# efibootmgr --bootorder 0004,0000,0002,0003<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0004,0000,0002,0003<br />
Boot0000* Windows Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Now reboot. You should get an error from your motherboard's UEFI BIOS that secure boot checks failed. Your computer should restart directly into ''MokManager'', if you rearranged the boot order. If not, you will need to select {{ic|UEFI OS}} from your UEFI boot menu. Navigate to the {{ic|signing.cer}} file we placed on the EFI partition and enroll the key. Select reboot, and the system should boot directly into linux with no problem.<br />
<br />
==== Booting only Linux ====<br />
<br />
{{note|Credit to this [https://lunaryorn.com/secure-boot-on-arch-linux-with-sbctl-and-dracut blog post by lunaryorn] for the inspiration.}}<br />
<br />
Install {{Pkg|sbctl}}. At this point you will likely need to reboot and adjust your secure boot settings. You want secure boot in '''setup mode'''. <br />
<br />
{{bc|<br />
$ sbctl status<br />
Installed: X Sbctl is not installed<br />
Setup Mode: X Enabled<br />
Secure Boot: X Disabled<br />
}}<br />
<br />
Run the following commands as root. See {{man|8|sbctl}} for more information on their function. Of particular note is the {{ic|-s}} flag which indicates {{ic|sbctl}} should remember the file for future verification and signing.<br />
<br />
Note your Linux EFI binary name may be slightly different.<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
<br />
# sbctl sign -s /efi/EFI/BOOT/BOOTx64.EFI<br />
✔ Signed /efi/EFI/BOOT/BOOTx64.EFI<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Finally, enroll the Secure Boot keys.<br />
<br />
{{bc|<br />
# sbctl enroll-keys<br />
Enrolling keys to EFI variables...✔<br />
Enrolled keys to the EFI variables!<br />
}}<br />
<br />
Verify that secure boot now has an owner GUID and setup mode is disabled.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✔ Sbctl is installed<br />
Owner GUID: a2ee3d08-725a-408b-9d95-28026a44611c<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
Now reboot. This reboot is required so we can get the TPM measurements into their (hopefully) permanent state.<br />
<br />
=== Enroll LUKS key in TPM ===<br />
{{warning|Yes, this will cause a system to automatically unlock it's encrypted root volume without any interaction from a human. Yes, this exposes it to any sufficently advanced Evil Maid attacks. If sealed against the appropriate registers (especially register 8 with the kernel arguments), the TPM measurements should force systemd to ask for your LUKS passphrase in almost any attempt to access the encrypted volume from outside your normal boot process.}}<br />
<br />
We are fortunate that in our shift to dracut includes utilizing systemd and sd-encrypt, as we can use systemd's native support for enrolling LUKS keys. A review of [[Trusted Platform Module#Using TPM 2.0]] is recommended but not very clear.<br />
<br />
==== Avoid dracut bugs ====<br />
<br />
Subtitle: The Case of the Missing {{ic|d}}<br />
<br />
Two bugs, one in systemd 249.4-1-arch [https://github.com/systemd/systemd/issues/19177] and one in dracut 055 [https://github.com/dracutdevs/dracut/pull/1526][https://github.com/dracutdevs/dracut/issues/1542] will combine to prevent your system from being able to boot. The dracut issue causes the '''tpm2-tss''' module to not be included in your image. The systemd issue causes systemd to go into an emergency when it can't locate the TPM2 libraries, instead of falling back to asking for your passcode.<br />
<br />
The systemd bug isn't a problem so long as you always have TPM2 libraries present.<br />
<br />
To resolve this, first check your version of dracut.<br />
<br />
{{bc|<br />
$ dracut --version<br />
dracut 055<br />
}}<br />
<br />
Since the next release of dracut should have this fixed, we can simply fix the script locally until the next release.<br />
<br />
{{warning|These steps are only necessary for dracut 055}}<br />
<br />
Find the following lines in {{ic|/usr/lib/dracut/modules.d/91tpm2-tss/module-setup.sh}}:<br />
<br />
{{bc|1=<br />
# Module dependency requirements.<br />
depends() {<br />
<br />
# This module has external dependency on other module(s).<br />
echo systemd-sysusers systemd-udev<br />
# Return 0 to include the dependent module(s) in the initramfs.<br />
return 0<br />
<br />
}<br />
}}<br />
<br />
Change the dependency {{ic|systemd-udev}} to <code>systemd-udev<b>d</b></code>.<br />
<br />
Continue with the remaining steps in this section.<br />
<br />
==== Enrollment ====<br />
<br />
First, be sure to install {{Pkg|tpm2-tools}}. Alternatively {{aur|ibm-tss}} can be used per [[Trusted Platform Module]], however this guide is not tested against those.<br />
<br />
{{note|A reboot may be required to convince {{ic|systemd-cryptenroll}} that TPM 2.0 devices now exist on the machine.}}<br />
<br />
There are several decisions to be made here. The table at [[Trusted Platform Module#Accessing PCR registers]] is accurate as of October 2021. Essentially, once you seal your LUKS key, if any of the registers you've sealed against change, then you will be asked for your LUKS passphrase. This is equivalent to when Windows 10 makes you enter your BitLocker recovery key after a hardware change or changing BIOS settings.<br />
<br />
Your mileage may vary, based on UEFI vendors. For my laptop, I went with 0+1+2+3+4+5+7+8 and have been able to invalidate my TPM. Unfortunately, if you change your system BACK the volume will unlock. I'm investigating how to disable that.<br />
<br />
Other options on {{man|1|systemd-cryptenroll}} will reveal that several hardware tokens can also be enrolled to allow unlocking the root LUKS volume automatically, but only if a key is present. Further testing is requried.<br />
<br />
To enroll your LUKS volume, simply run the following command as root<br />
<br />
# systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/nvme0n1p2<br />
<br />
To remove your key, run this command:<br />
<br />
# systemd-cryptenroll --wipe-slot=tpm2 /dev/nvme0n1p2<br />
<br />
You will need to add a kernel argument like below to enable the TPM2 bits. If following this guide, this should be located in {{ic|/etc/dracut.conf.d/cmdline.conf}}<br />
<br />
rd.luks.options={UUID}=tpm2-device=auto<br />
<br />
Ensure that dracut builds in the TPM2 libraries. Create the following file.<br />
<br />
{{hc|/etc/dracut.conf.d/tpm2-tss.conf|2=<br />
add_dracutmodules+=" tpm2-tss "<br />
}}<br />
<br />
Finally, rebuild your unified kernel image.<br />
<br />
# dracut --force --uefi<br />
<br />
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:<br />
<br />
{{hc|~/bin/luks_reenroll_tpm|2=<br />
sudo systemd-cryptenroll --wipe-slot=tpm2 /dev/disk/by-uuid/{UUID_HERE}<br />
systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/disk/by-uuid/{UUID_HERE}<br />
}}<br />
<br />
=== Wrapping up ===<br />
<br />
Set your UEFI password. <br />
<br />
Change your LUKS passphrase from something easily memorable to a good long recovery key.<br />
<br />
Keep both of these pieces of info somewhere safe. This varies depending on your threat model. If we're just talking about Stolen Laptops and Nosy Maids, a hard copy in your safe should be sufficient. If it's the NSA, I'm not sure this setup is appropriate for that model.<br />
<br />
This is an excellent base to handle stolen laptop and even some lower grade Evil Maids. From here, you should head into [[Security]]. Consider learning a framework to help you manage your system state such as [[Ansible]] or headless [[Puppet]].<br />
<br />
== Justifications ==<br />
<br />
=== LVM on LUKS vs other dm-crypt approaches ===<br />
<br />
LVM on LUKS was selected becasue it is simply the easiest to manage while conferring both encrypted swap and disk. The other approaches required much more tooling and manual fussing to utilize. This selection also gives room change freely between {{ic|busybox}} and {{ic|systemd}} initrds.<br />
<br />
=== Using dracut ===<br />
<br />
{{Pkg|dracut}} just makes it easier to build full unified kernels that {{man|7|systemd-boot}} can launch as EFI binaries. There is also available tooling in the [[AUR]] for automating the creation of these binaries. Finally, {{ic|dracut}} will sign the binaries it creates automatically when configured to do so.<br />
<br />
=== Unified kernel images ===<br />
<br />
While UKI's could be problematic on other distributions, they fit right in with an Arch Linux install. The automation is there through pacman hooks and {{Pkg|sbctl}} to sign our UKIs as they're created. Furthermore, you can only sign and create a new signed UKI while booted into a properly signed UKI. It creates a chain of trust, which means it's important to never disable Secure Boot once you've set it up.<br />
<br />
The UKI encompasses all of the following items inside the signature, which means you can't change any of them without invalidating the signature.<br />
<br />
* Kernel arguments<br />
* Initrd/Initramfs<br />
* Kernel<br />
<br />
In particular, all other flavors of secureboot do not sign or validate the initramfs. This is a big attack area and can be relatively trivialized that a semi-decent pawn shop owner with Google could likely find an image that would grant him access and make the TPM none the wiser the system has changed. One can prevent this with encrypted /boot, but that would limit you to GRUB2 and LUKS version 1 devices only. This also doesn't include the work to keep GRUB2's files signed with a PGP key by root.<br />
<br />
=== LUKS enrolled in TPM ===<br />
<br />
The goal here is to only require the passphrase when something spooky happens in your boot path.<br />
<br />
UEFI settings change? Request password.<br />
<br />
Some weird swap of some module of UEFI code that lives on your motherboard somewhere? Request password.<br />
<br />
Unified Kernel Image changes? Don't even boot.<br />
<br />
Drive in another computer? Request password.<br />
<br />
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.<br />
<br />
== Miscellaneous discussions ==<br />
<br />
=== Filesystem Selection ===<br />
<br />
Most examples on Arch utilize {{ic|ext4}}, but other file systems such as {{ic|brtfs}} can work equally well. As for performance or issues with being inside LVM, [https://btrfs.wiki.kernel.org/index.php/FAQ#Btrfs_has_subvolumes.2C_does_this_mean_I_don.27t_need_a_logical_volume_manager_and_I_can_create_a_big_Btrfs_filesystem_on_a_raw_partition.3F this question in the brtfs FAQ] implies that there is some performance loss but no other issues.<br />
<br />
=== LUKS TPM enrollment and managing luks keys ===<br />
<br />
Note that using {{man|1|systemd-cryptenroll}} will add a key to your LUKS volume. It's not clear how exactly the option {{ic|1=--wipe-slot=tpm2}} is able to identify which slot it needs to wipe, but it does. This even works if your TPM has changed.<br />
<br />
You can see the effects by comparing the output of {{ic|cryptsetup luksDump /dev/nvme0n1p2}} before and after you enroll or wipe a TPM based key. You can identify what slot your own passphrase is in with {{ic|cryptsetup --verbose open --test-passphrase /dev/nvme0n1p2}} and entering your passphrase. The output will inform you which key slot was unlocked.<br />
<br />
Finally, your passphrase may be changed with {{ic|cryptsetup luksChangeKey /dev/nvme0n1p2 -S 0}}.<br />
<br />
== Planned TODOs ==<br />
A panic command that can dump the TPM and shutdown the computer (without requiring the time of entering a password in sudo) forcing an adversary to resort to [https://en.wikipedia.org/wiki/Rubber-hose_cryptanalysis rubber-hose cryptanalysis] to get to the encrypted data.</div>Krinhttps://wiki.archlinux.org/index.php?title=User:Krin/Secure_Boot,_full_disk_encryption,_and_TPM2_unlocking_install&diff=701614User:Krin/Secure Boot, full disk encryption, and TPM2 unlocking install2021-11-11T16:07:02Z<p>Krin: /* Bootloader */ Don't use hostonly as currently dracut will have issues with tpm/luks if you use it.</p>
<hr />
<div>{{Unsupported|1 October 2021}}<br />
<br />
== Introduction ==<br />
<br />
This installation is based on my installing Arch on an Asus ROG Strix G G531 I got second hand and a desktop computer made of second hand parts that had to share space with Windows. The primary goals were to replace Windows 10 Pro with Bitlocker encryption and maintain the convenience and security balance of that original operating system.<br />
<br />
My requirements boiled down to:<br />
<br />
* A fully encrypted disk<br />
* Full Secure Boot validation of all UEFI components.<br />
* Use of the TPM to facilitate unlocking of the disk.<br />
* Hibernate/Suspend working.<br />
<br />
My primary use case here is to make it difficult enough for a baggage handler with sticky hands to get at my data that they just wipe the drive. A state level actor with the expertise and equipment to hot swap my ram in my hotel room is not something that I'm defending this ''particular'' laptop against. This is more for gaming and web browsing and uploading photos while traveling.<br />
<br />
I'll continue to update these notes as I develop further solutions.<br />
<br />
== Disclaimers ==<br />
<br />
This article is primarily for the author's own notes. It is assumed that the reader is familiar with the [[Installation guide]] and will refer to it often. Reading linked articles is recommended.<br />
<br />
== Dual Booting Modifications ==<br />
<br />
{{warning|If you use BitLocker on your Windows drive, ensure you have your recovery key handy. The installation process will change your TPM measurements causing Windows to require you enter the key manually the next time you boot it.}}<br />
<br />
For computers that will have to dual boot with windows, the easiest solution is to use two different physical drives and utilize your motherboard's UEFI boot menu to select which one to boot. This guide will follow that assumption. You can also attempt to have everything live on one EFI partition. Windows's 100 MiB EFI partition is especially problematic to this approach for secure boot, as Unified Kernel Images can approach 80 MiB and Windows 10 regularly uses up to 30 MiB. An alternative is to copy the Microsoft bootloader into your Linux EFI bootloader and then prioritize the Linux EFI disk over your Windows disk. You will want to copy the directory {{ic|WINDOWS_EFI_PARITION/EFI/Microsoft}} to the same location on your Linux EFI partition. Anytime Microsoft updates the bootloader, you will need to copy the Microsoft EFI folder again.<br />
<br />
There are two changes that will be made and will be noted in the relevant sections:<br />
<br />
* Do not clear your Secure Boot keys. Merely disable Secure Boot for the installation.<br />
* Use {{ic|shim}} to boot systemd-bootloader<br />
* Load your db.cer file into the MOKManager application.<br />
<br />
All remaining steps should remain the same, except your system will still be dependent on the factory provided Microsoft Certificates. But you can boot Windows 10 in Secure Boot, which will be important for Windows 11.<br />
<br />
== Initial setup ==<br />
<br />
=== Pre-installation ===<br />
<br />
If you will only boot linux, reset your Secure Boot settings in BIOS to enable setup mode. Usually this means you set Secure Boot to Enabled and then select the option to wipe out the keys.<br />
<br />
If you will be dual booting Windows, disable secure boot.<br />
<br />
Follow the [[Installation_guide#Pre-installation]] up to Paritioning the Disks.<br />
<br />
=== Disk preparation ===<br />
<br />
If you have data on your disks you want to overwrite, utilize [[Dm-crypt/Drive_preparation#dm-crypt_wipe_on_an_empty_disk_or_partition]] to wipe it. If this disk was previously encrypted, utilize [[Dm-crypt/Drive_preparation#Wipe_LUKS_header]] instead for a much faster disposal. Finally, use [[Dm-crypt/Encrypting_an_entire_system#LVM_on_LUKS]] to parition your drive with two differences.<br />
<br />
{{tip|Using a memorable LUKS passphrase until you've completed the install process can be helpful. It will take several reboots to finish setup.}}<br />
<br />
First, the partition layout will be similar to here. You may wish to break out the /home directory into it's own partition. The primary requirement is that only your EFI partition be unencrypted.<br />
<br />
{{hc|Partiton Layout|<br />
┌────────────────────┬─────────────────────────┬──────────────────────────┬───────────────────────────┐<br />
│ │ │ │ │<br />
│ EFI Boot Partition │ Logical Volume 1 │ Logical Volume 2 │ Logical Volume 3 │<br />
│ /efi │ [Swap] │ / │ /home │<br />
│ /dev/nvme0n1p1 │ /dev/CryptRootVG/swap │ /dev/CryptRootVG/root │ /dev/CryptRootVG/home │<br />
│ 512 MB │ 16GB (Or RAM Size) │ 50 GB │ Remaining Space │<br />
│ │ │ │ │<br />
│ ├─────────────────────────┴──────────────────────────┴───────────────────────────┤<br />
│ │ LUKS and LVM Physical Volume │<br />
│ │ /dev/nvme0n1p2 │<br />
│ │ │<br />
│ │ │<br />
│ │ │<br />
│ │ │<br />
└────────────────────┴────────────────────────────────────────────────────────────────────────────────┘<br />
}}<br />
<br />
Second, if your hard drive is an SSD, use the following command to open your LUKS volume.<br />
<br />
# cryptsetup open --perf-no_read_workqueue --perf-no_write_workqueue --persistent /dev/nvme0n1p2 cryptroot<br />
<br />
After completing your LUKS on LVM setup, format your EFI partition per [[EFI system partition]].<br />
<br />
# mkfs.fat -F32 /dev/nvme0n1p1<br />
<br />
Mount this partition at {{ic|/mnt/efi}}. It is very important to leave {{ic|/boot}} on your encrypted root partition.<br />
<br />
== Installation ==<br />
<br />
Continue with [[Installation_guide#Installation]]. Be sure to flesh out your {{man|8|pacstrap}} with the following list of packages:<br />
<br />
* {{Pkg|dracut}}<br />
* {{Pkg|sbsigntools}}<br />
* {{Pkg|intel-ucode}}<br />
* {{Pkg|lvm2}}<br />
* {{Pkg|openssh}}<br />
* {{Pkg|ansible}}<br />
* {{Pkg|git}}<br />
* {{Pkg|iwd}}<br />
* {{Pkg|efibootmgr}}<br />
<br />
<br />
We are going to leave off the installation guide at the initramfs section, so go ahead and reset your root password. <br />
<br />
# passwd<br />
<br />
=== Bootloader ===<br />
<br />
First, install {{ic|systemd-boot}} by following [[Systemd-boot#Installing_the_EFI_boot_manager]]. Next, install {{aur|dracut-hook-uefi}}.<br />
<br />
Ensure you drop in a systemd-boot hook to update your bootctl any time it's updated.<br />
<br />
{{hc|/etc/pacman.d/hooks/998-systemd-boot.hook|2=<br />
[Trigger]<br />
Type = Package<br />
Operation = Install<br />
Operation = Upgrade<br />
Target = systemd<br />
<br />
[Action]<br />
Description = Updating systemd-boot<br />
When = PostTransaction<br />
Exec = /usr/bin/bootctl update; <br />
}}<br />
<br />
Obtain the UUID of your LUKS drive via the following command:<br />
<br />
{{bc|<br />
blkid -s UUID -o value /dev/nvme0n1p2<br />
}}<br />
<br />
Create the following files with the listed content. Be sure to replace UUIDs with what you actually need. See {{man|5|dracut.conf}} for more information on what these commands do.<br />
<br />
This is just an example command line, you may need to rework this based on your partitions and UUIDs.<br />
<br />
{{hc|/etc/dracut.conf.d/cmdline.conf|2=<br />
kernel_cmdline="rd.luks.uuid=luks-17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02 rd.lvm.lv=CryptRoot/root rd.lvm.lv=CryptRoot/swap resume=/dev/mapper/CryptRoot-swap root=/dev/mapper/CryptRoot-root rootfstype=ext4 rootflags=rw,relatime"<br />
}}<br />
<br />
{{hc|/etc/dracut.conf.d/flags.conf|2=<br />
compress="zstd"<br />
hostonly="no"<br />
}}<br />
<br />
Run the following command to generate your EFI stub kernels.<br />
<br />
dracut --uefi<br />
<br />
=== Secure boot ===<br />
<br />
==== Dual Booting Windows ====<br />
<br />
Review [[Unified Extensible Firmware Interface/Secure Boot#shim]] to get a rough understanding of how it's going to work. Install {{aur|shim-signed}}. Perform the following commands to place files where both the UEFI boot entry and shim will load them.<br />
<br />
# mv /efi/EFI/BOOT/BOOTx64.EFI /efi/EFI/BOOT/grubx64.efi<br />
# cp /usr/share/shim-signed/shimx64.efi esp/EFI/BOOT/BOOTx64.EFI<br />
# cp /usr/share/shim-signed/mmx64.efi esp/EFI/BOOT/<br />
<br />
Install {{Pkg|sbctl}}. Use the following command to check that secure boot is in the right status. Your output should be similar.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✘ Sbctl is not installed<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/BOOT/grubx64.efi is not signed<br />
<br />
✘ /efi/EFI/BOOT/mmx64.efi is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
}}<br />
<br />
Note that shim and MOKManager (mmx) is included in this list, even though we will not be signing it.<br />
<br />
{{bc|<br />
# sbctl sign -s /efi/EFI/BOOT/ grubx64.efi <br />
<br />
✔ Signed /efi/EFI/BOOT/grubx64.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi <br />
<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi <br />
<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi<br />
# sbctl verify<br />
<br />
Verifying file database and EFI images in /efi...<br />
✔� /efi/EFI/BOOT/grubx64.efi is signed<br />
✔ /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi is signed<br />
✔ /efi/EFI/systemd/systemd-bootx64.efi is signed<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/BOOT/mmx64.efi is not signed<br />
}}<br />
<br />
You can validate that {{ic|BOOTx64.EFI}} and {{ic|mmx64.efi}} have signatures with {{man|1|sbverify}} from the {{Pkg|sbsigntools}} package.<br />
<br />
Next, we need to create the DER format certificate to load into ''MokManager''.<br />
<br />
# openssl x509 -outform DER -in /usr/share/secureboot/keys/db/db.pem -out /efi/signing.cer<br />
<br />
Use {{Pkg|efibootmgr}} ({{man|8|efibootmgr}}) to adjust your boot entries. Primarily, you will want to remove the {{ic|Linux Boot Manager}} entry.<br />
<br />
{{bc|<br />
# efibootmgr<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0001,0000,0002,0003,0004<br />
Boot0000* Windows Boot Manager<br />
Boot0001* Linux Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
}}<br />
<br />
In this example, we see that {{ic|0000}} is the Windows boot manager. {{ic|0001}} is the Linux Boot Manager and also the first in line to boot. {{ic|0001}} needs to be deleted and optionally the boot order modified so {{ic|0004}} is the default boot entry.<br />
<br />
{{bc|<br />
# efibootmgr --bootnum 0001 --delete-bootnum<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0000,0002,0003,0004<br />
Boot0000* Windows Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
<br />
# efibootmgr --bootorder 0004,0000,0002,0003<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0004,0000,0002,0003<br />
Boot0000* Windows Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Now reboot. You should get an error from your motherboard's UEFI BIOS that secure boot checks failed. Your computer should restart directly into ''MokManager'', if you rearranged the boot order. If not, you will need to select {{ic|UEFI OS}} from your UEFI boot menu. Navigate to the {{ic|signing.cer}} file we placed on the EFI partition and enroll the key. Select reboot, and the system should boot directly into linux with no problem.<br />
<br />
==== Booting only Linux ====<br />
<br />
{{note|Credit to this [https://lunaryorn.com/secure-boot-on-arch-linux-with-sbctl-and-dracut blog post by lunaryorn] for the inspiration.}}<br />
<br />
Install {{Pkg|sbctl}}. At this point you will likely need to reboot and adjust your secure boot settings. You want secure boot in '''setup mode'''. <br />
<br />
{{bc|<br />
$ sbctl status<br />
Installed: X Sbctl is not installed<br />
Setup Mode: X Enabled<br />
Secure Boot: X Disabled<br />
}}<br />
<br />
Run the following commands as root. See {{man|8|sbctl}} for more information on their function. Of particular note is the {{ic|-s}} flag which indicates {{ic|sbctl}} should remember the file for future verification and signing.<br />
<br />
Note your Linux EFI binary name may be slightly different.<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
<br />
# sbctl sign -s /efi/EFI/BOOT/BOOTx64.EFI<br />
✔ Signed /efi/EFI/BOOT/BOOTx64.EFI<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Finally, enroll the Secure Boot keys.<br />
<br />
{{bc|<br />
# sbctl enroll-keys<br />
Enrolling keys to EFI variables...✔<br />
Enrolled keys to the EFI variables!<br />
}}<br />
<br />
Verify that secure boot now has an owner GUID and setup mode is disabled.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✔ Sbctl is installed<br />
Owner GUID: a2ee3d08-725a-408b-9d95-28026a44611c<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
Now reboot. This reboot is required so we can get the TPM measurements into their (hopefully) permanent state.<br />
<br />
=== Enroll LUKS key in TPM ===<br />
{{warning|Yes, this will cause a system to automatically unlock it's encrypted root volume without any interaction from a human. Yes, this exposes it to any sufficently advanced Evil Maid attacks. If sealed against the appropriate registers (especially register 8 with the kernel arguments), the TPM measurements should force systemd to ask for your LUKS passphrase in almost any attempt to access the encrypted volume from outside your normal boot process.}}<br />
<br />
We are fortunate that in our shift to dracut includes utilizing systemd and sd-encrypt, as we can use systemd's native support for enrolling LUKS keys. A review of [[Trusted Platform Module#Using TPM 2.0]] is recommended but not very clear.<br />
<br />
==== Avoid dracut bugs ====<br />
<br />
Subtitle: The Case of the Missing {{ic|d}}<br />
<br />
Two bugs, one in systemd 249.4-1-arch [https://github.com/systemd/systemd/issues/19177] and one in dracut 055 [https://github.com/dracutdevs/dracut/pull/1526][https://github.com/dracutdevs/dracut/issues/1542] will combine to prevent your system from being able to boot. The dracut issue causes the '''tpm2-tss''' module to not be included in your image. The systemd issue causes systemd to go into an emergency when it can't locate the TPM2 libraries, instead of falling back to asking for your passcode.<br />
<br />
The systemd bug isn't a problem so long as you always have TPM2 libraries present.<br />
<br />
To resolve this, first check your version of dracut.<br />
<br />
{{bc|<br />
$ dracut --version<br />
dracut 055<br />
}}<br />
<br />
Since the next release of dracut should have this fixed, we can simply fix the script locally until the next release.<br />
<br />
{{warning|These steps are only necessary for dracut 055}}<br />
<br />
Find the following lines in {{ic|/usr/lib/dracut/modules.d/91tpm2-tss/module-setup.sh}}:<br />
<br />
{{bc|1=<br />
# Module dependency requirements.<br />
depends() {<br />
<br />
# This module has external dependency on other module(s).<br />
echo systemd-sysusers systemd-udev<br />
# Return 0 to include the dependent module(s) in the initramfs.<br />
return 0<br />
<br />
}<br />
}}<br />
<br />
Change the dependency {{ic|systemd-udev}} to <code>systemd-udev<b>d</b></code>.<br />
<br />
Continue with the remaining steps in this section.<br />
<br />
==== Enrollment ====<br />
<br />
First, be sure to install {{Pkg|tpm2-tools}}. Alternatively {{aur|ibm-tss}} can be used per [[Trusted Platform Module]], however this guide is not tested against those.<br />
<br />
{{note|A reboot may be required to convince {{ic|systemd-cryptenroll}} that TPM 2.0 devices now exist on the machine.}}<br />
<br />
There are several decisions to be made here. The table at [[Trusted Platform Module#Accessing PCR registers]] is accurate as of October 2021. Essentially, once you seal your LUKS key, if any of the registers you've sealed against change, then you will be asked for your LUKS passphrase. This is equivalent to when Windows 10 makes you enter your BitLocker recovery key after a hardware change or changing BIOS settings.<br />
<br />
Your mileage may vary, based on UEFI vendors. For my laptop, I went with 0+1+2+3+4+5+7+8 and have been able to invalidate my TPM. Unfortunately, if you change your system BACK the volume will unlock. I'm investigating how to disable that.<br />
<br />
Other options on {{man|1|systemd-cryptenroll}} will reveal that several hardware tokens can also be enrolled to allow unlocking the root LUKS volume automatically, but only if a key is present. Further testing is requried.<br />
<br />
To enroll your LUKS volume, simply run the following command as root<br />
<br />
# systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/nvme0n1p2<br />
<br />
To remove your key, run this command:<br />
<br />
# systemd-cryptenroll --wipe-slot=tpm2 /dev/nvme0n1p2<br />
<br />
You will need to add a kernel argument like below to enable the TPM2 bits. If following this guide, this should be located in {{ic|/etc/dracut.conf.d/cmdline.conf}}<br />
<br />
rd.luks.options={UUID}=tpm2-device=auto<br />
<br />
Ensure that dracut builds in the TPM2 libraries. Create the following file.<br />
<br />
{{hc|/etc/dracut.conf.d/tpm2-tss.conf|2=<br />
add_dracutmodules+=" tpm2-tss "<br />
}}<br />
<br />
Finally, rebuild your unified kernel image.<br />
<br />
# dracut --force --uefi<br />
<br />
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:<br />
<br />
{{hc|~/bin/luks_reenroll_tpm|2=<br />
sudo systemd-cryptenroll --wipe-slot=tpm2 /dev/disk/by-uuid/{UUID_HERE}<br />
systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/disk/by-uuid/{UUID_HERE}<br />
}}<br />
<br />
=== Wrapping up ===<br />
<br />
Set your UEFI password. <br />
<br />
Change your LUKS passphrase from something easily memorable to a good long recovery key.<br />
<br />
Keep both of these pieces of info somewhere safe. This varies depending on your threat model. If we're just talking about Stolen Laptops and Nosy Maids, a hard copy in your safe should be sufficient. If it's the NSA, I'm not sure this setup is appropriate for that model.<br />
<br />
This is an excellent base to handle stolen laptop and even some lower grade Evil Maids. From here, you should head into [[Security]]. Consider learning a framework to help you manage your system state such as [[Ansible]] or headless [[Puppet]].<br />
<br />
== Justifications ==<br />
<br />
=== LVM on LUKS vs other dm-crypt approaches ===<br />
<br />
LVM on LUKS was selected becasue it is simply the easiest to manage while conferring both encrypted swap and disk. The other approaches required much more tooling and manual fussing to utilize. This selection also gives room change freely between {{ic|busybox}} and {{ic|systemd}} initrds.<br />
<br />
=== Using dracut ===<br />
<br />
{{Pkg|dracut}} just makes it easier to build full unified kernels that {{man|7|systemd-boot}} can launch as EFI binaries. There is also available tooling in the [[AUR]] for automating the creation of these binaries. Finally, {{ic|dracut}} will sign the binaries it creates automatically when configured to do so.<br />
<br />
=== Unified kernel images ===<br />
<br />
While UKI's could be problematic on other distributions, they fit right in with an Arch Linux install. The automation is there through pacman hooks and {{Pkg|sbctl}} to sign our UKIs as they're created. Furthermore, you can only sign and create a new signed UKI while booted into a properly signed UKI. It creates a chain of trust, which means it's important to never disable Secure Boot once you've set it up.<br />
<br />
The UKI encompasses all of the following items inside the signature, which means you can't change any of them without invalidating the signature.<br />
<br />
* Kernel arguments<br />
* Initrd/Initramfs<br />
* Kernel<br />
<br />
In particular, all other flavors of secureboot do not sign or validate the initramfs. This is a big attack area and can be relatively trivialized that a semi-decent pawn shop owner with Google could likely find an image that would grant him access and make the TPM none the wiser the system has changed. One can prevent this with encrypted /boot, but that would limit you to GRUB2 and LUKS version 1 devices only. This also doesn't include the work to keep GRUB2's files signed with a PGP key by root.<br />
<br />
=== LUKS enrolled in TPM ===<br />
<br />
The goal here is to only require the passphrase when something spooky happens in your boot path.<br />
<br />
UEFI settings change? Request password.<br />
<br />
Some weird swap of some module of UEFI code that lives on your motherboard somewhere? Request password.<br />
<br />
Unified Kernel Image changes? Don't even boot.<br />
<br />
Drive in another computer? Request password.<br />
<br />
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.<br />
<br />
== Miscellaneous discussions ==<br />
<br />
=== Filesystem Selection ===<br />
<br />
Most examples on Arch utilize {{ic|ext4}}, but other file systems such as {{ic|brtfs}} can work equally well. As for performance or issues with being inside LVM, [https://btrfs.wiki.kernel.org/index.php/FAQ#Btrfs_has_subvolumes.2C_does_this_mean_I_don.27t_need_a_logical_volume_manager_and_I_can_create_a_big_Btrfs_filesystem_on_a_raw_partition.3F this question in the brtfs FAQ] implies that there is some performance loss but no other issues.<br />
<br />
=== LUKS TPM enrollment and managing luks keys ===<br />
<br />
Note that using {{man|1|systemd-cryptenroll}} will add a key to your LUKS volume. It's not clear how exactly the option {{ic|1=--wipe-slot=tpm2}} is able to identify which slot it needs to wipe, but it does. This even works if your TPM has changed.<br />
<br />
You can see the effects by comparing the output of {{ic|cryptsetup luksDump /dev/nvme0n1p2}} before and after you enroll or wipe a TPM based key. You can identify what slot your own passphrase is in with {{ic|cryptsetup --verbose open --test-passphrase /dev/nvme0n1p2}} and entering your passphrase. The output will inform you which key slot was unlocked.<br />
<br />
Finally, your passphrase may be changed with {{ic|cryptsetup luksChangeKey /dev/nvme0n1p2 -S 0}}.<br />
<br />
== Planned TODOs ==<br />
A panic command that can dump the TPM and shutdown the computer (without requiring the time of entering a password in sudo) forcing an adversary to resort to [https://en.wikipedia.org/wiki/Rubber-hose_cryptanalysis rubber-hose cryptanalysis] to get to the encrypted data.</div>Krinhttps://wiki.archlinux.org/index.php?title=User:Krin/Secure_Boot,_full_disk_encryption,_and_TPM2_unlocking_install&diff=701613User:Krin/Secure Boot, full disk encryption, and TPM2 unlocking install2021-11-11T16:03:35Z<p>Krin: /* Installation */ Add sbsigntools package to install instructions so dracut can sign uefi images.</p>
<hr />
<div>{{Unsupported|1 October 2021}}<br />
<br />
== Introduction ==<br />
<br />
This installation is based on my installing Arch on an Asus ROG Strix G G531 I got second hand and a desktop computer made of second hand parts that had to share space with Windows. The primary goals were to replace Windows 10 Pro with Bitlocker encryption and maintain the convenience and security balance of that original operating system.<br />
<br />
My requirements boiled down to:<br />
<br />
* A fully encrypted disk<br />
* Full Secure Boot validation of all UEFI components.<br />
* Use of the TPM to facilitate unlocking of the disk.<br />
* Hibernate/Suspend working.<br />
<br />
My primary use case here is to make it difficult enough for a baggage handler with sticky hands to get at my data that they just wipe the drive. A state level actor with the expertise and equipment to hot swap my ram in my hotel room is not something that I'm defending this ''particular'' laptop against. This is more for gaming and web browsing and uploading photos while traveling.<br />
<br />
I'll continue to update these notes as I develop further solutions.<br />
<br />
== Disclaimers ==<br />
<br />
This article is primarily for the author's own notes. It is assumed that the reader is familiar with the [[Installation guide]] and will refer to it often. Reading linked articles is recommended.<br />
<br />
== Dual Booting Modifications ==<br />
<br />
{{warning|If you use BitLocker on your Windows drive, ensure you have your recovery key handy. The installation process will change your TPM measurements causing Windows to require you enter the key manually the next time you boot it.}}<br />
<br />
For computers that will have to dual boot with windows, the easiest solution is to use two different physical drives and utilize your motherboard's UEFI boot menu to select which one to boot. This guide will follow that assumption. You can also attempt to have everything live on one EFI partition. Windows's 100 MiB EFI partition is especially problematic to this approach for secure boot, as Unified Kernel Images can approach 80 MiB and Windows 10 regularly uses up to 30 MiB. An alternative is to copy the Microsoft bootloader into your Linux EFI bootloader and then prioritize the Linux EFI disk over your Windows disk. You will want to copy the directory {{ic|WINDOWS_EFI_PARITION/EFI/Microsoft}} to the same location on your Linux EFI partition. Anytime Microsoft updates the bootloader, you will need to copy the Microsoft EFI folder again.<br />
<br />
There are two changes that will be made and will be noted in the relevant sections:<br />
<br />
* Do not clear your Secure Boot keys. Merely disable Secure Boot for the installation.<br />
* Use {{ic|shim}} to boot systemd-bootloader<br />
* Load your db.cer file into the MOKManager application.<br />
<br />
All remaining steps should remain the same, except your system will still be dependent on the factory provided Microsoft Certificates. But you can boot Windows 10 in Secure Boot, which will be important for Windows 11.<br />
<br />
== Initial setup ==<br />
<br />
=== Pre-installation ===<br />
<br />
If you will only boot linux, reset your Secure Boot settings in BIOS to enable setup mode. Usually this means you set Secure Boot to Enabled and then select the option to wipe out the keys.<br />
<br />
If you will be dual booting Windows, disable secure boot.<br />
<br />
Follow the [[Installation_guide#Pre-installation]] up to Paritioning the Disks.<br />
<br />
=== Disk preparation ===<br />
<br />
If you have data on your disks you want to overwrite, utilize [[Dm-crypt/Drive_preparation#dm-crypt_wipe_on_an_empty_disk_or_partition]] to wipe it. If this disk was previously encrypted, utilize [[Dm-crypt/Drive_preparation#Wipe_LUKS_header]] instead for a much faster disposal. Finally, use [[Dm-crypt/Encrypting_an_entire_system#LVM_on_LUKS]] to parition your drive with two differences.<br />
<br />
{{tip|Using a memorable LUKS passphrase until you've completed the install process can be helpful. It will take several reboots to finish setup.}}<br />
<br />
First, the partition layout will be similar to here. You may wish to break out the /home directory into it's own partition. The primary requirement is that only your EFI partition be unencrypted.<br />
<br />
{{hc|Partiton Layout|<br />
┌────────────────────┬─────────────────────────┬──────────────────────────┬───────────────────────────┐<br />
│ │ │ │ │<br />
│ EFI Boot Partition │ Logical Volume 1 │ Logical Volume 2 │ Logical Volume 3 │<br />
│ /efi │ [Swap] │ / │ /home │<br />
│ /dev/nvme0n1p1 │ /dev/CryptRootVG/swap │ /dev/CryptRootVG/root │ /dev/CryptRootVG/home │<br />
│ 512 MB │ 16GB (Or RAM Size) │ 50 GB │ Remaining Space │<br />
│ │ │ │ │<br />
│ ├─────────────────────────┴──────────────────────────┴───────────────────────────┤<br />
│ │ LUKS and LVM Physical Volume │<br />
│ │ /dev/nvme0n1p2 │<br />
│ │ │<br />
│ │ │<br />
│ │ │<br />
│ │ │<br />
└────────────────────┴────────────────────────────────────────────────────────────────────────────────┘<br />
}}<br />
<br />
Second, if your hard drive is an SSD, use the following command to open your LUKS volume.<br />
<br />
# cryptsetup open --perf-no_read_workqueue --perf-no_write_workqueue --persistent /dev/nvme0n1p2 cryptroot<br />
<br />
After completing your LUKS on LVM setup, format your EFI partition per [[EFI system partition]].<br />
<br />
# mkfs.fat -F32 /dev/nvme0n1p1<br />
<br />
Mount this partition at {{ic|/mnt/efi}}. It is very important to leave {{ic|/boot}} on your encrypted root partition.<br />
<br />
== Installation ==<br />
<br />
Continue with [[Installation_guide#Installation]]. Be sure to flesh out your {{man|8|pacstrap}} with the following list of packages:<br />
<br />
* {{Pkg|dracut}}<br />
* {{Pkg|sbsigntools}}<br />
* {{Pkg|intel-ucode}}<br />
* {{Pkg|lvm2}}<br />
* {{Pkg|openssh}}<br />
* {{Pkg|ansible}}<br />
* {{Pkg|git}}<br />
* {{Pkg|iwd}}<br />
* {{Pkg|efibootmgr}}<br />
<br />
<br />
We are going to leave off the installation guide at the initramfs section, so go ahead and reset your root password. <br />
<br />
# passwd<br />
<br />
=== Bootloader ===<br />
<br />
First, install {{ic|systemd-boot}} by following [[Systemd-boot#Installing_the_EFI_boot_manager]]. Next, install {{aur|dracut-hook-uefi}}.<br />
<br />
Ensure you drop in a systemd-boot hook to update your bootctl any time it's updated.<br />
<br />
{{hc|/etc/pacman.d/hooks/998-systemd-boot.hook|2=<br />
[Trigger]<br />
Type = Package<br />
Operation = Install<br />
Operation = Upgrade<br />
Target = systemd<br />
<br />
[Action]<br />
Description = Updating systemd-boot<br />
When = PostTransaction<br />
Exec = /usr/bin/bootctl update; <br />
}}<br />
<br />
Obtain the UUID of your LUKS drive via the following command:<br />
<br />
{{bc|<br />
blkid -s UUID -o value /dev/nvme0n1p2<br />
}}<br />
<br />
Create the following files with the listed content. Be sure to replace UUIDs with what you actually need. See {{man|5|dracut.conf}} for more information on what these commands do.<br />
<br />
A good portion of the kernel command line was as generated by dracut. Many are extraneous or you may wish to change some of the block device names.<br />
<br />
{{hc|/etc/dracut.conf.d/cmdline.conf|2=<br />
kernel_cmdline="rd.luks.uuid=luks-17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02 rd.lvm.lv=CryptRoot/root rd.lvm.lv=CryptRoot/swap resume=/dev/mapper/CryptRoot-swap root=/dev/mapper/CryptRoot-root rootfstype=ext4 rootflags=rw,relatime"<br />
}}<br />
<br />
{{hc|/etc/dracut.conf.d/flags.conf|2=<br />
compress="zstd"<br />
hostonly="yes"<br />
}}<br />
<br />
Run the following command to generate your EFI stub kernels.<br />
<br />
dracut --uefi<br />
<br />
=== Secure boot ===<br />
<br />
==== Dual Booting Windows ====<br />
<br />
Review [[Unified Extensible Firmware Interface/Secure Boot#shim]] to get a rough understanding of how it's going to work. Install {{aur|shim-signed}}. Perform the following commands to place files where both the UEFI boot entry and shim will load them.<br />
<br />
# mv /efi/EFI/BOOT/BOOTx64.EFI /efi/EFI/BOOT/grubx64.efi<br />
# cp /usr/share/shim-signed/shimx64.efi esp/EFI/BOOT/BOOTx64.EFI<br />
# cp /usr/share/shim-signed/mmx64.efi esp/EFI/BOOT/<br />
<br />
Install {{Pkg|sbctl}}. Use the following command to check that secure boot is in the right status. Your output should be similar.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✘ Sbctl is not installed<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/BOOT/grubx64.efi is not signed<br />
<br />
✘ /efi/EFI/BOOT/mmx64.efi is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
}}<br />
<br />
Note that shim and MOKManager (mmx) is included in this list, even though we will not be signing it.<br />
<br />
{{bc|<br />
# sbctl sign -s /efi/EFI/BOOT/ grubx64.efi <br />
<br />
✔ Signed /efi/EFI/BOOT/grubx64.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi <br />
<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi <br />
<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi<br />
# sbctl verify<br />
<br />
Verifying file database and EFI images in /efi...<br />
✔� /efi/EFI/BOOT/grubx64.efi is signed<br />
✔ /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi is signed<br />
✔ /efi/EFI/systemd/systemd-bootx64.efi is signed<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/BOOT/mmx64.efi is not signed<br />
}}<br />
<br />
You can validate that {{ic|BOOTx64.EFI}} and {{ic|mmx64.efi}} have signatures with {{man|1|sbverify}} from the {{Pkg|sbsigntools}} package.<br />
<br />
Next, we need to create the DER format certificate to load into ''MokManager''.<br />
<br />
# openssl x509 -outform DER -in /usr/share/secureboot/keys/db/db.pem -out /efi/signing.cer<br />
<br />
Use {{Pkg|efibootmgr}} ({{man|8|efibootmgr}}) to adjust your boot entries. Primarily, you will want to remove the {{ic|Linux Boot Manager}} entry.<br />
<br />
{{bc|<br />
# efibootmgr<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0001,0000,0002,0003,0004<br />
Boot0000* Windows Boot Manager<br />
Boot0001* Linux Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
}}<br />
<br />
In this example, we see that {{ic|0000}} is the Windows boot manager. {{ic|0001}} is the Linux Boot Manager and also the first in line to boot. {{ic|0001}} needs to be deleted and optionally the boot order modified so {{ic|0004}} is the default boot entry.<br />
<br />
{{bc|<br />
# efibootmgr --bootnum 0001 --delete-bootnum<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0000,0002,0003,0004<br />
Boot0000* Windows Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
<br />
# efibootmgr --bootorder 0004,0000,0002,0003<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0004,0000,0002,0003<br />
Boot0000* Windows Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Now reboot. You should get an error from your motherboard's UEFI BIOS that secure boot checks failed. Your computer should restart directly into ''MokManager'', if you rearranged the boot order. If not, you will need to select {{ic|UEFI OS}} from your UEFI boot menu. Navigate to the {{ic|signing.cer}} file we placed on the EFI partition and enroll the key. Select reboot, and the system should boot directly into linux with no problem.<br />
<br />
==== Booting only Linux ====<br />
<br />
{{note|Credit to this [https://lunaryorn.com/secure-boot-on-arch-linux-with-sbctl-and-dracut blog post by lunaryorn] for the inspiration.}}<br />
<br />
Install {{Pkg|sbctl}}. At this point you will likely need to reboot and adjust your secure boot settings. You want secure boot in '''setup mode'''. <br />
<br />
{{bc|<br />
$ sbctl status<br />
Installed: X Sbctl is not installed<br />
Setup Mode: X Enabled<br />
Secure Boot: X Disabled<br />
}}<br />
<br />
Run the following commands as root. See {{man|8|sbctl}} for more information on their function. Of particular note is the {{ic|-s}} flag which indicates {{ic|sbctl}} should remember the file for future verification and signing.<br />
<br />
Note your Linux EFI binary name may be slightly different.<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
<br />
# sbctl sign -s /efi/EFI/BOOT/BOOTx64.EFI<br />
✔ Signed /efi/EFI/BOOT/BOOTx64.EFI<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Finally, enroll the Secure Boot keys.<br />
<br />
{{bc|<br />
# sbctl enroll-keys<br />
Enrolling keys to EFI variables...✔<br />
Enrolled keys to the EFI variables!<br />
}}<br />
<br />
Verify that secure boot now has an owner GUID and setup mode is disabled.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✔ Sbctl is installed<br />
Owner GUID: a2ee3d08-725a-408b-9d95-28026a44611c<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
Now reboot. This reboot is required so we can get the TPM measurements into their (hopefully) permanent state.<br />
<br />
=== Enroll LUKS key in TPM ===<br />
{{warning|Yes, this will cause a system to automatically unlock it's encrypted root volume without any interaction from a human. Yes, this exposes it to any sufficently advanced Evil Maid attacks. If sealed against the appropriate registers (especially register 8 with the kernel arguments), the TPM measurements should force systemd to ask for your LUKS passphrase in almost any attempt to access the encrypted volume from outside your normal boot process.}}<br />
<br />
We are fortunate that in our shift to dracut includes utilizing systemd and sd-encrypt, as we can use systemd's native support for enrolling LUKS keys. A review of [[Trusted Platform Module#Using TPM 2.0]] is recommended but not very clear.<br />
<br />
==== Avoid dracut bugs ====<br />
<br />
Subtitle: The Case of the Missing {{ic|d}}<br />
<br />
Two bugs, one in systemd 249.4-1-arch [https://github.com/systemd/systemd/issues/19177] and one in dracut 055 [https://github.com/dracutdevs/dracut/pull/1526][https://github.com/dracutdevs/dracut/issues/1542] will combine to prevent your system from being able to boot. The dracut issue causes the '''tpm2-tss''' module to not be included in your image. The systemd issue causes systemd to go into an emergency when it can't locate the TPM2 libraries, instead of falling back to asking for your passcode.<br />
<br />
The systemd bug isn't a problem so long as you always have TPM2 libraries present.<br />
<br />
To resolve this, first check your version of dracut.<br />
<br />
{{bc|<br />
$ dracut --version<br />
dracut 055<br />
}}<br />
<br />
Since the next release of dracut should have this fixed, we can simply fix the script locally until the next release.<br />
<br />
{{warning|These steps are only necessary for dracut 055}}<br />
<br />
Find the following lines in {{ic|/usr/lib/dracut/modules.d/91tpm2-tss/module-setup.sh}}:<br />
<br />
{{bc|1=<br />
# Module dependency requirements.<br />
depends() {<br />
<br />
# This module has external dependency on other module(s).<br />
echo systemd-sysusers systemd-udev<br />
# Return 0 to include the dependent module(s) in the initramfs.<br />
return 0<br />
<br />
}<br />
}}<br />
<br />
Change the dependency {{ic|systemd-udev}} to <code>systemd-udev<b>d</b></code>.<br />
<br />
Continue with the remaining steps in this section.<br />
<br />
==== Enrollment ====<br />
<br />
First, be sure to install {{Pkg|tpm2-tools}}. Alternatively {{aur|ibm-tss}} can be used per [[Trusted Platform Module]], however this guide is not tested against those.<br />
<br />
{{note|A reboot may be required to convince {{ic|systemd-cryptenroll}} that TPM 2.0 devices now exist on the machine.}}<br />
<br />
There are several decisions to be made here. The table at [[Trusted Platform Module#Accessing PCR registers]] is accurate as of October 2021. Essentially, once you seal your LUKS key, if any of the registers you've sealed against change, then you will be asked for your LUKS passphrase. This is equivalent to when Windows 10 makes you enter your BitLocker recovery key after a hardware change or changing BIOS settings.<br />
<br />
Your mileage may vary, based on UEFI vendors. For my laptop, I went with 0+1+2+3+4+5+7+8 and have been able to invalidate my TPM. Unfortunately, if you change your system BACK the volume will unlock. I'm investigating how to disable that.<br />
<br />
Other options on {{man|1|systemd-cryptenroll}} will reveal that several hardware tokens can also be enrolled to allow unlocking the root LUKS volume automatically, but only if a key is present. Further testing is requried.<br />
<br />
To enroll your LUKS volume, simply run the following command as root<br />
<br />
# systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/nvme0n1p2<br />
<br />
To remove your key, run this command:<br />
<br />
# systemd-cryptenroll --wipe-slot=tpm2 /dev/nvme0n1p2<br />
<br />
You will need to add a kernel argument like below to enable the TPM2 bits. If following this guide, this should be located in {{ic|/etc/dracut.conf.d/cmdline.conf}}<br />
<br />
rd.luks.options={UUID}=tpm2-device=auto<br />
<br />
Ensure that dracut builds in the TPM2 libraries. Create the following file.<br />
<br />
{{hc|/etc/dracut.conf.d/tpm2-tss.conf|2=<br />
add_dracutmodules+=" tpm2-tss "<br />
}}<br />
<br />
Finally, rebuild your unified kernel image.<br />
<br />
# dracut --force --uefi<br />
<br />
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:<br />
<br />
{{hc|~/bin/luks_reenroll_tpm|2=<br />
sudo systemd-cryptenroll --wipe-slot=tpm2 /dev/disk/by-uuid/{UUID_HERE}<br />
systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/disk/by-uuid/{UUID_HERE}<br />
}}<br />
<br />
=== Wrapping up ===<br />
<br />
Set your UEFI password. <br />
<br />
Change your LUKS passphrase from something easily memorable to a good long recovery key.<br />
<br />
Keep both of these pieces of info somewhere safe. This varies depending on your threat model. If we're just talking about Stolen Laptops and Nosy Maids, a hard copy in your safe should be sufficient. If it's the NSA, I'm not sure this setup is appropriate for that model.<br />
<br />
This is an excellent base to handle stolen laptop and even some lower grade Evil Maids. From here, you should head into [[Security]]. Consider learning a framework to help you manage your system state such as [[Ansible]] or headless [[Puppet]].<br />
<br />
== Justifications ==<br />
<br />
=== LVM on LUKS vs other dm-crypt approaches ===<br />
<br />
LVM on LUKS was selected becasue it is simply the easiest to manage while conferring both encrypted swap and disk. The other approaches required much more tooling and manual fussing to utilize. This selection also gives room change freely between {{ic|busybox}} and {{ic|systemd}} initrds.<br />
<br />
=== Using dracut ===<br />
<br />
{{Pkg|dracut}} just makes it easier to build full unified kernels that {{man|7|systemd-boot}} can launch as EFI binaries. There is also available tooling in the [[AUR]] for automating the creation of these binaries. Finally, {{ic|dracut}} will sign the binaries it creates automatically when configured to do so.<br />
<br />
=== Unified kernel images ===<br />
<br />
While UKI's could be problematic on other distributions, they fit right in with an Arch Linux install. The automation is there through pacman hooks and {{Pkg|sbctl}} to sign our UKIs as they're created. Furthermore, you can only sign and create a new signed UKI while booted into a properly signed UKI. It creates a chain of trust, which means it's important to never disable Secure Boot once you've set it up.<br />
<br />
The UKI encompasses all of the following items inside the signature, which means you can't change any of them without invalidating the signature.<br />
<br />
* Kernel arguments<br />
* Initrd/Initramfs<br />
* Kernel<br />
<br />
In particular, all other flavors of secureboot do not sign or validate the initramfs. This is a big attack area and can be relatively trivialized that a semi-decent pawn shop owner with Google could likely find an image that would grant him access and make the TPM none the wiser the system has changed. One can prevent this with encrypted /boot, but that would limit you to GRUB2 and LUKS version 1 devices only. This also doesn't include the work to keep GRUB2's files signed with a PGP key by root.<br />
<br />
=== LUKS enrolled in TPM ===<br />
<br />
The goal here is to only require the passphrase when something spooky happens in your boot path.<br />
<br />
UEFI settings change? Request password.<br />
<br />
Some weird swap of some module of UEFI code that lives on your motherboard somewhere? Request password.<br />
<br />
Unified Kernel Image changes? Don't even boot.<br />
<br />
Drive in another computer? Request password.<br />
<br />
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.<br />
<br />
== Miscellaneous discussions ==<br />
<br />
=== Filesystem Selection ===<br />
<br />
Most examples on Arch utilize {{ic|ext4}}, but other file systems such as {{ic|brtfs}} can work equally well. As for performance or issues with being inside LVM, [https://btrfs.wiki.kernel.org/index.php/FAQ#Btrfs_has_subvolumes.2C_does_this_mean_I_don.27t_need_a_logical_volume_manager_and_I_can_create_a_big_Btrfs_filesystem_on_a_raw_partition.3F this question in the brtfs FAQ] implies that there is some performance loss but no other issues.<br />
<br />
=== LUKS TPM enrollment and managing luks keys ===<br />
<br />
Note that using {{man|1|systemd-cryptenroll}} will add a key to your LUKS volume. It's not clear how exactly the option {{ic|1=--wipe-slot=tpm2}} is able to identify which slot it needs to wipe, but it does. This even works if your TPM has changed.<br />
<br />
You can see the effects by comparing the output of {{ic|cryptsetup luksDump /dev/nvme0n1p2}} before and after you enroll or wipe a TPM based key. You can identify what slot your own passphrase is in with {{ic|cryptsetup --verbose open --test-passphrase /dev/nvme0n1p2}} and entering your passphrase. The output will inform you which key slot was unlocked.<br />
<br />
Finally, your passphrase may be changed with {{ic|cryptsetup luksChangeKey /dev/nvme0n1p2 -S 0}}.<br />
<br />
== Planned TODOs ==<br />
A panic command that can dump the TPM and shutdown the computer (without requiring the time of entering a password in sudo) forcing an adversary to resort to [https://en.wikipedia.org/wiki/Rubber-hose_cryptanalysis rubber-hose cryptanalysis] to get to the encrypted data.</div>Krinhttps://wiki.archlinux.org/index.php?title=User:Krin/Secure_Boot,_full_disk_encryption,_and_TPM2_unlocking_install&diff=701276User:Krin/Secure Boot, full disk encryption, and TPM2 unlocking install2021-11-08T02:29:33Z<p>Krin: Remove warning, section is complete.</p>
<hr />
<div>{{Unsupported|1 October 2021}}<br />
<br />
== Introduction ==<br />
<br />
This installation is based on my installing Arch on an Asus ROG Strix G G531 I got second hand and a desktop computer made of second hand parts that had to share space with Windows. The primary goals were to replace Windows 10 Pro with Bitlocker encryption and maintain the convenience and security balance of that original operating system.<br />
<br />
My requirements boiled down to:<br />
<br />
* A fully encrypted disk<br />
* Full Secure Boot validation of all UEFI components.<br />
* Use of the TPM to facilitate unlocking of the disk.<br />
* Hibernate/Suspend working.<br />
<br />
My primary use case here is to make it difficult enough for a baggage handler with sticky hands to get at my data that they just wipe the drive. A state level actor with the expertise and equipment to hot swap my ram in my hotel room is not something that I'm defending this ''particular'' laptop against. This is more for gaming and web browsing and uploading photos while traveling.<br />
<br />
I'll continue to update these notes as I develop further solutions.<br />
<br />
== Disclaimers ==<br />
<br />
This article is primarily for the author's own notes. It is assumed that the reader is familiar with the [[Installation guide]] and will refer to it often. Reading linked articles is recommended.<br />
<br />
== Dual Booting Modifications ==<br />
<br />
{{warning|If you use BitLocker on your Windows drive, ensure you have your recovery key handy. The installation process will change your TPM measurements causing Windows to require you enter the key manually the next time you boot it.}}<br />
<br />
For computers that will have to dual boot with windows, the easiest solution is to use two different physical drives and utilize your motherboard's UEFI boot menu to select which one to boot. This guide will follow that assumption. You can also attempt to have everything live on one EFI partition. Windows's 100 MiB EFI partition is especially problematic to this approach for secure boot, as Unified Kernel Images can approach 80 MiB and Windows 10 regularly uses up to 30 MiB. An alternative is to copy the Microsoft bootloader into your Linux EFI bootloader and then prioritize the Linux EFI disk over your Windows disk. You will want to copy the directory {{ic|WINDOWS_EFI_PARITION/EFI/Microsoft}} to the same location on your Linux EFI partition. Anytime Microsoft updates the bootloader, you will need to copy the Microsoft EFI folder again.<br />
<br />
There are two changes that will be made and will be noted in the relevant sections:<br />
<br />
* Do not clear your Secure Boot keys. Merely disable Secure Boot for the installation.<br />
* Use {{ic|shim}} to boot systemd-bootloader<br />
* Load your db.cer file into the MOKManager application.<br />
<br />
All remaining steps should remain the same, except your system will still be dependent on the factory provided Microsoft Certificates. But you can boot Windows 10 in Secure Boot, which will be important for Windows 11.<br />
<br />
== Initial setup ==<br />
<br />
=== Pre-installation ===<br />
<br />
If you will only boot linux, reset your Secure Boot settings in BIOS to enable setup mode. Usually this means you set Secure Boot to Enabled and then select the option to wipe out the keys.<br />
<br />
If you will be dual booting Windows, disable secure boot.<br />
<br />
Follow the [[Installation_guide#Pre-installation]] up to Paritioning the Disks.<br />
<br />
=== Disk preparation ===<br />
<br />
If you have data on your disks you want to overwrite, utilize [[Dm-crypt/Drive_preparation#dm-crypt_wipe_on_an_empty_disk_or_partition]] to wipe it. If this disk was previously encrypted, utilize [[Dm-crypt/Drive_preparation#Wipe_LUKS_header]] instead for a much faster disposal. Finally, use [[Dm-crypt/Encrypting_an_entire_system#LVM_on_LUKS]] to parition your drive with two differences.<br />
<br />
{{tip|Using a memorable LUKS passphrase until you've completed the install process can be helpful. It will take several reboots to finish setup.}}<br />
<br />
First, the partition layout will be similar to here. You may wish to break out the /home directory into it's own partition. The primary requirement is that only your EFI partition be unencrypted.<br />
<br />
{{hc|Partiton Layout|<br />
┌────────────────────┬─────────────────────────┬──────────────────────────┬───────────────────────────┐<br />
│ │ │ │ │<br />
│ EFI Boot Partition │ Logical Volume 1 │ Logical Volume 2 │ Logical Volume 3 │<br />
│ /efi │ [Swap] │ / │ /home │<br />
│ /dev/nvme0n1p1 │ /dev/CryptRootVG/swap │ /dev/CryptRootVG/root │ /dev/CryptRootVG/home │<br />
│ 512 MB │ 16GB (Or RAM Size) │ 50 GB │ Remaining Space │<br />
│ │ │ │ │<br />
│ ├─────────────────────────┴──────────────────────────┴───────────────────────────┤<br />
│ │ LUKS and LVM Physical Volume │<br />
│ │ /dev/nvme0n1p2 │<br />
│ │ │<br />
│ │ │<br />
│ │ │<br />
│ │ │<br />
└────────────────────┴────────────────────────────────────────────────────────────────────────────────┘<br />
}}<br />
<br />
Second, if your hard drive is an SSD, use the following command to open your LUKS volume.<br />
<br />
# cryptsetup open --perf-no_read_workqueue --perf-no_write_workqueue --persistent /dev/nvme0n1p2 cryptroot<br />
<br />
After completing your LUKS on LVM setup, format your EFI partition per [[EFI system partition]].<br />
<br />
# mkfs.fat -F32 /dev/nvme0n1p1<br />
<br />
Mount this partition at {{ic|/mnt/efi}}. It is very important to leave {{ic|/boot}} on your encrypted root partition.<br />
<br />
== Installation ==<br />
<br />
Continue with [[Installation_guide#Installation]]. Be sure to flesh out your {{man|8|pacstrap}} with the following list of packages:<br />
<br />
* {{Pkg|dracut}}<br />
* {{Pkg|intel-ucode}}<br />
* {{Pkg|lvm2}}<br />
* {{Pkg|openssh}}<br />
* {{Pkg|ansible}}<br />
* {{Pkg|git}}<br />
* {{Pkg|iwd}}<br />
* {{Pkg|efibootmgr}}<br />
<br />
<br />
We are going to leave off the installation guide at the initramfs section, so go ahead and reset your root password. <br />
<br />
# passwd<br />
<br />
=== Bootloader ===<br />
<br />
First, install {{ic|systemd-boot}} by following [[Systemd-boot#Installing_the_EFI_boot_manager]]. Next, install {{aur|dracut-hook-uefi}}.<br />
<br />
Ensure you drop in a systemd-boot hook to update your bootctl any time it's updated.<br />
<br />
{{hc|/etc/pacman.d/hooks/998-systemd-boot.hook|2=<br />
[Trigger]<br />
Type = Package<br />
Operation = Install<br />
Operation = Upgrade<br />
Target = systemd<br />
<br />
[Action]<br />
Description = Updating systemd-boot<br />
When = PostTransaction<br />
Exec = /usr/bin/bootctl update; <br />
}}<br />
<br />
Obtain the UUID of your LUKS drive via the following command:<br />
<br />
{{bc|<br />
blkid -s UUID -o value /dev/nvme0n1p2<br />
}}<br />
<br />
Create the following files with the listed content. Be sure to replace UUIDs with what you actually need. See {{man|5|dracut.conf}} for more information on what these commands do.<br />
<br />
A good portion of the kernel command line was as generated by dracut. Many are extraneous or you may wish to change some of the block device names.<br />
<br />
{{hc|/etc/dracut.conf.d/cmdline.conf|2=<br />
kernel_cmdline="rd.luks.uuid=luks-17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02 rd.lvm.lv=CryptRoot/root rd.lvm.lv=CryptRoot/swap resume=/dev/mapper/CryptRoot-swap root=/dev/mapper/CryptRoot-root rootfstype=ext4 rootflags=rw,relatime"<br />
}}<br />
<br />
{{hc|/etc/dracut.conf.d/flags.conf|2=<br />
compress="zstd"<br />
hostonly="yes"<br />
}}<br />
<br />
Run the following command to generate your EFI stub kernels.<br />
<br />
dracut --uefi<br />
<br />
=== Secure boot ===<br />
<br />
==== Dual Booting Windows ====<br />
<br />
Review [[Unified Extensible Firmware Interface/Secure Boot#shim]] to get a rough understanding of how it's going to work. Install {{aur|shim-signed}}. Perform the following commands to place files where both the UEFI boot entry and shim will load them.<br />
<br />
# mv /efi/EFI/BOOT/BOOTx64.EFI /efi/EFI/BOOT/grubx64.efi<br />
# cp /usr/share/shim-signed/shimx64.efi esp/EFI/BOOT/BOOTx64.EFI<br />
# cp /usr/share/shim-signed/mmx64.efi esp/EFI/BOOT/<br />
<br />
Install {{Pkg|sbctl}}. Use the following command to check that secure boot is in the right status. Your output should be similar.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✘ Sbctl is not installed<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/BOOT/grubx64.efi is not signed<br />
<br />
✘ /efi/EFI/BOOT/mmx64.efi is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
}}<br />
<br />
Note that shim and MOKManager (mmx) is included in this list, even though we will not be signing it.<br />
<br />
{{bc|<br />
# sbctl sign -s /efi/EFI/BOOT/ grubx64.efi <br />
<br />
✔ Signed /efi/EFI/BOOT/grubx64.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi <br />
<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi <br />
<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi<br />
# sbctl verify<br />
<br />
Verifying file database and EFI images in /efi...<br />
✔� /efi/EFI/BOOT/grubx64.efi is signed<br />
✔ /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi is signed<br />
✔ /efi/EFI/systemd/systemd-bootx64.efi is signed<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/BOOT/mmx64.efi is not signed<br />
}}<br />
<br />
You can validate that {{ic|BOOTx64.EFI}} and {{ic|mmx64.efi}} have signatures with {{man|1|sbverify}} from the {{Pkg|sbsigntools}} package.<br />
<br />
Next, we need to create the DER format certificate to load into ''MokManager''.<br />
<br />
# openssl x509 -outform DER -in /usr/share/secureboot/keys/db/db.pem -out /efi/signing.cer<br />
<br />
Use {{Pkg|efibootmgr}} ({{man|8|efibootmgr}}) to adjust your boot entries. Primarily, you will want to remove the {{ic|Linux Boot Manager}} entry.<br />
<br />
{{bc|<br />
# efibootmgr<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0001,0000,0002,0003,0004<br />
Boot0000* Windows Boot Manager<br />
Boot0001* Linux Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
}}<br />
<br />
In this example, we see that {{ic|0000}} is the Windows boot manager. {{ic|0001}} is the Linux Boot Manager and also the first in line to boot. {{ic|0001}} needs to be deleted and optionally the boot order modified so {{ic|0004}} is the default boot entry.<br />
<br />
{{bc|<br />
# efibootmgr --bootnum 0001 --delete-bootnum<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0000,0002,0003,0004<br />
Boot0000* Windows Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
<br />
# efibootmgr --bootorder 0004,0000,0002,0003<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0004,0000,0002,0003<br />
Boot0000* Windows Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Now reboot. You should get an error from your motherboard's UEFI BIOS that secure boot checks failed. Your computer should restart directly into ''MokManager'', if you rearranged the boot order. If not, you will need to select {{ic|UEFI OS}} from your UEFI boot menu. Navigate to the {{ic|signing.cer}} file we placed on the EFI partition and enroll the key. Select reboot, and the system should boot directly into linux with no problem.<br />
<br />
==== Booting only Linux ====<br />
<br />
{{note|Credit to this [https://lunaryorn.com/secure-boot-on-arch-linux-with-sbctl-and-dracut blog post by lunaryorn] for the inspiration.}}<br />
<br />
Install {{Pkg|sbctl}}. At this point you will likely need to reboot and adjust your secure boot settings. You want secure boot in '''setup mode'''. <br />
<br />
{{bc|<br />
$ sbctl status<br />
Installed: X Sbctl is not installed<br />
Setup Mode: X Enabled<br />
Secure Boot: X Disabled<br />
}}<br />
<br />
Run the following commands as root. See {{man|8|sbctl}} for more information on their function. Of particular note is the {{ic|-s}} flag which indicates {{ic|sbctl}} should remember the file for future verification and signing.<br />
<br />
Note your Linux EFI binary name may be slightly different.<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
<br />
# sbctl sign -s /efi/EFI/BOOT/BOOTx64.EFI<br />
✔ Signed /efi/EFI/BOOT/BOOTx64.EFI<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Finally, enroll the Secure Boot keys.<br />
<br />
{{bc|<br />
# sbctl enroll-keys<br />
Enrolling keys to EFI variables...✔<br />
Enrolled keys to the EFI variables!<br />
}}<br />
<br />
Verify that secure boot now has an owner GUID and setup mode is disabled.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✔ Sbctl is installed<br />
Owner GUID: a2ee3d08-725a-408b-9d95-28026a44611c<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
Now reboot. This reboot is required so we can get the TPM measurements into their (hopefully) permanent state.<br />
<br />
=== Enroll LUKS key in TPM ===<br />
{{warning|Yes, this will cause a system to automatically unlock it's encrypted root volume without any interaction from a human. Yes, this exposes it to any sufficently advanced Evil Maid attacks. If sealed against the appropriate registers (especially register 8 with the kernel arguments), the TPM measurements should force systemd to ask for your LUKS passphrase in almost any attempt to access the encrypted volume from outside your normal boot process.}}<br />
<br />
We are fortunate that in our shift to dracut includes utilizing systemd and sd-encrypt, as we can use systemd's native support for enrolling LUKS keys. A review of [[Trusted Platform Module#Using TPM 2.0]] is recommended but not very clear.<br />
<br />
==== Avoid dracut bugs ====<br />
<br />
Subtitle: The Case of the Missing {{ic|d}}<br />
<br />
Two bugs, one in systemd 249.4-1-arch [https://github.com/systemd/systemd/issues/19177] and one in dracut 055 [https://github.com/dracutdevs/dracut/pull/1526][https://github.com/dracutdevs/dracut/issues/1542] will combine to prevent your system from being able to boot. The dracut issue causes the '''tpm2-tss''' module to not be included in your image. The systemd issue causes systemd to go into an emergency when it can't locate the TPM2 libraries, instead of falling back to asking for your passcode.<br />
<br />
The systemd bug isn't a problem so long as you always have TPM2 libraries present.<br />
<br />
To resolve this, first check your version of dracut.<br />
<br />
{{bc|<br />
$ dracut --version<br />
dracut 055<br />
}}<br />
<br />
Since the next release of dracut should have this fixed, we can simply fix the script locally until the next release.<br />
<br />
{{warning|These steps are only necessary for dracut 055}}<br />
<br />
Find the following lines in {{ic|/usr/lib/dracut/modules.d/91tpm2-tss/module-setup.sh}}:<br />
<br />
{{bc|1=<br />
# Module dependency requirements.<br />
depends() {<br />
<br />
# This module has external dependency on other module(s).<br />
echo systemd-sysusers systemd-udev<br />
# Return 0 to include the dependent module(s) in the initramfs.<br />
return 0<br />
<br />
}<br />
}}<br />
<br />
Change the dependency {{ic|systemd-udev}} to <code>systemd-udev<b>d</b></code>.<br />
<br />
Continue with the remaining steps in this section.<br />
<br />
==== Enrollment ====<br />
<br />
First, be sure to install {{Pkg|tpm2-tools}}. Alternatively {{aur|ibm-tss}} can be used per [[Trusted Platform Module]], however this guide is not tested against those.<br />
<br />
{{note|A reboot may be required to convince {{ic|systemd-cryptenroll}} that TPM 2.0 devices now exist on the machine.}}<br />
<br />
There are several decisions to be made here. The table at [[Trusted Platform Module#Accessing PCR registers]] is accurate as of October 2021. Essentially, once you seal your LUKS key, if any of the registers you've sealed against change, then you will be asked for your LUKS passphrase. This is equivalent to when Windows 10 makes you enter your BitLocker recovery key after a hardware change or changing BIOS settings.<br />
<br />
Your mileage may vary, based on UEFI vendors. For my laptop, I went with 0+1+2+3+4+5+7+8 and have been able to invalidate my TPM. Unfortunately, if you change your system BACK the volume will unlock. I'm investigating how to disable that.<br />
<br />
Other options on {{man|1|systemd-cryptenroll}} will reveal that several hardware tokens can also be enrolled to allow unlocking the root LUKS volume automatically, but only if a key is present. Further testing is requried.<br />
<br />
To enroll your LUKS volume, simply run the following command as root<br />
<br />
# systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/nvme0n1p2<br />
<br />
To remove your key, run this command:<br />
<br />
# systemd-cryptenroll --wipe-slot=tpm2 /dev/nvme0n1p2<br />
<br />
You will need to add a kernel argument like below to enable the TPM2 bits. If following this guide, this should be located in {{ic|/etc/dracut.conf.d/cmdline.conf}}<br />
<br />
rd.luks.options={UUID}=tpm2-device=auto<br />
<br />
Ensure that dracut builds in the TPM2 libraries. Create the following file.<br />
<br />
{{hc|/etc/dracut.conf.d/tpm2-tss.conf|2=<br />
add_dracutmodules+=" tpm2-tss "<br />
}}<br />
<br />
Finally, rebuild your unified kernel image.<br />
<br />
# dracut --force --uefi<br />
<br />
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:<br />
<br />
{{hc|~/bin/luks_reenroll_tpm|2=<br />
sudo systemd-cryptenroll --wipe-slot=tpm2 /dev/disk/by-uuid/{UUID_HERE}<br />
systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/disk/by-uuid/{UUID_HERE}<br />
}}<br />
<br />
=== Wrapping up ===<br />
<br />
Set your UEFI password. <br />
<br />
Change your LUKS passphrase from something easily memorable to a good long recovery key.<br />
<br />
Keep both of these pieces of info somewhere safe. This varies depending on your threat model. If we're just talking about Stolen Laptops and Nosy Maids, a hard copy in your safe should be sufficient. If it's the NSA, I'm not sure this setup is appropriate for that model.<br />
<br />
This is an excellent base to handle stolen laptop and even some lower grade Evil Maids. From here, you should head into [[Security]]. Consider learning a framework to help you manage your system state such as [[Ansible]] or headless [[Puppet]].<br />
<br />
== Justifications ==<br />
<br />
=== LVM on LUKS vs other dm-crypt approaches ===<br />
<br />
LVM on LUKS was selected becasue it is simply the easiest to manage while conferring both encrypted swap and disk. The other approaches required much more tooling and manual fussing to utilize. This selection also gives room change freely between {{ic|busybox}} and {{ic|systemd}} initrds.<br />
<br />
=== Using dracut ===<br />
<br />
{{Pkg|dracut}} just makes it easier to build full unified kernels that {{man|7|systemd-boot}} can launch as EFI binaries. There is also available tooling in the [[AUR]] for automating the creation of these binaries. Finally, {{ic|dracut}} will sign the binaries it creates automatically when configured to do so.<br />
<br />
=== Unified kernel images ===<br />
<br />
While UKI's could be problematic on other distributions, they fit right in with an Arch Linux install. The automation is there through pacman hooks and {{Pkg|sbctl}} to sign our UKIs as they're created. Furthermore, you can only sign and create a new signed UKI while booted into a properly signed UKI. It creates a chain of trust, which means it's important to never disable Secure Boot once you've set it up.<br />
<br />
The UKI encompasses all of the following items inside the signature, which means you can't change any of them without invalidating the signature.<br />
<br />
* Kernel arguments<br />
* Initrd/Initramfs<br />
* Kernel<br />
<br />
In particular, all other flavors of secureboot do not sign or validate the initramfs. This is a big attack area and can be relatively trivialized that a semi-decent pawn shop owner with Google could likely find an image that would grant him access and make the TPM none the wiser the system has changed. One can prevent this with encrypted /boot, but that would limit you to GRUB2 and LUKS version 1 devices only. This also doesn't include the work to keep GRUB2's files signed with a PGP key by root.<br />
<br />
=== LUKS enrolled in TPM ===<br />
<br />
The goal here is to only require the passphrase when something spooky happens in your boot path.<br />
<br />
UEFI settings change? Request password.<br />
<br />
Some weird swap of some module of UEFI code that lives on your motherboard somewhere? Request password.<br />
<br />
Unified Kernel Image changes? Don't even boot.<br />
<br />
Drive in another computer? Request password.<br />
<br />
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.<br />
<br />
== Miscellaneous discussions ==<br />
<br />
=== Filesystem Selection ===<br />
<br />
Most examples on Arch utilize {{ic|ext4}}, but other file systems such as {{ic|brtfs}} can work equally well. As for performance or issues with being inside LVM, [https://btrfs.wiki.kernel.org/index.php/FAQ#Btrfs_has_subvolumes.2C_does_this_mean_I_don.27t_need_a_logical_volume_manager_and_I_can_create_a_big_Btrfs_filesystem_on_a_raw_partition.3F this question in the brtfs FAQ] implies that there is some performance loss but no other issues.<br />
<br />
=== LUKS TPM enrollment and managing luks keys ===<br />
<br />
Note that using {{man|1|systemd-cryptenroll}} will add a key to your LUKS volume. It's not clear how exactly the option {{ic|1=--wipe-slot=tpm2}} is able to identify which slot it needs to wipe, but it does. This even works if your TPM has changed.<br />
<br />
You can see the effects by comparing the output of {{ic|cryptsetup luksDump /dev/nvme0n1p2}} before and after you enroll or wipe a TPM based key. You can identify what slot your own passphrase is in with {{ic|cryptsetup --verbose open --test-passphrase /dev/nvme0n1p2}} and entering your passphrase. The output will inform you which key slot was unlocked.<br />
<br />
Finally, your passphrase may be changed with {{ic|cryptsetup luksChangeKey /dev/nvme0n1p2 -S 0}}.<br />
<br />
== Planned TODOs ==<br />
A panic command that can dump the TPM and shutdown the computer (without requiring the time of entering a password in sudo) forcing an adversary to resort to [https://en.wikipedia.org/wiki/Rubber-hose_cryptanalysis rubber-hose cryptanalysis] to get to the encrypted data.</div>Krinhttps://wiki.archlinux.org/index.php?title=User:Krin/Secure_Boot,_full_disk_encryption,_and_TPM2_unlocking_install&diff=701275User:Krin/Secure Boot, full disk encryption, and TPM2 unlocking install2021-11-08T02:25:08Z<p>Krin: /* Introduction */ Fix spelling.</p>
<hr />
<div>{{Unsupported|1 October 2021}}<br />
<br />
== Introduction ==<br />
<br />
This installation is based on my installing Arch on an Asus ROG Strix G G531 I got second hand and a desktop computer made of second hand parts that had to share space with Windows. The primary goals were to replace Windows 10 Pro with Bitlocker encryption and maintain the convenience and security balance of that original operating system.<br />
<br />
My requirements boiled down to:<br />
<br />
* A fully encrypted disk<br />
* Full Secure Boot validation of all UEFI components.<br />
* Use of the TPM to facilitate unlocking of the disk.<br />
* Hibernate/Suspend working.<br />
<br />
My primary use case here is to make it difficult enough for a baggage handler with sticky hands to get at my data that they just wipe the drive. A state level actor with the expertise and equipment to hot swap my ram in my hotel room is not something that I'm defending this ''particular'' laptop against. This is more for gaming and web browsing and uploading photos while traveling.<br />
<br />
I'll continue to update these notes as I develop further solutions.<br />
<br />
== Disclaimers ==<br />
<br />
This article is primarily for the author's own notes. It is assumed that the reader is familiar with the [[Installation guide]] and will refer to it often. Reading linked articles is recommended.<br />
<br />
== Dual Booting Modifications ==<br />
<br />
{{warning|If you use BitLocker on your Windows drive, ensure you have your recovery key handy. The installation process will change your TPM measurements causing Windows to require you enter the key manually the next time you boot it.}}<br />
<br />
For computers that will have to dual boot with windows, the easiest solution is to use two different physical drives and utilize your motherboard's UEFI boot menu to select which one to boot. This guide will follow that assumption. You can also attempt to have everything live on one EFI partition. Windows's 100 MiB EFI partition is especially problematic to this approach for secure boot, as Unified Kernel Images can approach 80 MiB and Windows 10 regularly uses up to 30 MiB. An alternative is to copy the Microsoft bootloader into your Linux EFI bootloader and then prioritize the Linux EFI disk over your Windows disk. You will want to copy the directory {{ic|WINDOWS_EFI_PARITION/EFI/Microsoft}} to the same location on your Linux EFI partition. Anytime Microsoft updates the bootloader, you will need to copy the Microsoft EFI folder again.<br />
<br />
There are two changes that will be made and will be noted in the relevant sections:<br />
<br />
* Do not clear your Secure Boot keys. Merely disable Secure Boot for the installation.<br />
* Use {{ic|shim}} to boot systemd-bootloader<br />
* Load your db.cer file into the MOKManager application.<br />
<br />
All remaining steps should remain the same, except your system will still be dependent on the factory provided Microsoft Certificates. But you can boot Windows 10 in Secure Boot, which will be important for Windows 11.<br />
<br />
== Initial setup ==<br />
<br />
=== Pre-installation ===<br />
<br />
If you will only boot linux, reset your Secure Boot settings in BIOS to enable setup mode. Usually this means you set Secure Boot to Enabled and then select the option to wipe out the keys.<br />
<br />
If you will be dual booting Windows, disable secure boot.<br />
<br />
Follow the [[Installation_guide#Pre-installation]] up to Paritioning the Disks.<br />
<br />
=== Disk preparation ===<br />
<br />
If you have data on your disks you want to overwrite, utilize [[Dm-crypt/Drive_preparation#dm-crypt_wipe_on_an_empty_disk_or_partition]] to wipe it. If this disk was previously encrypted, utilize [[Dm-crypt/Drive_preparation#Wipe_LUKS_header]] instead for a much faster disposal. Finally, use [[Dm-crypt/Encrypting_an_entire_system#LVM_on_LUKS]] to parition your drive with two differences.<br />
<br />
{{tip|Using a memorable LUKS passphrase until you've completed the install process can be helpful. It will take several reboots to finish setup.}}<br />
<br />
First, the partition layout will be similar to here. You may wish to break out the /home directory into it's own partition. The primary requirement is that only your EFI partition be unencrypted.<br />
<br />
{{hc|Partiton Layout|<br />
┌────────────────────┬─────────────────────────┬──────────────────────────┬───────────────────────────┐<br />
│ │ │ │ │<br />
│ EFI Boot Partition │ Logical Volume 1 │ Logical Volume 2 │ Logical Volume 3 │<br />
│ /efi │ [Swap] │ / │ /home │<br />
│ /dev/nvme0n1p1 │ /dev/CryptRootVG/swap │ /dev/CryptRootVG/root │ /dev/CryptRootVG/home │<br />
│ 512 MB │ 16GB (Or RAM Size) │ 50 GB │ Remaining Space │<br />
│ │ │ │ │<br />
│ ├─────────────────────────┴──────────────────────────┴───────────────────────────┤<br />
│ │ LUKS and LVM Physical Volume │<br />
│ │ /dev/nvme0n1p2 │<br />
│ │ │<br />
│ │ │<br />
│ │ │<br />
│ │ │<br />
└────────────────────┴────────────────────────────────────────────────────────────────────────────────┘<br />
}}<br />
<br />
Second, if your hard drive is an SSD, use the following command to open your LUKS volume.<br />
<br />
# cryptsetup open --perf-no_read_workqueue --perf-no_write_workqueue --persistent /dev/nvme0n1p2 cryptroot<br />
<br />
After completing your LUKS on LVM setup, format your EFI partition per [[EFI system partition]].<br />
<br />
# mkfs.fat -F32 /dev/nvme0n1p1<br />
<br />
Mount this partition at {{ic|/mnt/efi}}. It is very important to leave {{ic|/boot}} on your encrypted root partition.<br />
<br />
== Installation ==<br />
<br />
Continue with [[Installation_guide#Installation]]. Be sure to flesh out your {{man|8|pacstrap}} with the following list of packages:<br />
<br />
* {{Pkg|dracut}}<br />
* {{Pkg|intel-ucode}}<br />
* {{Pkg|lvm2}}<br />
* {{Pkg|openssh}}<br />
* {{Pkg|ansible}}<br />
* {{Pkg|git}}<br />
* {{Pkg|iwd}}<br />
* {{Pkg|efibootmgr}}<br />
<br />
<br />
We are going to leave off the installation guide at the initramfs section, so go ahead and reset your root password. <br />
<br />
# passwd<br />
<br />
=== Bootloader ===<br />
<br />
First, install {{ic|systemd-boot}} by following [[Systemd-boot#Installing_the_EFI_boot_manager]]. Next, install {{aur|dracut-hook-uefi}}.<br />
<br />
Ensure you drop in a systemd-boot hook to update your bootctl any time it's updated.<br />
<br />
{{hc|/etc/pacman.d/hooks/998-systemd-boot.hook|2=<br />
[Trigger]<br />
Type = Package<br />
Operation = Install<br />
Operation = Upgrade<br />
Target = systemd<br />
<br />
[Action]<br />
Description = Updating systemd-boot<br />
When = PostTransaction<br />
Exec = /usr/bin/bootctl update; <br />
}}<br />
<br />
Obtain the UUID of your LUKS drive via the following command:<br />
<br />
{{bc|<br />
blkid -s UUID -o value /dev/nvme0n1p2<br />
}}<br />
<br />
Create the following files with the listed content. Be sure to replace UUIDs with what you actually need. See {{man|5|dracut.conf}} for more information on what these commands do.<br />
<br />
A good portion of the kernel command line was as generated by dracut. Many are extraneous or you may wish to change some of the block device names.<br />
<br />
{{hc|/etc/dracut.conf.d/cmdline.conf|2=<br />
kernel_cmdline="rd.luks.uuid=luks-17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02 rd.lvm.lv=CryptRoot/root rd.lvm.lv=CryptRoot/swap resume=/dev/mapper/CryptRoot-swap root=/dev/mapper/CryptRoot-root rootfstype=ext4 rootflags=rw,relatime"<br />
}}<br />
<br />
{{hc|/etc/dracut.conf.d/flags.conf|2=<br />
compress="zstd"<br />
hostonly="yes"<br />
}}<br />
<br />
Run the following command to generate your EFI stub kernels.<br />
<br />
dracut --uefi<br />
<br />
=== Secure boot ===<br />
<br />
==== Dual Booting Windows ====<br />
<br />
{{warning|This section is still being written}}<br />
<br />
Review [[Unified Extensible Firmware Interface/Secure Boot#shim]] to get a rough understanding of how it's going to work. Install {{aur|shim-signed}}. Perform the following commands to place files where both the UEFI boot entry and shim will load them.<br />
<br />
# mv /efi/EFI/BOOT/BOOTx64.EFI /efi/EFI/BOOT/grubx64.efi<br />
# cp /usr/share/shim-signed/shimx64.efi esp/EFI/BOOT/BOOTx64.EFI<br />
# cp /usr/share/shim-signed/mmx64.efi esp/EFI/BOOT/<br />
<br />
Install {{Pkg|sbctl}}. Use the following command to check that secure boot is in the right status. Your output should be similar.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✘ Sbctl is not installed<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/BOOT/grubx64.efi is not signed<br />
<br />
✘ /efi/EFI/BOOT/mmx64.efi is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
}}<br />
<br />
Note that shim and MOKManager (mmx) is included in this list, even though we will not be signing it.<br />
<br />
{{bc|<br />
# sbctl sign -s /efi/EFI/BOOT/ grubx64.efi <br />
<br />
✔ Signed /efi/EFI/BOOT/grubx64.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi <br />
<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi <br />
<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi<br />
# sbctl verify<br />
<br />
Verifying file database and EFI images in /efi...<br />
✔� /efi/EFI/BOOT/grubx64.efi is signed<br />
✔ /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi is signed<br />
✔ /efi/EFI/systemd/systemd-bootx64.efi is signed<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/BOOT/mmx64.efi is not signed<br />
}}<br />
<br />
You can validate that {{ic|BOOTx64.EFI}} and {{ic|mmx64.efi}} have signatures with {{man|1|sbverify}} from the {{Pkg|sbsigntools}} package.<br />
<br />
Next, we need to create the DER format certificate to load into ''MokManager''.<br />
<br />
# openssl x509 -outform DER -in /usr/share/secureboot/keys/db/db.pem -out /efi/signing.cer<br />
<br />
Use {{Pkg|efibootmgr}} ({{man|8|efibootmgr}}) to adjust your boot entries. Primarily, you will want to remove the {{ic|Linux Boot Manager}} entry.<br />
<br />
{{bc|<br />
# efibootmgr<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0001,0000,0002,0003,0004<br />
Boot0000* Windows Boot Manager<br />
Boot0001* Linux Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
}}<br />
<br />
In this example, we see that {{ic|0000}} is the Windows boot manager. {{ic|0001}} is the Linux Boot Manager and also the first in line to boot. {{ic|0001}} needs to be deleted and optionally the boot order modified so {{ic|0004}} is the default boot entry.<br />
<br />
{{bc|<br />
# efibootmgr --bootnum 0001 --delete-bootnum<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0000,0002,0003,0004<br />
Boot0000* Windows Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
<br />
# efibootmgr --bootorder 0004,0000,0002,0003<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0004,0000,0002,0003<br />
Boot0000* Windows Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Now reboot. You should get an error from your motherboard's UEFI BIOS that secure boot checks failed. Your computer should restart directly into ''MokManager'', if you rearranged the boot order. If not, you will need to select {{ic|UEFI OS}} from your UEFI boot menu. Navigate to the {{ic|signing.cer}} file we placed on the EFI partition and enroll the key. Select reboot, and the system should boot directly into linux with no problem.<br />
<br />
==== Booting only Linux ====<br />
<br />
{{note|Credit to this [https://lunaryorn.com/secure-boot-on-arch-linux-with-sbctl-and-dracut blog post by lunaryorn] for the inspiration.}}<br />
<br />
Install {{Pkg|sbctl}}. At this point you will likely need to reboot and adjust your secure boot settings. You want secure boot in '''setup mode'''. <br />
<br />
{{bc|<br />
$ sbctl status<br />
Installed: X Sbctl is not installed<br />
Setup Mode: X Enabled<br />
Secure Boot: X Disabled<br />
}}<br />
<br />
Run the following commands as root. See {{man|8|sbctl}} for more information on their function. Of particular note is the {{ic|-s}} flag which indicates {{ic|sbctl}} should remember the file for future verification and signing.<br />
<br />
Note your Linux EFI binary name may be slightly different.<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
<br />
# sbctl sign -s /efi/EFI/BOOT/BOOTx64.EFI<br />
✔ Signed /efi/EFI/BOOT/BOOTx64.EFI<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Finally, enroll the Secure Boot keys.<br />
<br />
{{bc|<br />
# sbctl enroll-keys<br />
Enrolling keys to EFI variables...✔<br />
Enrolled keys to the EFI variables!<br />
}}<br />
<br />
Verify that secure boot now has an owner GUID and setup mode is disabled.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✔ Sbctl is installed<br />
Owner GUID: a2ee3d08-725a-408b-9d95-28026a44611c<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
Now reboot. This reboot is required so we can get the TPM measurements into their (hopefully) permanent state.<br />
<br />
=== Enroll LUKS key in TPM ===<br />
{{warning|Yes, this will cause a system to automatically unlock it's encrypted root volume without any interaction from a human. Yes, this exposes it to any sufficently advanced Evil Maid attacks. If sealed against the appropriate registers (especially register 8 with the kernel arguments), the TPM measurements should force systemd to ask for your LUKS passphrase in almost any attempt to access the encrypted volume from outside your normal boot process.}}<br />
<br />
We are fortunate that in our shift to dracut includes utilizing systemd and sd-encrypt, as we can use systemd's native support for enrolling LUKS keys. A review of [[Trusted Platform Module#Using TPM 2.0]] is recommended but not very clear.<br />
<br />
==== Avoid dracut bugs ====<br />
<br />
Subtitle: The Case of the Missing {{ic|d}}<br />
<br />
Two bugs, one in systemd 249.4-1-arch [https://github.com/systemd/systemd/issues/19177] and one in dracut 055 [https://github.com/dracutdevs/dracut/pull/1526][https://github.com/dracutdevs/dracut/issues/1542] will combine to prevent your system from being able to boot. The dracut issue causes the '''tpm2-tss''' module to not be included in your image. The systemd issue causes systemd to go into an emergency when it can't locate the TPM2 libraries, instead of falling back to asking for your passcode.<br />
<br />
The systemd bug isn't a problem so long as you always have TPM2 libraries present.<br />
<br />
To resolve this, first check your version of dracut.<br />
<br />
{{bc|<br />
$ dracut --version<br />
dracut 055<br />
}}<br />
<br />
Since the next release of dracut should have this fixed, we can simply fix the script locally until the next release.<br />
<br />
{{warning|These steps are only necessary for dracut 055}}<br />
<br />
Find the following lines in {{ic|/usr/lib/dracut/modules.d/91tpm2-tss/module-setup.sh}}:<br />
<br />
{{bc|1=<br />
# Module dependency requirements.<br />
depends() {<br />
<br />
# This module has external dependency on other module(s).<br />
echo systemd-sysusers systemd-udev<br />
# Return 0 to include the dependent module(s) in the initramfs.<br />
return 0<br />
<br />
}<br />
}}<br />
<br />
Change the dependency {{ic|systemd-udev}} to <code>systemd-udev<b>d</b></code>.<br />
<br />
Continue with the remaining steps in this section.<br />
<br />
==== Enrollment ====<br />
<br />
First, be sure to install {{Pkg|tpm2-tools}}. Alternatively {{aur|ibm-tss}} can be used per [[Trusted Platform Module]], however this guide is not tested against those.<br />
<br />
{{note|A reboot may be required to convince {{ic|systemd-cryptenroll}} that TPM 2.0 devices now exist on the machine.}}<br />
<br />
There are several decisions to be made here. The table at [[Trusted Platform Module#Accessing PCR registers]] is accurate as of October 2021. Essentially, once you seal your LUKS key, if any of the registers you've sealed against change, then you will be asked for your LUKS passphrase. This is equivalent to when Windows 10 makes you enter your BitLocker recovery key after a hardware change or changing BIOS settings.<br />
<br />
Your mileage may vary, based on UEFI vendors. For my laptop, I went with 0+1+2+3+4+5+7+8 and have been able to invalidate my TPM. Unfortunately, if you change your system BACK the volume will unlock. I'm investigating how to disable that.<br />
<br />
Other options on {{man|1|systemd-cryptenroll}} will reveal that several hardware tokens can also be enrolled to allow unlocking the root LUKS volume automatically, but only if a key is present. Further testing is requried.<br />
<br />
To enroll your LUKS volume, simply run the following command as root<br />
<br />
# systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/nvme0n1p2<br />
<br />
To remove your key, run this command:<br />
<br />
# systemd-cryptenroll --wipe-slot=tpm2 /dev/nvme0n1p2<br />
<br />
You will need to add a kernel argument like below to enable the TPM2 bits. If following this guide, this should be located in {{ic|/etc/dracut.conf.d/cmdline.conf}}<br />
<br />
rd.luks.options={UUID}=tpm2-device=auto<br />
<br />
Ensure that dracut builds in the TPM2 libraries. Create the following file.<br />
<br />
{{hc|/etc/dracut.conf.d/tpm2-tss.conf|2=<br />
add_dracutmodules+=" tpm2-tss "<br />
}}<br />
<br />
Finally, rebuild your unified kernel image.<br />
<br />
# dracut --force --uefi<br />
<br />
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:<br />
<br />
{{hc|~/bin/luks_reenroll_tpm|2=<br />
sudo systemd-cryptenroll --wipe-slot=tpm2 /dev/disk/by-uuid/{UUID_HERE}<br />
systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/disk/by-uuid/{UUID_HERE}<br />
}}<br />
<br />
=== Wrapping up ===<br />
<br />
Set your UEFI password. <br />
<br />
Change your LUKS passphrase from something easily memorable to a good long recovery key.<br />
<br />
Keep both of these pieces of info somewhere safe. This varies depending on your threat model. If we're just talking about Stolen Laptops and Nosy Maids, a hard copy in your safe should be sufficient. If it's the NSA, I'm not sure this setup is appropriate for that model.<br />
<br />
This is an excellent base to handle stolen laptop and even some lower grade Evil Maids. From here, you should head into [[Security]]. Consider learning a framework to help you manage your system state such as [[Ansible]] or headless [[Puppet]].<br />
<br />
== Justifications ==<br />
<br />
=== LVM on LUKS vs other dm-crypt approaches ===<br />
<br />
LVM on LUKS was selected becasue it is simply the easiest to manage while conferring both encrypted swap and disk. The other approaches required much more tooling and manual fussing to utilize. This selection also gives room change freely between {{ic|busybox}} and {{ic|systemd}} initrds.<br />
<br />
=== Using dracut ===<br />
<br />
{{Pkg|dracut}} just makes it easier to build full unified kernels that {{man|7|systemd-boot}} can launch as EFI binaries. There is also available tooling in the [[AUR]] for automating the creation of these binaries. Finally, {{ic|dracut}} will sign the binaries it creates automatically when configured to do so.<br />
<br />
=== Unified kernel images ===<br />
<br />
While UKI's could be problematic on other distributions, they fit right in with an Arch Linux install. The automation is there through pacman hooks and {{Pkg|sbctl}} to sign our UKIs as they're created. Furthermore, you can only sign and create a new signed UKI while booted into a properly signed UKI. It creates a chain of trust, which means it's important to never disable Secure Boot once you've set it up.<br />
<br />
The UKI encompasses all of the following items inside the signature, which means you can't change any of them without invalidating the signature.<br />
<br />
* Kernel arguments<br />
* Initrd/Initramfs<br />
* Kernel<br />
<br />
In particular, all other flavors of secureboot do not sign or validate the initramfs. This is a big attack area and can be relatively trivialized that a semi-decent pawn shop owner with Google could likely find an image that would grant him access and make the TPM none the wiser the system has changed. One can prevent this with encrypted /boot, but that would limit you to GRUB2 and LUKS version 1 devices only. This also doesn't include the work to keep GRUB2's files signed with a PGP key by root.<br />
<br />
=== LUKS enrolled in TPM ===<br />
<br />
The goal here is to only require the passphrase when something spooky happens in your boot path.<br />
<br />
UEFI settings change? Request password.<br />
<br />
Some weird swap of some module of UEFI code that lives on your motherboard somewhere? Request password.<br />
<br />
Unified Kernel Image changes? Don't even boot.<br />
<br />
Drive in another computer? Request password.<br />
<br />
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.<br />
<br />
== Miscellaneous discussions ==<br />
<br />
=== Filesystem Selection ===<br />
<br />
Most examples on Arch utilize {{ic|ext4}}, but other file systems such as {{ic|brtfs}} can work equally well. As for performance or issues with being inside LVM, [https://btrfs.wiki.kernel.org/index.php/FAQ#Btrfs_has_subvolumes.2C_does_this_mean_I_don.27t_need_a_logical_volume_manager_and_I_can_create_a_big_Btrfs_filesystem_on_a_raw_partition.3F this question in the brtfs FAQ] implies that there is some performance loss but no other issues.<br />
<br />
=== LUKS TPM enrollment and managing luks keys ===<br />
<br />
Note that using {{man|1|systemd-cryptenroll}} will add a key to your LUKS volume. It's not clear how exactly the option {{ic|1=--wipe-slot=tpm2}} is able to identify which slot it needs to wipe, but it does. This even works if your TPM has changed.<br />
<br />
You can see the effects by comparing the output of {{ic|cryptsetup luksDump /dev/nvme0n1p2}} before and after you enroll or wipe a TPM based key. You can identify what slot your own passphrase is in with {{ic|cryptsetup --verbose open --test-passphrase /dev/nvme0n1p2}} and entering your passphrase. The output will inform you which key slot was unlocked.<br />
<br />
Finally, your passphrase may be changed with {{ic|cryptsetup luksChangeKey /dev/nvme0n1p2 -S 0}}.<br />
<br />
== Planned TODOs ==<br />
A panic command that can dump the TPM and shutdown the computer (without requiring the time of entering a password in sudo) forcing an adversary to resort to [https://en.wikipedia.org/wiki/Rubber-hose_cryptanalysis rubber-hose cryptanalysis] to get to the encrypted data.</div>Krinhttps://wiki.archlinux.org/index.php?title=User:Krin/Secure_Boot,_full_disk_encryption,_and_TPM2_unlocking_install&diff=701274User:Krin/Secure Boot, full disk encryption, and TPM2 unlocking install2021-11-08T02:24:06Z<p>Krin: Fix typo.</p>
<hr />
<div>{{Unsupported|1 October 2021}}<br />
<br />
== Introduction ==<br />
<br />
This installation is based on my installing Arch on an Asus ROG Strix G G531 I got second hand and a desktop computer made of second hand parts that had to share space with Windows. The primary goals were to replace Windows 10 Pro with Bitlocker encryption and maintain the convienence and security balance of that original operating system.<br />
<br />
My requirements boiled down to:<br />
<br />
* A fully encrypted disk<br />
* Full Secure Boot validation of all UEFI components.<br />
* Use of the TPM to facilitate unlocking of the disk.<br />
* Hibernate/Suspend working.<br />
<br />
My primary use case here is to make it difficult enough for a baggage handler with sticky hands to get at my data that they just wipe the drive. A state level actor with the expertise and equipment to hot swap my ram in my hotel room is not something that I'm defending this ''particular'' laptop against. This is more for gaming and web browsing and uploading photos while traveling.<br />
<br />
I'll continue to update these notes as I develop further solutions.<br />
<br />
== Disclaimers ==<br />
<br />
This article is primarily for the author's own notes. It is assumed that the reader is familiar with the [[Installation guide]] and will refer to it often. Reading linked articles is recommended.<br />
<br />
== Dual Booting Modifications ==<br />
<br />
{{warning|If you use BitLocker on your Windows drive, ensure you have your recovery key handy. The installation process will change your TPM measurements causing Windows to require you enter the key manually the next time you boot it.}}<br />
<br />
For computers that will have to dual boot with windows, the easiest solution is to use two different physical drives and utilize your motherboard's UEFI boot menu to select which one to boot. This guide will follow that assumption. You can also attempt to have everything live on one EFI partition. Windows's 100 MiB EFI partition is especially problematic to this approach for secure boot, as Unified Kernel Images can approach 80 MiB and Windows 10 regularly uses up to 30 MiB. An alternative is to copy the Microsoft bootloader into your Linux EFI bootloader and then prioritize the Linux EFI disk over your Windows disk. You will want to copy the directory {{ic|WINDOWS_EFI_PARITION/EFI/Microsoft}} to the same location on your Linux EFI partition. Anytime Microsoft updates the bootloader, you will need to copy the Microsoft EFI folder again.<br />
<br />
There are two changes that will be made and will be noted in the relevant sections:<br />
<br />
* Do not clear your Secure Boot keys. Merely disable Secure Boot for the installation.<br />
* Use {{ic|shim}} to boot systemd-bootloader<br />
* Load your db.cer file into the MOKManager application.<br />
<br />
All remaining steps should remain the same, except your system will still be dependent on the factory provided Microsoft Certificates. But you can boot Windows 10 in Secure Boot, which will be important for Windows 11.<br />
<br />
== Initial setup ==<br />
<br />
=== Pre-installation ===<br />
<br />
If you will only boot linux, reset your Secure Boot settings in BIOS to enable setup mode. Usually this means you set Secure Boot to Enabled and then select the option to wipe out the keys.<br />
<br />
If you will be dual booting Windows, disable secure boot.<br />
<br />
Follow the [[Installation_guide#Pre-installation]] up to Paritioning the Disks.<br />
<br />
=== Disk preparation ===<br />
<br />
If you have data on your disks you want to overwrite, utilize [[Dm-crypt/Drive_preparation#dm-crypt_wipe_on_an_empty_disk_or_partition]] to wipe it. If this disk was previously encrypted, utilize [[Dm-crypt/Drive_preparation#Wipe_LUKS_header]] instead for a much faster disposal. Finally, use [[Dm-crypt/Encrypting_an_entire_system#LVM_on_LUKS]] to parition your drive with two differences.<br />
<br />
{{tip|Using a memorable LUKS passphrase until you've completed the install process can be helpful. It will take several reboots to finish setup.}}<br />
<br />
First, the partition layout will be similar to here. You may wish to break out the /home directory into it's own partition. The primary requirement is that only your EFI partition be unencrypted.<br />
<br />
{{hc|Partiton Layout|<br />
┌────────────────────┬─────────────────────────┬──────────────────────────┬───────────────────────────┐<br />
│ │ │ │ │<br />
│ EFI Boot Partition │ Logical Volume 1 │ Logical Volume 2 │ Logical Volume 3 │<br />
│ /efi │ [Swap] │ / │ /home │<br />
│ /dev/nvme0n1p1 │ /dev/CryptRootVG/swap │ /dev/CryptRootVG/root │ /dev/CryptRootVG/home │<br />
│ 512 MB │ 16GB (Or RAM Size) │ 50 GB │ Remaining Space │<br />
│ │ │ │ │<br />
│ ├─────────────────────────┴──────────────────────────┴───────────────────────────┤<br />
│ │ LUKS and LVM Physical Volume │<br />
│ │ /dev/nvme0n1p2 │<br />
│ │ │<br />
│ │ │<br />
│ │ │<br />
│ │ │<br />
└────────────────────┴────────────────────────────────────────────────────────────────────────────────┘<br />
}}<br />
<br />
Second, if your hard drive is an SSD, use the following command to open your LUKS volume.<br />
<br />
# cryptsetup open --perf-no_read_workqueue --perf-no_write_workqueue --persistent /dev/nvme0n1p2 cryptroot<br />
<br />
After completing your LUKS on LVM setup, format your EFI partition per [[EFI system partition]].<br />
<br />
# mkfs.fat -F32 /dev/nvme0n1p1<br />
<br />
Mount this partition at {{ic|/mnt/efi}}. It is very important to leave {{ic|/boot}} on your encrypted root partition.<br />
<br />
== Installation ==<br />
<br />
Continue with [[Installation_guide#Installation]]. Be sure to flesh out your {{man|8|pacstrap}} with the following list of packages:<br />
<br />
* {{Pkg|dracut}}<br />
* {{Pkg|intel-ucode}}<br />
* {{Pkg|lvm2}}<br />
* {{Pkg|openssh}}<br />
* {{Pkg|ansible}}<br />
* {{Pkg|git}}<br />
* {{Pkg|iwd}}<br />
* {{Pkg|efibootmgr}}<br />
<br />
<br />
We are going to leave off the installation guide at the initramfs section, so go ahead and reset your root password. <br />
<br />
# passwd<br />
<br />
=== Bootloader ===<br />
<br />
First, install {{ic|systemd-boot}} by following [[Systemd-boot#Installing_the_EFI_boot_manager]]. Next, install {{aur|dracut-hook-uefi}}.<br />
<br />
Ensure you drop in a systemd-boot hook to update your bootctl any time it's updated.<br />
<br />
{{hc|/etc/pacman.d/hooks/998-systemd-boot.hook|2=<br />
[Trigger]<br />
Type = Package<br />
Operation = Install<br />
Operation = Upgrade<br />
Target = systemd<br />
<br />
[Action]<br />
Description = Updating systemd-boot<br />
When = PostTransaction<br />
Exec = /usr/bin/bootctl update; <br />
}}<br />
<br />
Obtain the UUID of your LUKS drive via the following command:<br />
<br />
{{bc|<br />
blkid -s UUID -o value /dev/nvme0n1p2<br />
}}<br />
<br />
Create the following files with the listed content. Be sure to replace UUIDs with what you actually need. See {{man|5|dracut.conf}} for more information on what these commands do.<br />
<br />
A good portion of the kernel command line was as generated by dracut. Many are extraneous or you may wish to change some of the block device names.<br />
<br />
{{hc|/etc/dracut.conf.d/cmdline.conf|2=<br />
kernel_cmdline="rd.luks.uuid=luks-17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02 rd.lvm.lv=CryptRoot/root rd.lvm.lv=CryptRoot/swap resume=/dev/mapper/CryptRoot-swap root=/dev/mapper/CryptRoot-root rootfstype=ext4 rootflags=rw,relatime"<br />
}}<br />
<br />
{{hc|/etc/dracut.conf.d/flags.conf|2=<br />
compress="zstd"<br />
hostonly="yes"<br />
}}<br />
<br />
Run the following command to generate your EFI stub kernels.<br />
<br />
dracut --uefi<br />
<br />
=== Secure boot ===<br />
<br />
==== Dual Booting Windows ====<br />
<br />
{{warning|This section is still being written}}<br />
<br />
Review [[Unified Extensible Firmware Interface/Secure Boot#shim]] to get a rough understanding of how it's going to work. Install {{aur|shim-signed}}. Perform the following commands to place files where both the UEFI boot entry and shim will load them.<br />
<br />
# mv /efi/EFI/BOOT/BOOTx64.EFI /efi/EFI/BOOT/grubx64.efi<br />
# cp /usr/share/shim-signed/shimx64.efi esp/EFI/BOOT/BOOTx64.EFI<br />
# cp /usr/share/shim-signed/mmx64.efi esp/EFI/BOOT/<br />
<br />
Install {{Pkg|sbctl}}. Use the following command to check that secure boot is in the right status. Your output should be similar.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✘ Sbctl is not installed<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/BOOT/grubx64.efi is not signed<br />
<br />
✘ /efi/EFI/BOOT/mmx64.efi is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
}}<br />
<br />
Note that shim and MOKManager (mmx) is included in this list, even though we will not be signing it.<br />
<br />
{{bc|<br />
# sbctl sign -s /efi/EFI/BOOT/ grubx64.efi <br />
<br />
✔ Signed /efi/EFI/BOOT/grubx64.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi <br />
<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi <br />
<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi<br />
# sbctl verify<br />
<br />
Verifying file database and EFI images in /efi...<br />
✔� /efi/EFI/BOOT/grubx64.efi is signed<br />
✔ /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi is signed<br />
✔ /efi/EFI/systemd/systemd-bootx64.efi is signed<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/BOOT/mmx64.efi is not signed<br />
}}<br />
<br />
You can validate that {{ic|BOOTx64.EFI}} and {{ic|mmx64.efi}} have signatures with {{man|1|sbverify}} from the {{Pkg|sbsigntools}} package.<br />
<br />
Next, we need to create the DER format certificate to load into ''MokManager''.<br />
<br />
# openssl x509 -outform DER -in /usr/share/secureboot/keys/db/db.pem -out /efi/signing.cer<br />
<br />
Use {{Pkg|efibootmgr}} ({{man|8|efibootmgr}}) to adjust your boot entries. Primarily, you will want to remove the {{ic|Linux Boot Manager}} entry.<br />
<br />
{{bc|<br />
# efibootmgr<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0001,0000,0002,0003,0004<br />
Boot0000* Windows Boot Manager<br />
Boot0001* Linux Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
}}<br />
<br />
In this example, we see that {{ic|0000}} is the Windows boot manager. {{ic|0001}} is the Linux Boot Manager and also the first in line to boot. {{ic|0001}} needs to be deleted and optionally the boot order modified so {{ic|0004}} is the default boot entry.<br />
<br />
{{bc|<br />
# efibootmgr --bootnum 0001 --delete-bootnum<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0000,0002,0003,0004<br />
Boot0000* Windows Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
<br />
# efibootmgr --bootorder 0004,0000,0002,0003<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0004,0000,0002,0003<br />
Boot0000* Windows Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Now reboot. You should get an error from your motherboard's UEFI BIOS that secure boot checks failed. Your computer should restart directly into ''MokManager'', if you rearranged the boot order. If not, you will need to select {{ic|UEFI OS}} from your UEFI boot menu. Navigate to the {{ic|signing.cer}} file we placed on the EFI partition and enroll the key. Select reboot, and the system should boot directly into linux with no problem.<br />
<br />
==== Booting only Linux ====<br />
<br />
{{note|Credit to this [https://lunaryorn.com/secure-boot-on-arch-linux-with-sbctl-and-dracut blog post by lunaryorn] for the inspiration.}}<br />
<br />
Install {{Pkg|sbctl}}. At this point you will likely need to reboot and adjust your secure boot settings. You want secure boot in '''setup mode'''. <br />
<br />
{{bc|<br />
$ sbctl status<br />
Installed: X Sbctl is not installed<br />
Setup Mode: X Enabled<br />
Secure Boot: X Disabled<br />
}}<br />
<br />
Run the following commands as root. See {{man|8|sbctl}} for more information on their function. Of particular note is the {{ic|-s}} flag which indicates {{ic|sbctl}} should remember the file for future verification and signing.<br />
<br />
Note your Linux EFI binary name may be slightly different.<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
<br />
# sbctl sign -s /efi/EFI/BOOT/BOOTx64.EFI<br />
✔ Signed /efi/EFI/BOOT/BOOTx64.EFI<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Finally, enroll the Secure Boot keys.<br />
<br />
{{bc|<br />
# sbctl enroll-keys<br />
Enrolling keys to EFI variables...✔<br />
Enrolled keys to the EFI variables!<br />
}}<br />
<br />
Verify that secure boot now has an owner GUID and setup mode is disabled.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✔ Sbctl is installed<br />
Owner GUID: a2ee3d08-725a-408b-9d95-28026a44611c<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
Now reboot. This reboot is required so we can get the TPM measurements into their (hopefully) permanent state.<br />
<br />
=== Enroll LUKS key in TPM ===<br />
{{warning|Yes, this will cause a system to automatically unlock it's encrypted root volume without any interaction from a human. Yes, this exposes it to any sufficently advanced Evil Maid attacks. If sealed against the appropriate registers (especially register 8 with the kernel arguments), the TPM measurements should force systemd to ask for your LUKS passphrase in almost any attempt to access the encrypted volume from outside your normal boot process.}}<br />
<br />
We are fortunate that in our shift to dracut includes utilizing systemd and sd-encrypt, as we can use systemd's native support for enrolling LUKS keys. A review of [[Trusted Platform Module#Using TPM 2.0]] is recommended but not very clear.<br />
<br />
==== Avoid dracut bugs ====<br />
<br />
Subtitle: The Case of the Missing {{ic|d}}<br />
<br />
Two bugs, one in systemd 249.4-1-arch [https://github.com/systemd/systemd/issues/19177] and one in dracut 055 [https://github.com/dracutdevs/dracut/pull/1526][https://github.com/dracutdevs/dracut/issues/1542] will combine to prevent your system from being able to boot. The dracut issue causes the '''tpm2-tss''' module to not be included in your image. The systemd issue causes systemd to go into an emergency when it can't locate the TPM2 libraries, instead of falling back to asking for your passcode.<br />
<br />
The systemd bug isn't a problem so long as you always have TPM2 libraries present.<br />
<br />
To resolve this, first check your version of dracut.<br />
<br />
{{bc|<br />
$ dracut --version<br />
dracut 055<br />
}}<br />
<br />
Since the next release of dracut should have this fixed, we can simply fix the script locally until the next release.<br />
<br />
{{warning|These steps are only necessary for dracut 055}}<br />
<br />
Find the following lines in {{ic|/usr/lib/dracut/modules.d/91tpm2-tss/module-setup.sh}}:<br />
<br />
{{bc|1=<br />
# Module dependency requirements.<br />
depends() {<br />
<br />
# This module has external dependency on other module(s).<br />
echo systemd-sysusers systemd-udev<br />
# Return 0 to include the dependent module(s) in the initramfs.<br />
return 0<br />
<br />
}<br />
}}<br />
<br />
Change the dependency {{ic|systemd-udev}} to <code>systemd-udev<b>d</b></code>.<br />
<br />
Continue with the remaining steps in this section.<br />
<br />
==== Enrollment ====<br />
<br />
First, be sure to install {{Pkg|tpm2-tools}}. Alternatively {{aur|ibm-tss}} can be used per [[Trusted Platform Module]], however this guide is not tested against those.<br />
<br />
{{note|A reboot may be required to convince {{ic|systemd-cryptenroll}} that TPM 2.0 devices now exist on the machine.}}<br />
<br />
There are several decisions to be made here. The table at [[Trusted Platform Module#Accessing PCR registers]] is accurate as of October 2021. Essentially, once you seal your LUKS key, if any of the registers you've sealed against change, then you will be asked for your LUKS passphrase. This is equivalent to when Windows 10 makes you enter your BitLocker recovery key after a hardware change or changing BIOS settings.<br />
<br />
Your mileage may vary, based on UEFI vendors. For my laptop, I went with 0+1+2+3+4+5+7+8 and have been able to invalidate my TPM. Unfortunately, if you change your system BACK the volume will unlock. I'm investigating how to disable that.<br />
<br />
Other options on {{man|1|systemd-cryptenroll}} will reveal that several hardware tokens can also be enrolled to allow unlocking the root LUKS volume automatically, but only if a key is present. Further testing is requried.<br />
<br />
To enroll your LUKS volume, simply run the following command as root<br />
<br />
# systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/nvme0n1p2<br />
<br />
To remove your key, run this command:<br />
<br />
# systemd-cryptenroll --wipe-slot=tpm2 /dev/nvme0n1p2<br />
<br />
You will need to add a kernel argument like below to enable the TPM2 bits. If following this guide, this should be located in {{ic|/etc/dracut.conf.d/cmdline.conf}}<br />
<br />
rd.luks.options={UUID}=tpm2-device=auto<br />
<br />
Ensure that dracut builds in the TPM2 libraries. Create the following file.<br />
<br />
{{hc|/etc/dracut.conf.d/tpm2-tss.conf|2=<br />
add_dracutmodules+=" tpm2-tss "<br />
}}<br />
<br />
Finally, rebuild your unified kernel image.<br />
<br />
# dracut --force --uefi<br />
<br />
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:<br />
<br />
{{hc|~/bin/luks_reenroll_tpm|2=<br />
sudo systemd-cryptenroll --wipe-slot=tpm2 /dev/disk/by-uuid/{UUID_HERE}<br />
systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/disk/by-uuid/{UUID_HERE}<br />
}}<br />
<br />
=== Wrapping up ===<br />
<br />
Set your UEFI password. <br />
<br />
Change your LUKS passphrase from something easily memorable to a good long recovery key.<br />
<br />
Keep both of these pieces of info somewhere safe. This varies depending on your threat model. If we're just talking about Stolen Laptops and Nosy Maids, a hard copy in your safe should be sufficient. If it's the NSA, I'm not sure this setup is appropriate for that model.<br />
<br />
This is an excellent base to handle stolen laptop and even some lower grade Evil Maids. From here, you should head into [[Security]]. Consider learning a framework to help you manage your system state such as [[Ansible]] or headless [[Puppet]].<br />
<br />
== Justifications ==<br />
<br />
=== LVM on LUKS vs other dm-crypt approaches ===<br />
<br />
LVM on LUKS was selected becasue it is simply the easiest to manage while conferring both encrypted swap and disk. The other approaches required much more tooling and manual fussing to utilize. This selection also gives room change freely between {{ic|busybox}} and {{ic|systemd}} initrds.<br />
<br />
=== Using dracut ===<br />
<br />
{{Pkg|dracut}} just makes it easier to build full unified kernels that {{man|7|systemd-boot}} can launch as EFI binaries. There is also available tooling in the [[AUR]] for automating the creation of these binaries. Finally, {{ic|dracut}} will sign the binaries it creates automatically when configured to do so.<br />
<br />
=== Unified kernel images ===<br />
<br />
While UKI's could be problematic on other distributions, they fit right in with an Arch Linux install. The automation is there through pacman hooks and {{Pkg|sbctl}} to sign our UKIs as they're created. Furthermore, you can only sign and create a new signed UKI while booted into a properly signed UKI. It creates a chain of trust, which means it's important to never disable Secure Boot once you've set it up.<br />
<br />
The UKI encompasses all of the following items inside the signature, which means you can't change any of them without invalidating the signature.<br />
<br />
* Kernel arguments<br />
* Initrd/Initramfs<br />
* Kernel<br />
<br />
In particular, all other flavors of secureboot do not sign or validate the initramfs. This is a big attack area and can be relatively trivialized that a semi-decent pawn shop owner with Google could likely find an image that would grant him access and make the TPM none the wiser the system has changed. One can prevent this with encrypted /boot, but that would limit you to GRUB2 and LUKS version 1 devices only. This also doesn't include the work to keep GRUB2's files signed with a PGP key by root.<br />
<br />
=== LUKS enrolled in TPM ===<br />
<br />
The goal here is to only require the passphrase when something spooky happens in your boot path.<br />
<br />
UEFI settings change? Request password.<br />
<br />
Some weird swap of some module of UEFI code that lives on your motherboard somewhere? Request password.<br />
<br />
Unified Kernel Image changes? Don't even boot.<br />
<br />
Drive in another computer? Request password.<br />
<br />
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.<br />
<br />
== Miscellaneous discussions ==<br />
<br />
=== Filesystem Selection ===<br />
<br />
Most examples on Arch utilize {{ic|ext4}}, but other file systems such as {{ic|brtfs}} can work equally well. As for performance or issues with being inside LVM, [https://btrfs.wiki.kernel.org/index.php/FAQ#Btrfs_has_subvolumes.2C_does_this_mean_I_don.27t_need_a_logical_volume_manager_and_I_can_create_a_big_Btrfs_filesystem_on_a_raw_partition.3F this question in the brtfs FAQ] implies that there is some performance loss but no other issues.<br />
<br />
=== LUKS TPM enrollment and managing luks keys ===<br />
<br />
Note that using {{man|1|systemd-cryptenroll}} will add a key to your LUKS volume. It's not clear how exactly the option {{ic|1=--wipe-slot=tpm2}} is able to identify which slot it needs to wipe, but it does. This even works if your TPM has changed.<br />
<br />
You can see the effects by comparing the output of {{ic|cryptsetup luksDump /dev/nvme0n1p2}} before and after you enroll or wipe a TPM based key. You can identify what slot your own passphrase is in with {{ic|cryptsetup --verbose open --test-passphrase /dev/nvme0n1p2}} and entering your passphrase. The output will inform you which key slot was unlocked.<br />
<br />
Finally, your passphrase may be changed with {{ic|cryptsetup luksChangeKey /dev/nvme0n1p2 -S 0}}.<br />
<br />
== Planned TODOs ==<br />
A panic command that can dump the TPM and shutdown the computer (without requiring the time of entering a password in sudo) forcing an adversary to resort to [https://en.wikipedia.org/wiki/Rubber-hose_cryptanalysis rubber-hose cryptanalysis] to get to the encrypted data.</div>Krinhttps://wiki.archlinux.org/index.php?title=User:Krin/Secure_Boot,_full_disk_encryption,_and_TPM2_unlocking_install&diff=701273User:Krin/Secure Boot, full disk encryption, and TPM2 unlocking install2021-11-08T02:23:00Z<p>Krin: Update partition layout to reflect separate root partition.</p>
<hr />
<div>{{Unsupported|1 October 2021}}<br />
<br />
== Introduction ==<br />
<br />
This installation is based on my installing Arch on an Asus ROG Strix G G531 I got second hand and a desktop computer made of second hand parts that had to share space with Windows. The primary goals were to replace Windows 10 Pro with Bitlocker encryption and maintain the convienence and security balance of that original operating system.<br />
<br />
My requirements boiled down to:<br />
<br />
* A fully encrypted disk<br />
* Full Secure Boot validation of all UEFI components.<br />
* Use of the TPM to facilitate unlocking of the disk.<br />
* Hibernate/Suspend working.<br />
<br />
My primary use case here is to make it difficult enough for a baggage handler with sticky hands to get at my data that they just wipe the drive. A state level actor with the expertise and equipment to hot swap my ram in my hotel room is not something that I'm defending this ''particular'' laptop against. This is more for gaming and web browsing and uploading photos while traveling.<br />
<br />
I'll continue to update these notes as I develop further solutions.<br />
<br />
== Disclaimers ==<br />
<br />
This article is primarily for the author's own notes. It is assumed that the reader is familiar with the [[Installation guide]] and will refer to it often. Reading linked articles is recommended.<br />
<br />
== Dual Booting Modifications ==<br />
<br />
{{warning|If you use BitLocker on your Windows drive, ensure you have your recovery key handy. The installation process will change your TPM measurements causing Windows to require you enter the key manually the next time you boot it.}}<br />
<br />
For computers that will have to dual boot with windows, the easiest solution is to use two different physical drives and utilize your motherboard's UEFI boot menu to select which one to boot. This guide will follow that assumption. You can also attempt to have everything live on one EFI partition. Windows's 100 MiB EFI partition is especially problematic to this approach for secure boot, as Unified Kernel Images can approach 80 MiB and Windows 10 regularly uses up to 30 MiB. An alternative is to copy the Microsoft bootloader into your Linux EFI bootloader and then prioritize the Linux EFI disk over your Windows disk. You will want to copy the directory {{ic|WINDOWS_EFI_PARITION/EFI/Microsoft}} to the same location on your Linux EFI partition. Anytime Microsoft updates the bootloader, you will need to copy the Microsoft EFI folder again.<br />
<br />
There are two changes that will be made and will be noted in the relevant sections:<br />
<br />
* Do not clear your Secure Boot keys. Merely disable Secure Boot for the installation.<br />
* Use {{ic|shim}} to boot systemd-bootloader<br />
* Load your db.cer file into the MOKManager application.<br />
<br />
All remaining steps should remain the same, except your system will still be dependent on the factory provided Microsoft Certificates. But you can boot Windows 10 in Secure Boot, which will be important for Windows 11.<br />
<br />
== Initial setup ==<br />
<br />
=== Pre-installation ===<br />
<br />
If you will only boot linux, reset your Secure Boot settings in BIOS to enable setup mode. Usually this means you set Secure Boot to Enabled and then select the option to wipe out the keys.<br />
<br />
If you will be dual booting Windows, disable secure boot.<br />
<br />
Follow the [[Installation_guide#Pre-installation]] up to Paritioning the Disks.<br />
<br />
=== Disk preparation ===<br />
<br />
If you have data on your disks you want to overwrite, utilize [[Dm-crypt/Drive_preparation#dm-crypt_wipe_on_an_empty_disk_or_partition]] to wipe it. If this disk was previously encrypted, utilize [[Dm-crypt/Drive_preparation#Wipe_LUKS_header]] instead for a much faster disposal. Finally, use [[Dm-crypt/Encrypting_an_entire_system#LVM_on_LUKS]] to parition your drive with two differences.<br />
<br />
{{tip|Using a memorable LUKS passphrase until you've completed the install process can be helpful. It will take several reboots to finish setup.}}<br />
<br />
First, the partition layout will be similar to here. You may wish to break out the /home directory into it's own partition. The primary requirement is that only your EFI partition be unencrypted.<br />
<br />
{{hc|Partiton Layout|<br />
┌────────────────────┬─────────────────────────┬──────────────────────────┬───────────────────────────┐<br />
│ │ │ │ │<br />
│ EFI Boot Partition │ Logical Volume 1 │ Logical Volume 2 │ Logical Volume 3 │<br />
│ /efi │ [Swap] │ / │ /home │<br />
│ /dev/nvme0n1p1 │ /dev/CryptRootVG/swap │ /dev/CryptRootVG/root │ /dev/CryptRootVG/home │<br />
│ 512 MB │ 16GB (Or RAM Size) │ 50 GB │ Remaining Space │<br />
│ │ │ │ │<br />
│ ├─────────────────────────┴──────────────────────────┴───────────────────────────┤<br />
│ │ LUKS and LVM Physical Volume │<br />
│ │ /dev/nvme0n1p2 │<br />
│ │ │<br />
│ │ │<br />
│ │ │<br />
│ │ │<br />
└────────────────────┴────────────────────────────────────────────────────────────────────────────────┘<br />
}}<br />
<br />
Second, if your hard drive is an SSD, use the following command to open your LUKS volume.<br />
<br />
# cryptsetup open --perf-no_read_workqueue --perf-no_write_workqueue --persistent /dev/nvme0n1p2 cryptroot<br />
<br />
After completing your LUKS on LVM setup, format your EFI partition per [[EFI system partition]].<br />
<br />
# mkfs.fat -F32 /dev/nvme0n1p1<br />
<br />
Mount this partition at {{ic|/mnt/efi}}. It is very important to leave {{ic|/boot}} on your encrypted root partition.<br />
<br />
== Installation ==<br />
<br />
Continue with [[Installation_guide#Installation]]. Be sure to flesh out your {{man|8|pacstrap}} with the following list of packages:<br />
<br />
* {{Pkg|dracut}}<br />
* {{Pkg|intel-ucode}}<br />
* {{Pkg|lvm2}}<br />
* {{Pkg|openssh}}<br />
* {{Pkg|ansible}}<br />
* {{Pkg|git}}<br />
* {{Pkg|iwd}}<br />
* {{Pkg|efibootmgr}}<br />
<br />
<br />
We are going to leave off the installation guide at the initramfs section, so go ahead and reset your root password. <br />
<br />
# passwd<br />
<br />
=== Bootloader ===<br />
<br />
First, install {{ic|systemd-boot}} by following [[Systemd-boot#Installing_the_EFI_boot_manager]]. Next, install {{aur|dracut-hook-uefi}}.<br />
<br />
Ensure you drop in a systemd-boot hook to update your bootctl any time it's updated.<br />
<br />
{{hc|/etc/pacman.d/hooks/998-systemd-boot.hook|2=<br />
[Trigger]<br />
Type = Package<br />
Operation = Install<br />
Operation = Upgrade<br />
Target = systemd<br />
<br />
[Action]<br />
Description = Updating systemd-boot<br />
When = PostTransaction<br />
Exec = /usr/bin/bootctl update; <br />
}}<br />
<br />
Obtain the UUID of your LUKS drive via the following command:<br />
<br />
{{bc|<br />
blkid -s UUID -o value /dev/nvme0n1p2<br />
}}<br />
<br />
Create the following files with the listed content. Be sure to replace UUIDs with what you actually need. See {{man|5|dracut.conf}} for more information on what these commands do.<br />
<br />
A good portion of the kernel command line was as generated by dracut. Many are extraneous or you may wish to change some of the block device names.<br />
<br />
{{hc|/etc/dracut.conf.d/cmdline.conf|2=<br />
kernel_cmdline="rd.luks.uuid=luks-17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02 rd.lvm.lv=CryptRoot/root rd.lvm.lv=CryptRoot/swap resume=/dev/mapper/CryptRoot-swap root=/dev/mapper/CryptRoot-root rootfstype=ext4 rootflags=rw,relatime"<br />
}}<br />
<br />
{{hc|/etc/dracut.conf.d/flags.conf|2=<br />
compress="zstd"<br />
hostonly="yes"<br />
}}<br />
<br />
Run the following command to generate your EFI stub kernels.<br />
<br />
dracut --uefi<br />
<br />
=== Secure boot ===<br />
<br />
==== Dual Booting Windows ====<br />
<br />
{{warning|This section is still being written}}<br />
<br />
Review [[Unified Extensible Firmware Interface/Secure Boot#shim]] to get a rough understanding of how it's going to work. Install {{aur|shim-signed}}. Perform the following commands to place files where both the UEFI boot entry and shim will load them.<br />
<br />
# mv /efi/EFI/BOOT/BOOTx64.EFI /efi/EFI/BOOT/grubx64.efi<br />
# cp /usr/share/shim-signed/shimx64.efi esp/EFI/BOOT/BOOTx64.EFI<br />
# cp /usr/share/shim-signed/mmx64.efi esp/EFI/BOOT/<br />
<br />
Install {{Pkg|sbctl}}. Use the following command to check that secure boot is in the right status. Your output should be similar.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✘ Sbctl is not installed<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/BOOT/grubx64.efi is not signed<br />
<br />
✘ /efi/EFI/BOOT/mmx64.efi is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
}}<br />
<br />
Note that shim and MOKManager (mmx) is included in this list, even though we will not be signing it.<br />
<br />
{{bc|<br />
# sbctl sign -s /efi/EFI/BOOT/ grubx64.efi <br />
<br />
✔ Signed /efi/EFI/BOOT/grubx64.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi <br />
<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi <br />
<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi<br />
# sbctl verify<br />
<br />
Verifying file database and EFI images in /efi...<br />
✔� /efi/EFI/BOOT/grubx64.efi is signed<br />
✔ /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi is signed<br />
✔ /efi/EFI/systemd/systemd-bootx64.efi is signed<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/BOOT/mmx64.efi is not signed<br />
}}<br />
<br />
You can validate that {{ic|BOOTx64.EFI}} and {{ic|mmx64.efi}} have signatures with {{man|1|sbverify}} from the {{Pkg|sbsigntools}} package.<br />
<br />
Next, we need to create the DER format certificate to load into ''MokManager''.<br />
<br />
# openssl x509 -outform DER -in /usr/share/secureboot/keys/db/db.pem -out /efi/signing.cer<br />
<br />
Use {{Pkg|efibootmgr}} ({{man|8|efibootmgr}}) to adjust your boot entries. Primarily, you will want to remove the {{ic|Linux Boot Manager}} entry.<br />
<br />
{{bc|<br />
# efibootmgr<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0001,0000,0002,0003,0004<br />
Boot0000* Windows Boot Manager<br />
Boot0001* Linux Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
}}<br />
<br />
In this example, we see that {{ic|0000}} is the Windows boot manager. {{ic|0001}} is the Linux Boot Manager and also the first in line to boot. {{ic|0001}} needs to be deleted and optionally the boot order modified so {{ic|0004}} is the default boot entry.<br />
<br />
{{bc|<br />
# efibootmgr --bootnum 0001 --delete-bootnum<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0000,0002,0003,0004<br />
Boot0000* Windows Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
<br />
# efibootmgr --bootorder 0004,0000,0002,0003<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0004,0000,0002,0003<br />
Boot0000* Windows Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Now reboot. You should get an error from your motherboard's UEFI BIOS that secure boot checks failed. Your computer should restart directly into ''MokManager'', if you rearranged the boot order. If not, you will need to select {{ic|UEFI OS}} from your UEFI boot menu. Navigate to the {{ic|signing.cer}} file we placed on the EFI partition and enroll the key. Select reboot, and the system should boot directly into linux with no problem.<br />
<br />
==== Booting only Linux ====<br />
<br />
{{note|Credit to this [https://lunaryorn.com/secure-boot-on-arch-linux-with-sbctl-and-dracut blog post by lunaryorn] for the inspiration.}}<br />
<br />
Install {{Pkg|sbctl}}. At this point you will likely need to reboot and adjust your secure boot settings. You want secure boot in '''setup mode'''. <br />
<br />
{{bc|<br />
$ sbctl status<br />
Installed: X Sbctl is not installed<br />
Setup Mode: X Enabled<br />
Secure Boot: X Disabled<br />
}}<br />
<br />
Run the following commands as root. See {{man|8|sbctl}} for more information on their function. Of particular note is the {{ic|-s}} flag which indicates {{ic|sbctl}} should remember the file for future verification and signing.<br />
<br />
Note your Linux EFI binary name may be slightly different.<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
<br />
# sbctl sign -s /efi/EFI/BOOT/BOOTx64.EFI<br />
✔ Signed /efi/EFI/BOOT/BOOTx64.EFI<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Finally, enroll the Secure Boot keys.<br />
<br />
{{bc|<br />
# sbctl enroll-keys<br />
Enrolling keys to EFI variables...✔<br />
Enrolled keys to the EFI variables!<br />
}}<br />
<br />
Verify that secure boot now has an owner GUID and setup mode is disabled.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✔ Sbctl is installed<br />
Owner GUID: a2ee3d08-725a-408b-9d95-28026a44611c<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
Now reboot. This reboot is required so we can get the TPM measurements into their (hopefully) permanent state.<br />
<br />
=== Enroll LUKS key in TPM ===<br />
{{warning|Yes, this will cause a system to automatically unlock it's encrypted root volume without any interaction from a human. Yes, this exposes it to any sufficently advanced Evil Maid attacks. If sealed against the appropriate registers (especially register 8 with the kernel arguments), the TPM measurements should force systemd to ask for your LUKS passphrase in almost any attempt to access the encrypted volume from outside your normal boot process.}}<br />
<br />
We are fortunate that in our shift to dracut includes utilizing systemd and sd-encrypt, as we can use systemd's native support for enrolling LUKS keys. A review of [[Trusted Platform Module#Using TPM 2.0]] is recommended but not very clear.<br />
<br />
==== Avoid dracut bugs ====<br />
<br />
Subtitle: The Case of the Missing {{ic|d}}<br />
<br />
Two bugs, one in systemd 249.4-1-arch [https://github.com/systemd/systemd/issues/19177] and one in dracut 055 [https://github.com/dracutdevs/dracut/pull/1526][https://github.com/dracutdevs/dracut/issues/1542] will combine to prevent your system from being able to boot. The dracut issue causes the '''tpm2-tss''' module to not be included in your image. The systemd issue causes systemd to go into an emergency when it can't locate the TPM2 libraries, instead of falling back to asking for your passcode.<br />
<br />
The systemd bug isn't a problem so long as you always have TPM2 libraries present.<br />
<br />
To resolve this, first check your version of dracut.<br />
<br />
{{bc|<br />
$ dracut --version<br />
dracut 055<br />
}}<br />
<br />
Since the next release of dracut should have this fixed, we can simply fix the script locally until the next release.<br />
<br />
{{warning|These steps are only necessary for dracut 055}}<br />
<br />
Find the following lines in {{ic|/usr/lib/dracut/modules.d/91tpm2-tss/module-setup.sh}}:<br />
<br />
{{bc|1=<br />
# Module dependency requirements.<br />
depends() {<br />
<br />
# This module has external dependency on other module(s).<br />
echo systemd-sysusers systemd-udev<br />
# Return 0 to include the dependent module(s) in the initramfs.<br />
return 0<br />
<br />
}<br />
}}<br />
<br />
Change the dependency {{ic|systemd-udev}} to <code>systemd-udev<b>d</b></code>.<br />
<br />
Continue with the remaining steps in this section.<br />
<br />
==== Enrollment ====<br />
<br />
First, be sure to install {{Pkg|tpm2-tools}}. Alternatively {{aur|ibm-tss}} can be used per [[Trusted Platform Module]], however this guide is not tested against those.<br />
<br />
{{note|A reboot may be required to convince {{ic|systemd-cryptenroll}} that TPM 2.0 devices now exist on the machine.}}<br />
<br />
There are several decisions to be made here. The table at [[Trusted Platform Module#Accessing PCR registers]] is accurate as of October 2021. Essentially, once you seal your LUKS key, if any of the registers you've sealed against change, then you will be asked for your LUKS passphrase. This is equivalent to when Windows 10 makes you enter your BitLocker recovery key after a hardware change or changing BIOS settings.<br />
<br />
Your mileage may vary, based on UEFI vendors. For my laptop, I went with 0+1+2+3+4+5+7+8 and have been able to invalidate my TPM. Unfortunately, if you change your system BACK the volume will unlock. I'm investigating how to disable that.<br />
<br />
Other options on {{man|1|systemd-cryptenroll}} will reveal that several hardware tokens can also be enrolled to allow unlocking the root LUKS volume automatically, but only if a key is present. Further testing is requried.<br />
<br />
To enroll your LUKS volume, simply run the following command as root<br />
<br />
# systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/nvme0n1p2<br />
<br />
To remove your key, run this command:<br />
<br />
# systemd-cryptenroll --wipe-slot=tpm2 /dev/nvme0n1p2<br />
<br />
You will need to add a kernel argument like below to enable the TPM2 bits. If following this guide, this should be located in {{ic|/etc/dracut.conf.d/cmdline.conf}}<br />
<br />
rd.luks.options={UUID}=tpm2-device=auto<br />
<br />
Ensure that dracut builds in the TPM2 libraries. Create the following file.<br />
<br />
{{hc|/etc/dracut.conf.d/tpm2-tss.conf|2=<br />
add_dracutmodules+=" tpm2-tss "<br />
}}<br />
<br />
Finally, rebuild your unified kernel image.<br />
<br />
# dracut --force --uefi<br />
<br />
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:<br />
<br />
{{hc|~/bin/luks_reenroll_tpm|2=<br />
sudo systemd-cryptenroll --wipe-slot=tpm2 /dev/disk/by-uuid/{UUID_HERE}<br />
systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/disk/by-uuid/{UUID_HERE}<br />
}}<br />
<br />
=== Wrapping up ===<br />
<br />
Set your UEFI password. <br />
<br />
Change your LUKS passphrase from something easily memorable to a good long recovery key.<br />
<br />
Keep both of these pieces of info somewhere safe. This varies depending on your threat model. If we're just talking about Stolen Laptops and Nosy Maids, a hard copy in your safe should be sufficient. If it's the NSA, I'm not sure this setup is appropriate for that model.<br />
<br />
This is an excellent base to handle stolen laptop and even some lower grade Evil Maids. From here, you should head into [[Security]]. Consider learning a framework to help you manage your system state such as [[Ansible]] or headless [[Puppet]].<br />
<br />
== Justifications ==<br />
<br />
=== LVM on LUKS vs other dm-crypt approaches ===<br />
<br />
LVM on LUKS was selected becasue it is simply the easiest to manage while conferring both encrypted swap and disk. The other approaches required much more tooling and manual fussing to utilize. This selection also gives room change freely between {{ic|busybox}} and {{ic|systemd}} initrds.<br />
<br />
=== Using dracut ===<br />
<br />
{{Pkg|dracut}} just makes it easier to build full unified kernels that {{man|7|systemd-boot}} can launch as EFI binaries. There is also available tooling in the [[AUR]] for automating the creation of these binaries. Finally, {{ic|dracut}} will sign the binaries it creates automatically when configured to do so.<br />
<br />
=== Unified kernel images ===<br />
<br />
While UKI's could be problematic on other distributions, they fit right in with an Arch Linux install. The automation is there through pacman hooks and {{Pkg|sbctl}} to sign our UKIs as they're created. Furthermore, you can only sign and create a new signed UKI while booted into a properly signed UKI. It creates a chain of trust, which means it's important to never disable Secure Boot once you've set it up.<br />
<br />
The UKI encompasses all of the following items inside the signature, which means you can't change any of them without invalidating the signature.<br />
<br />
* Kernel arguments<br />
* Initrd/Initramfs<br />
* Kernel<br />
<br />
In particular, all other flavors of secureboot do not sign or validate the initramfs. This is a big attack area and can be relatively trivialized that a semi-decent pawn shop owner with Google could likely find an image that would grant him access and make the TPM none the wiser the system has changed. One can prevent this with encrypted /boot, but that would limit you to GRUB2 and LUKS version 1 devices only. This also doesn't include the work to keep GRUB2's files signed with a PGP key by root.<br />
<br />
=== LUKS enrolled in TPM ===<br />
<br />
The goal here is to only require the passphrase when something spooky happens in your boot path.<br />
<br />
UEFI settings change? Request password.<br />
<br />
Some weird swap of some module of UEFI code that lives on your motherboard somewhere? Request password.<br />
<br />
Unified Kernel Image changes? Don't even boot.<br />
<br />
Drive in another computer? Request password.<br />
<br />
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.<br />
<br />
== Miscellaneous discussions ==<br />
<br />
=== Filesystem Selection ===<br />
<br />
Most examples on Arch utilize {{ic|ext4}}, but other file systems such as {{ic|brtfs}} can work equally well. As for performance or issues with being inside LVM, [https://btrfs.wiki.kernel.org/index.php/FAQ#Btrfs_has_subvolumes.2C_does_this_mean_I_don.27t_need_a_logical_volume_manager_and_I_can_create_a_big_Btrfs_filesystem_on_a_raw_partition.3F this question in the brtfs FAQ] implie that there is some performance loss but no other issues.<br />
<br />
=== LUKS TPM enrollment and managing luks keys ===<br />
<br />
Note that using {{man|1|systemd-cryptenroll}} will add a key to your LUKS volume. It's not clear how exactly the option {{ic|1=--wipe-slot=tpm2}} is able to identify which slot it needs to wipe, but it does. This even works if your TPM has changed.<br />
<br />
You can see the effects by comparing the output of {{ic|cryptsetup luksDump /dev/nvme0n1p2}} before and after you enroll or wipe a TPM based key. You can identify what slot your own passphrase is in with {{ic|cryptsetup --verbose open --test-passphrase /dev/nvme0n1p2}} and entering your passphrase. The output will inform you which key slot was unlocked.<br />
<br />
Finally, your passphrase may be changed with {{ic|cryptsetup luksChangeKey /dev/nvme0n1p2 -S 0}}.<br />
<br />
== Planned TODOs ==<br />
A panic command that can dump the TPM and shutdown the computer (without requiring the time of entering a password in sudo) forcing an adversary to resort to [https://en.wikipedia.org/wiki/Rubber-hose_cryptanalysis rubber-hose cryptanalysis] to get to the encrypted data.</div>Krinhttps://wiki.archlinux.org/index.php?title=User:Krin/Secure_Boot,_full_disk_encryption,_and_TPM2_unlocking_install&diff=701272User:Krin/Secure Boot, full disk encryption, and TPM2 unlocking install2021-11-08T02:20:46Z<p>Krin: Expand paragraph on dual boot to match current usage on desktop.</p>
<hr />
<div>{{Unsupported|1 October 2021}}<br />
<br />
== Introduction ==<br />
<br />
This installation is based on my installing Arch on an Asus ROG Strix G G531 I got second hand and a desktop computer made of second hand parts that had to share space with Windows. The primary goals were to replace Windows 10 Pro with Bitlocker encryption and maintain the convienence and security balance of that original operating system.<br />
<br />
My requirements boiled down to:<br />
<br />
* A fully encrypted disk<br />
* Full Secure Boot validation of all UEFI components.<br />
* Use of the TPM to facilitate unlocking of the disk.<br />
* Hibernate/Suspend working.<br />
<br />
My primary use case here is to make it difficult enough for a baggage handler with sticky hands to get at my data that they just wipe the drive. A state level actor with the expertise and equipment to hot swap my ram in my hotel room is not something that I'm defending this ''particular'' laptop against. This is more for gaming and web browsing and uploading photos while traveling.<br />
<br />
I'll continue to update these notes as I develop further solutions.<br />
<br />
== Disclaimers ==<br />
<br />
This article is primarily for the author's own notes. It is assumed that the reader is familiar with the [[Installation guide]] and will refer to it often. Reading linked articles is recommended.<br />
<br />
== Dual Booting Modifications ==<br />
<br />
{{warning|If you use BitLocker on your Windows drive, ensure you have your recovery key handy. The installation process will change your TPM measurements causing Windows to require you enter the key manually the next time you boot it.}}<br />
<br />
For computers that will have to dual boot with windows, the easiest solution is to use two different physical drives and utilize your motherboard's UEFI boot menu to select which one to boot. This guide will follow that assumption. You can also attempt to have everything live on one EFI partition. Windows's 100 MiB EFI partition is especially problematic to this approach for secure boot, as Unified Kernel Images can approach 80 MiB and Windows 10 regularly uses up to 30 MiB. An alternative is to copy the Microsoft bootloader into your Linux EFI bootloader and then prioritize the Linux EFI disk over your Windows disk. You will want to copy the directory {{ic|WINDOWS_EFI_PARITION/EFI/Microsoft}} to the same location on your Linux EFI partition. Anytime Microsoft updates the bootloader, you will need to copy the Microsoft EFI folder again.<br />
<br />
There are two changes that will be made and will be noted in the relevant sections:<br />
<br />
* Do not clear your Secure Boot keys. Merely disable Secure Boot for the installation.<br />
* Use {{ic|shim}} to boot systemd-bootloader<br />
* Load your db.cer file into the MOKManager application.<br />
<br />
All remaining steps should remain the same, except your system will still be dependent on the factory provided Microsoft Certificates. But you can boot Windows 10 in Secure Boot, which will be important for Windows 11.<br />
<br />
== Initial setup ==<br />
<br />
=== Pre-installation ===<br />
<br />
If you will only boot linux, reset your Secure Boot settings in BIOS to enable setup mode. Usually this means you set Secure Boot to Enabled and then select the option to wipe out the keys.<br />
<br />
If you will be dual booting Windows, disable secure boot.<br />
<br />
Follow the [[Installation_guide#Pre-installation]] up to Paritioning the Disks.<br />
<br />
=== Disk preparation ===<br />
<br />
If you have data on your disks you want to overwrite, utilize [[Dm-crypt/Drive_preparation#dm-crypt_wipe_on_an_empty_disk_or_partition]] to wipe it. If this disk was previously encrypted, utilize [[Dm-crypt/Drive_preparation#Wipe_LUKS_header]] instead for a much faster disposal. Finally, use [[Dm-crypt/Encrypting_an_entire_system#LVM_on_LUKS]] to parition your drive with two differences.<br />
<br />
{{tip|Using a memorable LUKS passphrase until you've completed the install process can be helpful. It will take several reboots to finish setup.}}<br />
<br />
First, the partition layout will be similar to here. You may wish to break out the /home directory into it's own partition. The primary requirement is that only your EFI partition be unencrypted.<br />
<br />
{{hc|Partiton Layout|<br />
┌────────────────────┬──────────────────────────┬─────────────────────────────┐<br />
│ │ │ │<br />
│ EFI Boot Partition │ Logical Volume 1 │ Logical Volume 2 │<br />
│ │ │ │<br />
│ /efi │ [SWAP] │ / │<br />
│ │ │ │<br />
│ /dev/nvme0n1p1 │ /dev/CryptRootVG/swap │ /dev/CryptRootVG/root │<br />
│ │ │ │<br />
│ 512 MB │ 16 GB (Or RAM size) │ Remaining Free Space │<br />
│ │ │ │<br />
│ │ │ │<br />
│ ├──────────────────────────┴─────────────────────────────┤<br />
│ │ │<br />
│ │ LUKS and LVM Physical Volume │<br />
│ │ │<br />
│ │ /dev/nvme0n1p2 │<br />
│ │ │<br />
└────────────────────┴────────────────────────────────────────────────────────┘<br />
}}<br />
<br />
Second, if your hard drive is an SSD like this laptop, use the following command to open your LUKS volume.<br />
<br />
# cryptsetup open --perf-no_read_workqueue --perf-no_write_workqueue --persistent /dev/nvme0n1p2 cryptroot<br />
<br />
After completing your LUKS on LVM setup, format your EFI partition per [[EFI system partition]].<br />
<br />
# mkfs.fat -F32 /dev/nvme0n1p1<br />
<br />
Mount this partition at {{ic|/mnt/efi}}. It is very important to leave {{ic|/boot}} on your encrypted root partition.<br />
<br />
== Installation ==<br />
<br />
Continue with [[Installation_guide#Installation]]. Be sure to flesh out your {{man|8|pacstrap}} with the following list of packages:<br />
<br />
* {{Pkg|dracut}}<br />
* {{Pkg|intel-ucode}}<br />
* {{Pkg|lvm2}}<br />
* {{Pkg|openssh}}<br />
* {{Pkg|ansible}}<br />
* {{Pkg|git}}<br />
* {{Pkg|iwd}}<br />
* {{Pkg|efibootmgr}}<br />
<br />
<br />
We are going to leave off the installation guide at the initramfs section, so go ahead and reset your root password. <br />
<br />
# passwd<br />
<br />
=== Bootloader ===<br />
<br />
First, install {{ic|systemd-boot}} by following [[Systemd-boot#Installing_the_EFI_boot_manager]]. Next, install {{aur|dracut-hook-uefi}}.<br />
<br />
Ensure you drop in a systemd-boot hook to update your bootctl any time it's updated.<br />
<br />
{{hc|/etc/pacman.d/hooks/998-systemd-boot.hook|2=<br />
[Trigger]<br />
Type = Package<br />
Operation = Install<br />
Operation = Upgrade<br />
Target = systemd<br />
<br />
[Action]<br />
Description = Updating systemd-boot<br />
When = PostTransaction<br />
Exec = /usr/bin/bootctl update; <br />
}}<br />
<br />
Obtain the UUID of your LUKS drive via the following command:<br />
<br />
{{bc|<br />
blkid -s UUID -o value /dev/nvme0n1p2<br />
}}<br />
<br />
Create the following files with the listed content. Be sure to replace UUIDs with what you actually need. See {{man|5|dracut.conf}} for more information on what these commands do.<br />
<br />
A good portion of the kernel command line was as generated by dracut. Many are extraneous or you may wish to change some of the block device names.<br />
<br />
{{hc|/etc/dracut.conf.d/cmdline.conf|2=<br />
kernel_cmdline="rd.luks.uuid=luks-17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02 rd.lvm.lv=CryptRoot/root rd.lvm.lv=CryptRoot/swap resume=/dev/mapper/CryptRoot-swap root=/dev/mapper/CryptRoot-root rootfstype=ext4 rootflags=rw,relatime"<br />
}}<br />
<br />
{{hc|/etc/dracut.conf.d/flags.conf|2=<br />
compress="zstd"<br />
hostonly="yes"<br />
}}<br />
<br />
Run the following command to generate your EFI stub kernels.<br />
<br />
dracut --uefi<br />
<br />
=== Secure boot ===<br />
<br />
==== Dual Booting Windows ====<br />
<br />
{{warning|This section is still being written}}<br />
<br />
Review [[Unified Extensible Firmware Interface/Secure Boot#shim]] to get a rough understanding of how it's going to work. Install {{aur|shim-signed}}. Perform the following commands to place files where both the UEFI boot entry and shim will load them.<br />
<br />
# mv /efi/EFI/BOOT/BOOTx64.EFI /efi/EFI/BOOT/grubx64.efi<br />
# cp /usr/share/shim-signed/shimx64.efi esp/EFI/BOOT/BOOTx64.EFI<br />
# cp /usr/share/shim-signed/mmx64.efi esp/EFI/BOOT/<br />
<br />
Install {{Pkg|sbctl}}. Use the following command to check that secure boot is in the right status. Your output should be similar.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✘ Sbctl is not installed<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/BOOT/grubx64.efi is not signed<br />
<br />
✘ /efi/EFI/BOOT/mmx64.efi is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
}}<br />
<br />
Note that shim and MOKManager (mmx) is included in this list, even though we will not be signing it.<br />
<br />
{{bc|<br />
# sbctl sign -s /efi/EFI/BOOT/ grubx64.efi <br />
<br />
✔ Signed /efi/EFI/BOOT/grubx64.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi <br />
<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi <br />
<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi<br />
# sbctl verify<br />
<br />
Verifying file database and EFI images in /efi...<br />
✔� /efi/EFI/BOOT/grubx64.efi is signed<br />
✔ /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi is signed<br />
✔ /efi/EFI/systemd/systemd-bootx64.efi is signed<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/BOOT/mmx64.efi is not signed<br />
}}<br />
<br />
You can validate that {{ic|BOOTx64.EFI}} and {{ic|mmx64.efi}} have signatures with {{man|1|sbverify}} from the {{Pkg|sbsigntools}} package.<br />
<br />
Next, we need to create the DER format certificate to load into ''MokManager''.<br />
<br />
# openssl x509 -outform DER -in /usr/share/secureboot/keys/db/db.pem -out /efi/signing.cer<br />
<br />
Use {{Pkg|efibootmgr}} ({{man|8|efibootmgr}}) to adjust your boot entries. Primarily, you will want to remove the {{ic|Linux Boot Manager}} entry.<br />
<br />
{{bc|<br />
# efibootmgr<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0001,0000,0002,0003,0004<br />
Boot0000* Windows Boot Manager<br />
Boot0001* Linux Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
}}<br />
<br />
In this example, we see that {{ic|0000}} is the Windows boot manager. {{ic|0001}} is the Linux Boot Manager and also the first in line to boot. {{ic|0001}} needs to be deleted and optionally the boot order modified so {{ic|0004}} is the default boot entry.<br />
<br />
{{bc|<br />
# efibootmgr --bootnum 0001 --delete-bootnum<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0000,0002,0003,0004<br />
Boot0000* Windows Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
<br />
# efibootmgr --bootorder 0004,0000,0002,0003<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0004,0000,0002,0003<br />
Boot0000* Windows Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Now reboot. You should get an error from your motherboard's UEFI BIOS that secure boot checks failed. Your computer should restart directly into ''MokManager'', if you rearranged the boot order. If not, you will need to select {{ic|UEFI OS}} from your UEFI boot menu. Navigate to the {{ic|signing.cer}} file we placed on the EFI partition and enroll the key. Select reboot, and the system should boot directly into linux with no problem.<br />
<br />
==== Booting only Linux ====<br />
<br />
{{note|Credit to this [https://lunaryorn.com/secure-boot-on-arch-linux-with-sbctl-and-dracut blog post by lunaryorn] for the inspiration.}}<br />
<br />
Install {{Pkg|sbctl}}. At this point you will likely need to reboot and adjust your secure boot settings. You want secure boot in '''setup mode'''. <br />
<br />
{{bc|<br />
$ sbctl status<br />
Installed: X Sbctl is not installed<br />
Setup Mode: X Enabled<br />
Secure Boot: X Disabled<br />
}}<br />
<br />
Run the following commands as root. See {{man|8|sbctl}} for more information on their function. Of particular note is the {{ic|-s}} flag which indicates {{ic|sbctl}} should remember the file for future verification and signing.<br />
<br />
Note your Linux EFI binary name may be slightly different.<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
<br />
# sbctl sign -s /efi/EFI/BOOT/BOOTx64.EFI<br />
✔ Signed /efi/EFI/BOOT/BOOTx64.EFI<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Finally, enroll the Secure Boot keys.<br />
<br />
{{bc|<br />
# sbctl enroll-keys<br />
Enrolling keys to EFI variables...✔<br />
Enrolled keys to the EFI variables!<br />
}}<br />
<br />
Verify that secure boot now has an owner GUID and setup mode is disabled.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✔ Sbctl is installed<br />
Owner GUID: a2ee3d08-725a-408b-9d95-28026a44611c<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
Now reboot. This reboot is required so we can get the TPM measurements into their (hopefully) permanent state.<br />
<br />
=== Enroll LUKS key in TPM ===<br />
{{warning|Yes, this will cause a system to automatically unlock it's encrypted root volume without any interaction from a human. Yes, this exposes it to any sufficently advanced Evil Maid attacks. If sealed against the appropriate registers (especially register 8 with the kernel arguments), the TPM measurements should force systemd to ask for your LUKS passphrase in almost any attempt to access the encrypted volume from outside your normal boot process.}}<br />
<br />
We are fortunate that in our shift to dracut includes utilizing systemd and sd-encrypt, as we can use systemd's native support for enrolling LUKS keys. A review of [[Trusted Platform Module#Using TPM 2.0]] is recommended but not very clear.<br />
<br />
==== Avoid dracut bugs ====<br />
<br />
Subtitle: The Case of the Missing {{ic|d}}<br />
<br />
Two bugs, one in systemd 249.4-1-arch [https://github.com/systemd/systemd/issues/19177] and one in dracut 055 [https://github.com/dracutdevs/dracut/pull/1526][https://github.com/dracutdevs/dracut/issues/1542] will combine to prevent your system from being able to boot. The dracut issue causes the '''tpm2-tss''' module to not be included in your image. The systemd issue causes systemd to go into an emergency when it can't locate the TPM2 libraries, instead of falling back to asking for your passcode.<br />
<br />
The systemd bug isn't a problem so long as you always have TPM2 libraries present.<br />
<br />
To resolve this, first check your version of dracut.<br />
<br />
{{bc|<br />
$ dracut --version<br />
dracut 055<br />
}}<br />
<br />
Since the next release of dracut should have this fixed, we can simply fix the script locally until the next release.<br />
<br />
{{warning|These steps are only necessary for dracut 055}}<br />
<br />
Find the following lines in {{ic|/usr/lib/dracut/modules.d/91tpm2-tss/module-setup.sh}}:<br />
<br />
{{bc|1=<br />
# Module dependency requirements.<br />
depends() {<br />
<br />
# This module has external dependency on other module(s).<br />
echo systemd-sysusers systemd-udev<br />
# Return 0 to include the dependent module(s) in the initramfs.<br />
return 0<br />
<br />
}<br />
}}<br />
<br />
Change the dependency {{ic|systemd-udev}} to <code>systemd-udev<b>d</b></code>.<br />
<br />
Continue with the remaining steps in this section.<br />
<br />
==== Enrollment ====<br />
<br />
First, be sure to install {{Pkg|tpm2-tools}}. Alternatively {{aur|ibm-tss}} can be used per [[Trusted Platform Module]], however this guide is not tested against those.<br />
<br />
{{note|A reboot may be required to convince {{ic|systemd-cryptenroll}} that TPM 2.0 devices now exist on the machine.}}<br />
<br />
There are several decisions to be made here. The table at [[Trusted Platform Module#Accessing PCR registers]] is accurate as of October 2021. Essentially, once you seal your LUKS key, if any of the registers you've sealed against change, then you will be asked for your LUKS passphrase. This is equivalent to when Windows 10 makes you enter your BitLocker recovery key after a hardware change or changing BIOS settings.<br />
<br />
Your mileage may vary, based on UEFI vendors. For my laptop, I went with 0+1+2+3+4+5+7+8 and have been able to invalidate my TPM. Unfortunately, if you change your system BACK the volume will unlock. I'm investigating how to disable that.<br />
<br />
Other options on {{man|1|systemd-cryptenroll}} will reveal that several hardware tokens can also be enrolled to allow unlocking the root LUKS volume automatically, but only if a key is present. Further testing is requried.<br />
<br />
To enroll your LUKS volume, simply run the following command as root<br />
<br />
# systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/nvme0n1p2<br />
<br />
To remove your key, run this command:<br />
<br />
# systemd-cryptenroll --wipe-slot=tpm2 /dev/nvme0n1p2<br />
<br />
You will need to add a kernel argument like below to enable the TPM2 bits. If following this guide, this should be located in {{ic|/etc/dracut.conf.d/cmdline.conf}}<br />
<br />
rd.luks.options={UUID}=tpm2-device=auto<br />
<br />
Ensure that dracut builds in the TPM2 libraries. Create the following file.<br />
<br />
{{hc|/etc/dracut.conf.d/tpm2-tss.conf|2=<br />
add_dracutmodules+=" tpm2-tss "<br />
}}<br />
<br />
Finally, rebuild your unified kernel image.<br />
<br />
# dracut --force --uefi<br />
<br />
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:<br />
<br />
{{hc|~/bin/luks_reenroll_tpm|2=<br />
sudo systemd-cryptenroll --wipe-slot=tpm2 /dev/disk/by-uuid/{UUID_HERE}<br />
systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/disk/by-uuid/{UUID_HERE}<br />
}}<br />
<br />
=== Wrapping up ===<br />
<br />
Set your UEFI password. <br />
<br />
Change your LUKS passphrase from something easily memorable to a good long recovery key.<br />
<br />
Keep both of these pieces of info somewhere safe. This varies depending on your threat model. If we're just talking about Stolen Laptops and Nosy Maids, a hard copy in your safe should be sufficient. If it's the NSA, I'm not sure this setup is appropriate for that model.<br />
<br />
This is an excellent base to handle stolen laptop and even some lower grade Evil Maids. From here, you should head into [[Security]]. Consider learning a framework to help you manage your system state such as [[Ansible]] or headless [[Puppet]].<br />
<br />
== Justifications ==<br />
<br />
=== LVM on LUKS vs other dm-crypt approaches ===<br />
<br />
LVM on LUKS was selected becasue it is simply the easiest to manage while conferring both encrypted swap and disk. The other approaches required much more tooling and manual fussing to utilize. This selection also gives room change freely between {{ic|busybox}} and {{ic|systemd}} initrds.<br />
<br />
=== Using dracut ===<br />
<br />
{{Pkg|dracut}} just makes it easier to build full unified kernels that {{man|7|systemd-boot}} can launch as EFI binaries. There is also available tooling in the [[AUR]] for automating the creation of these binaries. Finally, {{ic|dracut}} will sign the binaries it creates automatically when configured to do so.<br />
<br />
=== Unified kernel images ===<br />
<br />
While UKI's could be problematic on other distributions, they fit right in with an Arch Linux install. The automation is there through pacman hooks and {{Pkg|sbctl}} to sign our UKIs as they're created. Furthermore, you can only sign and create a new signed UKI while booted into a properly signed UKI. It creates a chain of trust, which means it's important to never disable Secure Boot once you've set it up.<br />
<br />
The UKI encompasses all of the following items inside the signature, which means you can't change any of them without invalidating the signature.<br />
<br />
* Kernel arguments<br />
* Initrd/Initramfs<br />
* Kernel<br />
<br />
In particular, all other flavors of secureboot do not sign or validate the initramfs. This is a big attack area and can be relatively trivialized that a semi-decent pawn shop owner with Google could likely find an image that would grant him access and make the TPM none the wiser the system has changed. One can prevent this with encrypted /boot, but that would limit you to GRUB2 and LUKS version 1 devices only. This also doesn't include the work to keep GRUB2's files signed with a PGP key by root.<br />
<br />
=== LUKS enrolled in TPM ===<br />
<br />
The goal here is to only require the passphrase when something spooky happens in your boot path.<br />
<br />
UEFI settings change? Request password.<br />
<br />
Some weird swap of some module of UEFI code that lives on your motherboard somewhere? Request password.<br />
<br />
Unified Kernel Image changes? Don't even boot.<br />
<br />
Drive in another computer? Request password.<br />
<br />
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.<br />
<br />
== Miscellaneous discussions ==<br />
<br />
=== Filesystem Selection ===<br />
<br />
Most examples on Arch utilize {{ic|ext4}}, but other file systems such as {{ic|brtfs}} can work equally well. As for performance or issues with being inside LVM, [https://btrfs.wiki.kernel.org/index.php/FAQ#Btrfs_has_subvolumes.2C_does_this_mean_I_don.27t_need_a_logical_volume_manager_and_I_can_create_a_big_Btrfs_filesystem_on_a_raw_partition.3F this question in the brtfs FAQ] implie that there is some performance loss but no other issues.<br />
<br />
=== LUKS TPM enrollment and managing luks keys ===<br />
<br />
Note that using {{man|1|systemd-cryptenroll}} will add a key to your LUKS volume. It's not clear how exactly the option {{ic|1=--wipe-slot=tpm2}} is able to identify which slot it needs to wipe, but it does. This even works if your TPM has changed.<br />
<br />
You can see the effects by comparing the output of {{ic|cryptsetup luksDump /dev/nvme0n1p2}} before and after you enroll or wipe a TPM based key. You can identify what slot your own passphrase is in with {{ic|cryptsetup --verbose open --test-passphrase /dev/nvme0n1p2}} and entering your passphrase. The output will inform you which key slot was unlocked.<br />
<br />
Finally, your passphrase may be changed with {{ic|cryptsetup luksChangeKey /dev/nvme0n1p2 -S 0}}.<br />
<br />
== Planned TODOs ==<br />
A panic command that can dump the TPM and shutdown the computer (without requiring the time of entering a password in sudo) forcing an adversary to resort to [https://en.wikipedia.org/wiki/Rubber-hose_cryptanalysis rubber-hose cryptanalysis] to get to the encrypted data.</div>Krinhttps://wiki.archlinux.org/index.php?title=User:Krin/Secure_Boot,_full_disk_encryption,_and_TPM2_unlocking_install&diff=699276User:Krin/Secure Boot, full disk encryption, and TPM2 unlocking install2021-10-16T14:45:03Z<p>Krin: /* Booting only Linux */ Remove sbctl-git reference as there's a regular package for sbctl.</p>
<hr />
<div>{{Unsupported|1 October 2021}}<br />
<br />
== Introduction ==<br />
<br />
This installation is based on my installing Arch on an Asus ROG Strix G G531 I got second hand and a desktop computer made of second hand parts that had to share space with Windows. The primary goals were to replace Windows 10 Pro with Bitlocker encryption and maintain the convienence and security balance of that original operating system.<br />
<br />
My requirements boiled down to:<br />
<br />
* A fully encrypted disk<br />
* Full Secure Boot validation of all UEFI components.<br />
* Use of the TPM to facilitate unlocking of the disk.<br />
* Hibernate/Suspend working.<br />
<br />
My primary use case here is to make it difficult enough for a baggage handler with sticky hands to get at my data that they just wipe the drive. A state level actor with the expertise and equipment to hot swap my ram in my hotel room is not something that I'm defending this ''particular'' laptop against. This is more for gaming and web browsing and uploading photos while traveling.<br />
<br />
I'll continue to update these notes as I develop further solutions.<br />
<br />
== Disclaimers ==<br />
<br />
This article is primarily for the author's own notes. It is assumed that the reader is familiar with the [[Installation guide]] and will refer to it often. Reading linked articles is recommended.<br />
<br />
== Dual Booting Modifications ==<br />
<br />
{{warning|If you use BitLocker on your Windows drive, ensure you have your recovery key handy. The installation process will change your TPM measurements causing Windows to require you enter the key manually the next time you boot it.}}<br />
<br />
For computers that will have to dual boot with windows, the easiest solution is to use two different physical drives and utilize your motherboard's UEFI boot menu to select which one to boot. This guide will follow that assumption. You can also attempt to have everything live on one EFI partition. Windows's 100 MiB EFI partition is especially problematic to this approach for secure boot, as Unified Kernel Images can approach 80 MiB and Windows 10 regularly uses up to 30 MiB.<br />
<br />
There are two changes that will be made and will be noted in the relevant sections:<br />
<br />
* Do not clear your Secure Boot keys. Merely disable Secure Boot for the installation.<br />
* Use {{ic|shim}} to boot systemd-bootloader<br />
* Load your db.cer file into the MOKManager application.<br />
<br />
All remaining steps should remain the same, except your system will still be dependent on the factory provided Microsoft Certificates. But you can boot Windows 10 in Secure Boot, which will be important for Windows 11.<br />
<br />
== Initial setup ==<br />
<br />
=== Pre-installation ===<br />
<br />
If you will only boot linux, reset your Secure Boot settings in BIOS to enable setup mode. Usually this means you set Secure Boot to Enabled and then select the option to wipe out the keys.<br />
<br />
If you will be dual booting Windows, disable secure boot.<br />
<br />
Follow the [[Installation_guide#Pre-installation]] up to Paritioning the Disks.<br />
<br />
=== Disk preparation ===<br />
<br />
If you have data on your disks you want to overwrite, utilize [[Dm-crypt/Drive_preparation#dm-crypt_wipe_on_an_empty_disk_or_partition]] to wipe it. If this disk was previously encrypted, utilize [[Dm-crypt/Drive_preparation#Wipe_LUKS_header]] instead for a much faster disposal. Finally, use [[Dm-crypt/Encrypting_an_entire_system#LVM_on_LUKS]] to parition your drive with two differences.<br />
<br />
{{tip|Using a memorable LUKS passphrase until you've completed the install process can be helpful. It will take several reboots to finish setup.}}<br />
<br />
First, the partition layout will be similar to here. You may wish to break out the /home directory into it's own partition. The primary requirement is that only your EFI partition be unencrypted.<br />
<br />
{{hc|Partiton Layout|<br />
┌────────────────────┬──────────────────────────┬─────────────────────────────┐<br />
│ │ │ │<br />
│ EFI Boot Partition │ Logical Volume 1 │ Logical Volume 2 │<br />
│ │ │ │<br />
│ /efi │ [SWAP] │ / │<br />
│ │ │ │<br />
│ /dev/nvme0n1p1 │ /dev/CryptRootVG/swap │ /dev/CryptRootVG/root │<br />
│ │ │ │<br />
│ 512 MB │ 16 GB (Or RAM size) │ Remaining Free Space │<br />
│ │ │ │<br />
│ │ │ │<br />
│ ├──────────────────────────┴─────────────────────────────┤<br />
│ │ │<br />
│ │ LUKS and LVM Physical Volume │<br />
│ │ │<br />
│ │ /dev/nvme0n1p2 │<br />
│ │ │<br />
└────────────────────┴────────────────────────────────────────────────────────┘<br />
}}<br />
<br />
Second, if your hard drive is an SSD like this laptop, use the following command to open your LUKS volume.<br />
<br />
# cryptsetup open --perf-no_read_workqueue --perf-no_write_workqueue --persistent /dev/nvme0n1p2 cryptroot<br />
<br />
After completing your LUKS on LVM setup, format your EFI partition per [[EFI system partition]].<br />
<br />
# mkfs.fat -F32 /dev/nvme0n1p1<br />
<br />
Mount this partition at {{ic|/mnt/efi}}. It is very important to leave {{ic|/boot}} on your encrypted root partition.<br />
<br />
== Installation ==<br />
<br />
Continue with [[Installation_guide#Installation]]. Be sure to flesh out your {{man|8|pacstrap}} with the following list of packages:<br />
<br />
* {{Pkg|dracut}}<br />
* {{Pkg|intel-ucode}}<br />
* {{Pkg|lvm2}}<br />
* {{Pkg|openssh}}<br />
* {{Pkg|ansible}}<br />
* {{Pkg|git}}<br />
* {{Pkg|iwd}}<br />
* {{Pkg|efibootmgr}}<br />
<br />
<br />
We are going to leave off the installation guide at the initramfs section, so go ahead and reset your root password. <br />
<br />
# passwd<br />
<br />
=== Bootloader ===<br />
<br />
First, install {{ic|systemd-boot}} by following [[Systemd-boot#Installing_the_EFI_boot_manager]]. Next, install {{aur|dracut-hook-uefi}}.<br />
<br />
Ensure you drop in a systemd-boot hook to update your bootctl any time it's updated.<br />
<br />
{{hc|/etc/pacman.d/hooks/998-systemd-boot.hook|2=<br />
[Trigger]<br />
Type = Package<br />
Operation = Install<br />
Operation = Upgrade<br />
Target = systemd<br />
<br />
[Action]<br />
Description = Updating systemd-boot<br />
When = PostTransaction<br />
Exec = /usr/bin/bootctl update; <br />
}}<br />
<br />
Obtain the UUID of your LUKS drive via the following command:<br />
<br />
{{bc|<br />
blkid -s UUID -o value /dev/nvme0n1p2<br />
}}<br />
<br />
Create the following files with the listed content. Be sure to replace UUIDs with what you actually need. See {{man|5|dracut.conf}} for more information on what these commands do.<br />
<br />
A good portion of the kernel command line was as generated by dracut. Many are extraneous or you may wish to change some of the block device names.<br />
<br />
{{hc|/etc/dracut.conf.d/cmdline.conf|2=<br />
kernel_cmdline="rd.luks.uuid=luks-17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02 rd.lvm.lv=CryptRoot/root rd.lvm.lv=CryptRoot/swap resume=/dev/mapper/CryptRoot-swap root=/dev/mapper/CryptRoot-root rootfstype=ext4 rootflags=rw,relatime"<br />
}}<br />
<br />
{{hc|/etc/dracut.conf.d/flags.conf|2=<br />
compress="zstd"<br />
hostonly="yes"<br />
}}<br />
<br />
Run the following command to generate your EFI stub kernels.<br />
<br />
dracut --uefi<br />
<br />
=== Secure boot ===<br />
<br />
==== Dual Booting Windows ====<br />
<br />
{{warning|This section is still being written}}<br />
<br />
Review [[Unified Extensible Firmware Interface/Secure Boot#shim]] to get a rough understanding of how it's going to work. Install {{aur|shim-signed}}. Perform the following commands to place files where both the UEFI boot entry and shim will load them.<br />
<br />
# mv /efi/EFI/BOOT/BOOTx64.EFI /efi/EFI/BOOT/grubx64.efi<br />
# cp /usr/share/shim-signed/shimx64.efi esp/EFI/BOOT/BOOTx64.EFI<br />
# cp /usr/share/shim-signed/mmx64.efi esp/EFI/BOOT/<br />
<br />
Install {{Pkg|sbctl}}. Use the following command to check that secure boot is in the right status. Your output should be similar.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✘ Sbctl is not installed<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/BOOT/grubx64.efi is not signed<br />
<br />
✘ /efi/EFI/BOOT/mmx64.efi is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
}}<br />
<br />
Note that shim and MOKManager (mmx) is included in this list, even though we will not be signing it.<br />
<br />
{{bc|<br />
# sbctl sign -s /efi/EFI/BOOT/ grubx64.efi <br />
<br />
✔ Signed /efi/EFI/BOOT/grubx64.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi <br />
<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi <br />
<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi<br />
# sbctl verify<br />
<br />
Verifying file database and EFI images in /efi...<br />
✔� /efi/EFI/BOOT/grubx64.efi is signed<br />
✔ /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi is signed<br />
✔ /efi/EFI/systemd/systemd-bootx64.efi is signed<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/BOOT/mmx64.efi is not signed<br />
}}<br />
<br />
You can validate that {{ic|BOOTx64.EFI}} and {{ic|mmx64.efi}} have signatures with {{man|1|sbverify}} from the {{Pkg|sbsigntools}} package.<br />
<br />
Next, we need to create the DER format certificate to load into ''MokManager''.<br />
<br />
# openssl x509 -outform DER -in /usr/share/secureboot/keys/db/db.pem -out /efi/signing.cer<br />
<br />
Use {{Pkg|efibootmgr}} ({{man|8|efibootmgr}}) to adjust your boot entries. Primarily, you will want to remove the {{ic|Linux Boot Manager}} entry.<br />
<br />
{{bc|<br />
# efibootmgr<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0001,0000,0002,0003,0004<br />
Boot0000* Windows Boot Manager<br />
Boot0001* Linux Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
}}<br />
<br />
In this example, we see that {{ic|0000}} is the Windows boot manager. {{ic|0001}} is the Linux Boot Manager and also the first in line to boot. {{ic|0001}} needs to be deleted and optionally the boot order modified so {{ic|0004}} is the default boot entry.<br />
<br />
{{bc|<br />
# efibootmgr --bootnum 0001 --delete-bootnum<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0000,0002,0003,0004<br />
Boot0000* Windows Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
<br />
# efibootmgr --bootorder 0004,0000,0002,0003<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0004,0000,0002,0003<br />
Boot0000* Windows Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Now reboot. You should get an error from your motherboard's UEFI BIOS that secure boot checks failed. Your computer should restart directly into ''MokManager'', if you rearranged the boot order. If not, you will need to select {{ic|UEFI OS}} from your UEFI boot menu. Navigate to the {{ic|signing.cer}} file we placed on the EFI partition and enroll the key. Select reboot, and the system should boot directly into linux with no problem.<br />
<br />
==== Booting only Linux ====<br />
<br />
{{note|Credit to this [https://lunaryorn.com/secure-boot-on-arch-linux-with-sbctl-and-dracut blog post by lunaryorn] for the inspiration.}}<br />
<br />
Install {{Pkg|sbctl}}. At this point you will likely need to reboot and adjust your secure boot settings. You want secure boot in '''setup mode'''. <br />
<br />
{{bc|<br />
$ sbctl status<br />
Installed: X Sbctl is not installed<br />
Setup Mode: X Enabled<br />
Secure Boot: X Disabled<br />
}}<br />
<br />
Run the following commands as root. See {{man|8|sbctl}} for more information on their function. Of particular note is the {{ic|-s}} flag which indicates {{ic|sbctl}} should remember the file for future verification and signing.<br />
<br />
Note your Linux EFI binary name may be slightly different.<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
<br />
# sbctl sign -s /efi/EFI/BOOT/BOOTx64.EFI<br />
✔ Signed /efi/EFI/BOOT/BOOTx64.EFI<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Finally, enroll the Secure Boot keys.<br />
<br />
{{bc|<br />
# sbctl enroll-keys<br />
Enrolling keys to EFI variables...✔<br />
Enrolled keys to the EFI variables!<br />
}}<br />
<br />
Verify that secure boot now has an owner GUID and setup mode is disabled.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✔ Sbctl is installed<br />
Owner GUID: a2ee3d08-725a-408b-9d95-28026a44611c<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
Now reboot. This reboot is required so we can get the TPM measurements into their (hopefully) permanent state.<br />
<br />
=== Enroll LUKS key in TPM ===<br />
{{warning|Yes, this will cause a system to automatically unlock it's encrypted root volume without any interaction from a human. Yes, this exposes it to any sufficently advanced Evil Maid attacks. If sealed against the appropriate registers (especially register 8 with the kernel arguments), the TPM measurements should force systemd to ask for your LUKS passphrase in almost any attempt to access the encrypted volume from outside your normal boot process.}}<br />
<br />
We are fortunate that in our shift to dracut includes utilizing systemd and sd-encrypt, as we can use systemd's native support for enrolling LUKS keys. A review of [[Trusted Platform Module#Using TPM 2.0]] is recommended but not very clear.<br />
<br />
==== Avoid dracut bugs ====<br />
<br />
Subtitle: The Case of the Missing {{ic|d}}<br />
<br />
Two bugs, one in systemd 249.4-1-arch [https://github.com/systemd/systemd/issues/19177] and one in dracut 055 [https://github.com/dracutdevs/dracut/pull/1526][https://github.com/dracutdevs/dracut/issues/1542] will combine to prevent your system from being able to boot. The dracut issue causes the '''tpm2-tss''' module to not be included in your image. The systemd issue causes systemd to go into an emergency when it can't locate the TPM2 libraries, instead of falling back to asking for your passcode.<br />
<br />
The systemd bug isn't a problem so long as you always have TPM2 libraries present.<br />
<br />
To resolve this, first check your version of dracut.<br />
<br />
{{bc|<br />
$ dracut --version<br />
dracut 055<br />
}}<br />
<br />
Since the next release of dracut should have this fixed, we can simply fix the script locally until the next release.<br />
<br />
{{warning|These steps are only necessary for dracut 055}}<br />
<br />
Find the following lines in {{ic|/usr/lib/dracut/modules.d/91tpm2-tss/module-setup.sh}}:<br />
<br />
{{bc|1=<br />
# Module dependency requirements.<br />
depends() {<br />
<br />
# This module has external dependency on other module(s).<br />
echo systemd-sysusers systemd-udev<br />
# Return 0 to include the dependent module(s) in the initramfs.<br />
return 0<br />
<br />
}<br />
}}<br />
<br />
Change the dependency {{ic|systemd-udev}} to <code>systemd-udev<b>d</b></code>.<br />
<br />
Continue with the remaining steps in this section.<br />
<br />
==== Enrollment ====<br />
<br />
First, be sure to install {{Pkg|tpm2-tools}}. Alternatively {{aur|ibm-tss}} can be used per [[Trusted Platform Module]], however this guide is not tested against those.<br />
<br />
{{note|A reboot may be required to convince {{ic|systemd-cryptenroll}} that TPM 2.0 devices now exist on the machine.}}<br />
<br />
There are several decisions to be made here. The table at [[Trusted Platform Module#Accessing PCR registers]] is accurate as of October 2021. Essentially, once you seal your LUKS key, if any of the registers you've sealed against change, then you will be asked for your LUKS passphrase. This is equivalent to when Windows 10 makes you enter your BitLocker recovery key after a hardware change or changing BIOS settings.<br />
<br />
Your mileage may vary, based on UEFI vendors. For my laptop, I went with 0+1+2+3+4+5+7+8 and have been able to invalidate my TPM. Unfortunately, if you change your system BACK the volume will unlock. I'm investigating how to disable that.<br />
<br />
Other options on {{man|1|systemd-cryptenroll}} will reveal that several hardware tokens can also be enrolled to allow unlocking the root LUKS volume automatically, but only if a key is present. Further testing is requried.<br />
<br />
To enroll your LUKS volume, simply run the following command as root<br />
<br />
# systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/nvme0n1p2<br />
<br />
To remove your key, run this command:<br />
<br />
# systemd-cryptenroll --wipe-slot=tpm2 /dev/nvme0n1p2<br />
<br />
You will need to add a kernel argument like below to enable the TPM2 bits. If following this guide, this should be located in {{ic|/etc/dracut.conf.d/cmdline.conf}}<br />
<br />
rd.luks.options={UUID}=tpm2-device=auto<br />
<br />
Ensure that dracut builds in the TPM2 libraries. Create the following file.<br />
<br />
{{hc|/etc/dracut.conf.d/tpm2-tss.conf|2=<br />
add_dracutmodules+=" tpm2-tss "<br />
}}<br />
<br />
Finally, rebuild your unified kernel image.<br />
<br />
# dracut --force --uefi<br />
<br />
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:<br />
<br />
{{hc|~/bin/luks_reenroll_tpm|2=<br />
sudo systemd-cryptenroll --wipe-slot=tpm2 /dev/disk/by-uuid/{UUID_HERE}<br />
systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/disk/by-uuid/{UUID_HERE}<br />
}}<br />
<br />
=== Wrapping up ===<br />
<br />
Set your UEFI password. <br />
<br />
Change your LUKS passphrase from something easily memorable to a good long recovery key.<br />
<br />
Keep both of these pieces of info somewhere safe. This varies depending on your threat model. If we're just talking about Stolen Laptops and Nosy Maids, a hard copy in your safe should be sufficient. If it's the NSA, I'm not sure this setup is appropriate for that model.<br />
<br />
This is an excellent base to handle stolen laptop and even some lower grade Evil Maids. From here, you should head into [[Security]]. Consider learning a framework to help you manage your system state such as [[Ansible]] or headless [[Puppet]].<br />
<br />
== Justifications ==<br />
<br />
=== LVM on LUKS vs other dm-crypt approaches ===<br />
<br />
LVM on LUKS was selected becasue it is simply the easiest to manage while conferring both encrypted swap and disk. The other approaches required much more tooling and manual fussing to utilize. This selection also gives room change freely between {{ic|busybox}} and {{ic|systemd}} initrds.<br />
<br />
=== Using dracut ===<br />
<br />
{{Pkg|dracut}} just makes it easier to build full unified kernels that {{man|7|systemd-boot}} can launch as EFI binaries. There is also available tooling in the [[AUR]] for automating the creation of these binaries. Finally, {{ic|dracut}} will sign the binaries it creates automatically when configured to do so.<br />
<br />
=== Unified kernel images ===<br />
<br />
While UKI's could be problematic on other distributions, they fit right in with an Arch Linux install. The automation is there through pacman hooks and {{Pkg|sbctl}} to sign our UKIs as they're created. Furthermore, you can only sign and create a new signed UKI while booted into a properly signed UKI. It creates a chain of trust, which means it's important to never disable Secure Boot once you've set it up.<br />
<br />
The UKI encompasses all of the following items inside the signature, which means you can't change any of them without invalidating the signature.<br />
<br />
* Kernel arguments<br />
* Initrd/Initramfs<br />
* Kernel<br />
<br />
In particular, all other flavors of secureboot do not sign or validate the initramfs. This is a big attack area and can be relatively trivialized that a semi-decent pawn shop owner with Google could likely find an image that would grant him access and make the TPM none the wiser the system has changed. One can prevent this with encrypted /boot, but that would limit you to GRUB2 and LUKS version 1 devices only. This also doesn't include the work to keep GRUB2's files signed with a PGP key by root.<br />
<br />
=== LUKS enrolled in TPM ===<br />
<br />
The goal here is to only require the passphrase when something spooky happens in your boot path.<br />
<br />
UEFI settings change? Request password.<br />
<br />
Some weird swap of some module of UEFI code that lives on your motherboard somewhere? Request password.<br />
<br />
Unified Kernel Image changes? Don't even boot.<br />
<br />
Drive in another computer? Request password.<br />
<br />
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.<br />
<br />
== Miscellaneous discussions ==<br />
<br />
=== Filesystem Selection ===<br />
<br />
Most examples on Arch utilize {{ic|ext4}}, but other file systems such as {{ic|brtfs}} can work equally well. As for performance or issues with being inside LVM, [https://btrfs.wiki.kernel.org/index.php/FAQ#Btrfs_has_subvolumes.2C_does_this_mean_I_don.27t_need_a_logical_volume_manager_and_I_can_create_a_big_Btrfs_filesystem_on_a_raw_partition.3F this question in the brtfs FAQ] implie that there is some performance loss but no other issues.<br />
<br />
=== LUKS TPM enrollment and managing luks keys ===<br />
<br />
Note that using {{man|1|systemd-cryptenroll}} will add a key to your LUKS volume. It's not clear how exactly the option {{ic|1=--wipe-slot=tpm2}} is able to identify which slot it needs to wipe, but it does. This even works if your TPM has changed.<br />
<br />
You can see the effects by comparing the output of {{ic|cryptsetup luksDump /dev/nvme0n1p2}} before and after you enroll or wipe a TPM based key. You can identify what slot your own passphrase is in with {{ic|cryptsetup --verbose open --test-passphrase /dev/nvme0n1p2}} and entering your passphrase. The output will inform you which key slot was unlocked.<br />
<br />
Finally, your passphrase may be changed with {{ic|cryptsetup luksChangeKey /dev/nvme0n1p2 -S 0}}.<br />
<br />
== Planned TODOs ==<br />
A panic command that can dump the TPM and shutdown the computer (without requiring the time of entering a password in sudo) forcing an adversary to resort to [https://en.wikipedia.org/wiki/Rubber-hose_cryptanalysis rubber-hose cryptanalysis] to get to the encrypted data.</div>Krinhttps://wiki.archlinux.org/index.php?title=User:Krin/dm-crypt/Device-Encryption&diff=698046User:Krin/dm-crypt/Device-Encryption2021-10-02T02:55:12Z<p>Krin: Notes on changing keys</p>
<hr />
<div>== Tips and Tricks ==<br />
<br />
=== Changing your LUKS Passphrase Key ===<br />
<br />
First validate what slot the current key is in. As noted in [[dm-crypt/Device Encryption]], there can be multiple keys if you are utilizing your TPM or FIDO2 to unlock your partition.<br />
<br />
{{bc|1=<br />
# sudo cryptsetup open --type=luks --test-passphrase -vv /dev/nvme0n1p2<br />
No usable token is available.<br />
Enter passphrase for /dev/nvme0n1p2:<br />
Key slot 0 unlocked.<br />
Command successful.<br />
}}<br />
<br />
In this case,the old passphrase is in slot 0.<br />
<br />
First, add a new key.<br />
<br />
{{bc|1=<br />
# cryptsetup luksAddKey /dev/nvme0n1p2<br />
Enter any existing passphrase:<br />
Enter new passphrase for key slot:<br />
Verify passphrase:<br />
}}<br />
<br />
Then, wipe out the key matching the original passphrase. <br />
You will be required to enter your new passphrase finish this operation.<br />
<br />
{{bc|1=<br />
# cryptsetup luksKillSlot /dev/nvme0n1p2 0<br />
Enter any remaining passphrase:<br />
}}</div>Krinhttps://wiki.archlinux.org/index.php?title=User:Krin&diff=698045User:Krin2021-10-02T02:03:12Z<p>Krin: Rename notes section to be cooler. Add device encryption.</p>
<hr />
<div>* Install Notes<br />
** [[User:Krin/Secure Boot, full disk encryption, and TPM2 unlocking install]]: Notes on installing a (relatively) secured laptop for travel.<br />
* Shadow Pages<br />
** [[User:Krin/dracut]]<br />
** [[User:Krin/NVIDIA]]<br />
** [[User:Krin/dm-crypt/Device-Encryption]]</div>Krinhttps://wiki.archlinux.org/index.php?title=User:Krin/NVIDIA&diff=698023User:Krin/NVIDIA2021-10-01T20:48:42Z<p>Krin: Create tips on getting high res terminals with systemd-boot and dracut.</p>
<hr />
<div>== Tips and Tricks ==<br />
=== High resolution console via Unified Kernel Image generated by dracut ===<br />
<br />
Always backup your working kernel image!<br />
<br />
Create the following files.<br />
<br />
{{warning|The single space at the beginning and end of the string in {{ic|1=+=}} settings are extremely important. Without them your unified kernel image will not build and/or boot.}}<br />
<br />
{{hc|/etc/dracut.conf.d/nvidia.conf|2=<br />
add_drivers+=" nvidia nvidia_modeset nvidia_uvm nvidia_drm "<br />
}}<br />
<br />
Change the {{ic|console-mode}} setting in {{ic|/etc/loader/loader.conf}} to {{ic|max}}.<br />
<br />
Either customize existing or create new pacman hooks to rebuild the kernel on either of the following methods.<br />
<br />
{{note|There is likely already an existing hook or set of hooks to trigger dracut rebuilds. As they vary between path-based and package-based triggers, both are included here for ease of integration.}}<br />
<br />
{{bc|1=<br />
[Trigger]<br />
Type = Path<br />
Operation = Install<br />
Operation = Upgrade<br />
Target = usr/lib/modules/*/nvidia*<br />
}}<br />
<br />
{{bc|1=<br />
[Trigger]<br />
Type = Package<br />
Operation = Install<br />
Operation = Upgrade<br />
Target = nvidia<br />
}}</div>Krinhttps://wiki.archlinux.org/index.php?title=User:Krin/dracut&diff=698016User:Krin/dracut2021-10-01T18:12:36Z<p>Krin: /* Debugging dracut */ Refer to man page instead of external wiki.</p>
<hr />
<div>{{Unsupported|1 October 2021}}<br />
== Introduction ==<br />
<br />
These notes will follow in the format of [[EFI system partition]] and refer to the mount point of your EFI system partition as {{ic|''esp''}}.<br />
<br />
== Tips and tricks ==<br />
<br />
=== Testing Unified Kernel Image changes ===<br />
If a machine is only booting only from signed Unified Kernel Images (hereafter '''UKIs''') built from {{Pkg|dracut}}, changes to the kernel command line or the addition of drivers and files to the image should be tested first, without overwriting your old image. Otherwise, you could be left in an un-bootable state requiring the disabling of Secure Boot and the use of a recovery environment. There are multiple ways to do this.<br />
<br />
{{warning|All of these approaches will cause changes to your TPM PCR registers. If you use TPM in anyway, you will invalidate sealed secrets including but not limited to LUKS volumes. Have your recovery keys and pass phrases on hand and backed up before attempting.}}<br />
<br />
There are two primary approaches one can take. Both may be utilized for a greater measure of safety.<br />
<br />
==== Option 1: backup Your Current Image ====<br />
<br />
Simply copy the currently booted UKI to a new name.<br />
<br />
{{bc|<br />
# cp ''esp''/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi ''esp''/EFI/Linux/linux-backup.efi<br />
}}<br />
<br />
Edit options in {{ic|/etc/dracut.conf.d}} and rebuild your UKI with {{ic|dracut --force --uefi}}.<br />
<br />
==== Option 2: build using a different config directory ====<br />
<br />
Copy all dracut config files to a new working directory.<br />
<br />
{{bc|<br />
$ cp -r /etc/dracut.conf etc/dracut.conf.d ~/<br />
}}<br />
<br />
Build a new UKI with a different name:<br />
<br />
{{bc|<br />
$ sudo dracut --force --uefi --conf ~/dracut.conf --confdir ~/dracut.conf.d ''esp''/EFI/Linux/linux-new.efi<br />
}}<br />
<br />
=== Other testing tips ===<br />
<br />
See [[#Debugging dracut]] for why, but preemptively adding {{ic|rd.shell}} and removing {{ic|quiet}} is a good idea. It will save time when, inevitably, things go wrong. A reboot is already necessary to boot into the new, permanent image upon successful testing. So there is no penalty for making these additional changes, even if the first test is successful.<br />
<br />
You can change the naming of your test image easily by copying {{ic|/etc/os-release}} somewhere, updating the {{ic|BUILD}} variable from {{ic|rolling}} to {{ic|testing}}. Add the option {{ic|--include path/to/new/os-release /etc/os-release}} to your dracut command. This should change {{ic|Arch (rolling)}} to {{ic|Arch (testing)}} on your systemd-bootd selection screen. This may have useful effects with other bootloaders too.<br />
<br />
If building using a virtual console with limited scroll, all of the build messages are on {{ic|stderr}}, not {{ic|stdout}} so be sure to redirect {{ic|stderr}} to your pager.<br />
<br />
=== Debugging dracut ===<br />
<br />
Refer to {{man|8|dracut|TROUBLESHOOTING}}.<br />
<br />
Further disorganized tips:<br />
<br />
'''Do not jump immediately to {{ic|rd.shell}} ''and'' {{ic|rd.debug}}.''' {{ic|rd.debug}} is extremely noisy, especially if utilizing a low resolution virtual console. Rather, utilize {{ic|rd.shell}} and drop the {{ic|quiet}} parameter if present. This should help you identify what exactly is failing and then drop you into an emergency shell where you can peruse the wealth of information within {{ic|/run/initramfs/rdsosreport.txt}}.</div>Krinhttps://wiki.archlinux.org/index.php?title=User:Krin/dracut&diff=698014User:Krin/dracut2021-10-01T17:46:04Z<p>Krin: /* Other testing tips */ Add pager tip</p>
<hr />
<div>{{Unsupported|1 October 2021}}<br />
== Introduction ==<br />
<br />
These notes will follow in the format of [[EFI system partition]] and refer to the mount point of your EFI system partition as {{ic|''esp''}}.<br />
<br />
== Tips and tricks ==<br />
<br />
=== Testing Unified Kernel Image changes ===<br />
If a machine is only booting only from signed Unified Kernel Images (hereafter '''UKIs''') built from {{Pkg|dracut}}, changes to the kernel command line or the addition of drivers and files to the image should be tested first, without overwriting your old image. Otherwise, you could be left in an un-bootable state requiring the disabling of Secure Boot and the use of a recovery environment. There are multiple ways to do this.<br />
<br />
{{warning|All of these approaches will cause changes to your TPM PCR registers. If you use TPM in anyway, you will invalidate sealed secrets including but not limited to LUKS volumes. Have your recovery keys and pass phrases on hand and backed up before attempting.}}<br />
<br />
There are two primary approaches one can take. Both may be utilized for a greater measure of safety.<br />
<br />
==== Option 1: backup Your Current Image ====<br />
<br />
Simply copy the currently booted UKI to a new name.<br />
<br />
{{bc|<br />
# cp ''esp''/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi ''esp''/EFI/Linux/linux-backup.efi<br />
}}<br />
<br />
Edit options in {{ic|/etc/dracut.conf.d}} and rebuild your UKI with {{ic|dracut --force --uefi}}.<br />
<br />
==== Option 2: build using a different config directory ====<br />
<br />
Copy all dracut config files to a new working directory.<br />
<br />
{{bc|<br />
$ cp -r /etc/dracut.conf etc/dracut.conf.d ~/<br />
}}<br />
<br />
Build a new UKI with a different name:<br />
<br />
{{bc|<br />
$ sudo dracut --force --uefi --conf ~/dracut.conf --confdir ~/dracut.conf.d ''esp''/EFI/Linux/linux-new.efi<br />
}}<br />
<br />
=== Other testing tips ===<br />
<br />
See [[#Debugging dracut]] for why, but preemptively adding {{ic|rd.shell}} and removing {{ic|quiet}} is a good idea. It will save time when, inevitably, things go wrong. A reboot is already necessary to boot into the new, permanent image upon successful testing. So there is no penalty for making these additional changes, even if the first test is successful.<br />
<br />
You can change the naming of your test image easily by copying {{ic|/etc/os-release}} somewhere, updating the {{ic|BUILD}} variable from {{ic|rolling}} to {{ic|testing}}. Add the option {{ic|--include path/to/new/os-release /etc/os-release}} to your dracut command. This should change {{ic|Arch (rolling)}} to {{ic|Arch (testing)}} on your systemd-bootd selection screen. This may have useful effects with other bootloaders too.<br />
<br />
If building using a virtual console with limited scroll, all of the build messages are on {{ic|stderr}}, not {{ic|stdout}} so be sure to redirect {{ic|stderr}} to your pager.<br />
<br />
=== Debugging dracut ===<br />
<br />
Refer to this page on the Fedora Wiki: [[https://fedoraproject.org/wiki/How_to_debug_Dracut_problems How To Debug Dracut Problems]].<br />
<br />
Further disorganized tips:<br />
<br />
'''Do not jump immediately to {{ic|rd.shell}} ''and'' {{ic|rd.debug}}.''' {{ic|rd.debug}} is extremely noisy, especially if utilizing a low resolution virtual console. Rather, utilize {{ic|rd.shell}} and drop the {{ic|quiet}} parameter if present. This should help you identify what exactly is failing and then drop you into an emergency shell where you can peruse the wealth of information within {{ic|/run/initramfs/rdsosreport.txt}}.</div>Krinhttps://wiki.archlinux.org/index.php?title=User:Krin/dracut&diff=698013User:Krin/dracut2021-10-01T17:42:34Z<p>Krin: /* Option 2: build using a different config directory */ Update dracut command.</p>
<hr />
<div>{{Unsupported|1 October 2021}}<br />
== Introduction ==<br />
<br />
These notes will follow in the format of [[EFI system partition]] and refer to the mount point of your EFI system partition as {{ic|''esp''}}.<br />
<br />
== Tips and tricks ==<br />
<br />
=== Testing Unified Kernel Image changes ===<br />
If a machine is only booting only from signed Unified Kernel Images (hereafter '''UKIs''') built from {{Pkg|dracut}}, changes to the kernel command line or the addition of drivers and files to the image should be tested first, without overwriting your old image. Otherwise, you could be left in an un-bootable state requiring the disabling of Secure Boot and the use of a recovery environment. There are multiple ways to do this.<br />
<br />
{{warning|All of these approaches will cause changes to your TPM PCR registers. If you use TPM in anyway, you will invalidate sealed secrets including but not limited to LUKS volumes. Have your recovery keys and pass phrases on hand and backed up before attempting.}}<br />
<br />
There are two primary approaches one can take. Both may be utilized for a greater measure of safety.<br />
<br />
==== Option 1: backup Your Current Image ====<br />
<br />
Simply copy the currently booted UKI to a new name.<br />
<br />
{{bc|<br />
# cp ''esp''/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi ''esp''/EFI/Linux/linux-backup.efi<br />
}}<br />
<br />
Edit options in {{ic|/etc/dracut.conf.d}} and rebuild your UKI with {{ic|dracut --force --uefi}}.<br />
<br />
==== Option 2: build using a different config directory ====<br />
<br />
Copy all dracut config files to a new working directory.<br />
<br />
{{bc|<br />
$ cp -r /etc/dracut.conf etc/dracut.conf.d ~/<br />
}}<br />
<br />
Build a new UKI with a different name:<br />
<br />
{{bc|<br />
$ sudo dracut --force --uefi --conf ~/dracut.conf --confdir ~/dracut.conf.d ''esp''/EFI/Linux/linux-new.efi<br />
}}<br />
<br />
=== Other testing tips ===<br />
<br />
See [[#Debugging dracut]] for why, but preemptively adding {{ic|rd.shell}} and removing {{ic|quiet}} is a good idea. It will save time when, inevitably, things go wrong. A reboot is already necessary to boot into the new, permanent image upon successful testing. So there is no penalty for making these additional changes, even if the first test is successful.<br />
<br />
You can change the naming of your test image easily by copying {{ic|/etc/os-release}} somewhere, updating the {{ic|BUILD}} variable from {{ic|rolling}} to {{ic|testing}}. Add the option {{ic|--include path/to/new/os-release /etc/os-release}} to your dracut command. This should change {{ic|Arch (rolling)}} to {{ic|Arch (testing)}} on your systemd-bootd selection screen. This may have useful effects with other bootloaders too.<br />
<br />
=== Debugging dracut ===<br />
<br />
Refer to this page on the Fedora Wiki: [[https://fedoraproject.org/wiki/How_to_debug_Dracut_problems How To Debug Dracut Problems]].<br />
<br />
Further disorganized tips:<br />
<br />
'''Do not jump immediately to {{ic|rd.shell}} ''and'' {{ic|rd.debug}}.''' {{ic|rd.debug}} is extremely noisy, especially if utilizing a low resolution virtual console. Rather, utilize {{ic|rd.shell}} and drop the {{ic|quiet}} parameter if present. This should help you identify what exactly is failing and then drop you into an emergency shell where you can peruse the wealth of information within {{ic|/run/initramfs/rdsosreport.txt}}.</div>Krinhttps://wiki.archlinux.org/index.php?title=User:Krin/dracut&diff=698012User:Krin/dracut2021-10-01T17:41:24Z<p>Krin: /* Other testing tips */ Add how to change the build tag on systemd-bootd's screen.</p>
<hr />
<div>{{Unsupported|1 October 2021}}<br />
== Introduction ==<br />
<br />
These notes will follow in the format of [[EFI system partition]] and refer to the mount point of your EFI system partition as {{ic|''esp''}}.<br />
<br />
== Tips and tricks ==<br />
<br />
=== Testing Unified Kernel Image changes ===<br />
If a machine is only booting only from signed Unified Kernel Images (hereafter '''UKIs''') built from {{Pkg|dracut}}, changes to the kernel command line or the addition of drivers and files to the image should be tested first, without overwriting your old image. Otherwise, you could be left in an un-bootable state requiring the disabling of Secure Boot and the use of a recovery environment. There are multiple ways to do this.<br />
<br />
{{warning|All of these approaches will cause changes to your TPM PCR registers. If you use TPM in anyway, you will invalidate sealed secrets including but not limited to LUKS volumes. Have your recovery keys and pass phrases on hand and backed up before attempting.}}<br />
<br />
There are two primary approaches one can take. Both may be utilized for a greater measure of safety.<br />
<br />
==== Option 1: backup Your Current Image ====<br />
<br />
Simply copy the currently booted UKI to a new name.<br />
<br />
{{bc|<br />
# cp ''esp''/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi ''esp''/EFI/Linux/linux-backup.efi<br />
}}<br />
<br />
Edit options in {{ic|/etc/dracut.conf.d}} and rebuild your UKI with {{ic|dracut --force --uefi}}.<br />
<br />
==== Option 2: build using a different config directory ====<br />
<br />
Copy all dracut config files to a new working directory.<br />
<br />
{{bc|<br />
$ cp -r /etc/dracut.conf etc/dracut.conf.d ~/<br />
}}<br />
<br />
Build a new UKI with a different name:<br />
<br />
{{bc|<br />
$ sudo dracut --conf ~/dracut.conf --confdir ~/dracut.conf.d ''esp''/EFI/Linux/linux-new.efi<br />
}}<br />
<br />
=== Other testing tips ===<br />
<br />
See [[#Debugging dracut]] for why, but preemptively adding {{ic|rd.shell}} and removing {{ic|quiet}} is a good idea. It will save time when, inevitably, things go wrong. A reboot is already necessary to boot into the new, permanent image upon successful testing. So there is no penalty for making these additional changes, even if the first test is successful.<br />
<br />
You can change the naming of your test image easily by copying {{ic|/etc/os-release}} somewhere, updating the {{ic|BUILD}} variable from {{ic|rolling}} to {{ic|testing}}. Add the option {{ic|--include path/to/new/os-release /etc/os-release}} to your dracut command. This should change {{ic|Arch (rolling)}} to {{ic|Arch (testing)}} on your systemd-bootd selection screen. This may have useful effects with other bootloaders too.<br />
<br />
=== Debugging dracut ===<br />
<br />
Refer to this page on the Fedora Wiki: [[https://fedoraproject.org/wiki/How_to_debug_Dracut_problems How To Debug Dracut Problems]].<br />
<br />
Further disorganized tips:<br />
<br />
'''Do not jump immediately to {{ic|rd.shell}} ''and'' {{ic|rd.debug}}.''' {{ic|rd.debug}} is extremely noisy, especially if utilizing a low resolution virtual console. Rather, utilize {{ic|rd.shell}} and drop the {{ic|quiet}} parameter if present. This should help you identify what exactly is failing and then drop you into an emergency shell where you can peruse the wealth of information within {{ic|/run/initramfs/rdsosreport.txt}}.</div>Krinhttps://wiki.archlinux.org/index.php?title=User:Krin/dracut&diff=698011User:Krin/dracut2021-10-01T17:29:21Z<p>Krin: Add unsupported template.</p>
<hr />
<div>{{Unsupported|1 October 2021}}<br />
== Introduction ==<br />
<br />
These notes will follow in the format of [[EFI system partition]] and refer to the mount point of your EFI system partition as {{ic|''esp''}}.<br />
<br />
== Tips and tricks ==<br />
<br />
=== Testing Unified Kernel Image changes ===<br />
If a machine is only booting only from signed Unified Kernel Images (hereafter '''UKIs''') built from {{Pkg|dracut}}, changes to the kernel command line or the addition of drivers and files to the image should be tested first, without overwriting your old image. Otherwise, you could be left in an un-bootable state requiring the disabling of Secure Boot and the use of a recovery environment. There are multiple ways to do this.<br />
<br />
{{warning|All of these approaches will cause changes to your TPM PCR registers. If you use TPM in anyway, you will invalidate sealed secrets including but not limited to LUKS volumes. Have your recovery keys and pass phrases on hand and backed up before attempting.}}<br />
<br />
There are two primary approaches one can take. Both may be utilized for a greater measure of safety.<br />
<br />
==== Option 1: backup Your Current Image ====<br />
<br />
Simply copy the currently booted UKI to a new name.<br />
<br />
{{bc|<br />
# cp ''esp''/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi ''esp''/EFI/Linux/linux-backup.efi<br />
}}<br />
<br />
Edit options in {{ic|/etc/dracut.conf.d}} and rebuild your UKI with {{ic|dracut --force --uefi}}.<br />
<br />
==== Option 2: build using a different config directory ====<br />
<br />
Copy all dracut config files to a new working directory.<br />
<br />
{{bc|<br />
$ cp -r /etc/dracut.conf etc/dracut.conf.d ~/<br />
}}<br />
<br />
Build a new UKI with a different name:<br />
<br />
{{bc|<br />
$ sudo dracut --conf ~/dracut.conf --confdir ~/dracut.conf.d ''esp''/EFI/Linux/linux-new.efi<br />
}}<br />
<br />
=== Other testing tips ===<br />
<br />
See [[#Debugging dracut]] for why, but preemptively adding {{ic|rd.shell}} and removing {{ic|quiet}} is a good idea. It will save time when, inevitably, things go wrong. A reboot is already necessary to boot into the new, permanent image upon successful testing. So there is no penalty for making these additional changes, even if the first test is successful.<br />
<br />
=== Debugging dracut ===<br />
<br />
Refer to this page on the Fedora Wiki: [[https://fedoraproject.org/wiki/How_to_debug_Dracut_problems How To Debug Dracut Problems]].<br />
<br />
Further disorganized tips:<br />
<br />
'''Do not jump immediately to {{ic|rd.shell}} ''and'' {{ic|rd.debug}}.''' {{ic|rd.debug}} is extremely noisy, especially if utilizing a low resolution virtual console. Rather, utilize {{ic|rd.shell}} and drop the {{ic|quiet}} parameter if present. This should help you identify what exactly is failing and then drop you into an emergency shell where you can peruse the wealth of information within {{ic|/run/initramfs/rdsosreport.txt}}.</div>Krinhttps://wiki.archlinux.org/index.php?title=User:Krin&diff=698010User:Krin2021-10-01T17:28:55Z<p>Krin: Add page for NVIDIA driver notes</p>
<hr />
<div>* Install Notes<br />
** [[User:Krin/Secure Boot, full disk encryption, and TPM2 unlocking install]]: Notes on installing a (relatively) secured laptop for travel.<br />
* Miscellaneous Notes<br />
** [[User:Krin/dracut]]: Notes on working with dracut and UKI's.<br />
** [[User:Krin/NVIDIA]]: Notes on using the proprietary NVIDIA driver</div>Krinhttps://wiki.archlinux.org/index.php?title=User:Krin/dracut&diff=698009User:Krin/dracut2021-10-01T17:27:05Z<p>Krin: Add debugging initrd tips. Add tip to preemptively add debugging kernel params.</p>
<hr />
<div>== Introduction ==<br />
<br />
These notes will follow in the format of [[EFI system partition]] and refer to the mount point of your EFI system partition as {{ic|''esp''}}.<br />
<br />
== Tips and tricks ==<br />
<br />
=== Testing Unified Kernel Image changes ===<br />
If a machine is only booting only from signed Unified Kernel Images (hereafter '''UKIs''') built from {{Pkg|dracut}}, changes to the kernel command line or the addition of drivers and files to the image should be tested first, without overwriting your old image. Otherwise, you could be left in an un-bootable state requiring the disabling of Secure Boot and the use of a recovery environment. There are multiple ways to do this.<br />
<br />
{{warning|All of these approaches will cause changes to your TPM PCR registers. If you use TPM in anyway, you will invalidate sealed secrets including but not limited to LUKS volumes. Have your recovery keys and pass phrases on hand and backed up before attempting.}}<br />
<br />
There are two primary approaches one can take. Both may be utilized for a greater measure of safety.<br />
<br />
==== Option 1: backup Your Current Image ====<br />
<br />
Simply copy the currently booted UKI to a new name.<br />
<br />
{{bc|<br />
# cp ''esp''/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi ''esp''/EFI/Linux/linux-backup.efi<br />
}}<br />
<br />
Edit options in {{ic|/etc/dracut.conf.d}} and rebuild your UKI with {{ic|dracut --force --uefi}}.<br />
<br />
==== Option 2: build using a different config directory ====<br />
<br />
Copy all dracut config files to a new working directory.<br />
<br />
{{bc|<br />
$ cp -r /etc/dracut.conf etc/dracut.conf.d ~/<br />
}}<br />
<br />
Build a new UKI with a different name:<br />
<br />
{{bc|<br />
$ sudo dracut --conf ~/dracut.conf --confdir ~/dracut.conf.d ''esp''/EFI/Linux/linux-new.efi<br />
}}<br />
<br />
=== Other testing tips ===<br />
<br />
See [[#Debugging dracut]] for why, but preemptively adding {{ic|rd.shell}} and removing {{ic|quiet}} is a good idea. It will save time when, inevitably, things go wrong. A reboot is already necessary to boot into the new, permanent image upon successful testing. So there is no penalty for making these additional changes, even if the first test is successful.<br />
<br />
=== Debugging dracut ===<br />
<br />
Refer to this page on the Fedora Wiki: [[https://fedoraproject.org/wiki/How_to_debug_Dracut_problems How To Debug Dracut Problems]].<br />
<br />
Further disorganized tips:<br />
<br />
'''Do not jump immediately to {{ic|rd.shell}} ''and'' {{ic|rd.debug}}.''' {{ic|rd.debug}} is extremely noisy, especially if utilizing a low resolution virtual console. Rather, utilize {{ic|rd.shell}} and drop the {{ic|quiet}} parameter if present. This should help you identify what exactly is failing and then drop you into an emergency shell where you can peruse the wealth of information within {{ic|/run/initramfs/rdsosreport.txt}}.</div>Krinhttps://wiki.archlinux.org/index.php?title=User:Krin/dracut&diff=698008User:Krin/dracut2021-10-01T17:14:34Z<p>Krin: Update warning to cover more than LUKS.</p>
<hr />
<div>== Introduction ==<br />
<br />
These notes will follow in the format of [[EFI system partition]] and refer to the mount point of your EFI system partition as {{ic|''esp''}}.<br />
<br />
== Tips and tricks ==<br />
<br />
=== Testing Unified Kernel Image changes ===<br />
If a machine is only booting only from signed Unified Kernel Images (hereafter '''UKIs''') built from {{Pkg|dracut}}, changes to the kernel command line or the addition of drivers and files to the image should be tested first, without overwriting your old image. Otherwise, you could be left in an un-bootable state requiring the disabling of Secure Boot and the use of a recovery environment. There are multiple ways to do this.<br />
<br />
{{warning|All of these approaches will cause changes to your TPM PCR registers. If you use TPM in anyway, you will invalidate sealed secrets including but not limited to LUKS volumes. Have your recovery keys and pass phrases on hand and backed up before attempting.}}<br />
<br />
There are two primary approaches one can take. Both may be utilized for a greater measure of safety.<br />
<br />
==== Option 1: backup Your Current Image ====<br />
<br />
Simply copy the currently booted UKI to a new name.<br />
<br />
{{bc|<br />
# cp ''esp''/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi ''esp''/EFI/Linux/linux-backup.efi<br />
}}<br />
<br />
Edit options in {{ic|/etc/dracut.conf.d}} and rebuild your UKI with {{ic|dracut --force --uefi}}.<br />
<br />
==== Option 2: build using a different config directory ====<br />
<br />
Copy all dracut config files to a new working directory.<br />
<br />
{{bc|<br />
$ cp -r /etc/dracut.conf etc/dracut.conf.d ~/<br />
}}<br />
<br />
Build a new UKI with a different name:<br />
<br />
{{bc|<br />
$ sudo dracut --conf ~/dracut.conf --confdir ~/dracut.conf.d ''esp''/EFI/Linux/linux-new.efi<br />
}}</div>Krinhttps://wiki.archlinux.org/index.php?title=User:Krin/dracut&diff=698007User:Krin/dracut2021-10-01T17:12:17Z<p>Krin: Create section on testing new dracut images.</p>
<hr />
<div>== Introduction ==<br />
<br />
These notes will follow in the format of [[EFI system partition]] and refer to the mount point of your EFI system partition as {{ic|''esp''}}.<br />
<br />
== Tips and tricks ==<br />
<br />
=== Testing Unified Kernel Image changes ===<br />
If a machine is only booting only from signed Unified Kernel Images (hereafter '''UKIs''') built from {{Pkg|dracut}}, changes to the kernel command line or the addition of drivers and files to the image should be tested first, without overwriting your old image. There are multiple ways to do this.<br />
<br />
{{warning|All of these approaches will cause changes to your TPM PCR registers. If your root LUKS encrypted volume is unlocked via the TPM, ensure you have your passphrase on hand. Otherwise you will be unable to unlock your root device. Depending on what registers you have sealed your LUKS key against, you may have to re-enroll a new key after this process.}}<br />
<br />
There are two primary approaches one can take. Both may be utilized for a greater measure of safety.<br />
<br />
==== Option 1: backup Your Current Image ====<br />
<br />
Simply copy the currently booted UKI to a new name.<br />
<br />
{{bc|<br />
# cp ''esp''/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi ''esp''/EFI/Linux/linux-backup.efi<br />
}}<br />
<br />
Edit options in {{ic|/etc/dracut.conf.d}} and rebuild your UKI with {{ic|dracut --force --uefi}}.<br />
<br />
==== Option 2: build using a different config directory ====<br />
<br />
Copy all dracut config files to a new working directory.<br />
<br />
{{bc|<br />
$ cp -r /etc/dracut.conf etc/dracut.conf.d ~/<br />
}}<br />
<br />
Build a new UKI with a different name:<br />
<br />
{{bc|<br />
$ sudo dracut --conf ~/dracut.conf --confdir ~/dracut.conf.d ''esp''/EFI/Linux/linux-new.efi<br />
}}</div>Krinhttps://wiki.archlinux.org/index.php?title=User:Krin/Secure_Boot,_full_disk_encryption,_and_TPM2_unlocking_install&diff=698006User:Krin/Secure Boot, full disk encryption, and TPM2 unlocking install2021-10-01T16:54:07Z<p>Krin: Remove expansion. Update review date.</p>
<hr />
<div>{{Unsupported|1 October 2021}}<br />
<br />
== Introduction ==<br />
<br />
This installation is based on my installing Arch on an Asus ROG Strix G G531 I got second hand and a desktop computer made of second hand parts that had to share space with Windows. The primary goals were to replace Windows 10 Pro with Bitlocker encryption and maintain the convienence and security balance of that original operating system.<br />
<br />
My requirements boiled down to:<br />
<br />
* A fully encrypted disk<br />
* Full Secure Boot validation of all UEFI components.<br />
* Use of the TPM to facilitate unlocking of the disk.<br />
* Hibernate/Suspend working.<br />
<br />
My primary use case here is to make it difficult enough for a baggage handler with sticky hands to get at my data that they just wipe the drive. A state level actor with the expertise and equipment to hot swap my ram in my hotel room is not something that I'm defending this ''particular'' laptop against. This is more for gaming and web browsing and uploading photos while traveling.<br />
<br />
I'll continue to update these notes as I develop further solutions.<br />
<br />
== Disclaimers ==<br />
<br />
This article is primarily for the author's own notes. It is assumed that the reader is familiar with the [[Installation guide]] and will refer to it often. Reading linked articles is recommended.<br />
<br />
== Dual Booting Modifications ==<br />
<br />
{{warning|If you use BitLocker on your Windows drive, ensure you have your recovery key handy. The installation process will change your TPM measurements causing Windows to require you enter the key manually the next time you boot it.}}<br />
<br />
For computers that will have to dual boot with windows, the easiest solution is to use two different physical drives and utilize your motherboard's UEFI boot menu to select which one to boot. This guide will follow that assumption. You can also attempt to have everything live on one EFI partition. Windows's 100 MiB EFI partition is especially problematic to this approach for secure boot, as Unified Kernel Images can approach 80 MiB and Windows 10 regularly uses up to 30 MiB.<br />
<br />
There are two changes that will be made and will be noted in the relevant sections:<br />
<br />
* Do not clear your Secure Boot keys. Merely disable Secure Boot for the installation.<br />
* Use {{ic|shim}} to boot systemd-bootloader<br />
* Load your db.cer file into the MOKManager application.<br />
<br />
All remaining steps should remain the same, except your system will still be dependent on the factory provided Microsoft Certificates. But you can boot Windows 10 in Secure Boot, which will be important for Windows 11.<br />
<br />
== Initial setup ==<br />
<br />
=== Pre-installation ===<br />
<br />
If you will only boot linux, reset your Secure Boot settings in BIOS to enable setup mode. Usually this means you set Secure Boot to Enabled and then select the option to wipe out the keys.<br />
<br />
If you will be dual booting Windows, disable secure boot.<br />
<br />
Follow the [[Installation_guide#Pre-installation]] up to Paritioning the Disks.<br />
<br />
=== Disk preparation ===<br />
<br />
If you have data on your disks you want to overwrite, utilize [[Dm-crypt/Drive_preparation#dm-crypt_wipe_on_an_empty_disk_or_partition]] to wipe it. If this disk was previously encrypted, utilize [[Dm-crypt/Drive_preparation#Wipe_LUKS_header]] instead for a much faster disposal. Finally, use [[Dm-crypt/Encrypting_an_entire_system#LVM_on_LUKS]] to parition your drive with two differences.<br />
<br />
{{tip|Using a memorable LUKS passphrase until you've completed the install process can be helpful. It will take several reboots to finish setup.}}<br />
<br />
First, the partition layout will be similar to here. You may wish to break out the /home directory into it's own partition. The primary requirement is that only your EFI partition be unencrypted.<br />
<br />
{{hc|Partiton Layout|<br />
┌────────────────────┬──────────────────────────┬─────────────────────────────┐<br />
│ │ │ │<br />
│ EFI Boot Partition │ Logical Volume 1 │ Logical Volume 2 │<br />
│ │ │ │<br />
│ /efi │ [SWAP] │ / │<br />
│ │ │ │<br />
│ /dev/nvme0n1p1 │ /dev/CryptRootVG/swap │ /dev/CryptRootVG/root │<br />
│ │ │ │<br />
│ 512 MB │ 16 GB (Or RAM size) │ Remaining Free Space │<br />
│ │ │ │<br />
│ │ │ │<br />
│ ├──────────────────────────┴─────────────────────────────┤<br />
│ │ │<br />
│ │ LUKS and LVM Physical Volume │<br />
│ │ │<br />
│ │ /dev/nvme0n1p2 │<br />
│ │ │<br />
└────────────────────┴────────────────────────────────────────────────────────┘<br />
}}<br />
<br />
Second, if your hard drive is an SSD like this laptop, use the following command to open your LUKS volume.<br />
<br />
# cryptsetup open --perf-no_read_workqueue --perf-no_write_workqueue --persistent /dev/nvme0n1p2 cryptroot<br />
<br />
After completing your LUKS on LVM setup, format your EFI partition per [[EFI system partition]].<br />
<br />
# mkfs.fat -F32 /dev/nvme0n1p1<br />
<br />
Mount this partition at {{ic|/mnt/efi}}. It is very important to leave {{ic|/boot}} on your encrypted root partition.<br />
<br />
== Installation ==<br />
<br />
Continue with [[Installation_guide#Installation]]. Be sure to flesh out your {{man|8|pacstrap}} with the following list of packages:<br />
<br />
* {{Pkg|dracut}}<br />
* {{Pkg|intel-ucode}}<br />
* {{Pkg|lvm2}}<br />
* {{Pkg|openssh}}<br />
* {{Pkg|ansible}}<br />
* {{Pkg|git}}<br />
* {{Pkg|iwd}}<br />
* {{Pkg|efibootmgr}}<br />
<br />
<br />
We are going to leave off the installation guide at the initramfs section, so go ahead and reset your root password. <br />
<br />
# passwd<br />
<br />
=== Bootloader ===<br />
<br />
First, install {{ic|systemd-boot}} by following [[Systemd-boot#Installing_the_EFI_boot_manager]]. Next, install {{aur|dracut-hook-uefi}}.<br />
<br />
Ensure you drop in a systemd-boot hook to update your bootctl any time it's updated.<br />
<br />
{{hc|/etc/pacman.d/hooks/998-systemd-boot.hook|2=<br />
[Trigger]<br />
Type = Package<br />
Operation = Install<br />
Operation = Upgrade<br />
Target = systemd<br />
<br />
[Action]<br />
Description = Updating systemd-boot<br />
When = PostTransaction<br />
Exec = /usr/bin/bootctl update; <br />
}}<br />
<br />
Obtain the UUID of your LUKS drive via the following command:<br />
<br />
{{bc|<br />
blkid -s UUID -o value /dev/nvme0n1p2<br />
}}<br />
<br />
Create the following files with the listed content. Be sure to replace UUIDs with what you actually need. See {{man|5|dracut.conf}} for more information on what these commands do.<br />
<br />
A good portion of the kernel command line was as generated by dracut. Many are extraneous or you may wish to change some of the block device names.<br />
<br />
{{hc|/etc/dracut.conf.d/cmdline.conf|2=<br />
kernel_cmdline="rd.luks.uuid=luks-17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02 rd.lvm.lv=CryptRoot/root rd.lvm.lv=CryptRoot/swap resume=/dev/mapper/CryptRoot-swap root=/dev/mapper/CryptRoot-root rootfstype=ext4 rootflags=rw,relatime"<br />
}}<br />
<br />
{{hc|/etc/dracut.conf.d/flags.conf|2=<br />
compress="zstd"<br />
hostonly="yes"<br />
}}<br />
<br />
Run the following command to generate your EFI stub kernels.<br />
<br />
dracut --uefi<br />
<br />
=== Secure boot ===<br />
<br />
==== Dual Booting Windows ====<br />
<br />
{{warning|This section is still being written}}<br />
<br />
Review [[Unified Extensible Firmware Interface/Secure Boot#shim]] to get a rough understanding of how it's going to work. Install {{aur|shim-signed}}. Perform the following commands to place files where both the UEFI boot entry and shim will load them.<br />
<br />
# mv /efi/EFI/BOOT/BOOTx64.EFI /efi/EFI/BOOT/grubx64.efi<br />
# cp /usr/share/shim-signed/shimx64.efi esp/EFI/BOOT/BOOTx64.EFI<br />
# cp /usr/share/shim-signed/mmx64.efi esp/EFI/BOOT/<br />
<br />
Install {{Pkg|sbctl}}. Use the following command to check that secure boot is in the right status. Your output should be similar.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✘ Sbctl is not installed<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/BOOT/grubx64.efi is not signed<br />
<br />
✘ /efi/EFI/BOOT/mmx64.efi is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
}}<br />
<br />
Note that shim and MOKManager (mmx) is included in this list, even though we will not be signing it.<br />
<br />
{{bc|<br />
# sbctl sign -s /efi/EFI/BOOT/ grubx64.efi <br />
<br />
✔ Signed /efi/EFI/BOOT/grubx64.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi <br />
<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi <br />
<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi<br />
# sbctl verify<br />
<br />
Verifying file database and EFI images in /efi...<br />
✔� /efi/EFI/BOOT/grubx64.efi is signed<br />
✔ /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi is signed<br />
✔ /efi/EFI/systemd/systemd-bootx64.efi is signed<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/BOOT/mmx64.efi is not signed<br />
}}<br />
<br />
You can validate that {{ic|BOOTx64.EFI}} and {{ic|mmx64.efi}} have signatures with {{man|1|sbverify}} from the {{Pkg|sbsigntools}} package.<br />
<br />
Next, we need to create the DER format certificate to load into ''MokManager''.<br />
<br />
# openssl x509 -outform DER -in /usr/share/secureboot/keys/db/db.pem -out /efi/signing.cer<br />
<br />
Use {{Pkg|efibootmgr}} ({{man|8|efibootmgr}}) to adjust your boot entries. Primarily, you will want to remove the {{ic|Linux Boot Manager}} entry.<br />
<br />
{{bc|<br />
# efibootmgr<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0001,0000,0002,0003,0004<br />
Boot0000* Windows Boot Manager<br />
Boot0001* Linux Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
}}<br />
<br />
In this example, we see that {{ic|0000}} is the Windows boot manager. {{ic|0001}} is the Linux Boot Manager and also the first in line to boot. {{ic|0001}} needs to be deleted and optionally the boot order modified so {{ic|0004}} is the default boot entry.<br />
<br />
{{bc|<br />
# efibootmgr --bootnum 0001 --delete-bootnum<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0000,0002,0003,0004<br />
Boot0000* Windows Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
<br />
# efibootmgr --bootorder 0004,0000,0002,0003<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0004,0000,0002,0003<br />
Boot0000* Windows Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Now reboot. You should get an error from your motherboard's UEFI BIOS that secure boot checks failed. Your computer should restart directly into ''MokManager'', if you rearranged the boot order. If not, you will need to select {{ic|UEFI OS}} from your UEFI boot menu. Navigate to the {{ic|signing.cer}} file we placed on the EFI partition and enroll the key. Select reboot, and the system should boot directly into linux with no problem.<br />
<br />
==== Booting only Linux ====<br />
<br />
{{note|The very newly developed [https://github.com/Foxboron/sbctl sbctl], availble via {{aur|sbctl-git}} has completely revamped this process and will only get better as they approach 1.0. From here on out, as of October 2021, this process should greatly simplify.}}<br />
<br />
{{note|Credit to this [https://lunaryorn.com/secure-boot-on-arch-linux-with-sbctl-and-dracut blog post by lunaryorn] for the inspiration.}}<br />
<br />
Install {{Pkg|sbctl}}. At this point you will likely need to reboot and adjust your secure boot settings. You want secure boot in '''setup mode'''. <br />
<br />
{{bc|<br />
$ sbctl status<br />
Installed: X Sbctl is not installed<br />
Setup Mode: X Enabled<br />
Secure Boot: X Disabled<br />
}}<br />
<br />
Run the following commands as root. See {{man|8|sbctl}} for more information on their function. Of particular note is the {{ic|-s}} flag which indicates {{ic|sbctl}} should remember the file for future verification and signing.<br />
<br />
Note your Linux EFI binary name may be slightly different.<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
<br />
# sbctl sign -s /efi/EFI/BOOT/BOOTx64.EFI<br />
✔ Signed /efi/EFI/BOOT/BOOTx64.EFI<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Finally, enroll the Secure Boot keys.<br />
<br />
{{bc|<br />
# sbctl enroll-keys<br />
Enrolling keys to EFI variables...✔<br />
Enrolled keys to the EFI variables!<br />
}}<br />
<br />
Verify that secure boot now has an owner GUID and setup mode is disabled.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✔ Sbctl is installed<br />
Owner GUID: a2ee3d08-725a-408b-9d95-28026a44611c<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
Now reboot. This reboot is required so we can get the TPM measurements into their (hopefully) permanent state.<br />
<br />
=== Enroll LUKS key in TPM ===<br />
{{warning|Yes, this will cause a system to automatically unlock it's encrypted root volume without any interaction from a human. Yes, this exposes it to any sufficently advanced Evil Maid attacks. If sealed against the appropriate registers (especially register 8 with the kernel arguments), the TPM measurements should force systemd to ask for your LUKS passphrase in almost any attempt to access the encrypted volume from outside your normal boot process.}}<br />
<br />
We are fortunate that in our shift to dracut includes utilizing systemd and sd-encrypt, as we can use systemd's native support for enrolling LUKS keys. A review of [[Trusted Platform Module#Using TPM 2.0]] is recommended but not very clear.<br />
<br />
==== Avoid dracut bugs ====<br />
<br />
Subtitle: The Case of the Missing {{ic|d}}<br />
<br />
Two bugs, one in systemd 249.4-1-arch [https://github.com/systemd/systemd/issues/19177] and one in dracut 055 [https://github.com/dracutdevs/dracut/pull/1526][https://github.com/dracutdevs/dracut/issues/1542] will combine to prevent your system from being able to boot. The dracut issue causes the '''tpm2-tss''' module to not be included in your image. The systemd issue causes systemd to go into an emergency when it can't locate the TPM2 libraries, instead of falling back to asking for your passcode.<br />
<br />
The systemd bug isn't a problem so long as you always have TPM2 libraries present.<br />
<br />
To resolve this, first check your version of dracut.<br />
<br />
{{bc|<br />
$ dracut --version<br />
dracut 055<br />
}}<br />
<br />
Since the next release of dracut should have this fixed, we can simply fix the script locally until the next release.<br />
<br />
{{warning|These steps are only necessary for dracut 055}}<br />
<br />
Find the following lines in {{ic|/usr/lib/dracut/modules.d/91tpm2-tss/module-setup.sh}}:<br />
<br />
{{bc|1=<br />
# Module dependency requirements.<br />
depends() {<br />
<br />
# This module has external dependency on other module(s).<br />
echo systemd-sysusers systemd-udev<br />
# Return 0 to include the dependent module(s) in the initramfs.<br />
return 0<br />
<br />
}<br />
}}<br />
<br />
Change the dependency {{ic|systemd-udev}} to <code>systemd-udev<b>d</b></code>.<br />
<br />
Continue with the remaining steps in this section.<br />
<br />
==== Enrollment ====<br />
<br />
First, be sure to install {{Pkg|tpm2-tools}}. Alternatively {{aur|ibm-tss}} can be used per [[Trusted Platform Module]], however this guide is not tested against those.<br />
<br />
{{note|A reboot may be required to convince {{ic|systemd-cryptenroll}} that TPM 2.0 devices now exist on the machine.}}<br />
<br />
There are several decisions to be made here. The table at [[Trusted Platform Module#Accessing PCR registers]] is accurate as of October 2021. Essentially, once you seal your LUKS key, if any of the registers you've sealed against change, then you will be asked for your LUKS passphrase. This is equivalent to when Windows 10 makes you enter your BitLocker recovery key after a hardware change or changing BIOS settings.<br />
<br />
Your mileage may vary, based on UEFI vendors. For my laptop, I went with 0+1+2+3+4+5+7+8 and have been able to invalidate my TPM. Unfortunately, if you change your system BACK the volume will unlock. I'm investigating how to disable that.<br />
<br />
Other options on {{man|1|systemd-cryptenroll}} will reveal that several hardware tokens can also be enrolled to allow unlocking the root LUKS volume automatically, but only if a key is present. Further testing is requried.<br />
<br />
To enroll your LUKS volume, simply run the following command as root<br />
<br />
# systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/nvme0n1p2<br />
<br />
To remove your key, run this command:<br />
<br />
# systemd-cryptenroll --wipe-slot=tpm2 /dev/nvme0n1p2<br />
<br />
You will need to add a kernel argument like below to enable the TPM2 bits. If following this guide, this should be located in {{ic|/etc/dracut.conf.d/cmdline.conf}}<br />
<br />
rd.luks.options={UUID}=tpm2-device=auto<br />
<br />
Ensure that dracut builds in the TPM2 libraries. Create the following file.<br />
<br />
{{hc|/etc/dracut.conf.d/tpm2-tss.conf|2=<br />
add_dracutmodules+=" tpm2-tss "<br />
}}<br />
<br />
Finally, rebuild your unified kernel image.<br />
<br />
# dracut --force --uefi<br />
<br />
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:<br />
<br />
{{hc|~/bin/luks_reenroll_tpm|2=<br />
sudo systemd-cryptenroll --wipe-slot=tpm2 /dev/disk/by-uuid/{UUID_HERE}<br />
systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/disk/by-uuid/{UUID_HERE}<br />
}}<br />
<br />
=== Wrapping up ===<br />
<br />
Set your UEFI password. <br />
<br />
Change your LUKS passphrase from something easily memorable to a good long recovery key.<br />
<br />
Keep both of these pieces of info somewhere safe. This varies depending on your threat model. If we're just talking about Stolen Laptops and Nosy Maids, a hard copy in your safe should be sufficient. If it's the NSA, I'm not sure this setup is appropriate for that model.<br />
<br />
This is an excellent base to handle stolen laptop and even some lower grade Evil Maids. From here, you should head into [[Security]]. Consider learning a framework to help you manage your system state such as [[Ansible]] or headless [[Puppet]].<br />
<br />
== Justifications ==<br />
<br />
=== LVM on LUKS vs other dm-crypt approaches ===<br />
<br />
LVM on LUKS was selected becasue it is simply the easiest to manage while conferring both encrypted swap and disk. The other approaches required much more tooling and manual fussing to utilize. This selection also gives room change freely between {{ic|busybox}} and {{ic|systemd}} initrds.<br />
<br />
=== Using dracut ===<br />
<br />
{{Pkg|dracut}} just makes it easier to build full unified kernels that {{man|7|systemd-boot}} can launch as EFI binaries. There is also available tooling in the [[AUR]] for automating the creation of these binaries. Finally, {{ic|dracut}} will sign the binaries it creates automatically when configured to do so.<br />
<br />
=== Unified kernel images ===<br />
<br />
While UKI's could be problematic on other distributions, they fit right in with an Arch Linux install. The automation is there through pacman hooks and {{Pkg|sbctl}} to sign our UKIs as they're created. Furthermore, you can only sign and create a new signed UKI while booted into a properly signed UKI. It creates a chain of trust, which means it's important to never disable Secure Boot once you've set it up.<br />
<br />
The UKI encompasses all of the following items inside the signature, which means you can't change any of them without invalidating the signature.<br />
<br />
* Kernel arguments<br />
* Initrd/Initramfs<br />
* Kernel<br />
<br />
In particular, all other flavors of secureboot do not sign or validate the initramfs. This is a big attack area and can be relatively trivialized that a semi-decent pawn shop owner with Google could likely find an image that would grant him access and make the TPM none the wiser the system has changed. One can prevent this with encrypted /boot, but that would limit you to GRUB2 and LUKS version 1 devices only. This also doesn't include the work to keep GRUB2's files signed with a PGP key by root.<br />
<br />
=== LUKS enrolled in TPM ===<br />
<br />
The goal here is to only require the passphrase when something spooky happens in your boot path.<br />
<br />
UEFI settings change? Request password.<br />
<br />
Some weird swap of some module of UEFI code that lives on your motherboard somewhere? Request password.<br />
<br />
Unified Kernel Image changes? Don't even boot.<br />
<br />
Drive in another computer? Request password.<br />
<br />
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.<br />
<br />
== Miscellaneous discussions ==<br />
<br />
=== Filesystem Selection ===<br />
<br />
Most examples on Arch utilize {{ic|ext4}}, but other file systems such as {{ic|brtfs}} can work equally well. As for performance or issues with being inside LVM, [https://btrfs.wiki.kernel.org/index.php/FAQ#Btrfs_has_subvolumes.2C_does_this_mean_I_don.27t_need_a_logical_volume_manager_and_I_can_create_a_big_Btrfs_filesystem_on_a_raw_partition.3F this question in the brtfs FAQ] implie that there is some performance loss but no other issues.<br />
<br />
=== LUKS TPM enrollment and managing luks keys ===<br />
<br />
Note that using {{man|1|systemd-cryptenroll}} will add a key to your LUKS volume. It's not clear how exactly the option {{ic|1=--wipe-slot=tpm2}} is able to identify which slot it needs to wipe, but it does. This even works if your TPM has changed.<br />
<br />
You can see the effects by comparing the output of {{ic|cryptsetup luksDump /dev/nvme0n1p2}} before and after you enroll or wipe a TPM based key. You can identify what slot your own passphrase is in with {{ic|cryptsetup --verbose open --test-passphrase /dev/nvme0n1p2}} and entering your passphrase. The output will inform you which key slot was unlocked.<br />
<br />
Finally, your passphrase may be changed with {{ic|cryptsetup luksChangeKey /dev/nvme0n1p2 -S 0}}.<br />
<br />
== Planned TODOs ==<br />
A panic command that can dump the TPM and shutdown the computer (without requiring the time of entering a password in sudo) forcing an adversary to resort to [https://en.wikipedia.org/wiki/Rubber-hose_cryptanalysis rubber-hose cryptanalysis] to get to the encrypted data.</div>Krinhttps://wiki.archlinux.org/index.php?title=User:Krin&diff=698005User:Krin2021-10-01T16:52:46Z<p>Krin: Update link</p>
<hr />
<div>* Install Notes<br />
** [[User:Krin/Secure Boot, full disk encryption, and TPM2 unlocking install]]: Notes on installing a (relatively) secured laptop for travel.<br />
* Miscellaneous Notes<br />
** [[User:Krin/dracut]]: Notes on working with dracut and UKI's.</div>Krinhttps://wiki.archlinux.org/index.php?title=User:Krin&diff=698004User:Krin2021-10-01T16:51:28Z<p>Krin: </p>
<hr />
<div>* Install Notes<br />
** [[User:Krin/Secured Laptop]]: Notes on installing a (relatively) secured laptop for travel.<br />
* Miscellaneous Notes<br />
** [[User:Krin/dracut]]: Notes on working with dracut and UKI's.</div>Krinhttps://wiki.archlinux.org/index.php?title=User:Krin/Secured_laptop&diff=698003User:Krin/Secured laptop2021-10-01T16:50:29Z<p>Krin: Krin moved page User:Krin/Secured laptop to User:Krin/Secure Boot, full disk encryption, and TPM2 unlocking install: Better description since the article has been genericized a bit from the specific laptop</p>
<hr />
<div>#REDIRECT [[User:Krin/Secure Boot, full disk encryption, and TPM2 unlocking install]]</div>Krinhttps://wiki.archlinux.org/index.php?title=User:Krin/Secure_Boot,_full_disk_encryption,_and_TPM2_unlocking_install&diff=698002User:Krin/Secure Boot, full disk encryption, and TPM2 unlocking install2021-10-01T16:50:29Z<p>Krin: Krin moved page User:Krin/Secured laptop to User:Krin/Secure Boot, full disk encryption, and TPM2 unlocking install: Better description since the article has been genericized a bit from the specific laptop</p>
<hr />
<div>{{Unsupported|30 September 2021}}<br />
{{Expansion|Work In Progress, Draft from Installation Notes, Needs Testing}}<br />
<br />
== Introduction ==<br />
<br />
This installation is based on my installing Arch on an Asus ROG Strix G G531 I got second hand and a desktop computer made of second hand parts that had to share space with Windows. The primary goals were to replace Windows 10 Pro with Bitlocker encryption and maintain the convienence and security balance of that original operating system.<br />
<br />
My requirements boiled down to:<br />
<br />
* A fully encrypted disk<br />
* Full Secure Boot validation of all UEFI components.<br />
* Use of the TPM to facilitate unlocking of the disk.<br />
* Hibernate/Suspend working.<br />
<br />
My primary use case here is to make it difficult enough for a baggage handler with sticky hands to get at my data that they just wipe the drive. A state level actor with the expertise and equipment to hot swap my ram in my hotel room is not something that I'm defending this ''particular'' laptop against. This is more for gaming and web browsing and uploading photos while traveling.<br />
<br />
I'll continue to update these notes as I develop further solutions.<br />
<br />
== Disclaimers ==<br />
<br />
This article is primarily for the author's own notes. It is assumed that the reader is familiar with the [[Installation guide]] and will refer to it often. Reading linked articles is recommended.<br />
<br />
== Dual Booting Modifications ==<br />
<br />
{{warning|If you use BitLocker on your Windows drive, ensure you have your recovery key handy. The installation process will change your TPM measurements causing Windows to require you enter the key manually the next time you boot it.}}<br />
<br />
For computers that will have to dual boot with windows, the easiest solution is to use two different physical drives and utilize your motherboard's UEFI boot menu to select which one to boot. This guide will follow that assumption. You can also attempt to have everything live on one EFI partition. Windows's 100 MiB EFI partition is especially problematic to this approach for secure boot, as Unified Kernel Images can approach 80 MiB and Windows 10 regularly uses up to 30 MiB.<br />
<br />
There are two changes that will be made and will be noted in the relevant sections:<br />
<br />
* Do not clear your Secure Boot keys. Merely disable Secure Boot for the installation.<br />
* Use {{ic|shim}} to boot systemd-bootloader<br />
* Load your db.cer file into the MOKManager application.<br />
<br />
All remaining steps should remain the same, except your system will still be dependent on the factory provided Microsoft Certificates. But you can boot Windows 10 in Secure Boot, which will be important for Windows 11.<br />
<br />
== Initial setup ==<br />
<br />
=== Pre-installation ===<br />
<br />
If you will only boot linux, reset your Secure Boot settings in BIOS to enable setup mode. Usually this means you set Secure Boot to Enabled and then select the option to wipe out the keys.<br />
<br />
If you will be dual booting Windows, disable secure boot.<br />
<br />
Follow the [[Installation_guide#Pre-installation]] up to Paritioning the Disks.<br />
<br />
=== Disk preparation ===<br />
<br />
If you have data on your disks you want to overwrite, utilize [[Dm-crypt/Drive_preparation#dm-crypt_wipe_on_an_empty_disk_or_partition]] to wipe it. If this disk was previously encrypted, utilize [[Dm-crypt/Drive_preparation#Wipe_LUKS_header]] instead for a much faster disposal. Finally, use [[Dm-crypt/Encrypting_an_entire_system#LVM_on_LUKS]] to parition your drive with two differences.<br />
<br />
{{tip|Using a memorable LUKS passphrase until you've completed the install process can be helpful. It will take several reboots to finish setup.}}<br />
<br />
First, the partition layout will be similar to here. You may wish to break out the /home directory into it's own partition. The primary requirement is that only your EFI partition be unencrypted.<br />
<br />
{{hc|Partiton Layout|<br />
┌────────────────────┬──────────────────────────┬─────────────────────────────┐<br />
│ │ │ │<br />
│ EFI Boot Partition │ Logical Volume 1 │ Logical Volume 2 │<br />
│ │ │ │<br />
│ /efi │ [SWAP] │ / │<br />
│ │ │ │<br />
│ /dev/nvme0n1p1 │ /dev/CryptRootVG/swap │ /dev/CryptRootVG/root │<br />
│ │ │ │<br />
│ 512 MB │ 16 GB (Or RAM size) │ Remaining Free Space │<br />
│ │ │ │<br />
│ │ │ │<br />
│ ├──────────────────────────┴─────────────────────────────┤<br />
│ │ │<br />
│ │ LUKS and LVM Physical Volume │<br />
│ │ │<br />
│ │ /dev/nvme0n1p2 │<br />
│ │ │<br />
└────────────────────┴────────────────────────────────────────────────────────┘<br />
}}<br />
<br />
Second, if your hard drive is an SSD like this laptop, use the following command to open your LUKS volume.<br />
<br />
# cryptsetup open --perf-no_read_workqueue --perf-no_write_workqueue --persistent /dev/nvme0n1p2 cryptroot<br />
<br />
After completing your LUKS on LVM setup, format your EFI partition per [[EFI system partition]].<br />
<br />
# mkfs.fat -F32 /dev/nvme0n1p1<br />
<br />
Mount this partition at {{ic|/mnt/efi}}. It is very important to leave {{ic|/boot}} on your encrypted root partition.<br />
<br />
== Installation ==<br />
<br />
Continue with [[Installation_guide#Installation]]. Be sure to flesh out your {{man|8|pacstrap}} with the following list of packages:<br />
<br />
* {{Pkg|dracut}}<br />
* {{Pkg|intel-ucode}}<br />
* {{Pkg|lvm2}}<br />
* {{Pkg|openssh}}<br />
* {{Pkg|ansible}}<br />
* {{Pkg|git}}<br />
* {{Pkg|iwd}}<br />
* {{Pkg|efibootmgr}}<br />
<br />
<br />
We are going to leave off the installation guide at the initramfs section, so go ahead and reset your root password. <br />
<br />
# passwd<br />
<br />
=== Bootloader ===<br />
<br />
First, install {{ic|systemd-boot}} by following [[Systemd-boot#Installing_the_EFI_boot_manager]]. Next, install {{aur|dracut-hook-uefi}}.<br />
<br />
Ensure you drop in a systemd-boot hook to update your bootctl any time it's updated.<br />
<br />
{{hc|/etc/pacman.d/hooks/998-systemd-boot.hook|2=<br />
[Trigger]<br />
Type = Package<br />
Operation = Install<br />
Operation = Upgrade<br />
Target = systemd<br />
<br />
[Action]<br />
Description = Updating systemd-boot<br />
When = PostTransaction<br />
Exec = /usr/bin/bootctl update; <br />
}}<br />
<br />
Obtain the UUID of your LUKS drive via the following command:<br />
<br />
{{bc|<br />
blkid -s UUID -o value /dev/nvme0n1p2<br />
}}<br />
<br />
Create the following files with the listed content. Be sure to replace UUIDs with what you actually need. See {{man|5|dracut.conf}} for more information on what these commands do.<br />
<br />
A good portion of the kernel command line was as generated by dracut. Many are extraneous or you may wish to change some of the block device names.<br />
<br />
{{hc|/etc/dracut.conf.d/cmdline.conf|2=<br />
kernel_cmdline="rd.luks.uuid=luks-17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02 rd.lvm.lv=CryptRoot/root rd.lvm.lv=CryptRoot/swap resume=/dev/mapper/CryptRoot-swap root=/dev/mapper/CryptRoot-root rootfstype=ext4 rootflags=rw,relatime"<br />
}}<br />
<br />
{{hc|/etc/dracut.conf.d/flags.conf|2=<br />
compress="zstd"<br />
hostonly="yes"<br />
}}<br />
<br />
Run the following command to generate your EFI stub kernels.<br />
<br />
dracut --uefi<br />
<br />
=== Secure boot ===<br />
<br />
==== Dual Booting Windows ====<br />
<br />
{{warning|This section is still being written}}<br />
<br />
Review [[Unified Extensible Firmware Interface/Secure Boot#shim]] to get a rough understanding of how it's going to work. Install {{aur|shim-signed}}. Perform the following commands to place files where both the UEFI boot entry and shim will load them.<br />
<br />
# mv /efi/EFI/BOOT/BOOTx64.EFI /efi/EFI/BOOT/grubx64.efi<br />
# cp /usr/share/shim-signed/shimx64.efi esp/EFI/BOOT/BOOTx64.EFI<br />
# cp /usr/share/shim-signed/mmx64.efi esp/EFI/BOOT/<br />
<br />
Install {{Pkg|sbctl}}. Use the following command to check that secure boot is in the right status. Your output should be similar.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✘ Sbctl is not installed<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/BOOT/grubx64.efi is not signed<br />
<br />
✘ /efi/EFI/BOOT/mmx64.efi is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
}}<br />
<br />
Note that shim and MOKManager (mmx) is included in this list, even though we will not be signing it.<br />
<br />
{{bc|<br />
# sbctl sign -s /efi/EFI/BOOT/ grubx64.efi <br />
<br />
✔ Signed /efi/EFI/BOOT/grubx64.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi <br />
<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi <br />
<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi<br />
# sbctl verify<br />
<br />
Verifying file database and EFI images in /efi...<br />
✔� /efi/EFI/BOOT/grubx64.efi is signed<br />
✔ /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi is signed<br />
✔ /efi/EFI/systemd/systemd-bootx64.efi is signed<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/BOOT/mmx64.efi is not signed<br />
}}<br />
<br />
You can validate that {{ic|BOOTx64.EFI}} and {{ic|mmx64.efi}} have signatures with {{man|1|sbverify}} from the {{Pkg|sbsigntools}} package.<br />
<br />
Next, we need to create the DER format certificate to load into ''MokManager''.<br />
<br />
# openssl x509 -outform DER -in /usr/share/secureboot/keys/db/db.pem -out /efi/signing.cer<br />
<br />
Use {{Pkg|efibootmgr}} ({{man|8|efibootmgr}}) to adjust your boot entries. Primarily, you will want to remove the {{ic|Linux Boot Manager}} entry.<br />
<br />
{{bc|<br />
# efibootmgr<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0001,0000,0002,0003,0004<br />
Boot0000* Windows Boot Manager<br />
Boot0001* Linux Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
}}<br />
<br />
In this example, we see that {{ic|0000}} is the Windows boot manager. {{ic|0001}} is the Linux Boot Manager and also the first in line to boot. {{ic|0001}} needs to be deleted and optionally the boot order modified so {{ic|0004}} is the default boot entry.<br />
<br />
{{bc|<br />
# efibootmgr --bootnum 0001 --delete-bootnum<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0000,0002,0003,0004<br />
Boot0000* Windows Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
<br />
# efibootmgr --bootorder 0004,0000,0002,0003<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0004,0000,0002,0003<br />
Boot0000* Windows Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Now reboot. You should get an error from your motherboard's UEFI BIOS that secure boot checks failed. Your computer should restart directly into ''MokManager'', if you rearranged the boot order. If not, you will need to select {{ic|UEFI OS}} from your UEFI boot menu. Navigate to the {{ic|signing.cer}} file we placed on the EFI partition and enroll the key. Select reboot, and the system should boot directly into linux with no problem.<br />
<br />
==== Booting only Linux ====<br />
<br />
{{note|The very newly developed [https://github.com/Foxboron/sbctl sbctl], availble via {{aur|sbctl-git}} has completely revamped this process and will only get better as they approach 1.0. From here on out, as of October 2021, this process should greatly simplify.}}<br />
<br />
{{note|Credit to this [https://lunaryorn.com/secure-boot-on-arch-linux-with-sbctl-and-dracut blog post by lunaryorn] for the inspiration.}}<br />
<br />
Install {{Pkg|sbctl}}. At this point you will likely need to reboot and adjust your secure boot settings. You want secure boot in '''setup mode'''. <br />
<br />
{{bc|<br />
$ sbctl status<br />
Installed: X Sbctl is not installed<br />
Setup Mode: X Enabled<br />
Secure Boot: X Disabled<br />
}}<br />
<br />
Run the following commands as root. See {{man|8|sbctl}} for more information on their function. Of particular note is the {{ic|-s}} flag which indicates {{ic|sbctl}} should remember the file for future verification and signing.<br />
<br />
Note your Linux EFI binary name may be slightly different.<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
<br />
# sbctl sign -s /efi/EFI/BOOT/BOOTx64.EFI<br />
✔ Signed /efi/EFI/BOOT/BOOTx64.EFI<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Finally, enroll the Secure Boot keys.<br />
<br />
{{bc|<br />
# sbctl enroll-keys<br />
Enrolling keys to EFI variables...✔<br />
Enrolled keys to the EFI variables!<br />
}}<br />
<br />
Verify that secure boot now has an owner GUID and setup mode is disabled.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✔ Sbctl is installed<br />
Owner GUID: a2ee3d08-725a-408b-9d95-28026a44611c<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
Now reboot. This reboot is required so we can get the TPM measurements into their (hopefully) permanent state.<br />
<br />
=== Enroll LUKS key in TPM ===<br />
{{warning|Yes, this will cause a system to automatically unlock it's encrypted root volume without any interaction from a human. Yes, this exposes it to any sufficently advanced Evil Maid attacks. If sealed against the appropriate registers (especially register 8 with the kernel arguments), the TPM measurements should force systemd to ask for your LUKS passphrase in almost any attempt to access the encrypted volume from outside your normal boot process.}}<br />
<br />
We are fortunate that in our shift to dracut includes utilizing systemd and sd-encrypt, as we can use systemd's native support for enrolling LUKS keys. A review of [[Trusted Platform Module#Using TPM 2.0]] is recommended but not very clear.<br />
<br />
==== Avoid dracut bugs ====<br />
<br />
Subtitle: The Case of the Missing {{ic|d}}<br />
<br />
Two bugs, one in systemd 249.4-1-arch [https://github.com/systemd/systemd/issues/19177] and one in dracut 055 [https://github.com/dracutdevs/dracut/pull/1526][https://github.com/dracutdevs/dracut/issues/1542] will combine to prevent your system from being able to boot. The dracut issue causes the '''tpm2-tss''' module to not be included in your image. The systemd issue causes systemd to go into an emergency when it can't locate the TPM2 libraries, instead of falling back to asking for your passcode.<br />
<br />
The systemd bug isn't a problem so long as you always have TPM2 libraries present.<br />
<br />
To resolve this, first check your version of dracut.<br />
<br />
{{bc|<br />
$ dracut --version<br />
dracut 055<br />
}}<br />
<br />
Since the next release of dracut should have this fixed, we can simply fix the script locally until the next release.<br />
<br />
{{warning|These steps are only necessary for dracut 055}}<br />
<br />
Find the following lines in {{ic|/usr/lib/dracut/modules.d/91tpm2-tss/module-setup.sh}}:<br />
<br />
{{bc|1=<br />
# Module dependency requirements.<br />
depends() {<br />
<br />
# This module has external dependency on other module(s).<br />
echo systemd-sysusers systemd-udev<br />
# Return 0 to include the dependent module(s) in the initramfs.<br />
return 0<br />
<br />
}<br />
}}<br />
<br />
Change the dependency {{ic|systemd-udev}} to <code>systemd-udev<b>d</b></code>.<br />
<br />
Continue with the remaining steps in this section.<br />
<br />
==== Enrollment ====<br />
<br />
First, be sure to install {{Pkg|tpm2-tools}}. Alternatively {{aur|ibm-tss}} can be used per [[Trusted Platform Module]], however this guide is not tested against those.<br />
<br />
{{note|A reboot may be required to convince {{ic|systemd-cryptenroll}} that TPM 2.0 devices now exist on the machine.}}<br />
<br />
There are several decisions to be made here. The table at [[Trusted Platform Module#Accessing PCR registers]] is accurate as of October 2021. Essentially, once you seal your LUKS key, if any of the registers you've sealed against change, then you will be asked for your LUKS passphrase. This is equivalent to when Windows 10 makes you enter your BitLocker recovery key after a hardware change or changing BIOS settings.<br />
<br />
Your mileage may vary, based on UEFI vendors. For my laptop, I went with 0+1+2+3+4+5+7+8 and have been able to invalidate my TPM. Unfortunately, if you change your system BACK the volume will unlock. I'm investigating how to disable that.<br />
<br />
Other options on {{man|1|systemd-cryptenroll}} will reveal that several hardware tokens can also be enrolled to allow unlocking the root LUKS volume automatically, but only if a key is present. Further testing is requried.<br />
<br />
To enroll your LUKS volume, simply run the following command as root<br />
<br />
# systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/nvme0n1p2<br />
<br />
To remove your key, run this command:<br />
<br />
# systemd-cryptenroll --wipe-slot=tpm2 /dev/nvme0n1p2<br />
<br />
You will need to add a kernel argument like below to enable the TPM2 bits. If following this guide, this should be located in {{ic|/etc/dracut.conf.d/cmdline.conf}}<br />
<br />
rd.luks.options={UUID}=tpm2-device=auto<br />
<br />
Ensure that dracut builds in the TPM2 libraries. Create the following file.<br />
<br />
{{hc|/etc/dracut.conf.d/tpm2-tss.conf|2=<br />
add_dracutmodules+=" tpm2-tss "<br />
}}<br />
<br />
Finally, rebuild your unified kernel image.<br />
<br />
# dracut --force --uefi<br />
<br />
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:<br />
<br />
{{hc|~/bin/luks_reenroll_tpm|2=<br />
sudo systemd-cryptenroll --wipe-slot=tpm2 /dev/disk/by-uuid/{UUID_HERE}<br />
systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/disk/by-uuid/{UUID_HERE}<br />
}}<br />
<br />
=== Wrapping up ===<br />
<br />
Set your UEFI password. <br />
<br />
Change your LUKS passphrase from something easily memorable to a good long recovery key.<br />
<br />
Keep both of these pieces of info somewhere safe. This varies depending on your threat model. If we're just talking about Stolen Laptops and Nosy Maids, a hard copy in your safe should be sufficient. If it's the NSA, I'm not sure this setup is appropriate for that model.<br />
<br />
This is an excellent base to handle stolen laptop and even some lower grade Evil Maids. From here, you should head into [[Security]]. Consider learning a framework to help you manage your system state such as [[Ansible]] or headless [[Puppet]].<br />
<br />
== Justifications ==<br />
<br />
=== LVM on LUKS vs other dm-crypt approaches ===<br />
<br />
LVM on LUKS was selected becasue it is simply the easiest to manage while conferring both encrypted swap and disk. The other approaches required much more tooling and manual fussing to utilize. This selection also gives room change freely between {{ic|busybox}} and {{ic|systemd}} initrds.<br />
<br />
=== Using dracut ===<br />
<br />
{{Pkg|dracut}} just makes it easier to build full unified kernels that {{man|7|systemd-boot}} can launch as EFI binaries. There is also available tooling in the [[AUR]] for automating the creation of these binaries. Finally, {{ic|dracut}} will sign the binaries it creates automatically when configured to do so.<br />
<br />
=== Unified kernel images ===<br />
<br />
While UKI's could be problematic on other distributions, they fit right in with an Arch Linux install. The automation is there through pacman hooks and {{Pkg|sbctl}} to sign our UKIs as they're created. Furthermore, you can only sign and create a new signed UKI while booted into a properly signed UKI. It creates a chain of trust, which means it's important to never disable Secure Boot once you've set it up.<br />
<br />
The UKI encompasses all of the following items inside the signature, which means you can't change any of them without invalidating the signature.<br />
<br />
* Kernel arguments<br />
* Initrd/Initramfs<br />
* Kernel<br />
<br />
In particular, all other flavors of secureboot do not sign or validate the initramfs. This is a big attack area and can be relatively trivialized that a semi-decent pawn shop owner with Google could likely find an image that would grant him access and make the TPM none the wiser the system has changed. One can prevent this with encrypted /boot, but that would limit you to GRUB2 and LUKS version 1 devices only. This also doesn't include the work to keep GRUB2's files signed with a PGP key by root.<br />
<br />
=== LUKS enrolled in TPM ===<br />
<br />
The goal here is to only require the passphrase when something spooky happens in your boot path.<br />
<br />
UEFI settings change? Request password.<br />
<br />
Some weird swap of some module of UEFI code that lives on your motherboard somewhere? Request password.<br />
<br />
Unified Kernel Image changes? Don't even boot.<br />
<br />
Drive in another computer? Request password.<br />
<br />
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.<br />
<br />
== Miscellaneous discussions ==<br />
<br />
=== Filesystem Selection ===<br />
<br />
Most examples on Arch utilize {{ic|ext4}}, but other file systems such as {{ic|brtfs}} can work equally well. As for performance or issues with being inside LVM, [https://btrfs.wiki.kernel.org/index.php/FAQ#Btrfs_has_subvolumes.2C_does_this_mean_I_don.27t_need_a_logical_volume_manager_and_I_can_create_a_big_Btrfs_filesystem_on_a_raw_partition.3F this question in the brtfs FAQ] implie that there is some performance loss but no other issues.<br />
<br />
=== LUKS TPM enrollment and managing luks keys ===<br />
<br />
Note that using {{man|1|systemd-cryptenroll}} will add a key to your LUKS volume. It's not clear how exactly the option {{ic|1=--wipe-slot=tpm2}} is able to identify which slot it needs to wipe, but it does. This even works if your TPM has changed.<br />
<br />
You can see the effects by comparing the output of {{ic|cryptsetup luksDump /dev/nvme0n1p2}} before and after you enroll or wipe a TPM based key. You can identify what slot your own passphrase is in with {{ic|cryptsetup --verbose open --test-passphrase /dev/nvme0n1p2}} and entering your passphrase. The output will inform you which key slot was unlocked.<br />
<br />
Finally, your passphrase may be changed with {{ic|cryptsetup luksChangeKey /dev/nvme0n1p2 -S 0}}.<br />
<br />
== Planned TODOs ==<br />
A panic command that can dump the TPM and shutdown the computer (without requiring the time of entering a password in sudo) forcing an adversary to resort to [https://en.wikipedia.org/wiki/Rubber-hose_cryptanalysis rubber-hose cryptanalysis] to get to the encrypted data.</div>Krinhttps://wiki.archlinux.org/index.php?title=User:Krin/Secure_Boot,_full_disk_encryption,_and_TPM2_unlocking_install&diff=697970User:Krin/Secure Boot, full disk encryption, and TPM2 unlocking install2021-10-01T12:41:48Z<p>Krin: /* Enrollment */ Add step to rebuild image.</p>
<hr />
<div>{{Unsupported|30 September 2021}}<br />
{{Expansion|Work In Progress, Draft from Installation Notes, Needs Testing}}<br />
<br />
== Introduction ==<br />
<br />
This installation is based on my installing Arch on an Asus ROG Strix G G531 I got second hand and a desktop computer made of second hand parts that had to share space with Windows. The primary goals were to replace Windows 10 Pro with Bitlocker encryption and maintain the convienence and security balance of that original operating system.<br />
<br />
My requirements boiled down to:<br />
<br />
* A fully encrypted disk<br />
* Full Secure Boot validation of all UEFI components.<br />
* Use of the TPM to facilitate unlocking of the disk.<br />
* Hibernate/Suspend working.<br />
<br />
My primary use case here is to make it difficult enough for a baggage handler with sticky hands to get at my data that they just wipe the drive. A state level actor with the expertise and equipment to hot swap my ram in my hotel room is not something that I'm defending this ''particular'' laptop against. This is more for gaming and web browsing and uploading photos while traveling.<br />
<br />
I'll continue to update these notes as I develop further solutions.<br />
<br />
== Disclaimers ==<br />
<br />
This article is primarily for the author's own notes. It is assumed that the reader is familiar with the [[Installation guide]] and will refer to it often. Reading linked articles is recommended.<br />
<br />
== Dual Booting Modifications ==<br />
<br />
{{warning|If you use BitLocker on your Windows drive, ensure you have your recovery key handy. The installation process will change your TPM measurements causing Windows to require you enter the key manually the next time you boot it.}}<br />
<br />
For computers that will have to dual boot with windows, the easiest solution is to use two different physical drives and utilize your motherboard's UEFI boot menu to select which one to boot. This guide will follow that assumption. You can also attempt to have everything live on one EFI partition. Windows's 100 MiB EFI partition is especially problematic to this approach for secure boot, as Unified Kernel Images can approach 80 MiB and Windows 10 regularly uses up to 30 MiB.<br />
<br />
There are two changes that will be made and will be noted in the relevant sections:<br />
<br />
* Do not clear your Secure Boot keys. Merely disable Secure Boot for the installation.<br />
* Use {{ic|shim}} to boot systemd-bootloader<br />
* Load your db.cer file into the MOKManager application.<br />
<br />
All remaining steps should remain the same, except your system will still be dependent on the factory provided Microsoft Certificates. But you can boot Windows 10 in Secure Boot, which will be important for Windows 11.<br />
<br />
== Initial setup ==<br />
<br />
=== Pre-installation ===<br />
<br />
If you will only boot linux, reset your Secure Boot settings in BIOS to enable setup mode. Usually this means you set Secure Boot to Enabled and then select the option to wipe out the keys.<br />
<br />
If you will be dual booting Windows, disable secure boot.<br />
<br />
Follow the [[Installation_guide#Pre-installation]] up to Paritioning the Disks.<br />
<br />
=== Disk preparation ===<br />
<br />
If you have data on your disks you want to overwrite, utilize [[Dm-crypt/Drive_preparation#dm-crypt_wipe_on_an_empty_disk_or_partition]] to wipe it. If this disk was previously encrypted, utilize [[Dm-crypt/Drive_preparation#Wipe_LUKS_header]] instead for a much faster disposal. Finally, use [[Dm-crypt/Encrypting_an_entire_system#LVM_on_LUKS]] to parition your drive with two differences.<br />
<br />
{{tip|Using a memorable LUKS passphrase until you've completed the install process can be helpful. It will take several reboots to finish setup.}}<br />
<br />
First, the partition layout will be similar to here. You may wish to break out the /home directory into it's own partition. The primary requirement is that only your EFI partition be unencrypted.<br />
<br />
{{hc|Partiton Layout|<br />
┌────────────────────┬──────────────────────────┬─────────────────────────────┐<br />
│ │ │ │<br />
│ EFI Boot Partition │ Logical Volume 1 │ Logical Volume 2 │<br />
│ │ │ │<br />
│ /efi │ [SWAP] │ / │<br />
│ │ │ │<br />
│ /dev/nvme0n1p1 │ /dev/CryptRootVG/swap │ /dev/CryptRootVG/root │<br />
│ │ │ │<br />
│ 512 MB │ 16 GB (Or RAM size) │ Remaining Free Space │<br />
│ │ │ │<br />
│ │ │ │<br />
│ ├──────────────────────────┴─────────────────────────────┤<br />
│ │ │<br />
│ │ LUKS and LVM Physical Volume │<br />
│ │ │<br />
│ │ /dev/nvme0n1p2 │<br />
│ │ │<br />
└────────────────────┴────────────────────────────────────────────────────────┘<br />
}}<br />
<br />
Second, if your hard drive is an SSD like this laptop, use the following command to open your LUKS volume.<br />
<br />
# cryptsetup open --perf-no_read_workqueue --perf-no_write_workqueue --persistent /dev/nvme0n1p2 cryptroot<br />
<br />
After completing your LUKS on LVM setup, format your EFI partition per [[EFI system partition]].<br />
<br />
# mkfs.fat -F32 /dev/nvme0n1p1<br />
<br />
Mount this partition at {{ic|/mnt/efi}}. It is very important to leave {{ic|/boot}} on your encrypted root partition.<br />
<br />
== Installation ==<br />
<br />
Continue with [[Installation_guide#Installation]]. Be sure to flesh out your {{man|8|pacstrap}} with the following list of packages:<br />
<br />
* {{Pkg|dracut}}<br />
* {{Pkg|intel-ucode}}<br />
* {{Pkg|lvm2}}<br />
* {{Pkg|openssh}}<br />
* {{Pkg|ansible}}<br />
* {{Pkg|git}}<br />
* {{Pkg|iwd}}<br />
* {{Pkg|efibootmgr}}<br />
<br />
<br />
We are going to leave off the installation guide at the initramfs section, so go ahead and reset your root password. <br />
<br />
# passwd<br />
<br />
=== Bootloader ===<br />
<br />
First, install {{ic|systemd-boot}} by following [[Systemd-boot#Installing_the_EFI_boot_manager]]. Next, install {{aur|dracut-hook-uefi}}.<br />
<br />
Ensure you drop in a systemd-boot hook to update your bootctl any time it's updated.<br />
<br />
{{hc|/etc/pacman.d/hooks/998-systemd-boot.hook|2=<br />
[Trigger]<br />
Type = Package<br />
Operation = Install<br />
Operation = Upgrade<br />
Target = systemd<br />
<br />
[Action]<br />
Description = Updating systemd-boot<br />
When = PostTransaction<br />
Exec = /usr/bin/bootctl update; <br />
}}<br />
<br />
Obtain the UUID of your LUKS drive via the following command:<br />
<br />
{{bc|<br />
blkid -s UUID -o value /dev/nvme0n1p2<br />
}}<br />
<br />
Create the following files with the listed content. Be sure to replace UUIDs with what you actually need. See {{man|5|dracut.conf}} for more information on what these commands do.<br />
<br />
A good portion of the kernel command line was as generated by dracut. Many are extraneous or you may wish to change some of the block device names.<br />
<br />
{{hc|/etc/dracut.conf.d/cmdline.conf|2=<br />
kernel_cmdline="rd.luks.uuid=luks-17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02 rd.lvm.lv=CryptRoot/root rd.lvm.lv=CryptRoot/swap resume=/dev/mapper/CryptRoot-swap root=/dev/mapper/CryptRoot-root rootfstype=ext4 rootflags=rw,relatime"<br />
}}<br />
<br />
{{hc|/etc/dracut.conf.d/flags.conf|2=<br />
compress="zstd"<br />
hostonly="yes"<br />
}}<br />
<br />
Run the following command to generate your EFI stub kernels.<br />
<br />
dracut --uefi<br />
<br />
=== Secure boot ===<br />
<br />
==== Dual Booting Windows ====<br />
<br />
{{warning|This section is still being written}}<br />
<br />
Review [[Unified Extensible Firmware Interface/Secure Boot#shim]] to get a rough understanding of how it's going to work. Install {{aur|shim-signed}}. Perform the following commands to place files where both the UEFI boot entry and shim will load them.<br />
<br />
# mv /efi/EFI/BOOT/BOOTx64.EFI /efi/EFI/BOOT/grubx64.efi<br />
# cp /usr/share/shim-signed/shimx64.efi esp/EFI/BOOT/BOOTx64.EFI<br />
# cp /usr/share/shim-signed/mmx64.efi esp/EFI/BOOT/<br />
<br />
Install {{Pkg|sbctl}}. Use the following command to check that secure boot is in the right status. Your output should be similar.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✘ Sbctl is not installed<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/BOOT/grubx64.efi is not signed<br />
<br />
✘ /efi/EFI/BOOT/mmx64.efi is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
}}<br />
<br />
Note that shim and MOKManager (mmx) is included in this list, even though we will not be signing it.<br />
<br />
{{bc|<br />
# sbctl sign -s /efi/EFI/BOOT/ grubx64.efi <br />
<br />
✔ Signed /efi/EFI/BOOT/grubx64.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi <br />
<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi <br />
<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi<br />
# sbctl verify<br />
<br />
Verifying file database and EFI images in /efi...<br />
✔� /efi/EFI/BOOT/grubx64.efi is signed<br />
✔ /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi is signed<br />
✔ /efi/EFI/systemd/systemd-bootx64.efi is signed<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/BOOT/mmx64.efi is not signed<br />
}}<br />
<br />
You can validate that {{ic|BOOTx64.EFI}} and {{ic|mmx64.efi}} have signatures with {{man|1|sbverify}} from the {{Pkg|sbsigntools}} package.<br />
<br />
Next, we need to create the DER format certificate to load into ''MokManager''.<br />
<br />
# openssl x509 -outform DER -in /usr/share/secureboot/keys/db/db.pem -out /efi/signing.cer<br />
<br />
Use {{Pkg|efibootmgr}} ({{man|8|efibootmgr}}) to adjust your boot entries. Primarily, you will want to remove the {{ic|Linux Boot Manager}} entry.<br />
<br />
{{bc|<br />
# efibootmgr<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0001,0000,0002,0003,0004<br />
Boot0000* Windows Boot Manager<br />
Boot0001* Linux Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
}}<br />
<br />
In this example, we see that {{ic|0000}} is the Windows boot manager. {{ic|0001}} is the Linux Boot Manager and also the first in line to boot. {{ic|0001}} needs to be deleted and optionally the boot order modified so {{ic|0004}} is the default boot entry.<br />
<br />
{{bc|<br />
# efibootmgr --bootnum 0001 --delete-bootnum<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0000,0002,0003,0004<br />
Boot0000* Windows Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
<br />
# efibootmgr --bootorder 0004,0000,0002,0003<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0004,0000,0002,0003<br />
Boot0000* Windows Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Now reboot. You should get an error from your motherboard's UEFI BIOS that secure boot checks failed. Your computer should restart directly into ''MokManager'', if you rearranged the boot order. If not, you will need to select {{ic|UEFI OS}} from your UEFI boot menu. Navigate to the {{ic|signing.cer}} file we placed on the EFI partition and enroll the key. Select reboot, and the system should boot directly into linux with no problem.<br />
<br />
==== Booting only Linux ====<br />
<br />
{{note|The very newly developed [https://github.com/Foxboron/sbctl sbctl], availble via {{aur|sbctl-git}} has completely revamped this process and will only get better as they approach 1.0. From here on out, as of October 2021, this process should greatly simplify.}}<br />
<br />
{{note|Credit to this [https://lunaryorn.com/secure-boot-on-arch-linux-with-sbctl-and-dracut blog post by lunaryorn] for the inspiration.}}<br />
<br />
Install {{Pkg|sbctl}}. At this point you will likely need to reboot and adjust your secure boot settings. You want secure boot in '''setup mode'''. <br />
<br />
{{bc|<br />
$ sbctl status<br />
Installed: X Sbctl is not installed<br />
Setup Mode: X Enabled<br />
Secure Boot: X Disabled<br />
}}<br />
<br />
Run the following commands as root. See {{man|8|sbctl}} for more information on their function. Of particular note is the {{ic|-s}} flag which indicates {{ic|sbctl}} should remember the file for future verification and signing.<br />
<br />
Note your Linux EFI binary name may be slightly different.<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
<br />
# sbctl sign -s /efi/EFI/BOOT/BOOTx64.EFI<br />
✔ Signed /efi/EFI/BOOT/BOOTx64.EFI<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Finally, enroll the Secure Boot keys.<br />
<br />
{{bc|<br />
# sbctl enroll-keys<br />
Enrolling keys to EFI variables...✔<br />
Enrolled keys to the EFI variables!<br />
}}<br />
<br />
Verify that secure boot now has an owner GUID and setup mode is disabled.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✔ Sbctl is installed<br />
Owner GUID: a2ee3d08-725a-408b-9d95-28026a44611c<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
Now reboot. This reboot is required so we can get the TPM measurements into their (hopefully) permanent state.<br />
<br />
=== Enroll LUKS key in TPM ===<br />
{{warning|Yes, this will cause a system to automatically unlock it's encrypted root volume without any interaction from a human. Yes, this exposes it to any sufficently advanced Evil Maid attacks. If sealed against the appropriate registers (especially register 8 with the kernel arguments), the TPM measurements should force systemd to ask for your LUKS passphrase in almost any attempt to access the encrypted volume from outside your normal boot process.}}<br />
<br />
We are fortunate that in our shift to dracut includes utilizing systemd and sd-encrypt, as we can use systemd's native support for enrolling LUKS keys. A review of [[Trusted Platform Module#Using TPM 2.0]] is recommended but not very clear.<br />
<br />
==== Avoid dracut bugs ====<br />
<br />
Subtitle: The Case of the Missing {{ic|d}}<br />
<br />
Two bugs, one in systemd 249.4-1-arch [https://github.com/systemd/systemd/issues/19177] and one in dracut 055 [https://github.com/dracutdevs/dracut/pull/1526][https://github.com/dracutdevs/dracut/issues/1542] will combine to prevent your system from being able to boot. The dracut issue causes the '''tpm2-tss''' module to not be included in your image. The systemd issue causes systemd to go into an emergency when it can't locate the TPM2 libraries, instead of falling back to asking for your passcode.<br />
<br />
The systemd bug isn't a problem so long as you always have TPM2 libraries present.<br />
<br />
To resolve this, first check your version of dracut.<br />
<br />
{{bc|<br />
$ dracut --version<br />
dracut 055<br />
}}<br />
<br />
Since the next release of dracut should have this fixed, we can simply fix the script locally until the next release.<br />
<br />
{{warning|These steps are only necessary for dracut 055}}<br />
<br />
Find the following lines in {{ic|/usr/lib/dracut/modules.d/91tpm2-tss/module-setup.sh}}:<br />
<br />
{{bc|1=<br />
# Module dependency requirements.<br />
depends() {<br />
<br />
# This module has external dependency on other module(s).<br />
echo systemd-sysusers systemd-udev<br />
# Return 0 to include the dependent module(s) in the initramfs.<br />
return 0<br />
<br />
}<br />
}}<br />
<br />
Change the dependency {{ic|systemd-udev}} to <code>systemd-udev<b>d</b></code>.<br />
<br />
Continue with the remaining steps in this section.<br />
<br />
==== Enrollment ====<br />
<br />
First, be sure to install {{Pkg|tpm2-tools}}. Alternatively {{aur|ibm-tss}} can be used per [[Trusted Platform Module]], however this guide is not tested against those.<br />
<br />
{{note|A reboot may be required to convince {{ic|systemd-cryptenroll}} that TPM 2.0 devices now exist on the machine.}}<br />
<br />
There are several decisions to be made here. The table at [[Trusted Platform Module#Accessing PCR registers]] is accurate as of October 2021. Essentially, once you seal your LUKS key, if any of the registers you've sealed against change, then you will be asked for your LUKS passphrase. This is equivalent to when Windows 10 makes you enter your BitLocker recovery key after a hardware change or changing BIOS settings.<br />
<br />
Your mileage may vary, based on UEFI vendors. For my laptop, I went with 0+1+2+3+4+5+7+8 and have been able to invalidate my TPM. Unfortunately, if you change your system BACK the volume will unlock. I'm investigating how to disable that.<br />
<br />
Other options on {{man|1|systemd-cryptenroll}} will reveal that several hardware tokens can also be enrolled to allow unlocking the root LUKS volume automatically, but only if a key is present. Further testing is requried.<br />
<br />
To enroll your LUKS volume, simply run the following command as root<br />
<br />
# systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/nvme0n1p2<br />
<br />
To remove your key, run this command:<br />
<br />
# systemd-cryptenroll --wipe-slot=tpm2 /dev/nvme0n1p2<br />
<br />
You will need to add a kernel argument like below to enable the TPM2 bits. If following this guide, this should be located in {{ic|/etc/dracut.conf.d/cmdline.conf}}<br />
<br />
rd.luks.options={UUID}=tpm2-device=auto<br />
<br />
Ensure that dracut builds in the TPM2 libraries. Create the following file.<br />
<br />
{{hc|/etc/dracut.conf.d/tpm2-tss.conf|2=<br />
add_dracutmodules+=" tpm2-tss "<br />
}}<br />
<br />
Finally, rebuild your unified kernel image.<br />
<br />
# dracut --force --uefi<br />
<br />
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:<br />
<br />
{{hc|~/bin/luks_reenroll_tpm|2=<br />
sudo systemd-cryptenroll --wipe-slot=tpm2 /dev/disk/by-uuid/{UUID_HERE}<br />
systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/disk/by-uuid/{UUID_HERE}<br />
}}<br />
<br />
=== Wrapping up ===<br />
<br />
Set your UEFI password. <br />
<br />
Change your LUKS passphrase from something easily memorable to a good long recovery key.<br />
<br />
Keep both of these pieces of info somewhere safe. This varies depending on your threat model. If we're just talking about Stolen Laptops and Nosy Maids, a hard copy in your safe should be sufficient. If it's the NSA, I'm not sure this setup is appropriate for that model.<br />
<br />
This is an excellent base to handle stolen laptop and even some lower grade Evil Maids. From here, you should head into [[Security]]. Consider learning a framework to help you manage your system state such as [[Ansible]] or headless [[Puppet]].<br />
<br />
== Justifications ==<br />
<br />
=== LVM on LUKS vs other dm-crypt approaches ===<br />
<br />
LVM on LUKS was selected becasue it is simply the easiest to manage while conferring both encrypted swap and disk. The other approaches required much more tooling and manual fussing to utilize. This selection also gives room change freely between {{ic|busybox}} and {{ic|systemd}} initrds.<br />
<br />
=== Using dracut ===<br />
<br />
{{Pkg|dracut}} just makes it easier to build full unified kernels that {{man|7|systemd-boot}} can launch as EFI binaries. There is also available tooling in the [[AUR]] for automating the creation of these binaries. Finally, {{ic|dracut}} will sign the binaries it creates automatically when configured to do so.<br />
<br />
=== Unified kernel images ===<br />
<br />
While UKI's could be problematic on other distributions, they fit right in with an Arch Linux install. The automation is there through pacman hooks and {{Pkg|sbctl}} to sign our UKIs as they're created. Furthermore, you can only sign and create a new signed UKI while booted into a properly signed UKI. It creates a chain of trust, which means it's important to never disable Secure Boot once you've set it up.<br />
<br />
The UKI encompasses all of the following items inside the signature, which means you can't change any of them without invalidating the signature.<br />
<br />
* Kernel arguments<br />
* Initrd/Initramfs<br />
* Kernel<br />
<br />
In particular, all other flavors of secureboot do not sign or validate the initramfs. This is a big attack area and can be relatively trivialized that a semi-decent pawn shop owner with Google could likely find an image that would grant him access and make the TPM none the wiser the system has changed. One can prevent this with encrypted /boot, but that would limit you to GRUB2 and LUKS version 1 devices only. This also doesn't include the work to keep GRUB2's files signed with a PGP key by root.<br />
<br />
=== LUKS enrolled in TPM ===<br />
<br />
The goal here is to only require the passphrase when something spooky happens in your boot path.<br />
<br />
UEFI settings change? Request password.<br />
<br />
Some weird swap of some module of UEFI code that lives on your motherboard somewhere? Request password.<br />
<br />
Unified Kernel Image changes? Don't even boot.<br />
<br />
Drive in another computer? Request password.<br />
<br />
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.<br />
<br />
== Miscellaneous discussions ==<br />
<br />
=== Filesystem Selection ===<br />
<br />
Most examples on Arch utilize {{ic|ext4}}, but other file systems such as {{ic|brtfs}} can work equally well. As for performance or issues with being inside LVM, [https://btrfs.wiki.kernel.org/index.php/FAQ#Btrfs_has_subvolumes.2C_does_this_mean_I_don.27t_need_a_logical_volume_manager_and_I_can_create_a_big_Btrfs_filesystem_on_a_raw_partition.3F this question in the brtfs FAQ] implie that there is some performance loss but no other issues.<br />
<br />
=== LUKS TPM enrollment and managing luks keys ===<br />
<br />
Note that using {{man|1|systemd-cryptenroll}} will add a key to your LUKS volume. It's not clear how exactly the option {{ic|1=--wipe-slot=tpm2}} is able to identify which slot it needs to wipe, but it does. This even works if your TPM has changed.<br />
<br />
You can see the effects by comparing the output of {{ic|cryptsetup luksDump /dev/nvme0n1p2}} before and after you enroll or wipe a TPM based key. You can identify what slot your own passphrase is in with {{ic|cryptsetup --verbose open --test-passphrase /dev/nvme0n1p2}} and entering your passphrase. The output will inform you which key slot was unlocked.<br />
<br />
Finally, your passphrase may be changed with {{ic|cryptsetup luksChangeKey /dev/nvme0n1p2 -S 0}}.<br />
<br />
== Planned TODOs ==<br />
A panic command that can dump the TPM and shutdown the computer (without requiring the time of entering a password in sudo) forcing an adversary to resort to [https://en.wikipedia.org/wiki/Rubber-hose_cryptanalysis rubber-hose cryptanalysis] to get to the encrypted data.</div>Krinhttps://wiki.archlinux.org/index.php?title=User:Krin/Secure_Boot,_full_disk_encryption,_and_TPM2_unlocking_install&diff=697969User:Krin/Secure Boot, full disk encryption, and TPM2 unlocking install2021-10-01T12:37:49Z<p>Krin: /* Enrollment */ Add dracut config</p>
<hr />
<div>{{Unsupported|30 September 2021}}<br />
{{Expansion|Work In Progress, Draft from Installation Notes, Needs Testing}}<br />
<br />
== Introduction ==<br />
<br />
This installation is based on my installing Arch on an Asus ROG Strix G G531 I got second hand and a desktop computer made of second hand parts that had to share space with Windows. The primary goals were to replace Windows 10 Pro with Bitlocker encryption and maintain the convienence and security balance of that original operating system.<br />
<br />
My requirements boiled down to:<br />
<br />
* A fully encrypted disk<br />
* Full Secure Boot validation of all UEFI components.<br />
* Use of the TPM to facilitate unlocking of the disk.<br />
* Hibernate/Suspend working.<br />
<br />
My primary use case here is to make it difficult enough for a baggage handler with sticky hands to get at my data that they just wipe the drive. A state level actor with the expertise and equipment to hot swap my ram in my hotel room is not something that I'm defending this ''particular'' laptop against. This is more for gaming and web browsing and uploading photos while traveling.<br />
<br />
I'll continue to update these notes as I develop further solutions.<br />
<br />
== Disclaimers ==<br />
<br />
This article is primarily for the author's own notes. It is assumed that the reader is familiar with the [[Installation guide]] and will refer to it often. Reading linked articles is recommended.<br />
<br />
== Dual Booting Modifications ==<br />
<br />
{{warning|If you use BitLocker on your Windows drive, ensure you have your recovery key handy. The installation process will change your TPM measurements causing Windows to require you enter the key manually the next time you boot it.}}<br />
<br />
For computers that will have to dual boot with windows, the easiest solution is to use two different physical drives and utilize your motherboard's UEFI boot menu to select which one to boot. This guide will follow that assumption. You can also attempt to have everything live on one EFI partition. Windows's 100 MiB EFI partition is especially problematic to this approach for secure boot, as Unified Kernel Images can approach 80 MiB and Windows 10 regularly uses up to 30 MiB.<br />
<br />
There are two changes that will be made and will be noted in the relevant sections:<br />
<br />
* Do not clear your Secure Boot keys. Merely disable Secure Boot for the installation.<br />
* Use {{ic|shim}} to boot systemd-bootloader<br />
* Load your db.cer file into the MOKManager application.<br />
<br />
All remaining steps should remain the same, except your system will still be dependent on the factory provided Microsoft Certificates. But you can boot Windows 10 in Secure Boot, which will be important for Windows 11.<br />
<br />
== Initial setup ==<br />
<br />
=== Pre-installation ===<br />
<br />
If you will only boot linux, reset your Secure Boot settings in BIOS to enable setup mode. Usually this means you set Secure Boot to Enabled and then select the option to wipe out the keys.<br />
<br />
If you will be dual booting Windows, disable secure boot.<br />
<br />
Follow the [[Installation_guide#Pre-installation]] up to Paritioning the Disks.<br />
<br />
=== Disk preparation ===<br />
<br />
If you have data on your disks you want to overwrite, utilize [[Dm-crypt/Drive_preparation#dm-crypt_wipe_on_an_empty_disk_or_partition]] to wipe it. If this disk was previously encrypted, utilize [[Dm-crypt/Drive_preparation#Wipe_LUKS_header]] instead for a much faster disposal. Finally, use [[Dm-crypt/Encrypting_an_entire_system#LVM_on_LUKS]] to parition your drive with two differences.<br />
<br />
{{tip|Using a memorable LUKS passphrase until you've completed the install process can be helpful. It will take several reboots to finish setup.}}<br />
<br />
First, the partition layout will be similar to here. You may wish to break out the /home directory into it's own partition. The primary requirement is that only your EFI partition be unencrypted.<br />
<br />
{{hc|Partiton Layout|<br />
┌────────────────────┬──────────────────────────┬─────────────────────────────┐<br />
│ │ │ │<br />
│ EFI Boot Partition │ Logical Volume 1 │ Logical Volume 2 │<br />
│ │ │ │<br />
│ /efi │ [SWAP] │ / │<br />
│ │ │ │<br />
│ /dev/nvme0n1p1 │ /dev/CryptRootVG/swap │ /dev/CryptRootVG/root │<br />
│ │ │ │<br />
│ 512 MB │ 16 GB (Or RAM size) │ Remaining Free Space │<br />
│ │ │ │<br />
│ │ │ │<br />
│ ├──────────────────────────┴─────────────────────────────┤<br />
│ │ │<br />
│ │ LUKS and LVM Physical Volume │<br />
│ │ │<br />
│ │ /dev/nvme0n1p2 │<br />
│ │ │<br />
└────────────────────┴────────────────────────────────────────────────────────┘<br />
}}<br />
<br />
Second, if your hard drive is an SSD like this laptop, use the following command to open your LUKS volume.<br />
<br />
# cryptsetup open --perf-no_read_workqueue --perf-no_write_workqueue --persistent /dev/nvme0n1p2 cryptroot<br />
<br />
After completing your LUKS on LVM setup, format your EFI partition per [[EFI system partition]].<br />
<br />
# mkfs.fat -F32 /dev/nvme0n1p1<br />
<br />
Mount this partition at {{ic|/mnt/efi}}. It is very important to leave {{ic|/boot}} on your encrypted root partition.<br />
<br />
== Installation ==<br />
<br />
Continue with [[Installation_guide#Installation]]. Be sure to flesh out your {{man|8|pacstrap}} with the following list of packages:<br />
<br />
* {{Pkg|dracut}}<br />
* {{Pkg|intel-ucode}}<br />
* {{Pkg|lvm2}}<br />
* {{Pkg|openssh}}<br />
* {{Pkg|ansible}}<br />
* {{Pkg|git}}<br />
* {{Pkg|iwd}}<br />
* {{Pkg|efibootmgr}}<br />
<br />
<br />
We are going to leave off the installation guide at the initramfs section, so go ahead and reset your root password. <br />
<br />
# passwd<br />
<br />
=== Bootloader ===<br />
<br />
First, install {{ic|systemd-boot}} by following [[Systemd-boot#Installing_the_EFI_boot_manager]]. Next, install {{aur|dracut-hook-uefi}}.<br />
<br />
Ensure you drop in a systemd-boot hook to update your bootctl any time it's updated.<br />
<br />
{{hc|/etc/pacman.d/hooks/998-systemd-boot.hook|2=<br />
[Trigger]<br />
Type = Package<br />
Operation = Install<br />
Operation = Upgrade<br />
Target = systemd<br />
<br />
[Action]<br />
Description = Updating systemd-boot<br />
When = PostTransaction<br />
Exec = /usr/bin/bootctl update; <br />
}}<br />
<br />
Obtain the UUID of your LUKS drive via the following command:<br />
<br />
{{bc|<br />
blkid -s UUID -o value /dev/nvme0n1p2<br />
}}<br />
<br />
Create the following files with the listed content. Be sure to replace UUIDs with what you actually need. See {{man|5|dracut.conf}} for more information on what these commands do.<br />
<br />
A good portion of the kernel command line was as generated by dracut. Many are extraneous or you may wish to change some of the block device names.<br />
<br />
{{hc|/etc/dracut.conf.d/cmdline.conf|2=<br />
kernel_cmdline="rd.luks.uuid=luks-17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02 rd.lvm.lv=CryptRoot/root rd.lvm.lv=CryptRoot/swap resume=/dev/mapper/CryptRoot-swap root=/dev/mapper/CryptRoot-root rootfstype=ext4 rootflags=rw,relatime"<br />
}}<br />
<br />
{{hc|/etc/dracut.conf.d/flags.conf|2=<br />
compress="zstd"<br />
hostonly="yes"<br />
}}<br />
<br />
Run the following command to generate your EFI stub kernels.<br />
<br />
dracut --uefi<br />
<br />
=== Secure boot ===<br />
<br />
==== Dual Booting Windows ====<br />
<br />
{{warning|This section is still being written}}<br />
<br />
Review [[Unified Extensible Firmware Interface/Secure Boot#shim]] to get a rough understanding of how it's going to work. Install {{aur|shim-signed}}. Perform the following commands to place files where both the UEFI boot entry and shim will load them.<br />
<br />
# mv /efi/EFI/BOOT/BOOTx64.EFI /efi/EFI/BOOT/grubx64.efi<br />
# cp /usr/share/shim-signed/shimx64.efi esp/EFI/BOOT/BOOTx64.EFI<br />
# cp /usr/share/shim-signed/mmx64.efi esp/EFI/BOOT/<br />
<br />
Install {{Pkg|sbctl}}. Use the following command to check that secure boot is in the right status. Your output should be similar.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✘ Sbctl is not installed<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/BOOT/grubx64.efi is not signed<br />
<br />
✘ /efi/EFI/BOOT/mmx64.efi is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
}}<br />
<br />
Note that shim and MOKManager (mmx) is included in this list, even though we will not be signing it.<br />
<br />
{{bc|<br />
# sbctl sign -s /efi/EFI/BOOT/ grubx64.efi <br />
<br />
✔ Signed /efi/EFI/BOOT/grubx64.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi <br />
<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi <br />
<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi<br />
# sbctl verify<br />
<br />
Verifying file database and EFI images in /efi...<br />
✔� /efi/EFI/BOOT/grubx64.efi is signed<br />
✔ /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi is signed<br />
✔ /efi/EFI/systemd/systemd-bootx64.efi is signed<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/BOOT/mmx64.efi is not signed<br />
}}<br />
<br />
You can validate that {{ic|BOOTx64.EFI}} and {{ic|mmx64.efi}} have signatures with {{man|1|sbverify}} from the {{Pkg|sbsigntools}} package.<br />
<br />
Next, we need to create the DER format certificate to load into ''MokManager''.<br />
<br />
# openssl x509 -outform DER -in /usr/share/secureboot/keys/db/db.pem -out /efi/signing.cer<br />
<br />
Use {{Pkg|efibootmgr}} ({{man|8|efibootmgr}}) to adjust your boot entries. Primarily, you will want to remove the {{ic|Linux Boot Manager}} entry.<br />
<br />
{{bc|<br />
# efibootmgr<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0001,0000,0002,0003,0004<br />
Boot0000* Windows Boot Manager<br />
Boot0001* Linux Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
}}<br />
<br />
In this example, we see that {{ic|0000}} is the Windows boot manager. {{ic|0001}} is the Linux Boot Manager and also the first in line to boot. {{ic|0001}} needs to be deleted and optionally the boot order modified so {{ic|0004}} is the default boot entry.<br />
<br />
{{bc|<br />
# efibootmgr --bootnum 0001 --delete-bootnum<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0000,0002,0003,0004<br />
Boot0000* Windows Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
<br />
# efibootmgr --bootorder 0004,0000,0002,0003<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0004,0000,0002,0003<br />
Boot0000* Windows Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Now reboot. You should get an error from your motherboard's UEFI BIOS that secure boot checks failed. Your computer should restart directly into ''MokManager'', if you rearranged the boot order. If not, you will need to select {{ic|UEFI OS}} from your UEFI boot menu. Navigate to the {{ic|signing.cer}} file we placed on the EFI partition and enroll the key. Select reboot, and the system should boot directly into linux with no problem.<br />
<br />
==== Booting only Linux ====<br />
<br />
{{note|The very newly developed [https://github.com/Foxboron/sbctl sbctl], availble via {{aur|sbctl-git}} has completely revamped this process and will only get better as they approach 1.0. From here on out, as of October 2021, this process should greatly simplify.}}<br />
<br />
{{note|Credit to this [https://lunaryorn.com/secure-boot-on-arch-linux-with-sbctl-and-dracut blog post by lunaryorn] for the inspiration.}}<br />
<br />
Install {{Pkg|sbctl}}. At this point you will likely need to reboot and adjust your secure boot settings. You want secure boot in '''setup mode'''. <br />
<br />
{{bc|<br />
$ sbctl status<br />
Installed: X Sbctl is not installed<br />
Setup Mode: X Enabled<br />
Secure Boot: X Disabled<br />
}}<br />
<br />
Run the following commands as root. See {{man|8|sbctl}} for more information on their function. Of particular note is the {{ic|-s}} flag which indicates {{ic|sbctl}} should remember the file for future verification and signing.<br />
<br />
Note your Linux EFI binary name may be slightly different.<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
<br />
# sbctl sign -s /efi/EFI/BOOT/BOOTx64.EFI<br />
✔ Signed /efi/EFI/BOOT/BOOTx64.EFI<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Finally, enroll the Secure Boot keys.<br />
<br />
{{bc|<br />
# sbctl enroll-keys<br />
Enrolling keys to EFI variables...✔<br />
Enrolled keys to the EFI variables!<br />
}}<br />
<br />
Verify that secure boot now has an owner GUID and setup mode is disabled.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✔ Sbctl is installed<br />
Owner GUID: a2ee3d08-725a-408b-9d95-28026a44611c<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
Now reboot. This reboot is required so we can get the TPM measurements into their (hopefully) permanent state.<br />
<br />
=== Enroll LUKS key in TPM ===<br />
{{warning|Yes, this will cause a system to automatically unlock it's encrypted root volume without any interaction from a human. Yes, this exposes it to any sufficently advanced Evil Maid attacks. If sealed against the appropriate registers (especially register 8 with the kernel arguments), the TPM measurements should force systemd to ask for your LUKS passphrase in almost any attempt to access the encrypted volume from outside your normal boot process.}}<br />
<br />
We are fortunate that in our shift to dracut includes utilizing systemd and sd-encrypt, as we can use systemd's native support for enrolling LUKS keys. A review of [[Trusted Platform Module#Using TPM 2.0]] is recommended but not very clear.<br />
<br />
==== Avoid dracut bugs ====<br />
<br />
Subtitle: The Case of the Missing {{ic|d}}<br />
<br />
Two bugs, one in systemd 249.4-1-arch [https://github.com/systemd/systemd/issues/19177] and one in dracut 055 [https://github.com/dracutdevs/dracut/pull/1526][https://github.com/dracutdevs/dracut/issues/1542] will combine to prevent your system from being able to boot. The dracut issue causes the '''tpm2-tss''' module to not be included in your image. The systemd issue causes systemd to go into an emergency when it can't locate the TPM2 libraries, instead of falling back to asking for your passcode.<br />
<br />
The systemd bug isn't a problem so long as you always have TPM2 libraries present.<br />
<br />
To resolve this, first check your version of dracut.<br />
<br />
{{bc|<br />
$ dracut --version<br />
dracut 055<br />
}}<br />
<br />
Since the next release of dracut should have this fixed, we can simply fix the script locally until the next release.<br />
<br />
{{warning|These steps are only necessary for dracut 055}}<br />
<br />
Find the following lines in {{ic|/usr/lib/dracut/modules.d/91tpm2-tss/module-setup.sh}}:<br />
<br />
{{bc|1=<br />
# Module dependency requirements.<br />
depends() {<br />
<br />
# This module has external dependency on other module(s).<br />
echo systemd-sysusers systemd-udev<br />
# Return 0 to include the dependent module(s) in the initramfs.<br />
return 0<br />
<br />
}<br />
}}<br />
<br />
Change the dependency {{ic|systemd-udev}} to <code>systemd-udev<b>d</b></code>.<br />
<br />
Continue with the remaining steps in this section.<br />
<br />
==== Enrollment ====<br />
<br />
First, be sure to install {{Pkg|tpm2-tools}}. Alternatively {{aur|ibm-tss}} can be used per [[Trusted Platform Module]], however this guide is not tested against those.<br />
<br />
{{note|A reboot may be required to convince {{ic|systemd-cryptenroll}} that TPM 2.0 devices now exist on the machine.}}<br />
<br />
There are several decisions to be made here. The table at [[Trusted Platform Module#Accessing PCR registers]] is accurate as of October 2021. Essentially, once you seal your LUKS key, if any of the registers you've sealed against change, then you will be asked for your LUKS passphrase. This is equivalent to when Windows 10 makes you enter your BitLocker recovery key after a hardware change or changing BIOS settings.<br />
<br />
Your mileage may vary, based on UEFI vendors. For my laptop, I went with 0+1+2+3+4+5+7+8 and have been able to invalidate my TPM. Unfortunately, if you change your system BACK the volume will unlock. I'm investigating how to disable that.<br />
<br />
Other options on {{man|1|systemd-cryptenroll}} will reveal that several hardware tokens can also be enrolled to allow unlocking the root LUKS volume automatically, but only if a key is present. Further testing is requried.<br />
<br />
To enroll your LUKS volume, simply run the following command as root<br />
<br />
# systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/nvme0n1p2<br />
<br />
To remove your key, run this command:<br />
<br />
# systemd-cryptenroll --wipe-slot=tpm2 /dev/nvme0n1p2<br />
<br />
You will need to add a kernel argument like below to enable the TPM2 bits. If following this guide, this should be located in {{ic|/etc/dracut.conf.d/cmdline.conf}}<br />
<br />
rd.luks.options={UUID}=tpm2-device=auto<br />
<br />
Finally, ensure that dracut builds in the TPM2 libraries. Create the following file.<br />
<br />
{{hc|/etc/dracut.conf.d/tpm2-tss.conf|2=<br />
add_dracutmodules+=" tpm2-tss "<br />
}}<br />
<br />
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:<br />
<br />
{{hc|~/bin/luks_reenroll_tpm|2=<br />
sudo systemd-cryptenroll --wipe-slot=tpm2 /dev/disk/by-uuid/{UUID_HERE}<br />
systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/disk/by-uuid/{UUID_HERE}<br />
}}<br />
<br />
=== Wrapping up ===<br />
<br />
Set your UEFI password. <br />
<br />
Change your LUKS passphrase from something easily memorable to a good long recovery key.<br />
<br />
Keep both of these pieces of info somewhere safe. This varies depending on your threat model. If we're just talking about Stolen Laptops and Nosy Maids, a hard copy in your safe should be sufficient. If it's the NSA, I'm not sure this setup is appropriate for that model.<br />
<br />
This is an excellent base to handle stolen laptop and even some lower grade Evil Maids. From here, you should head into [[Security]]. Consider learning a framework to help you manage your system state such as [[Ansible]] or headless [[Puppet]].<br />
<br />
== Justifications ==<br />
<br />
=== LVM on LUKS vs other dm-crypt approaches ===<br />
<br />
LVM on LUKS was selected becasue it is simply the easiest to manage while conferring both encrypted swap and disk. The other approaches required much more tooling and manual fussing to utilize. This selection also gives room change freely between {{ic|busybox}} and {{ic|systemd}} initrds.<br />
<br />
=== Using dracut ===<br />
<br />
{{Pkg|dracut}} just makes it easier to build full unified kernels that {{man|7|systemd-boot}} can launch as EFI binaries. There is also available tooling in the [[AUR]] for automating the creation of these binaries. Finally, {{ic|dracut}} will sign the binaries it creates automatically when configured to do so.<br />
<br />
=== Unified kernel images ===<br />
<br />
While UKI's could be problematic on other distributions, they fit right in with an Arch Linux install. The automation is there through pacman hooks and {{Pkg|sbctl}} to sign our UKIs as they're created. Furthermore, you can only sign and create a new signed UKI while booted into a properly signed UKI. It creates a chain of trust, which means it's important to never disable Secure Boot once you've set it up.<br />
<br />
The UKI encompasses all of the following items inside the signature, which means you can't change any of them without invalidating the signature.<br />
<br />
* Kernel arguments<br />
* Initrd/Initramfs<br />
* Kernel<br />
<br />
In particular, all other flavors of secureboot do not sign or validate the initramfs. This is a big attack area and can be relatively trivialized that a semi-decent pawn shop owner with Google could likely find an image that would grant him access and make the TPM none the wiser the system has changed. One can prevent this with encrypted /boot, but that would limit you to GRUB2 and LUKS version 1 devices only. This also doesn't include the work to keep GRUB2's files signed with a PGP key by root.<br />
<br />
=== LUKS enrolled in TPM ===<br />
<br />
The goal here is to only require the passphrase when something spooky happens in your boot path.<br />
<br />
UEFI settings change? Request password.<br />
<br />
Some weird swap of some module of UEFI code that lives on your motherboard somewhere? Request password.<br />
<br />
Unified Kernel Image changes? Don't even boot.<br />
<br />
Drive in another computer? Request password.<br />
<br />
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.<br />
<br />
== Miscellaneous discussions ==<br />
<br />
=== Filesystem Selection ===<br />
<br />
Most examples on Arch utilize {{ic|ext4}}, but other file systems such as {{ic|brtfs}} can work equally well. As for performance or issues with being inside LVM, [https://btrfs.wiki.kernel.org/index.php/FAQ#Btrfs_has_subvolumes.2C_does_this_mean_I_don.27t_need_a_logical_volume_manager_and_I_can_create_a_big_Btrfs_filesystem_on_a_raw_partition.3F this question in the brtfs FAQ] implie that there is some performance loss but no other issues.<br />
<br />
=== LUKS TPM enrollment and managing luks keys ===<br />
<br />
Note that using {{man|1|systemd-cryptenroll}} will add a key to your LUKS volume. It's not clear how exactly the option {{ic|1=--wipe-slot=tpm2}} is able to identify which slot it needs to wipe, but it does. This even works if your TPM has changed.<br />
<br />
You can see the effects by comparing the output of {{ic|cryptsetup luksDump /dev/nvme0n1p2}} before and after you enroll or wipe a TPM based key. You can identify what slot your own passphrase is in with {{ic|cryptsetup --verbose open --test-passphrase /dev/nvme0n1p2}} and entering your passphrase. The output will inform you which key slot was unlocked.<br />
<br />
Finally, your passphrase may be changed with {{ic|cryptsetup luksChangeKey /dev/nvme0n1p2 -S 0}}.<br />
<br />
== Planned TODOs ==<br />
A panic command that can dump the TPM and shutdown the computer (without requiring the time of entering a password in sudo) forcing an adversary to resort to [https://en.wikipedia.org/wiki/Rubber-hose_cryptanalysis rubber-hose cryptanalysis] to get to the encrypted data.</div>Krinhttps://wiki.archlinux.org/index.php?title=User:Krin/Secure_Boot,_full_disk_encryption,_and_TPM2_unlocking_install&diff=697968User:Krin/Secure Boot, full disk encryption, and TPM2 unlocking install2021-10-01T12:32:40Z<p>Krin: /* Enroll LUKS key in TPM */ Add warnings about dracut bug and workaround.</p>
<hr />
<div>{{Unsupported|30 September 2021}}<br />
{{Expansion|Work In Progress, Draft from Installation Notes, Needs Testing}}<br />
<br />
== Introduction ==<br />
<br />
This installation is based on my installing Arch on an Asus ROG Strix G G531 I got second hand and a desktop computer made of second hand parts that had to share space with Windows. The primary goals were to replace Windows 10 Pro with Bitlocker encryption and maintain the convienence and security balance of that original operating system.<br />
<br />
My requirements boiled down to:<br />
<br />
* A fully encrypted disk<br />
* Full Secure Boot validation of all UEFI components.<br />
* Use of the TPM to facilitate unlocking of the disk.<br />
* Hibernate/Suspend working.<br />
<br />
My primary use case here is to make it difficult enough for a baggage handler with sticky hands to get at my data that they just wipe the drive. A state level actor with the expertise and equipment to hot swap my ram in my hotel room is not something that I'm defending this ''particular'' laptop against. This is more for gaming and web browsing and uploading photos while traveling.<br />
<br />
I'll continue to update these notes as I develop further solutions.<br />
<br />
== Disclaimers ==<br />
<br />
This article is primarily for the author's own notes. It is assumed that the reader is familiar with the [[Installation guide]] and will refer to it often. Reading linked articles is recommended.<br />
<br />
== Dual Booting Modifications ==<br />
<br />
{{warning|If you use BitLocker on your Windows drive, ensure you have your recovery key handy. The installation process will change your TPM measurements causing Windows to require you enter the key manually the next time you boot it.}}<br />
<br />
For computers that will have to dual boot with windows, the easiest solution is to use two different physical drives and utilize your motherboard's UEFI boot menu to select which one to boot. This guide will follow that assumption. You can also attempt to have everything live on one EFI partition. Windows's 100 MiB EFI partition is especially problematic to this approach for secure boot, as Unified Kernel Images can approach 80 MiB and Windows 10 regularly uses up to 30 MiB.<br />
<br />
There are two changes that will be made and will be noted in the relevant sections:<br />
<br />
* Do not clear your Secure Boot keys. Merely disable Secure Boot for the installation.<br />
* Use {{ic|shim}} to boot systemd-bootloader<br />
* Load your db.cer file into the MOKManager application.<br />
<br />
All remaining steps should remain the same, except your system will still be dependent on the factory provided Microsoft Certificates. But you can boot Windows 10 in Secure Boot, which will be important for Windows 11.<br />
<br />
== Initial setup ==<br />
<br />
=== Pre-installation ===<br />
<br />
If you will only boot linux, reset your Secure Boot settings in BIOS to enable setup mode. Usually this means you set Secure Boot to Enabled and then select the option to wipe out the keys.<br />
<br />
If you will be dual booting Windows, disable secure boot.<br />
<br />
Follow the [[Installation_guide#Pre-installation]] up to Paritioning the Disks.<br />
<br />
=== Disk preparation ===<br />
<br />
If you have data on your disks you want to overwrite, utilize [[Dm-crypt/Drive_preparation#dm-crypt_wipe_on_an_empty_disk_or_partition]] to wipe it. If this disk was previously encrypted, utilize [[Dm-crypt/Drive_preparation#Wipe_LUKS_header]] instead for a much faster disposal. Finally, use [[Dm-crypt/Encrypting_an_entire_system#LVM_on_LUKS]] to parition your drive with two differences.<br />
<br />
{{tip|Using a memorable LUKS passphrase until you've completed the install process can be helpful. It will take several reboots to finish setup.}}<br />
<br />
First, the partition layout will be similar to here. You may wish to break out the /home directory into it's own partition. The primary requirement is that only your EFI partition be unencrypted.<br />
<br />
{{hc|Partiton Layout|<br />
┌────────────────────┬──────────────────────────┬─────────────────────────────┐<br />
│ │ │ │<br />
│ EFI Boot Partition │ Logical Volume 1 │ Logical Volume 2 │<br />
│ │ │ │<br />
│ /efi │ [SWAP] │ / │<br />
│ │ │ │<br />
│ /dev/nvme0n1p1 │ /dev/CryptRootVG/swap │ /dev/CryptRootVG/root │<br />
│ │ │ │<br />
│ 512 MB │ 16 GB (Or RAM size) │ Remaining Free Space │<br />
│ │ │ │<br />
│ │ │ │<br />
│ ├──────────────────────────┴─────────────────────────────┤<br />
│ │ │<br />
│ │ LUKS and LVM Physical Volume │<br />
│ │ │<br />
│ │ /dev/nvme0n1p2 │<br />
│ │ │<br />
└────────────────────┴────────────────────────────────────────────────────────┘<br />
}}<br />
<br />
Second, if your hard drive is an SSD like this laptop, use the following command to open your LUKS volume.<br />
<br />
# cryptsetup open --perf-no_read_workqueue --perf-no_write_workqueue --persistent /dev/nvme0n1p2 cryptroot<br />
<br />
After completing your LUKS on LVM setup, format your EFI partition per [[EFI system partition]].<br />
<br />
# mkfs.fat -F32 /dev/nvme0n1p1<br />
<br />
Mount this partition at {{ic|/mnt/efi}}. It is very important to leave {{ic|/boot}} on your encrypted root partition.<br />
<br />
== Installation ==<br />
<br />
Continue with [[Installation_guide#Installation]]. Be sure to flesh out your {{man|8|pacstrap}} with the following list of packages:<br />
<br />
* {{Pkg|dracut}}<br />
* {{Pkg|intel-ucode}}<br />
* {{Pkg|lvm2}}<br />
* {{Pkg|openssh}}<br />
* {{Pkg|ansible}}<br />
* {{Pkg|git}}<br />
* {{Pkg|iwd}}<br />
* {{Pkg|efibootmgr}}<br />
<br />
<br />
We are going to leave off the installation guide at the initramfs section, so go ahead and reset your root password. <br />
<br />
# passwd<br />
<br />
=== Bootloader ===<br />
<br />
First, install {{ic|systemd-boot}} by following [[Systemd-boot#Installing_the_EFI_boot_manager]]. Next, install {{aur|dracut-hook-uefi}}.<br />
<br />
Ensure you drop in a systemd-boot hook to update your bootctl any time it's updated.<br />
<br />
{{hc|/etc/pacman.d/hooks/998-systemd-boot.hook|2=<br />
[Trigger]<br />
Type = Package<br />
Operation = Install<br />
Operation = Upgrade<br />
Target = systemd<br />
<br />
[Action]<br />
Description = Updating systemd-boot<br />
When = PostTransaction<br />
Exec = /usr/bin/bootctl update; <br />
}}<br />
<br />
Obtain the UUID of your LUKS drive via the following command:<br />
<br />
{{bc|<br />
blkid -s UUID -o value /dev/nvme0n1p2<br />
}}<br />
<br />
Create the following files with the listed content. Be sure to replace UUIDs with what you actually need. See {{man|5|dracut.conf}} for more information on what these commands do.<br />
<br />
A good portion of the kernel command line was as generated by dracut. Many are extraneous or you may wish to change some of the block device names.<br />
<br />
{{hc|/etc/dracut.conf.d/cmdline.conf|2=<br />
kernel_cmdline="rd.luks.uuid=luks-17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02 rd.lvm.lv=CryptRoot/root rd.lvm.lv=CryptRoot/swap resume=/dev/mapper/CryptRoot-swap root=/dev/mapper/CryptRoot-root rootfstype=ext4 rootflags=rw,relatime"<br />
}}<br />
<br />
{{hc|/etc/dracut.conf.d/flags.conf|2=<br />
compress="zstd"<br />
hostonly="yes"<br />
}}<br />
<br />
Run the following command to generate your EFI stub kernels.<br />
<br />
dracut --uefi<br />
<br />
=== Secure boot ===<br />
<br />
==== Dual Booting Windows ====<br />
<br />
{{warning|This section is still being written}}<br />
<br />
Review [[Unified Extensible Firmware Interface/Secure Boot#shim]] to get a rough understanding of how it's going to work. Install {{aur|shim-signed}}. Perform the following commands to place files where both the UEFI boot entry and shim will load them.<br />
<br />
# mv /efi/EFI/BOOT/BOOTx64.EFI /efi/EFI/BOOT/grubx64.efi<br />
# cp /usr/share/shim-signed/shimx64.efi esp/EFI/BOOT/BOOTx64.EFI<br />
# cp /usr/share/shim-signed/mmx64.efi esp/EFI/BOOT/<br />
<br />
Install {{Pkg|sbctl}}. Use the following command to check that secure boot is in the right status. Your output should be similar.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✘ Sbctl is not installed<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/BOOT/grubx64.efi is not signed<br />
<br />
✘ /efi/EFI/BOOT/mmx64.efi is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
}}<br />
<br />
Note that shim and MOKManager (mmx) is included in this list, even though we will not be signing it.<br />
<br />
{{bc|<br />
# sbctl sign -s /efi/EFI/BOOT/ grubx64.efi <br />
<br />
✔ Signed /efi/EFI/BOOT/grubx64.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi <br />
<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi <br />
<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi<br />
# sbctl verify<br />
<br />
Verifying file database and EFI images in /efi...<br />
✔� /efi/EFI/BOOT/grubx64.efi is signed<br />
✔ /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi is signed<br />
✔ /efi/EFI/systemd/systemd-bootx64.efi is signed<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/BOOT/mmx64.efi is not signed<br />
}}<br />
<br />
You can validate that {{ic|BOOTx64.EFI}} and {{ic|mmx64.efi}} have signatures with {{man|1|sbverify}} from the {{Pkg|sbsigntools}} package.<br />
<br />
Next, we need to create the DER format certificate to load into ''MokManager''.<br />
<br />
# openssl x509 -outform DER -in /usr/share/secureboot/keys/db/db.pem -out /efi/signing.cer<br />
<br />
Use {{Pkg|efibootmgr}} ({{man|8|efibootmgr}}) to adjust your boot entries. Primarily, you will want to remove the {{ic|Linux Boot Manager}} entry.<br />
<br />
{{bc|<br />
# efibootmgr<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0001,0000,0002,0003,0004<br />
Boot0000* Windows Boot Manager<br />
Boot0001* Linux Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
}}<br />
<br />
In this example, we see that {{ic|0000}} is the Windows boot manager. {{ic|0001}} is the Linux Boot Manager and also the first in line to boot. {{ic|0001}} needs to be deleted and optionally the boot order modified so {{ic|0004}} is the default boot entry.<br />
<br />
{{bc|<br />
# efibootmgr --bootnum 0001 --delete-bootnum<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0000,0002,0003,0004<br />
Boot0000* Windows Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
<br />
# efibootmgr --bootorder 0004,0000,0002,0003<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0004,0000,0002,0003<br />
Boot0000* Windows Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Now reboot. You should get an error from your motherboard's UEFI BIOS that secure boot checks failed. Your computer should restart directly into ''MokManager'', if you rearranged the boot order. If not, you will need to select {{ic|UEFI OS}} from your UEFI boot menu. Navigate to the {{ic|signing.cer}} file we placed on the EFI partition and enroll the key. Select reboot, and the system should boot directly into linux with no problem.<br />
<br />
==== Booting only Linux ====<br />
<br />
{{note|The very newly developed [https://github.com/Foxboron/sbctl sbctl], availble via {{aur|sbctl-git}} has completely revamped this process and will only get better as they approach 1.0. From here on out, as of October 2021, this process should greatly simplify.}}<br />
<br />
{{note|Credit to this [https://lunaryorn.com/secure-boot-on-arch-linux-with-sbctl-and-dracut blog post by lunaryorn] for the inspiration.}}<br />
<br />
Install {{Pkg|sbctl}}. At this point you will likely need to reboot and adjust your secure boot settings. You want secure boot in '''setup mode'''. <br />
<br />
{{bc|<br />
$ sbctl status<br />
Installed: X Sbctl is not installed<br />
Setup Mode: X Enabled<br />
Secure Boot: X Disabled<br />
}}<br />
<br />
Run the following commands as root. See {{man|8|sbctl}} for more information on their function. Of particular note is the {{ic|-s}} flag which indicates {{ic|sbctl}} should remember the file for future verification and signing.<br />
<br />
Note your Linux EFI binary name may be slightly different.<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
<br />
# sbctl sign -s /efi/EFI/BOOT/BOOTx64.EFI<br />
✔ Signed /efi/EFI/BOOT/BOOTx64.EFI<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Finally, enroll the Secure Boot keys.<br />
<br />
{{bc|<br />
# sbctl enroll-keys<br />
Enrolling keys to EFI variables...✔<br />
Enrolled keys to the EFI variables!<br />
}}<br />
<br />
Verify that secure boot now has an owner GUID and setup mode is disabled.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✔ Sbctl is installed<br />
Owner GUID: a2ee3d08-725a-408b-9d95-28026a44611c<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
Now reboot. This reboot is required so we can get the TPM measurements into their (hopefully) permanent state.<br />
<br />
=== Enroll LUKS key in TPM ===<br />
{{warning|Yes, this will cause a system to automatically unlock it's encrypted root volume without any interaction from a human. Yes, this exposes it to any sufficently advanced Evil Maid attacks. If sealed against the appropriate registers (especially register 8 with the kernel arguments), the TPM measurements should force systemd to ask for your LUKS passphrase in almost any attempt to access the encrypted volume from outside your normal boot process.}}<br />
<br />
We are fortunate that in our shift to dracut includes utilizing systemd and sd-encrypt, as we can use systemd's native support for enrolling LUKS keys. A review of [[Trusted Platform Module#Using TPM 2.0]] is recommended but not very clear.<br />
<br />
==== Avoid dracut bugs ====<br />
<br />
Subtitle: The Case of the Missing {{ic|d}}<br />
<br />
Two bugs, one in systemd 249.4-1-arch [https://github.com/systemd/systemd/issues/19177] and one in dracut 055 [https://github.com/dracutdevs/dracut/pull/1526][https://github.com/dracutdevs/dracut/issues/1542] will combine to prevent your system from being able to boot. The dracut issue causes the '''tpm2-tss''' module to not be included in your image. The systemd issue causes systemd to go into an emergency when it can't locate the TPM2 libraries, instead of falling back to asking for your passcode.<br />
<br />
The systemd bug isn't a problem so long as you always have TPM2 libraries present.<br />
<br />
To resolve this, first check your version of dracut.<br />
<br />
{{bc|<br />
$ dracut --version<br />
dracut 055<br />
}}<br />
<br />
Since the next release of dracut should have this fixed, we can simply fix the script locally until the next release.<br />
<br />
{{warning|These steps are only necessary for dracut 055}}<br />
<br />
Find the following lines in {{ic|/usr/lib/dracut/modules.d/91tpm2-tss/module-setup.sh}}:<br />
<br />
{{bc|1=<br />
# Module dependency requirements.<br />
depends() {<br />
<br />
# This module has external dependency on other module(s).<br />
echo systemd-sysusers systemd-udev<br />
# Return 0 to include the dependent module(s) in the initramfs.<br />
return 0<br />
<br />
}<br />
}}<br />
<br />
Change the dependency {{ic|systemd-udev}} to <code>systemd-udev<b>d</b></code>.<br />
<br />
Continue with the remaining steps in this section.<br />
<br />
==== Enrollment ====<br />
<br />
First, be sure to install {{Pkg|tpm2-tools}}. Alternatively {{aur|ibm-tss}} can be used per [[Trusted Platform Module]], however this guide is not tested against those.<br />
<br />
{{note|A reboot may be required to convince {{ic|systemd-cryptenroll}} that TPM 2.0 devices now exist on the machine.}}<br />
<br />
There are several decisions to be made here. The table at [[Trusted Platform Module#Accessing PCR registers]] is accurate as of October 2021. Essentially, once you seal your LUKS key, if any of the registers you've sealed against change, then you will be asked for your LUKS passphrase. This is equivalent to when Windows 10 makes you enter your BitLocker recovery key after a hardware change or changing BIOS settings.<br />
<br />
Your mileage may vary, based on UEFI vendors. For my laptop, I went with 0+1+2+3+4+5+7+8 and have been able to invalidate my TPM. Unfortunately, if you change your system BACK the volume will unlock. I'm investigating how to disable that.<br />
<br />
Other options on {{man|1|systemd-cryptenroll}} will reveal that several hardware tokens can also be enrolled to allow unlocking the root LUKS volume automatically, but only if a key is present. Further testing is requried.<br />
<br />
To enroll your LUKS volume, simply run the following command as root<br />
<br />
# systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/nvme0n1p2<br />
<br />
To remove your key, run this command:<br />
<br />
# systemd-cryptenroll --wipe-slot=tpm2 /dev/nvme0n1p2<br />
<br />
You will need to add a kernel argument like below to enable the TPM2 bits.<br />
<br />
rd.luks.options={UUID}=tpm2-device=auto<br />
<br />
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:<br />
<br />
{{hc|~/bin/luks_reenroll_tpm|2=<br />
sudo systemd-cryptenroll --wipe-slot=tpm2 /dev/disk/by-uuid/{UUID_HERE}<br />
systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/disk/by-uuid/{UUID_HERE}<br />
}}<br />
<br />
=== Wrapping up ===<br />
<br />
Set your UEFI password. <br />
<br />
Change your LUKS passphrase from something easily memorable to a good long recovery key.<br />
<br />
Keep both of these pieces of info somewhere safe. This varies depending on your threat model. If we're just talking about Stolen Laptops and Nosy Maids, a hard copy in your safe should be sufficient. If it's the NSA, I'm not sure this setup is appropriate for that model.<br />
<br />
This is an excellent base to handle stolen laptop and even some lower grade Evil Maids. From here, you should head into [[Security]]. Consider learning a framework to help you manage your system state such as [[Ansible]] or headless [[Puppet]].<br />
<br />
== Justifications ==<br />
<br />
=== LVM on LUKS vs other dm-crypt approaches ===<br />
<br />
LVM on LUKS was selected becasue it is simply the easiest to manage while conferring both encrypted swap and disk. The other approaches required much more tooling and manual fussing to utilize. This selection also gives room change freely between {{ic|busybox}} and {{ic|systemd}} initrds.<br />
<br />
=== Using dracut ===<br />
<br />
{{Pkg|dracut}} just makes it easier to build full unified kernels that {{man|7|systemd-boot}} can launch as EFI binaries. There is also available tooling in the [[AUR]] for automating the creation of these binaries. Finally, {{ic|dracut}} will sign the binaries it creates automatically when configured to do so.<br />
<br />
=== Unified kernel images ===<br />
<br />
While UKI's could be problematic on other distributions, they fit right in with an Arch Linux install. The automation is there through pacman hooks and {{Pkg|sbctl}} to sign our UKIs as they're created. Furthermore, you can only sign and create a new signed UKI while booted into a properly signed UKI. It creates a chain of trust, which means it's important to never disable Secure Boot once you've set it up.<br />
<br />
The UKI encompasses all of the following items inside the signature, which means you can't change any of them without invalidating the signature.<br />
<br />
* Kernel arguments<br />
* Initrd/Initramfs<br />
* Kernel<br />
<br />
In particular, all other flavors of secureboot do not sign or validate the initramfs. This is a big attack area and can be relatively trivialized that a semi-decent pawn shop owner with Google could likely find an image that would grant him access and make the TPM none the wiser the system has changed. One can prevent this with encrypted /boot, but that would limit you to GRUB2 and LUKS version 1 devices only. This also doesn't include the work to keep GRUB2's files signed with a PGP key by root.<br />
<br />
=== LUKS enrolled in TPM ===<br />
<br />
The goal here is to only require the passphrase when something spooky happens in your boot path.<br />
<br />
UEFI settings change? Request password.<br />
<br />
Some weird swap of some module of UEFI code that lives on your motherboard somewhere? Request password.<br />
<br />
Unified Kernel Image changes? Don't even boot.<br />
<br />
Drive in another computer? Request password.<br />
<br />
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.<br />
<br />
== Miscellaneous discussions ==<br />
<br />
=== Filesystem Selection ===<br />
<br />
Most examples on Arch utilize {{ic|ext4}}, but other file systems such as {{ic|brtfs}} can work equally well. As for performance or issues with being inside LVM, [https://btrfs.wiki.kernel.org/index.php/FAQ#Btrfs_has_subvolumes.2C_does_this_mean_I_don.27t_need_a_logical_volume_manager_and_I_can_create_a_big_Btrfs_filesystem_on_a_raw_partition.3F this question in the brtfs FAQ] implie that there is some performance loss but no other issues.<br />
<br />
=== LUKS TPM enrollment and managing luks keys ===<br />
<br />
Note that using {{man|1|systemd-cryptenroll}} will add a key to your LUKS volume. It's not clear how exactly the option {{ic|1=--wipe-slot=tpm2}} is able to identify which slot it needs to wipe, but it does. This even works if your TPM has changed.<br />
<br />
You can see the effects by comparing the output of {{ic|cryptsetup luksDump /dev/nvme0n1p2}} before and after you enroll or wipe a TPM based key. You can identify what slot your own passphrase is in with {{ic|cryptsetup --verbose open --test-passphrase /dev/nvme0n1p2}} and entering your passphrase. The output will inform you which key slot was unlocked.<br />
<br />
Finally, your passphrase may be changed with {{ic|cryptsetup luksChangeKey /dev/nvme0n1p2 -S 0}}.<br />
<br />
== Planned TODOs ==<br />
A panic command that can dump the TPM and shutdown the computer (without requiring the time of entering a password in sudo) forcing an adversary to resort to [https://en.wikipedia.org/wiki/Rubber-hose_cryptanalysis rubber-hose cryptanalysis] to get to the encrypted data.</div>Krinhttps://wiki.archlinux.org/index.php?title=User:Krin/Secure_Boot,_full_disk_encryption,_and_TPM2_unlocking_install&diff=697935User:Krin/Secure Boot, full disk encryption, and TPM2 unlocking install2021-10-01T04:04:20Z<p>Krin: Remove kernel argument. Add warning.</p>
<hr />
<div>{{Unsupported|30 September 2021}}<br />
{{Expansion|Work In Progress, Draft from Installation Notes, Needs Testing}}<br />
<br />
== Introduction ==<br />
<br />
This installation is based on my installing Arch on an Asus ROG Strix G G531 I got second hand and a desktop computer made of second hand parts that had to share space with Windows. The primary goals were to replace Windows 10 Pro with Bitlocker encryption and maintain the convienence and security balance of that original operating system.<br />
<br />
My requirements boiled down to:<br />
<br />
* A fully encrypted disk<br />
* Full Secure Boot validation of all UEFI components.<br />
* Use of the TPM to facilitate unlocking of the disk.<br />
* Hibernate/Suspend working.<br />
<br />
My primary use case here is to make it difficult enough for a baggage handler with sticky hands to get at my data that they just wipe the drive. A state level actor with the expertise and equipment to hot swap my ram in my hotel room is not something that I'm defending this ''particular'' laptop against. This is more for gaming and web browsing and uploading photos while traveling.<br />
<br />
I'll continue to update these notes as I develop further solutions.<br />
<br />
== Disclaimers ==<br />
<br />
This article is primarily for the author's own notes. It is assumed that the reader is familiar with the [[Installation guide]] and will refer to it often. Reading linked articles is recommended.<br />
<br />
== Dual Booting Modifications ==<br />
<br />
{{warning|If you use BitLocker on your Windows drive, ensure you have your recovery key handy. The installation process will change your TPM measurements causing Windows to require you enter the key manually the next time you boot it.}}<br />
<br />
For computers that will have to dual boot with windows, the easiest solution is to use two different physical drives and utilize your motherboard's UEFI boot menu to select which one to boot. This guide will follow that assumption. You can also attempt to have everything live on one EFI partition. Windows's 100 MiB EFI partition is especially problematic to this approach for secure boot, as Unified Kernel Images can approach 80 MiB and Windows 10 regularly uses up to 30 MiB.<br />
<br />
There are two changes that will be made and will be noted in the relevant sections:<br />
<br />
* Do not clear your Secure Boot keys. Merely disable Secure Boot for the installation.<br />
* Use {{ic|shim}} to boot systemd-bootloader<br />
* Load your db.cer file into the MOKManager application.<br />
<br />
All remaining steps should remain the same, except your system will still be dependent on the factory provided Microsoft Certificates. But you can boot Windows 10 in Secure Boot, which will be important for Windows 11.<br />
<br />
== Initial setup ==<br />
<br />
=== Pre-installation ===<br />
<br />
If you will only boot linux, reset your Secure Boot settings in BIOS to enable setup mode. Usually this means you set Secure Boot to Enabled and then select the option to wipe out the keys.<br />
<br />
If you will be dual booting Windows, disable secure boot.<br />
<br />
Follow the [[Installation_guide#Pre-installation]] up to Paritioning the Disks.<br />
<br />
=== Disk preparation ===<br />
<br />
If you have data on your disks you want to overwrite, utilize [[Dm-crypt/Drive_preparation#dm-crypt_wipe_on_an_empty_disk_or_partition]] to wipe it. If this disk was previously encrypted, utilize [[Dm-crypt/Drive_preparation#Wipe_LUKS_header]] instead for a much faster disposal. Finally, use [[Dm-crypt/Encrypting_an_entire_system#LVM_on_LUKS]] to parition your drive with two differences.<br />
<br />
{{tip|Using a memorable LUKS passphrase until you've completed the install process can be helpful. It will take several reboots to finish setup.}}<br />
<br />
First, the partition layout will be similar to here. You may wish to break out the /home directory into it's own partition. The primary requirement is that only your EFI partition be unencrypted.<br />
<br />
{{hc|Partiton Layout|<br />
┌────────────────────┬──────────────────────────┬─────────────────────────────┐<br />
│ │ │ │<br />
│ EFI Boot Partition │ Logical Volume 1 │ Logical Volume 2 │<br />
│ │ │ │<br />
│ /efi │ [SWAP] │ / │<br />
│ │ │ │<br />
│ /dev/nvme0n1p1 │ /dev/CryptRootVG/swap │ /dev/CryptRootVG/root │<br />
│ │ │ │<br />
│ 512 MB │ 16 GB (Or RAM size) │ Remaining Free Space │<br />
│ │ │ │<br />
│ │ │ │<br />
│ ├──────────────────────────┴─────────────────────────────┤<br />
│ │ │<br />
│ │ LUKS and LVM Physical Volume │<br />
│ │ │<br />
│ │ /dev/nvme0n1p2 │<br />
│ │ │<br />
└────────────────────┴────────────────────────────────────────────────────────┘<br />
}}<br />
<br />
Second, if your hard drive is an SSD like this laptop, use the following command to open your LUKS volume.<br />
<br />
# cryptsetup open --perf-no_read_workqueue --perf-no_write_workqueue --persistent /dev/nvme0n1p2 cryptroot<br />
<br />
After completing your LUKS on LVM setup, format your EFI partition per [[EFI system partition]].<br />
<br />
# mkfs.fat -F32 /dev/nvme0n1p1<br />
<br />
Mount this partition at {{ic|/mnt/efi}}. It is very important to leave {{ic|/boot}} on your encrypted root partition.<br />
<br />
== Installation ==<br />
<br />
Continue with [[Installation_guide#Installation]]. Be sure to flesh out your {{man|8|pacstrap}} with the following list of packages:<br />
<br />
* {{Pkg|dracut}}<br />
* {{Pkg|intel-ucode}}<br />
* {{Pkg|lvm2}}<br />
* {{Pkg|openssh}}<br />
* {{Pkg|ansible}}<br />
* {{Pkg|git}}<br />
* {{Pkg|iwd}}<br />
* {{Pkg|efibootmgr}}<br />
<br />
<br />
We are going to leave off the installation guide at the initramfs section, so go ahead and reset your root password. <br />
<br />
# passwd<br />
<br />
=== Bootloader ===<br />
<br />
First, install {{ic|systemd-boot}} by following [[Systemd-boot#Installing_the_EFI_boot_manager]]. Next, install {{aur|dracut-hook-uefi}}.<br />
<br />
Ensure you drop in a systemd-boot hook to update your bootctl any time it's updated.<br />
<br />
{{hc|/etc/pacman.d/hooks/998-systemd-boot.hook|2=<br />
[Trigger]<br />
Type = Package<br />
Operation = Install<br />
Operation = Upgrade<br />
Target = systemd<br />
<br />
[Action]<br />
Description = Updating systemd-boot<br />
When = PostTransaction<br />
Exec = /usr/bin/bootctl update; <br />
}}<br />
<br />
Obtain the UUID of your LUKS drive via the following command:<br />
<br />
{{bc|<br />
blkid -s UUID -o value /dev/nvme0n1p2<br />
}}<br />
<br />
Create the following files with the listed content. Be sure to replace UUIDs with what you actually need. See {{man|5|dracut.conf}} for more information on what these commands do.<br />
<br />
A good portion of the kernel command line was as generated by dracut. Many are extraneous or you may wish to change some of the block device names.<br />
<br />
{{hc|/etc/dracut.conf.d/cmdline.conf|2=<br />
kernel_cmdline="rd.luks.uuid=luks-17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02 rd.lvm.lv=CryptRoot/root rd.lvm.lv=CryptRoot/swap resume=/dev/mapper/CryptRoot-swap root=/dev/mapper/CryptRoot-root rootfstype=ext4 rootflags=rw,relatime"<br />
}}<br />
<br />
{{hc|/etc/dracut.conf.d/flags.conf|2=<br />
compress="zstd"<br />
hostonly="yes"<br />
}}<br />
<br />
Run the following command to generate your EFI stub kernels.<br />
<br />
dracut --uefi<br />
<br />
=== Secure boot ===<br />
<br />
==== Dual Booting Windows ====<br />
<br />
{{warning|This section is still being written}}<br />
<br />
Review [[Unified Extensible Firmware Interface/Secure Boot#shim]] to get a rough understanding of how it's going to work. Install {{aur|shim-signed}}. Perform the following commands to place files where both the UEFI boot entry and shim will load them.<br />
<br />
# mv /efi/EFI/BOOT/BOOTx64.EFI /efi/EFI/BOOT/grubx64.efi<br />
# cp /usr/share/shim-signed/shimx64.efi esp/EFI/BOOT/BOOTx64.EFI<br />
# cp /usr/share/shim-signed/mmx64.efi esp/EFI/BOOT/<br />
<br />
Install {{Pkg|sbctl}}. Use the following command to check that secure boot is in the right status. Your output should be similar.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✘ Sbctl is not installed<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/BOOT/grubx64.efi is not signed<br />
<br />
✘ /efi/EFI/BOOT/mmx64.efi is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
}}<br />
<br />
Note that shim and MOKManager (mmx) is included in this list, even though we will not be signing it.<br />
<br />
{{bc|<br />
# sbctl sign -s /efi/EFI/BOOT/ grubx64.efi <br />
<br />
✔ Signed /efi/EFI/BOOT/grubx64.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi <br />
<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi <br />
<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi<br />
# sbctl verify<br />
<br />
Verifying file database and EFI images in /efi...<br />
✔� /efi/EFI/BOOT/grubx64.efi is signed<br />
✔ /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi is signed<br />
✔ /efi/EFI/systemd/systemd-bootx64.efi is signed<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/BOOT/mmx64.efi is not signed<br />
}}<br />
<br />
You can validate that {{ic|BOOTx64.EFI}} and {{ic|mmx64.efi}} have signatures with {{man|1|sbverify}} from the {{Pkg|sbsigntools}} package.<br />
<br />
Next, we need to create the DER format certificate to load into ''MokManager''.<br />
<br />
# openssl x509 -outform DER -in /usr/share/secureboot/keys/db/db.pem -out /efi/signing.cer<br />
<br />
Use {{Pkg|efibootmgr}} ({{man|8|efibootmgr}}) to adjust your boot entries. Primarily, you will want to remove the {{ic|Linux Boot Manager}} entry.<br />
<br />
{{bc|<br />
# efibootmgr<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0001,0000,0002,0003,0004<br />
Boot0000* Windows Boot Manager<br />
Boot0001* Linux Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
}}<br />
<br />
In this example, we see that {{ic|0000}} is the Windows boot manager. {{ic|0001}} is the Linux Boot Manager and also the first in line to boot. {{ic|0001}} needs to be deleted and optionally the boot order modified so {{ic|0004}} is the default boot entry.<br />
<br />
{{bc|<br />
# efibootmgr --bootnum 0001 --delete-bootnum<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0000,0002,0003,0004<br />
Boot0000* Windows Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
<br />
# efibootmgr --bootorder 0004,0000,0002,0003<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0004,0000,0002,0003<br />
Boot0000* Windows Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Now reboot. You should get an error from your motherboard's UEFI BIOS that secure boot checks failed. Your computer should restart directly into ''MokManager'', if you rearranged the boot order. If not, you will need to select {{ic|UEFI OS}} from your UEFI boot menu. Navigate to the {{ic|signing.cer}} file we placed on the EFI partition and enroll the key. Select reboot, and the system should boot directly into linux with no problem.<br />
<br />
==== Booting only Linux ====<br />
<br />
{{note|The very newly developed [https://github.com/Foxboron/sbctl sbctl], availble via {{aur|sbctl-git}} has completely revamped this process and will only get better as they approach 1.0. From here on out, as of October 2021, this process should greatly simplify.}}<br />
<br />
{{note|Credit to this [https://lunaryorn.com/secure-boot-on-arch-linux-with-sbctl-and-dracut blog post by lunaryorn] for the inspiration.}}<br />
<br />
Install {{Pkg|sbctl}}. At this point you will likely need to reboot and adjust your secure boot settings. You want secure boot in '''setup mode'''. <br />
<br />
{{bc|<br />
$ sbctl status<br />
Installed: X Sbctl is not installed<br />
Setup Mode: X Enabled<br />
Secure Boot: X Disabled<br />
}}<br />
<br />
Run the following commands as root. See {{man|8|sbctl}} for more information on their function. Of particular note is the {{ic|-s}} flag which indicates {{ic|sbctl}} should remember the file for future verification and signing.<br />
<br />
Note your Linux EFI binary name may be slightly different.<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
<br />
# sbctl sign -s /efi/EFI/BOOT/BOOTx64.EFI<br />
✔ Signed /efi/EFI/BOOT/BOOTx64.EFI<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Finally, enroll the Secure Boot keys.<br />
<br />
{{bc|<br />
# sbctl enroll-keys<br />
Enrolling keys to EFI variables...✔<br />
Enrolled keys to the EFI variables!<br />
}}<br />
<br />
Verify that secure boot now has an owner GUID and setup mode is disabled.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✔ Sbctl is installed<br />
Owner GUID: a2ee3d08-725a-408b-9d95-28026a44611c<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
Now reboot. This reboot is required so we can get the TPM measurements into their (hopefully) permanent state.<br />
<br />
=== Enroll LUKS key in TPM ===<br />
{{warning|Yes, this will cause a system to automatically unlock it's encrypted root volume without any interaction from a human. Yes, this exposes it to any sufficently advanced Evil Maid attacks. If sealed against the appropriate registers (especially register 8 with the kernel arguments), the TPM measurements should force systemd to ask for your LUKS passphrase in almost any attempt to access the encrypted volume from outside your normal boot process.}}<br />
<br />
{{warning|Currently I've been struggling to get this working. I had it working with images but when I converted to UEFI systemd-cryptsetup started crashing out.}}<br />
<br />
We are fortunate that in our shift to dracut includes utilizing systemd and sd-encrypt, as we can use systemd's native support for enrolling LUKS keys. A review of [[Trusted Platform Module#Using TPM 2.0]] is recommended but not very clear.<br />
<br />
First, be sure to install {{Pkg|tpm2-tools}}. Alternatively {{aur|ibm-tss}} can be used per [[Trusted Platform Module]], however this guide is not tested against those.<br />
<br />
{{note|A reboot may be required to convince {{ic|systemd-cryptenroll}} that TPM 2.0 devices now exist on the machine.}}<br />
<br />
There are several decisions to be made here. The table at [[Trusted Platform Module#Accessing PCR registers]] is accurate as of October 2021. Essentially, once you seal your LUKS key, if any of the registers you've sealed against change, then you will be asked for your LUKS passphrase. This is equivalent to when Windows 10 makes you enter your BitLocker recovery key after a hardware change or changing BIOS settings.<br />
<br />
Your mileage may vary, based on UEFI vendors. For my laptop, I went with 0+1+2+3+4+5+7+8 and have been able to invalidate my TPM. Unfortunately, if you change your system BACK the volume will unlock. I'm investigating how to disable that.<br />
<br />
Other options on {{man|1|systemd-cryptenroll}} will reveal that several hardware tokens can also be enrolled to allow unlocking the root LUKS volume automatically, but only if a key is present. Further testing is requried.<br />
<br />
To enroll your LUKS volume, simply run the following command as root<br />
<br />
# systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/nvme0n1p2<br />
<br />
To remove your key, run this command:<br />
<br />
# systemd-cryptenroll --wipe-slot=tpm2 /dev/nvme0n1p2<br />
<br />
You will need to add a kernel argument like below to enable the TPM2 bits.<br />
<br />
rd.luks.options={UUID}=tpm2-device=auto<br />
<br />
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:<br />
<br />
{{hc|~/bin/luks_reenroll_tpm|2=<br />
sudo systemd-cryptenroll --wipe-slot=tpm2 /dev/disk/by-uuid/{UUID_HERE}<br />
systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/disk/by-uuid/{UUID_HERE}<br />
}}<br />
<br />
=== Wrapping up ===<br />
<br />
Set your UEFI password. <br />
<br />
Change your LUKS passphrase from something easily memorable to a good long recovery key.<br />
<br />
Keep both of these pieces of info somewhere safe. This varies depending on your threat model. If we're just talking about Stolen Laptops and Nosy Maids, a hard copy in your safe should be sufficient. If it's the NSA, I'm not sure this setup is appropriate for that model.<br />
<br />
This is an excellent base to handle stolen laptop and even some lower grade Evil Maids. From here, you should head into [[Security]]. Consider learning a framework to help you manage your system state such as [[Ansible]] or headless [[Puppet]].<br />
<br />
== Justifications ==<br />
<br />
=== LVM on LUKS vs other dm-crypt approaches ===<br />
<br />
LVM on LUKS was selected becasue it is simply the easiest to manage while conferring both encrypted swap and disk. The other approaches required much more tooling and manual fussing to utilize. This selection also gives room change freely between {{ic|busybox}} and {{ic|systemd}} initrds.<br />
<br />
=== Using dracut ===<br />
<br />
{{Pkg|dracut}} just makes it easier to build full unified kernels that {{man|7|systemd-boot}} can launch as EFI binaries. There is also available tooling in the [[AUR]] for automating the creation of these binaries. Finally, {{ic|dracut}} will sign the binaries it creates automatically when configured to do so.<br />
<br />
=== Unified kernel images ===<br />
<br />
While UKI's could be problematic on other distributions, they fit right in with an Arch Linux install. The automation is there through pacman hooks and {{Pkg|sbctl}} to sign our UKIs as they're created. Furthermore, you can only sign and create a new signed UKI while booted into a properly signed UKI. It creates a chain of trust, which means it's important to never disable Secure Boot once you've set it up.<br />
<br />
The UKI encompasses all of the following items inside the signature, which means you can't change any of them without invalidating the signature.<br />
<br />
* Kernel arguments<br />
* Initrd/Initramfs<br />
* Kernel<br />
<br />
In particular, all other flavors of secureboot do not sign or validate the initramfs. This is a big attack area and can be relatively trivialized that a semi-decent pawn shop owner with Google could likely find an image that would grant him access and make the TPM none the wiser the system has changed. One can prevent this with encrypted /boot, but that would limit you to GRUB2 and LUKS version 1 devices only. This also doesn't include the work to keep GRUB2's files signed with a PGP key by root.<br />
<br />
=== LUKS enrolled in TPM ===<br />
<br />
The goal here is to only require the passphrase when something spooky happens in your boot path.<br />
<br />
UEFI settings change? Request password.<br />
<br />
Some weird swap of some module of UEFI code that lives on your motherboard somewhere? Request password.<br />
<br />
Unified Kernel Image changes? Don't even boot.<br />
<br />
Drive in another computer? Request password.<br />
<br />
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.<br />
<br />
== Miscellaneous discussions ==<br />
<br />
=== Filesystem Selection ===<br />
<br />
Most examples on Arch utilize {{ic|ext4}}, but other file systems such as {{ic|brtfs}} can work equally well. As for performance or issues with being inside LVM, [https://btrfs.wiki.kernel.org/index.php/FAQ#Btrfs_has_subvolumes.2C_does_this_mean_I_don.27t_need_a_logical_volume_manager_and_I_can_create_a_big_Btrfs_filesystem_on_a_raw_partition.3F this question in the brtfs FAQ] implie that there is some performance loss but no other issues.<br />
<br />
=== LUKS TPM enrollment and managing luks keys ===<br />
<br />
Note that using {{man|1|systemd-cryptenroll}} will add a key to your LUKS volume. It's not clear how exactly the option {{ic|1=--wipe-slot=tpm2}} is able to identify which slot it needs to wipe, but it does. This even works if your TPM has changed.<br />
<br />
You can see the effects by comparing the output of {{ic|cryptsetup luksDump /dev/nvme0n1p2}} before and after you enroll or wipe a TPM based key. You can identify what slot your own passphrase is in with {{ic|cryptsetup --verbose open --test-passphrase /dev/nvme0n1p2}} and entering your passphrase. The output will inform you which key slot was unlocked.<br />
<br />
Finally, your passphrase may be changed with {{ic|cryptsetup luksChangeKey /dev/nvme0n1p2 -S 0}}.<br />
<br />
== Planned TODOs ==<br />
A panic command that can dump the TPM and shutdown the computer (without requiring the time of entering a password in sudo) forcing an adversary to resort to [https://en.wikipedia.org/wiki/Rubber-hose_cryptanalysis rubber-hose cryptanalysis] to get to the encrypted data.</div>Krinhttps://wiki.archlinux.org/index.php?title=User:Krin/Secure_Boot,_full_disk_encryption,_and_TPM2_unlocking_install&diff=697934User:Krin/Secure Boot, full disk encryption, and TPM2 unlocking install2021-10-01T02:41:37Z<p>Krin: Style and tone updates</p>
<hr />
<div>{{Unsupported|30 September 2021}}<br />
{{Expansion|Work In Progress, Draft from Installation Notes, Needs Testing}}<br />
<br />
== Introduction ==<br />
<br />
This installation is based on my installing Arch on an Asus ROG Strix G G531 I got second hand and a desktop computer made of second hand parts that had to share space with Windows. The primary goals were to replace Windows 10 Pro with Bitlocker encryption and maintain the convienence and security balance of that original operating system.<br />
<br />
My requirements boiled down to:<br />
<br />
* A fully encrypted disk<br />
* Full Secure Boot validation of all UEFI components.<br />
* Use of the TPM to facilitate unlocking of the disk.<br />
* Hibernate/Suspend working.<br />
<br />
My primary use case here is to make it difficult enough for a baggage handler with sticky hands to get at my data that they just wipe the drive. A state level actor with the expertise and equipment to hot swap my ram in my hotel room is not something that I'm defending this ''particular'' laptop against. This is more for gaming and web browsing and uploading photos while traveling.<br />
<br />
I'll continue to update these notes as I develop further solutions.<br />
<br />
== Disclaimers ==<br />
<br />
This article is primarily for the author's own notes. It is assumed that the reader is familiar with the [[Installation guide]] and will refer to it often. Reading linked articles is recommended.<br />
<br />
== Dual Booting Modifications ==<br />
<br />
{{warning|If you use BitLocker on your Windows drive, ensure you have your recovery key handy. The installation process will change your TPM measurements causing Windows to require you enter the key manually the next time you boot it.}}<br />
<br />
For computers that will have to dual boot with windows, the easiest solution is to use two different physical drives and utilize your motherboard's UEFI boot menu to select which one to boot. This guide will follow that assumption. You can also attempt to have everything live on one EFI partition. Windows's 100 MiB EFI partition is especially problematic to this approach for secure boot, as Unified Kernel Images can approach 80 MiB and Windows 10 regularly uses up to 30 MiB.<br />
<br />
There are two changes that will be made and will be noted in the relevant sections:<br />
<br />
* Do not clear your Secure Boot keys. Merely disable Secure Boot for the installation.<br />
* Use {{ic|shim}} to boot systemd-bootloader<br />
* Load your db.cer file into the MOKManager application.<br />
<br />
All remaining steps should remain the same, except your system will still be dependent on the factory provided Microsoft Certificates. But you can boot Windows 10 in Secure Boot, which will be important for Windows 11.<br />
<br />
== Initial setup ==<br />
<br />
=== Pre-installation ===<br />
<br />
If you will only boot linux, reset your Secure Boot settings in BIOS to enable setup mode. Usually this means you set Secure Boot to Enabled and then select the option to wipe out the keys.<br />
<br />
If you will be dual booting Windows, disable secure boot.<br />
<br />
Follow the [[Installation_guide#Pre-installation]] up to Paritioning the Disks.<br />
<br />
=== Disk preparation ===<br />
<br />
If you have data on your disks you want to overwrite, utilize [[Dm-crypt/Drive_preparation#dm-crypt_wipe_on_an_empty_disk_or_partition]] to wipe it. If this disk was previously encrypted, utilize [[Dm-crypt/Drive_preparation#Wipe_LUKS_header]] instead for a much faster disposal. Finally, use [[Dm-crypt/Encrypting_an_entire_system#LVM_on_LUKS]] to parition your drive with two differences.<br />
<br />
{{tip|Using a memorable LUKS passphrase until you've completed the install process can be helpful. It will take several reboots to finish setup.}}<br />
<br />
First, the partition layout will be similar to here. You may wish to break out the /home directory into it's own partition. The primary requirement is that only your EFI partition be unencrypted.<br />
<br />
{{hc|Partiton Layout|<br />
┌────────────────────┬──────────────────────────┬─────────────────────────────┐<br />
│ │ │ │<br />
│ EFI Boot Partition │ Logical Volume 1 │ Logical Volume 2 │<br />
│ │ │ │<br />
│ /efi │ [SWAP] │ / │<br />
│ │ │ │<br />
│ /dev/nvme0n1p1 │ /dev/CryptRootVG/swap │ /dev/CryptRootVG/root │<br />
│ │ │ │<br />
│ 512 MB │ 16 GB (Or RAM size) │ Remaining Free Space │<br />
│ │ │ │<br />
│ │ │ │<br />
│ ├──────────────────────────┴─────────────────────────────┤<br />
│ │ │<br />
│ │ LUKS and LVM Physical Volume │<br />
│ │ │<br />
│ │ /dev/nvme0n1p2 │<br />
│ │ │<br />
└────────────────────┴────────────────────────────────────────────────────────┘<br />
}}<br />
<br />
Second, if your hard drive is an SSD like this laptop, use the following command to open your LUKS volume.<br />
<br />
# cryptsetup open --perf-no_read_workqueue --perf-no_write_workqueue --persistent /dev/nvme0n1p2 cryptroot<br />
<br />
After completing your LUKS on LVM setup, format your EFI partition per [[EFI system partition]].<br />
<br />
# mkfs.fat -F32 /dev/nvme0n1p1<br />
<br />
Mount this partition at {{ic|/mnt/efi}}. It is very important to leave {{ic|/boot}} on your encrypted root partition.<br />
<br />
== Installation ==<br />
<br />
Continue with [[Installation_guide#Installation]]. Be sure to flesh out your {{man|8|pacstrap}} with the following list of packages:<br />
<br />
* {{Pkg|dracut}}<br />
* {{Pkg|intel-ucode}}<br />
* {{Pkg|lvm2}}<br />
* {{Pkg|openssh}}<br />
* {{Pkg|ansible}}<br />
* {{Pkg|git}}<br />
* {{Pkg|iwd}}<br />
* {{Pkg|efibootmgr}}<br />
<br />
<br />
We are going to leave off the installation guide at the initramfs section, so go ahead and reset your root password. <br />
<br />
# passwd<br />
<br />
=== Bootloader ===<br />
<br />
First, install {{ic|systemd-boot}} by following [[Systemd-boot#Installing_the_EFI_boot_manager]]. Next, install {{aur|dracut-hook-uefi}}.<br />
<br />
Ensure you drop in a systemd-boot hook to update your bootctl any time it's updated.<br />
<br />
{{hc|/etc/pacman.d/hooks/998-systemd-boot.hook|2=<br />
[Trigger]<br />
Type = Package<br />
Operation = Install<br />
Operation = Upgrade<br />
Target = systemd<br />
<br />
[Action]<br />
Description = Updating systemd-boot<br />
When = PostTransaction<br />
Exec = /usr/bin/bootctl update; <br />
}}<br />
<br />
Obtain the UUID of your LUKS drive via the following command:<br />
<br />
{{bc|<br />
blkid -s UUID -o value /dev/nvme0n1p2<br />
}}<br />
<br />
Create the following files with the listed content. Be sure to replace UUIDs with what you actually need. The extraneous {{ic:rd.luks.options}} should not cause an issue, but will be used once we've enabled secure boot. See {{man|5|dracut.conf}} for more information on what these commands do.<br />
<br />
A good portion of the kernel command line was as generated by dracut. Many are extraneous or you may wish to change some of the block device names.<br />
<br />
{{hc|/etc/dracut.conf.d/cmdline.conf|2=<br />
kernel_cmdline="rd.luks.uuid=luks-17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02 rd.luks.options=17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02=tpm2-device=auto rd.lvm.lv=CryptRoot/root rd.lvm.lv=CryptRoot/swap resume=/dev/mapper/CryptRoot-swap root=/dev/mapper/CryptRoot-root rootfstype=ext4 rootflags=rw,relatime"<br />
}}<br />
<br />
{{hc|/etc/dracut.conf.d/flags.conf|2=<br />
compress="zstd"<br />
hostonly="yes"<br />
}}<br />
<br />
Run the following command to generate your EFI stub kernels.<br />
<br />
dracut --uefi<br />
<br />
=== Secure boot ===<br />
<br />
==== Dual Booting Windows ====<br />
<br />
{{warning|This section is still being written}}<br />
<br />
Review [[Unified Extensible Firmware Interface/Secure Boot#shim]] to get a rough understanding of how it's going to work. Install {{aur|shim-signed}}. Perform the following commands to place files where both the UEFI boot entry and shim will load them.<br />
<br />
# mv /efi/EFI/BOOT/BOOTx64.EFI /efi/EFI/BOOT/grubx64.efi<br />
# cp /usr/share/shim-signed/shimx64.efi esp/EFI/BOOT/BOOTx64.EFI<br />
# cp /usr/share/shim-signed/mmx64.efi esp/EFI/BOOT/<br />
<br />
Install {{Pkg|sbctl}}. Use the following command to check that secure boot is in the right status. Your output should be similar.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✘ Sbctl is not installed<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/BOOT/grubx64.efi is not signed<br />
<br />
✘ /efi/EFI/BOOT/mmx64.efi is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
}}<br />
<br />
Note that shim and MOKManager (mmx) is included in this list, even though we will not be signing it.<br />
<br />
{{bc|<br />
# sbctl sign -s /efi/EFI/BOOT/ grubx64.efi <br />
<br />
✔ Signed /efi/EFI/BOOT/grubx64.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi <br />
<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi <br />
<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi<br />
# sbctl verify<br />
<br />
Verifying file database and EFI images in /efi...<br />
✔� /efi/EFI/BOOT/grubx64.efi is signed<br />
✔ /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi is signed<br />
✔ /efi/EFI/systemd/systemd-bootx64.efi is signed<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/BOOT/mmx64.efi is not signed<br />
}}<br />
<br />
You can validate that {{ic|BOOTx64.EFI}} and {{ic|mmx64.efi}} have signatures with {{man|1|sbverify}} from the {{Pkg|sbsigntools}} package.<br />
<br />
Next, we need to create the DER format certificate to load into ''MokManager''.<br />
<br />
# openssl x509 -outform DER -in /usr/share/secureboot/keys/db/db.pem -out /efi/signing.cer<br />
<br />
Use {{Pkg|efibootmgr}} ({{man|8|efibootmgr}}) to adjust your boot entries. Primarily, you will want to remove the {{ic|Linux Boot Manager}} entry.<br />
<br />
{{bc|<br />
# efibootmgr<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0001,0000,0002,0003,0004<br />
Boot0000* Windows Boot Manager<br />
Boot0001* Linux Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
}}<br />
<br />
In this example, we see that {{ic|0000}} is the Windows boot manager. {{ic|0001}} is the Linux Boot Manager and also the first in line to boot. {{ic|0001}} needs to be deleted and optionally the boot order modified so {{ic|0004}} is the default boot entry.<br />
<br />
{{bc|<br />
# efibootmgr --bootnum 0001 --delete-bootnum<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0000,0002,0003,0004<br />
Boot0000* Windows Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
<br />
# efibootmgr --bootorder 0004,0000,0002,0003<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0004,0000,0002,0003<br />
Boot0000* Windows Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Now reboot. You should get an error from your motherboard's UEFI BIOS that secure boot checks failed. Your computer should restart directly into ''MokManager'', if you rearranged the boot order. If not, you will need to select {{ic|UEFI OS}} from your UEFI boot menu. Navigate to the {{ic|signing.cer}} file we placed on the EFI partition and enroll the key. Select reboot, and the system should boot directly into linux with no problem.<br />
<br />
==== Booting only Linux ====<br />
<br />
{{note|The very newly developed [https://github.com/Foxboron/sbctl sbctl], availble via {{aur|sbctl-git}} has completely revamped this process and will only get better as they approach 1.0. From here on out, as of October 2021, this process should greatly simplify.}}<br />
<br />
{{note|Credit to this [https://lunaryorn.com/secure-boot-on-arch-linux-with-sbctl-and-dracut blog post by lunaryorn] for the inspiration.}}<br />
<br />
Install {{Pkg|sbctl}}. At this point you will likely need to reboot and adjust your secure boot settings. You want secure boot in '''setup mode'''. <br />
<br />
{{bc|<br />
$ sbctl status<br />
Installed: X Sbctl is not installed<br />
Setup Mode: X Enabled<br />
Secure Boot: X Disabled<br />
}}<br />
<br />
Run the following commands as root. See {{man|8|sbctl}} for more information on their function. Of particular note is the {{ic|-s}} flag which indicates {{ic|sbctl}} should remember the file for future verification and signing.<br />
<br />
Note your Linux EFI binary name may be slightly different.<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
<br />
# sbctl sign -s /efi/EFI/BOOT/BOOTx64.EFI<br />
✔ Signed /efi/EFI/BOOT/BOOTx64.EFI<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Finally, enroll the Secure Boot keys.<br />
<br />
{{bc|<br />
# sbctl enroll-keys<br />
Enrolling keys to EFI variables...✔<br />
Enrolled keys to the EFI variables!<br />
}}<br />
<br />
Verify that secure boot now has an owner GUID and setup mode is disabled.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✔ Sbctl is installed<br />
Owner GUID: a2ee3d08-725a-408b-9d95-28026a44611c<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
Now reboot. This reboot is required so we can get the TPM measurements into their (hopefully) permanent state.<br />
<br />
=== Enroll LUKS key in TPM ===<br />
{{warning|Yes, this will cause a system to automatically unlock it's encrypted root volume without any interaction from a human. Yes, this exposes it to any sufficently advanced Evil Maid attacks. If sealed against the appropriate registers (especially register 8 with the kernel arguments), the TPM measurements should force systemd to ask for your LUKS passphrase in almost any attempt to access the encrypted volume from outside your normal boot process.}}<br />
<br />
We are fortunate that in our shift to dracut includes utilizing systemd and sd-encrypt, as we can use systemd's native support for enrolling LUKS keys. A review of [[Trusted Platform Module#Using TPM 2.0]] is recommended but not very clear.<br />
<br />
First, be sure to install {{Pkg|tpm2-tools}}. Alternatively {{aur|ibm-tss}} can be used per [[Trusted Platform Module]], however this guide is not tested against those.<br />
<br />
{{note|A reboot may be required to convince {{ic|systemd-cryptenroll}} that TPM 2.0 devices now exist on the machine.}}<br />
<br />
There are several decisions to be made here. The table at [[Trusted Platform Module#Accessing PCR registers]] is accurate as of October 2021. Essentially, once you seal your LUKS key, if any of the registers you've sealed against change, then you will be asked for your LUKS passphrase. This is equivalent to when Windows 10 makes you enter your BitLocker recovery key after a hardware change or changing BIOS settings.<br />
<br />
Your mileage may vary, based on UEFI vendors. For my laptop, I went with 0+1+2+3+4+5+7+8 and have been able to invalidate my TPM. Unfortunately, if you change your system BACK the volume will unlock. I'm investigating how to disable that.<br />
<br />
Other options on {{man|1|systemd-cryptenroll}} will reveal that several hardware tokens can also be enrolled to allow unlocking the root LUKS volume automatically, but only if a key is present. Further testing is requried.<br />
<br />
To enroll your LUKS volume, simply run the following command as root<br />
<br />
# systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/nvme0n1p2<br />
<br />
To remove your key, run this command:<br />
<br />
# systemd-cryptenroll --wipe-slot=tpm2 /dev/nvme0n1p2<br />
<br />
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:<br />
<br />
{{hc|~/bin/luks_reenroll_tpm|2=<br />
sudo systemd-cryptenroll --wipe-slot=tpm2 /dev/disk/by-uuid/{UUID_HERE}<br />
systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/disk/by-uuid/{UUID_HERE}<br />
}}<br />
<br />
=== Wrapping up ===<br />
<br />
Set your UEFI password. <br />
<br />
Change your LUKS passphrase from something easily memorable to a good long recovery key.<br />
<br />
Keep both of these pieces of info somewhere safe. This varies depending on your threat model. If we're just talking about Stolen Laptops and Nosy Maids, a hard copy in your safe should be sufficient. If it's the NSA, I'm not sure this setup is appropriate for that model.<br />
<br />
This is an excellent base to handle stolen laptop and even some lower grade Evil Maids. From here, you should head into [[Security]]. Consider learning a framework to help you manage your system state such as [[Ansible]] or headless [[Puppet]].<br />
<br />
== Justifications ==<br />
<br />
=== LVM on LUKS vs other dm-crypt approaches ===<br />
<br />
LVM on LUKS was selected becasue it is simply the easiest to manage while conferring both encrypted swap and disk. The other approaches required much more tooling and manual fussing to utilize. This selection also gives room change freely between {{ic|busybox}} and {{ic|systemd}} initrds.<br />
<br />
=== Using dracut ===<br />
<br />
{{Pkg|dracut}} just makes it easier to build full unified kernels that {{man|7|systemd-boot}} can launch as EFI binaries. There is also available tooling in the [[AUR]] for automating the creation of these binaries. Finally, {{ic|dracut}} will sign the binaries it creates automatically when configured to do so.<br />
<br />
=== Unified kernel images ===<br />
<br />
While UKI's could be problematic on other distributions, they fit right in with an Arch Linux install. The automation is there through pacman hooks and {{Pkg|sbctl}} to sign our UKIs as they're created. Furthermore, you can only sign and create a new signed UKI while booted into a properly signed UKI. It creates a chain of trust, which means it's important to never disable Secure Boot once you've set it up.<br />
<br />
The UKI encompasses all of the following items inside the signature, which means you can't change any of them without invalidating the signature.<br />
<br />
* Kernel arguments<br />
* Initrd/Initramfs<br />
* Kernel<br />
<br />
In particular, all other flavors of secureboot do not sign or validate the initramfs. This is a big attack area and can be relatively trivialized that a semi-decent pawn shop owner with Google could likely find an image that would grant him access and make the TPM none the wiser the system has changed. One can prevent this with encrypted /boot, but that would limit you to GRUB2 and LUKS version 1 devices only. This also doesn't include the work to keep GRUB2's files signed with a PGP key by root.<br />
<br />
=== LUKS enrolled in TPM ===<br />
<br />
The goal here is to only require the passphrase when something spooky happens in your boot path.<br />
<br />
UEFI settings change? Request password.<br />
<br />
Some weird swap of some module of UEFI code that lives on your motherboard somewhere? Request password.<br />
<br />
Unified Kernel Image changes? Don't even boot.<br />
<br />
Drive in another computer? Request password.<br />
<br />
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.<br />
<br />
== Miscellaneous discussions ==<br />
<br />
=== Filesystem Selection ===<br />
<br />
Most examples on Arch utilize {{ic|ext4}}, but other file systems such as {{ic|brtfs}} can work equally well. As for performance or issues with being inside LVM, [https://btrfs.wiki.kernel.org/index.php/FAQ#Btrfs_has_subvolumes.2C_does_this_mean_I_don.27t_need_a_logical_volume_manager_and_I_can_create_a_big_Btrfs_filesystem_on_a_raw_partition.3F this question in the brtfs FAQ] implie that there is some performance loss but no other issues.<br />
<br />
=== LUKS TPM enrollment and managing luks keys ===<br />
<br />
Note that using {{man|1|systemd-cryptenroll}} will add a key to your LUKS volume. It's not clear how exactly the option {{ic|1=--wipe-slot=tpm2}} is able to identify which slot it needs to wipe, but it does. This even works if your TPM has changed.<br />
<br />
You can see the effects by comparing the output of {{ic|cryptsetup luksDump /dev/nvme0n1p2}} before and after you enroll or wipe a TPM based key. You can identify what slot your own passphrase is in with {{ic|cryptsetup --verbose open --test-passphrase /dev/nvme0n1p2}} and entering your passphrase. The output will inform you which key slot was unlocked.<br />
<br />
Finally, your passphrase may be changed with {{ic|cryptsetup luksChangeKey /dev/nvme0n1p2 -S 0}}.<br />
<br />
== Planned TODOs ==<br />
A panic command that can dump the TPM and shutdown the computer (without requiring the time of entering a password in sudo) forcing an adversary to resort to [https://en.wikipedia.org/wiki/Rubber-hose_cryptanalysis rubber-hose cryptanalysis] to get to the encrypted data.</div>Krinhttps://wiki.archlinux.org/index.php?title=User:Krin/Secure_Boot,_full_disk_encryption,_and_TPM2_unlocking_install&diff=697933User:Krin/Secure Boot, full disk encryption, and TPM2 unlocking install2021-10-01T02:34:32Z<p>Krin: Justification for LUKS+TPM</p>
<hr />
<div>{{Unsupported|30 September 2021}}<br />
{{Expansion|Work In Progress, Draft from Installation Notes, Needs Testing}}<br />
<br />
== Introduction ==<br />
<br />
This installation is based on my installing Arch on an Asus ROG Strix G G531 I got second hand and a desktop computer made of second hand parts that had to share space with Windows. The primary goals were to replace Windows 10 Pro with Bitlocker encryption and maintain the convienence and security balance of that original operating system.<br />
<br />
My requirements boiled down to:<br />
<br />
* A fully encrypted disk<br />
* Full Secure Boot validation of all UEFI components.<br />
* Use of the TPM to facilitate unlocking of the disk.<br />
* Hibernate/Suspend working.<br />
<br />
My primary use case here is to make it difficult enough for a baggage handler with sticky hands to get at my data that they just wipe the drive. A state level actor with the expertise and equipment to hot swap my ram in my hotel room is not something that I'm defending this ''particular'' laptop against. This is more for gaming and web browsing and uploading photos while traveling.<br />
<br />
I'll continue to update these notes as I develop further solutions.<br />
<br />
== Disclaimers ==<br />
<br />
This article is primarily for the author's own notes. It is assumed that the reader is familiar with the [[Installation guide]] and will refer to it often. Reading linked articles is recommended.<br />
<br />
== Dual Booting Modifications ==<br />
<br />
{{warning|If you use BitLocker on your Windows drive, ensure you have your recovery key handy. The installation process will change your TPM measurements causing Windows to require you enter the key manually the next time you boot it.}}<br />
<br />
For computers that will have to dual boot with windows, the easiest solution is to use two different physical drives and utilize your motherboard's UEFI boot menu to select which one to boot. This guide will follow that assumption. You can also attempt to have everything live on one EFI partition. Windows's 100 MiB EFI partition is especially problematic to this approach for secure boot, as Unified Kernel Images can approach 80 MiB and Windows 10 regularly uses up to 30 MiB.<br />
<br />
There are two changes that will be made and will be noted in the relevant sections:<br />
<br />
* Do not clear your Secure Boot keys. Merely disable Secure Boot for the installation.<br />
* Use {{ic|shim}} to boot systemd-bootloader<br />
* Load your db.cer file into the MOKManager application.<br />
<br />
All remaining steps should remain the same, except your system will still be dependent on the factory provided Microsoft Certificates. But you can boot Windows 10 in Secure Boot, which will be important for Windows 11.<br />
<br />
== Initial setup ==<br />
<br />
=== Pre-installation ===<br />
<br />
If you will only boot linux, reset your Secure Boot settings in BIOS to enable setup mode. Usually this means you set Secure Boot to Enabled and then select the option to wipe out the keys.<br />
<br />
If you will be dual booting Windows, disable secure boot.<br />
<br />
Follow the [[Installation_guide#Pre-installation]] up to Paritioning the Disks.<br />
<br />
=== Disk preparation ===<br />
<br />
If you have data on your disks you want to overwrite, utilize [[Dm-crypt/Drive_preparation#dm-crypt_wipe_on_an_empty_disk_or_partition]] to wipe it. If this disk was previously encrypted, utilize [[Dm-crypt/Drive_preparation#Wipe_LUKS_header]] instead for a much faster disposal. Finally, use [[Dm-crypt/Encrypting_an_entire_system#LVM_on_LUKS]] to parition your drive with two differences.<br />
<br />
{{tip|Using a memorable LUKS passphrase until you've completed the install process can be helpful. It will take several reboots to finish setup.}}<br />
<br />
First, the partition layout will be similar to here. You may wish to break out the /home directory into it's own partition. The primary requirement is that only your EFI partition be unencrypted.<br />
<br />
{{hc|Partiton Layout|<br />
┌────────────────────┬──────────────────────────┬─────────────────────────────┐<br />
│ │ │ │<br />
│ EFI Boot Partition │ Logical Volume 1 │ Logical Volume 2 │<br />
│ │ │ │<br />
│ /efi │ [SWAP] │ / │<br />
│ │ │ │<br />
│ /dev/nvme0n1p1 │ /dev/CryptRootVG/swap │ /dev/CryptRootVG/root │<br />
│ │ │ │<br />
│ 512 MB │ 16 GB (Or RAM size) │ Remaining Free Space │<br />
│ │ │ │<br />
│ │ │ │<br />
│ ├──────────────────────────┴─────────────────────────────┤<br />
│ │ │<br />
│ │ LUKS and LVM Physical Volume │<br />
│ │ │<br />
│ │ /dev/nvme0n1p2 │<br />
│ │ │<br />
└────────────────────┴────────────────────────────────────────────────────────┘<br />
}}<br />
<br />
Second, if your hard drive is an SSD like this laptop, use the following command to open your LUKS volume.<br />
<br />
# cryptsetup open --perf-no_read_workqueue --perf-no_write_workqueue --persistent /dev/nvme0n1p2 cryptroot<br />
<br />
After completing your LUKS on LVM setup, format your EFI partition per [[EFI system partition]].<br />
<br />
# mkfs.fat -F32 /dev/nvme0n1p1<br />
<br />
Mount this partition at {{ic|/mnt/efi}}. It is very important to leave {{ic|/boot}} on your encrypted root partition.<br />
<br />
== Installation ==<br />
<br />
Continue with [[Installation_guide#Installation]]. Be sure to flesh out your {{man|8|pacstrap}} with the following list of packages:<br />
<br />
* {{Pkg|dracut}}<br />
* {{Pkg|intel-ucode}}<br />
* {{Pkg|lvm2}}<br />
* {{Pkg|openssh}}<br />
* {{Pkg|ansible}}<br />
* {{Pkg|git}}<br />
* {{Pkg|iwd}}<br />
* {{Pkg|efibootmgr}}<br />
<br />
<br />
We are going to leave off the installation guide at the initramfs section, so go ahead and reset your root password. <br />
<br />
# passwd<br />
<br />
=== Bootloader ===<br />
<br />
First, install {{ic|systemd-boot}} by following [[Systemd-boot#Installing_the_EFI_boot_manager]]. Next, install {{aur|dracut-hook-uefi}}.<br />
<br />
Ensure you drop in a systemd-boot hook to update your bootctl any time it's updated.<br />
<br />
{{hc|/etc/pacman.d/hooks/998-systemd-boot.hook|2=<br />
[Trigger]<br />
Type = Package<br />
Operation = Install<br />
Operation = Upgrade<br />
Target = systemd<br />
<br />
[Action]<br />
Description = Updating systemd-boot<br />
When = PostTransaction<br />
Exec = /usr/bin/bootctl update; <br />
}}<br />
<br />
Obtain the UUID of your LUKS drive via the following command:<br />
<br />
{{bc|<br />
blkid -s UUID -o value /dev/nvme0n1p2<br />
}}<br />
<br />
Create the following files with the listed content. Be sure to replace UUIDs with what you actually need. The extraneous {{ic:rd.luks.options}} should not cause an issue, but will be used once we've enabled secure boot. See {{man|5|dracut.conf}} for more information on what these commands do.<br />
<br />
A good portion of the kernel command line was as generated by dracut. Many are extraneous or you may wish to change some of the block device names.<br />
<br />
{{hc|/etc/dracut.conf.d/cmdline.conf|2=<br />
kernel_cmdline="rd.luks.uuid=luks-17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02 rd.luks.options=17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02=tpm2-device=auto rd.lvm.lv=CryptRoot/root rd.lvm.lv=CryptRoot/swap resume=/dev/mapper/CryptRoot-swap root=/dev/mapper/CryptRoot-root rootfstype=ext4 rootflags=rw,relatime"<br />
}}<br />
<br />
{{hc|/etc/dracut.conf.d/flags.conf|2=<br />
compress="zstd"<br />
hostonly="yes"<br />
}}<br />
<br />
Run the following command to generate your EFI stub kernels.<br />
<br />
dracut --uefi<br />
<br />
=== Secure boot ===<br />
<br />
==== Dual Booting Windows ====<br />
<br />
{{warning|This section is still being written}}<br />
<br />
Review [[Unified Extensible Firmware Interface/Secure Boot#shim]] to get a rough understanding of how it's going to work. Install {{aur|shim-signed}}. Perform the following commands to place files where both the UEFI boot entry and shim will load them.<br />
<br />
# mv /efi/EFI/BOOT/BOOTx64.EFI /efi/EFI/BOOT/grubx64.efi<br />
# cp /usr/share/shim-signed/shimx64.efi esp/EFI/BOOT/BOOTx64.EFI<br />
# cp /usr/share/shim-signed/mmx64.efi esp/EFI/BOOT/<br />
<br />
Install {{Pkg|sbctl}}. Use the following command to check that secure boot is in the right status. Your output should be similar.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✘ Sbctl is not installed<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/BOOT/grubx64.efi is not signed<br />
<br />
✘ /efi/EFI/BOOT/mmx64.efi is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
}}<br />
<br />
Note that shim and MOKManager (mmx) is included in this list, even though we will not be signing it.<br />
<br />
{{bc|<br />
# sbctl sign -s /efi/EFI/BOOT/ grubx64.efi <br />
<br />
✔ Signed /efi/EFI/BOOT/grubx64.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi <br />
<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi <br />
<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi<br />
# sbctl verify<br />
<br />
Verifying file database and EFI images in /efi...<br />
✔� /efi/EFI/BOOT/grubx64.efi is signed<br />
✔ /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi is signed<br />
✔ /efi/EFI/systemd/systemd-bootx64.efi is signed<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/BOOT/mmx64.efi is not signed<br />
}}<br />
<br />
You can validate that {{ic|BOOTx64.EFI}} and {{ic|mmx64.efi}} have signatures with {{man|1|sbverify}} from the {{Pkg|sbsigntools}} package.<br />
<br />
Next, we need to create the DER format certificate to load into ''MokManager''.<br />
<br />
# openssl x509 -outform DER -in /usr/share/secureboot/keys/db/db.pem -out /efi/signing.cer<br />
<br />
Use {{Pkg|efibootmgr}} ({{man|8|efibootmgr}}) to adjust your boot entries. Primarily, you will want to remove the {{ic|Linux Boot Manager}} entry.<br />
<br />
{{bc|<br />
# efibootmgr<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0001,0000,0002,0003,0004<br />
Boot0000* Windows Boot Manager<br />
Boot0001* Linux Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
}}<br />
<br />
In this example, we see that {{ic|0000}} is the Windows boot manager. {{ic|0001}} is the Linux Boot Manager and also the first in line to boot. {{ic|0001}} needs to be deleted and optionally the boot order modified so {{ic|0004}} is the default boot entry.<br />
<br />
{{bc|<br />
# efibootmgr --bootnum 0001 --delete-bootnum<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0000,0002,0003,0004<br />
Boot0000* Windows Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
<br />
# efibootmgr --bootorder 0004,0000,0002,0003<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0004,0000,0002,0003<br />
Boot0000* Windows Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Now reboot. You should get an error from your motherboard's UEFI BIOS that secure boot checks failed. Your computer should restart directly into ''MokManager'', if you rearranged the boot order. If not, you will need to select {{ic|UEFI OS}} from your UEFI boot menu. Navigate to the {{ic|signing.cer}} file we placed on the EFI partition and enroll the key. Select reboot, and the system should boot directly into linux with no problem.<br />
<br />
==== Booting only Linux ====<br />
<br />
{{note|The very newly developed [https://github.com/Foxboron/sbctl sbctl], availble via {{aur|sbctl-git}} has completely revamped this process and will only get better as they approach 1.0. From here on out, as of October 2021, this process should greatly simplify.}}<br />
<br />
{{note|Credit to this [https://lunaryorn.com/secure-boot-on-arch-linux-with-sbctl-and-dracut blog post by lunaryorn] for the inspiration.}}<br />
<br />
Install {{Pkg|sbctl}}. At this point you will likely need to reboot and adjust your secure boot settings. You want secure boot in '''setup mode'''. <br />
<br />
{{bc|<br />
$ sbctl status<br />
Installed: X Sbctl is not installed<br />
Setup Mode: X Enabled<br />
Secure Boot: X Disabled<br />
}}<br />
<br />
Run the following commands as root. See {{man|8|sbctl}} for more information on their function. Of particular note is the {{ic|-s}} flag which indicates {{ic|sbctl}} should remember the file for future verification and signing.<br />
<br />
Note your Linux EFI binary name may be slightly different.<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
<br />
# sbctl sign -s /efi/EFI/BOOT/BOOTx64.EFI<br />
✔ Signed /efi/EFI/BOOT/BOOTx64.EFI<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Finally, enroll the Secure Boot keys.<br />
<br />
{{bc|<br />
# sbctl enroll-keys<br />
Enrolling keys to EFI variables...✔<br />
Enrolled keys to the EFI variables!<br />
}}<br />
<br />
Verify that secure boot now has an owner GUID and setup mode is disabled.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✔ Sbctl is installed<br />
Owner GUID: a2ee3d08-725a-408b-9d95-28026a44611c<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
Now reboot. This reboot is required so we can get the TPM measurements into their (hopefully) permanent state.<br />
<br />
=== Enroll LUKS key in TPM ===<br />
{{warning|Yes, this will cause a system to automatically unlock it's encrypted root volume without any interaction from a human. Yes, this exposes it to any sufficently advanced Evil Maid attacks. If sealed against the appropriate registers (especially register 8 with the kernel arguments), the TPM measurements should force systemd to ask for your LUKS passphrase in almost any attempt to access the encrypted volume from outside your normal boot process.}}<br />
<br />
We are fortunate that in our shift to dracut includes utilizing systemd and sd-encrypt, as we can use systemd's native support for enrolling LUKS keys. A review of [[Trusted Platform Module#Using TPM 2.0]] is recommended but not very clear.<br />
<br />
First, be sure to install {{Pkg|tpm2-tools}}. Alternatively {{aur|ibm-tss}} can be used per [[Trusted Platform Module]], however this guide is not tested against those.<br />
<br />
{{note|A reboot may be required to convince {{ic|systemd-cryptenroll}} that TPM 2.0 devices now exist on the machine.}}<br />
<br />
There are several decisions to be made here. The table at [[Trusted Platform Module#Accessing PCR registers]] is accurate as of October 2021. Essentially, once you seal your LUKS key, if any of the registers you've sealed against change, then you will be asked for your LUKS passphrase. This is equivalent to when Windows 10 makes you enter your BitLocker recovery key after a hardware change or changing BIOS settings.<br />
<br />
Your mileage may vary, based on UEFI vendors. For my laptop, I went with 0+1+2+3+4+5+7+8 and have been able to invalidate my TPM. Unfortunately, if you change your system BACK the volume will unlock. I'm investigating how to disable that.<br />
<br />
Other options on {{man|1|systemd-cryptenroll}} will reveal that several hardware tokens can also be enrolled to allow unlocking the root LUKS volume automatically, but only if a key is present. Further testing is requried.<br />
<br />
To enroll your LUKS volume, simply run the following command as root<br />
<br />
# systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/nvme0n1p2<br />
<br />
To remove your key, run this command:<br />
<br />
# systemd-cryptenroll --wipe-slot=tpm2 /dev/nvme0n1p2<br />
<br />
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:<br />
<br />
{{hc|~/bin/luks_reenroll_tpm|2=<br />
sudo systemd-cryptenroll --wipe-slot=tpm2 /dev/disk/by-uuid/{UUID_HERE}<br />
systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/disk/by-uuid/{UUID_HERE}<br />
}}<br />
<br />
== Justifications ==<br />
<br />
=== LVM on LUKS vs other dm-crypt approaches ===<br />
<br />
LVM on LUKS was selected becasue it is simply the easiest to manage while conferring both encrypted swap and disk. The other approaches required much more tooling and manual fussing to utilize. This selection also gives room change freely between {{ic|busybox}} and {{ic|systemd}} initrds.<br />
<br />
=== Using dracut ===<br />
<br />
{{Pkg|dracut}} just makes it easier to build full unified kernels that {{man|7|systemd-boot}} can launch as EFI binaries. There is also available tooling in the [[AUR]] for automating the creation of these binaries. Finally, {{ic|dracut}} will sign the binaries it creates automatically when configured to do so.<br />
<br />
=== Unified kernel images ===<br />
<br />
While UKI's could be problematic on other distributions, they fit right in with an Arch Linux install. The automation is there through pacman hooks and {{Pkg|sbctl}} to sign our UKIs as they're created. Furthermore, you can only sign and create a new signed UKI while booted into a properly signed UKI. It creates a chain of trust, which means it's important to never disable Secure Boot once you've set it up.<br />
<br />
The UKI encompasses all of the following items inside the signature, which means you can't change any of them without invalidating the signature.<br />
<br />
* Kernel arguments<br />
* Initrd/Initramfs<br />
* Kernel<br />
<br />
In particular, all other flavors of secureboot do not sign or validate the initramfs. This is a big attack area and can be relatively trivialized that a semi-decent pawn shop owner with Google could likely find an image that would grant him access and make the TPM none the wiser the system has changed. One can prevent this with encrypted /boot, but that would limit you to GRUB2 and LUKS version 1 devices only. This also doesn't include the work to keep GRUB2's files signed with a PGP key by root.<br />
<br />
=== LUKS enrolled in TPM ===<br />
<br />
Yes, the goal here is to only require the passphrase when something spooky happens in your boot path. UEFI settings change? Gimmie password. Some weird swap of some module of UEFI code that lives on your motherboard somewhere? Gimmie password. Unified Kernel Image changes? No boot. Drive in another computer? Give password.<br />
<br />
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.<br />
<br />
== Miscellaneous discussions ==<br />
<br />
=== Filesystem Selection ===<br />
<br />
Most examples on Arch utilize {{ic|ext4}}, but other file systems such as {{ic|brtfs}} can work equally well. As for performance or issues with being inside LVM, [https://btrfs.wiki.kernel.org/index.php/FAQ#Btrfs_has_subvolumes.2C_does_this_mean_I_don.27t_need_a_logical_volume_manager_and_I_can_create_a_big_Btrfs_filesystem_on_a_raw_partition.3F this question in the brtfs FAQ] implie that there is some performance loss but no other issues.<br />
<br />
=== LUKS TPM enrollment and managing luks keys ===<br />
<br />
Note that using {{man|1|systemd-cryptenroll}} will add a key to your LUKS volume. It's not clear how exactly the option {{ic|1=--wipe-slot=tpm2}} is able to identify which slot it needs to wipe, but it does. This even works if your TPM has changed.<br />
<br />
You can see the effects by comparing the output of {{ic|cryptsetup luksDump /dev/nvme0n1p2}} before and after you enroll or wipe a TPM based key. You can identify what slot your own passphrase is in with {{ic|cryptsetup --verbose open --test-passphrase /dev/nvme0n1p2}} and entering your passphrase. The output will inform you which key slot was unlocked.<br />
<br />
Finally, your passphrase may be changed with {{ic|cryptsetup luksChangeKey /dev/nvme0n1p2 -S 0}}.<br />
<br />
== Planned TODOs ==<br />
A panic command that can dump the TPM and shutdown the computer (without requiring the time of entering a password in sudo) forcing an adversary to resort to [https://en.wikipedia.org/wiki/Rubber-hose_cryptanalysis rubber-hose cryptanalysis] to get to the encrypted data.</div>Krinhttps://wiki.archlinux.org/index.php?title=User:Krin/Secure_Boot,_full_disk_encryption,_and_TPM2_unlocking_install&diff=697932User:Krin/Secure Boot, full disk encryption, and TPM2 unlocking install2021-10-01T02:14:14Z<p>Krin: /* Dual Booting Modifications */ Add bitlocker warning</p>
<hr />
<div>{{Unsupported|30 September 2021}}<br />
{{Expansion|Work In Progress, Draft from Installation Notes, Needs Testing}}<br />
<br />
== Introduction ==<br />
<br />
This installation is based on my installing Arch on an Asus ROG Strix G G531 I got second hand and a desktop computer made of second hand parts that had to share space with Windows. The primary goals were to replace Windows 10 Pro with Bitlocker encryption and maintain the convienence and security balance of that original operating system.<br />
<br />
My requirements boiled down to:<br />
<br />
* A fully encrypted disk<br />
* Full Secure Boot validation of all UEFI components.<br />
* Use of the TPM to facilitate unlocking of the disk.<br />
* Hibernate/Suspend working.<br />
<br />
My primary use case here is to make it difficult enough for a baggage handler with sticky hands to get at my data that they just wipe the drive. A state level actor with the expertise and equipment to hot swap my ram in my hotel room is not something that I'm defending this ''particular'' laptop against. This is more for gaming and web browsing and uploading photos while traveling.<br />
<br />
I'll continue to update these notes as I develop further solutions.<br />
<br />
== Disclaimers ==<br />
<br />
This article is primarily for the author's own notes. It is assumed that the reader is familiar with the [[Installation guide]] and will refer to it often. Reading linked articles is recommended.<br />
<br />
== Dual Booting Modifications ==<br />
<br />
{{warning|If you use BitLocker on your Windows drive, ensure you have your recovery key handy. The installation process will change your TPM measurements causing Windows to require you enter the key manually the next time you boot it.}}<br />
<br />
For computers that will have to dual boot with windows, the easiest solution is to use two different physical drives and utilize your motherboard's UEFI boot menu to select which one to boot. This guide will follow that assumption. You can also attempt to have everything live on one EFI partition. Windows's 100 MiB EFI partition is especially problematic to this approach for secure boot, as Unified Kernel Images can approach 80 MiB and Windows 10 regularly uses up to 30 MiB.<br />
<br />
There are two changes that will be made and will be noted in the relevant sections:<br />
<br />
* Do not clear your Secure Boot keys. Merely disable Secure Boot for the installation.<br />
* Use {{ic|shim}} to boot systemd-bootloader<br />
* Load your db.cer file into the MOKManager application.<br />
<br />
All remaining steps should remain the same, except your system will still be dependent on the factory provided Microsoft Certificates. But you can boot Windows 10 in Secure Boot, which will be important for Windows 11.<br />
<br />
== Initial setup ==<br />
<br />
=== Pre-installation ===<br />
<br />
If you will only boot linux, reset your Secure Boot settings in BIOS to enable setup mode. Usually this means you set Secure Boot to Enabled and then select the option to wipe out the keys.<br />
<br />
If you will be dual booting Windows, disable secure boot.<br />
<br />
Follow the [[Installation_guide#Pre-installation]] up to Paritioning the Disks.<br />
<br />
=== Disk preparation ===<br />
<br />
If you have data on your disks you want to overwrite, utilize [[Dm-crypt/Drive_preparation#dm-crypt_wipe_on_an_empty_disk_or_partition]] to wipe it. If this disk was previously encrypted, utilize [[Dm-crypt/Drive_preparation#Wipe_LUKS_header]] instead for a much faster disposal. Finally, use [[Dm-crypt/Encrypting_an_entire_system#LVM_on_LUKS]] to parition your drive with two differences.<br />
<br />
{{tip|Using a memorable LUKS passphrase until you've completed the install process can be helpful. It will take several reboots to finish setup.}}<br />
<br />
First, the partition layout will be similar to here. You may wish to break out the /home directory into it's own partition. The primary requirement is that only your EFI partition be unencrypted.<br />
<br />
{{hc|Partiton Layout|<br />
┌────────────────────┬──────────────────────────┬─────────────────────────────┐<br />
│ │ │ │<br />
│ EFI Boot Partition │ Logical Volume 1 │ Logical Volume 2 │<br />
│ │ │ │<br />
│ /efi │ [SWAP] │ / │<br />
│ │ │ │<br />
│ /dev/nvme0n1p1 │ /dev/CryptRootVG/swap │ /dev/CryptRootVG/root │<br />
│ │ │ │<br />
│ 512 MB │ 16 GB (Or RAM size) │ Remaining Free Space │<br />
│ │ │ │<br />
│ │ │ │<br />
│ ├──────────────────────────┴─────────────────────────────┤<br />
│ │ │<br />
│ │ LUKS and LVM Physical Volume │<br />
│ │ │<br />
│ │ /dev/nvme0n1p2 │<br />
│ │ │<br />
└────────────────────┴────────────────────────────────────────────────────────┘<br />
}}<br />
<br />
Second, if your hard drive is an SSD like this laptop, use the following command to open your LUKS volume.<br />
<br />
# cryptsetup open --perf-no_read_workqueue --perf-no_write_workqueue --persistent /dev/nvme0n1p2 cryptroot<br />
<br />
After completing your LUKS on LVM setup, format your EFI partition per [[EFI system partition]].<br />
<br />
# mkfs.fat -F32 /dev/nvme0n1p1<br />
<br />
Mount this partition at {{ic|/mnt/efi}}. It is very important to leave {{ic|/boot}} on your encrypted root partition.<br />
<br />
== Installation ==<br />
<br />
Continue with [[Installation_guide#Installation]]. Be sure to flesh out your {{man|8|pacstrap}} with the following list of packages:<br />
<br />
* {{Pkg|dracut}}<br />
* {{Pkg|intel-ucode}}<br />
* {{Pkg|lvm2}}<br />
* {{Pkg|openssh}}<br />
* {{Pkg|ansible}}<br />
* {{Pkg|git}}<br />
* {{Pkg|iwd}}<br />
* {{Pkg|efibootmgr}}<br />
<br />
<br />
We are going to leave off the installation guide at the initramfs section, so go ahead and reset your root password. <br />
<br />
# passwd<br />
<br />
=== Bootloader ===<br />
<br />
First, install {{ic|systemd-boot}} by following [[Systemd-boot#Installing_the_EFI_boot_manager]]. Next, install {{aur|dracut-hook-uefi}}.<br />
<br />
Ensure you drop in a systemd-boot hook to update your bootctl any time it's updated.<br />
<br />
{{hc|/etc/pacman.d/hooks/998-systemd-boot.hook|2=<br />
[Trigger]<br />
Type = Package<br />
Operation = Install<br />
Operation = Upgrade<br />
Target = systemd<br />
<br />
[Action]<br />
Description = Updating systemd-boot<br />
When = PostTransaction<br />
Exec = /usr/bin/bootctl update; <br />
}}<br />
<br />
Obtain the UUID of your LUKS drive via the following command:<br />
<br />
{{bc|<br />
blkid -s UUID -o value /dev/nvme0n1p2<br />
}}<br />
<br />
Create the following files with the listed content. Be sure to replace UUIDs with what you actually need. The extraneous {{ic:rd.luks.options}} should not cause an issue, but will be used once we've enabled secure boot. See {{man|5|dracut.conf}} for more information on what these commands do.<br />
<br />
A good portion of the kernel command line was as generated by dracut. Many are extraneous or you may wish to change some of the block device names.<br />
<br />
{{hc|/etc/dracut.conf.d/cmdline.conf|2=<br />
kernel_cmdline="rd.luks.uuid=luks-17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02 rd.luks.options=17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02=tpm2-device=auto rd.lvm.lv=CryptRoot/root rd.lvm.lv=CryptRoot/swap resume=/dev/mapper/CryptRoot-swap root=/dev/mapper/CryptRoot-root rootfstype=ext4 rootflags=rw,relatime"<br />
}}<br />
<br />
{{hc|/etc/dracut.conf.d/flags.conf|2=<br />
compress="zstd"<br />
hostonly="yes"<br />
}}<br />
<br />
Run the following command to generate your EFI stub kernels.<br />
<br />
dracut --uefi<br />
<br />
=== Secure boot ===<br />
<br />
==== Dual Booting Windows ====<br />
<br />
{{warning|This section is still being written}}<br />
<br />
Review [[Unified Extensible Firmware Interface/Secure Boot#shim]] to get a rough understanding of how it's going to work. Install {{aur|shim-signed}}. Perform the following commands to place files where both the UEFI boot entry and shim will load them.<br />
<br />
# mv /efi/EFI/BOOT/BOOTx64.EFI /efi/EFI/BOOT/grubx64.efi<br />
# cp /usr/share/shim-signed/shimx64.efi esp/EFI/BOOT/BOOTx64.EFI<br />
# cp /usr/share/shim-signed/mmx64.efi esp/EFI/BOOT/<br />
<br />
Install {{Pkg|sbctl}}. Use the following command to check that secure boot is in the right status. Your output should be similar.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✘ Sbctl is not installed<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/BOOT/grubx64.efi is not signed<br />
<br />
✘ /efi/EFI/BOOT/mmx64.efi is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
}}<br />
<br />
Note that shim and MOKManager (mmx) is included in this list, even though we will not be signing it.<br />
<br />
{{bc|<br />
# sbctl sign -s /efi/EFI/BOOT/ grubx64.efi <br />
<br />
✔ Signed /efi/EFI/BOOT/grubx64.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi <br />
<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi <br />
<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi<br />
# sbctl verify<br />
<br />
Verifying file database and EFI images in /efi...<br />
✔� /efi/EFI/BOOT/grubx64.efi is signed<br />
✔ /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi is signed<br />
✔ /efi/EFI/systemd/systemd-bootx64.efi is signed<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/BOOT/mmx64.efi is not signed<br />
}}<br />
<br />
You can validate that {{ic|BOOTx64.EFI}} and {{ic|mmx64.efi}} have signatures with {{man|1|sbverify}} from the {{Pkg|sbsigntools}} package.<br />
<br />
Next, we need to create the DER format certificate to load into ''MokManager''.<br />
<br />
# openssl x509 -outform DER -in /usr/share/secureboot/keys/db/db.pem -out /efi/signing.cer<br />
<br />
Use {{Pkg|efibootmgr}} ({{man|8|efibootmgr}}) to adjust your boot entries. Primarily, you will want to remove the {{ic|Linux Boot Manager}} entry.<br />
<br />
{{bc|<br />
# efibootmgr<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0001,0000,0002,0003,0004<br />
Boot0000* Windows Boot Manager<br />
Boot0001* Linux Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
}}<br />
<br />
In this example, we see that {{ic|0000}} is the Windows boot manager. {{ic|0001}} is the Linux Boot Manager and also the first in line to boot. {{ic|0001}} needs to be deleted and optionally the boot order modified so {{ic|0004}} is the default boot entry.<br />
<br />
{{bc|<br />
# efibootmgr --bootnum 0001 --delete-bootnum<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0000,0002,0003,0004<br />
Boot0000* Windows Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
<br />
# efibootmgr --bootorder 0004,0000,0002,0003<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0004,0000,0002,0003<br />
Boot0000* Windows Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Now reboot. You should get an error from your motherboard's UEFI BIOS that secure boot checks failed. Your computer should restart directly into ''MokManager'', if you rearranged the boot order. If not, you will need to select {{ic|UEFI OS}} from your UEFI boot menu. Navigate to the {{ic|signing.cer}} file we placed on the EFI partition and enroll the key. Select reboot, and the system should boot directly into linux with no problem.<br />
<br />
==== Booting only Linux ====<br />
<br />
{{note|The very newly developed [https://github.com/Foxboron/sbctl sbctl], availble via {{aur|sbctl-git}} has completely revamped this process and will only get better as they approach 1.0. From here on out, as of October 2021, this process should greatly simplify.}}<br />
<br />
{{note|Credit to this [https://lunaryorn.com/secure-boot-on-arch-linux-with-sbctl-and-dracut blog post by lunaryorn] for the inspiration.}}<br />
<br />
Install {{Pkg|sbctl}}. At this point you will likely need to reboot and adjust your secure boot settings. You want secure boot in '''setup mode'''. <br />
<br />
{{bc|<br />
$ sbctl status<br />
Installed: X Sbctl is not installed<br />
Setup Mode: X Enabled<br />
Secure Boot: X Disabled<br />
}}<br />
<br />
Run the following commands as root. See {{man|8|sbctl}} for more information on their function. Of particular note is the {{ic|-s}} flag which indicates {{ic|sbctl}} should remember the file for future verification and signing.<br />
<br />
Note your Linux EFI binary name may be slightly different.<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
<br />
# sbctl sign -s /efi/EFI/BOOT/BOOTx64.EFI<br />
✔ Signed /efi/EFI/BOOT/BOOTx64.EFI<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Finally, enroll the Secure Boot keys.<br />
<br />
{{bc|<br />
# sbctl enroll-keys<br />
Enrolling keys to EFI variables...✔<br />
Enrolled keys to the EFI variables!<br />
}}<br />
<br />
Verify that secure boot now has an owner GUID and setup mode is disabled.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✔ Sbctl is installed<br />
Owner GUID: a2ee3d08-725a-408b-9d95-28026a44611c<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
Now reboot. This reboot is required so we can get the TPM measurements into their (hopefully) permanent state.<br />
<br />
=== Enroll LUKS key in TPM ===<br />
{{warning|Yes, this will cause a system to automatically unlock it's encrypted root volume without any interaction from a human. Yes, this exposes it to any sufficently advanced Evil Maid attacks. If sealed against the appropriate registers (especially register 8 with the kernel arguments), the TPM measurements should force systemd to ask for your LUKS passphrase in almost any attempt to access the encrypted volume from outside your normal boot process.}}<br />
<br />
We are fortunate that in our shift to dracut includes utilizing systemd and sd-encrypt, as we can use systemd's native support for enrolling LUKS keys. A review of [[Trusted Platform Module#Using TPM 2.0]] is recommended but not very clear.<br />
<br />
First, be sure to install {{Pkg|tpm2-tools}}. Alternatively {{aur|ibm-tss}} can be used per [[Trusted Platform Module]], however this guide is not tested against those.<br />
<br />
{{note|A reboot may be required to convince {{ic|systemd-cryptenroll}} that TPM 2.0 devices now exist on the machine.}}<br />
<br />
There are several decisions to be made here. The table at [[Trusted Platform Module#Accessing PCR registers]] is accurate as of October 2021. Essentially, once you seal your LUKS key, if any of the registers you've sealed against change, then you will be asked for your LUKS passphrase. This is equivalent to when Windows 10 makes you enter your BitLocker recovery key after a hardware change or changing BIOS settings.<br />
<br />
Your mileage may vary, based on UEFI vendors. For my laptop, I went with 0+1+2+3+4+5+7+8 and have been able to invalidate my TPM. Unfortunately, if you change your system BACK the volume will unlock. I'm investigating how to disable that.<br />
<br />
Other options on {{man|1|systemd-cryptenroll}} will reveal that several hardware tokens can also be enrolled to allow unlocking the root LUKS volume automatically, but only if a key is present. Further testing is requried.<br />
<br />
To enroll your LUKS volume, simply run the following command as root<br />
<br />
# systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/nvme0n1p2<br />
<br />
To remove your key, run this command:<br />
<br />
# systemd-cryptenroll --wipe-slot=tpm2 /dev/nvme0n1p2<br />
<br />
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:<br />
<br />
{{hc|~/bin/luks_reenroll_tpm|2=<br />
sudo systemd-cryptenroll --wipe-slot=tpm2 /dev/disk/by-uuid/{UUID_HERE}<br />
systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/disk/by-uuid/{UUID_HERE}<br />
}}<br />
<br />
== Justifications ==<br />
<br />
=== LVM on LUKS vs other dm-crypt approaches ===<br />
<br />
LVM on LUKS was selected becasue it is simply the easiest to manage while conferring both encrypted swap and disk. The other approaches required much more tooling and manual fussing to utilize. This selection also gives room change freely between {{ic|busybox}} and {{ic|systemd}} initrds.<br />
<br />
=== Using dracut ===<br />
<br />
{{Pkg|dracut}} just makes it easier to build full unified kernels that {{man|7|systemd-boot}} can launch as EFI binaries. There is also available tooling in the [[AUR]] for automating the creation of these binaries. Finally, {{ic|dracut}} will sign the binaries it creates automatically when configured to do so.<br />
<br />
=== Unified kernel images ===<br />
<br />
While UKI's could be problematic on other distributions, they fit right in with an Arch Linux install. The automation is there through pacman hooks and {{Pkg|sbctl}} to sign our UKIs as they're created. Furthermore, you can only sign and create a new signed UKI while booted into a properly signed UKI. It creates a chain of trust, which means it's important to never disable Secure Boot once you've set it up.<br />
<br />
The UKI encompasses all of the following items inside the signature, which means you can't change any of them without invalidating the signature.<br />
<br />
* Kernel arguments<br />
* Initrd/Initramfs<br />
* Kernel<br />
<br />
In particular, all other flavors of secureboot do not sign or validate the initramfs. This is a big attack area and can be relatively trivialized that a semi-decent pawn shop owner with Google could likely find an image that would grant him access and make the TPM none the wiser the system has changed. One can prevent this with encrypted /boot, but that would limit you to GRUB2 and LUKS version 1 devices only. This also doesn't include the work to keep GRUB2's files signed with a PGP key by root.<br />
<br />
== Miscellaneous discussions ==<br />
<br />
=== Filesystem Selection ===<br />
<br />
Most examples on Arch utilize {{ic|ext4}}, but other file systems such as {{ic|brtfs}} can work equally well. As for performance or issues with being inside LVM, [https://btrfs.wiki.kernel.org/index.php/FAQ#Btrfs_has_subvolumes.2C_does_this_mean_I_don.27t_need_a_logical_volume_manager_and_I_can_create_a_big_Btrfs_filesystem_on_a_raw_partition.3F this question in the brtfs FAQ] implie that there is some performance loss but no other issues.<br />
<br />
=== LUKS TPM enrollment and managing luks keys ===<br />
<br />
Note that using {{man|1|systemd-cryptenroll}} will add a key to your LUKS volume. It's not clear how exactly the option {{ic|1=--wipe-slot=tpm2}} is able to identify which slot it needs to wipe, but it does. This even works if your TPM has changed.<br />
<br />
You can see the effects by comparing the output of {{ic|cryptsetup luksDump /dev/nvme0n1p2}} before and after you enroll or wipe a TPM based key. You can identify what slot your own passphrase is in with {{ic|cryptsetup --verbose open --test-passphrase /dev/nvme0n1p2}} and entering your passphrase. The output will inform you which key slot was unlocked.<br />
<br />
Finally, your passphrase may be changed with {{ic|cryptsetup luksChangeKey /dev/nvme0n1p2 -S 0}}.<br />
<br />
== Planned TODOs ==<br />
A panic command that can dump the TPM and shutdown the computer (without requiring the time of entering a password in sudo) forcing an adversary to resort to [https://en.wikipedia.org/wiki/Rubber-hose_cryptanalysis rubber-hose cryptanalysis] to get to the encrypted data.</div>Krinhttps://wiki.archlinux.org/index.php?title=User:Krin/Secure_Boot,_full_disk_encryption,_and_TPM2_unlocking_install&diff=697931User:Krin/Secure Boot, full disk encryption, and TPM2 unlocking install2021-10-01T02:12:52Z<p>Krin: /* Dual Booting Windows */ Update with final steps to enroll key.</p>
<hr />
<div>{{Unsupported|30 September 2021}}<br />
{{Expansion|Work In Progress, Draft from Installation Notes, Needs Testing}}<br />
<br />
== Introduction ==<br />
<br />
This installation is based on my installing Arch on an Asus ROG Strix G G531 I got second hand and a desktop computer made of second hand parts that had to share space with Windows. The primary goals were to replace Windows 10 Pro with Bitlocker encryption and maintain the convienence and security balance of that original operating system.<br />
<br />
My requirements boiled down to:<br />
<br />
* A fully encrypted disk<br />
* Full Secure Boot validation of all UEFI components.<br />
* Use of the TPM to facilitate unlocking of the disk.<br />
* Hibernate/Suspend working.<br />
<br />
My primary use case here is to make it difficult enough for a baggage handler with sticky hands to get at my data that they just wipe the drive. A state level actor with the expertise and equipment to hot swap my ram in my hotel room is not something that I'm defending this ''particular'' laptop against. This is more for gaming and web browsing and uploading photos while traveling.<br />
<br />
I'll continue to update these notes as I develop further solutions.<br />
<br />
== Disclaimers ==<br />
<br />
This article is primarily for the author's own notes. It is assumed that the reader is familiar with the [[Installation guide]] and will refer to it often. Reading linked articles is recommended.<br />
<br />
== Dual Booting Modifications ==<br />
<br />
For computers that will have to dual boot with windows, the easiest solution is to use two different physical drives and utilize your motherboard's UEFI boot menu to select which one to boot. This guide will follow that assumption. You can also attempt to have everything live on one EFI partition. Windows's 100 MiB EFI partition is especially problematic to this approach for secure boot, as Unified Kernel Images can approach 80 MiB and Windows 10 regularly uses up to 30 MiB.<br />
<br />
There are two changes that will be made and will be noted in the relevant sections:<br />
<br />
* Do not clear your Secure Boot keys. Merely disable Secure Boot for the installation.<br />
* Use {{ic|shim}} to boot systemd-bootloader<br />
* Load your db.cer file into the MOKManager application.<br />
<br />
All remaining steps should remain the same, except your system will still be dependent on the factory provided Microsoft Certificates. But you can boot Windows 10 in Secure Boot, which will be important for Windows 11.<br />
<br />
== Initial setup ==<br />
<br />
=== Pre-installation ===<br />
<br />
If you will only boot linux, reset your Secure Boot settings in BIOS to enable setup mode. Usually this means you set Secure Boot to Enabled and then select the option to wipe out the keys.<br />
<br />
If you will be dual booting Windows, disable secure boot.<br />
<br />
Follow the [[Installation_guide#Pre-installation]] up to Paritioning the Disks.<br />
<br />
=== Disk preparation ===<br />
<br />
If you have data on your disks you want to overwrite, utilize [[Dm-crypt/Drive_preparation#dm-crypt_wipe_on_an_empty_disk_or_partition]] to wipe it. If this disk was previously encrypted, utilize [[Dm-crypt/Drive_preparation#Wipe_LUKS_header]] instead for a much faster disposal. Finally, use [[Dm-crypt/Encrypting_an_entire_system#LVM_on_LUKS]] to parition your drive with two differences.<br />
<br />
{{tip|Using a memorable LUKS passphrase until you've completed the install process can be helpful. It will take several reboots to finish setup.}}<br />
<br />
First, the partition layout will be similar to here. You may wish to break out the /home directory into it's own partition. The primary requirement is that only your EFI partition be unencrypted.<br />
<br />
{{hc|Partiton Layout|<br />
┌────────────────────┬──────────────────────────┬─────────────────────────────┐<br />
│ │ │ │<br />
│ EFI Boot Partition │ Logical Volume 1 │ Logical Volume 2 │<br />
│ │ │ │<br />
│ /efi │ [SWAP] │ / │<br />
│ │ │ │<br />
│ /dev/nvme0n1p1 │ /dev/CryptRootVG/swap │ /dev/CryptRootVG/root │<br />
│ │ │ │<br />
│ 512 MB │ 16 GB (Or RAM size) │ Remaining Free Space │<br />
│ │ │ │<br />
│ │ │ │<br />
│ ├──────────────────────────┴─────────────────────────────┤<br />
│ │ │<br />
│ │ LUKS and LVM Physical Volume │<br />
│ │ │<br />
│ │ /dev/nvme0n1p2 │<br />
│ │ │<br />
└────────────────────┴────────────────────────────────────────────────────────┘<br />
}}<br />
<br />
Second, if your hard drive is an SSD like this laptop, use the following command to open your LUKS volume.<br />
<br />
# cryptsetup open --perf-no_read_workqueue --perf-no_write_workqueue --persistent /dev/nvme0n1p2 cryptroot<br />
<br />
After completing your LUKS on LVM setup, format your EFI partition per [[EFI system partition]].<br />
<br />
# mkfs.fat -F32 /dev/nvme0n1p1<br />
<br />
Mount this partition at {{ic|/mnt/efi}}. It is very important to leave {{ic|/boot}} on your encrypted root partition.<br />
<br />
== Installation ==<br />
<br />
Continue with [[Installation_guide#Installation]]. Be sure to flesh out your {{man|8|pacstrap}} with the following list of packages:<br />
<br />
* {{Pkg|dracut}}<br />
* {{Pkg|intel-ucode}}<br />
* {{Pkg|lvm2}}<br />
* {{Pkg|openssh}}<br />
* {{Pkg|ansible}}<br />
* {{Pkg|git}}<br />
* {{Pkg|iwd}}<br />
* {{Pkg|efibootmgr}}<br />
<br />
<br />
We are going to leave off the installation guide at the initramfs section, so go ahead and reset your root password. <br />
<br />
# passwd<br />
<br />
=== Bootloader ===<br />
<br />
First, install {{ic|systemd-boot}} by following [[Systemd-boot#Installing_the_EFI_boot_manager]]. Next, install {{aur|dracut-hook-uefi}}.<br />
<br />
Ensure you drop in a systemd-boot hook to update your bootctl any time it's updated.<br />
<br />
{{hc|/etc/pacman.d/hooks/998-systemd-boot.hook|2=<br />
[Trigger]<br />
Type = Package<br />
Operation = Install<br />
Operation = Upgrade<br />
Target = systemd<br />
<br />
[Action]<br />
Description = Updating systemd-boot<br />
When = PostTransaction<br />
Exec = /usr/bin/bootctl update; <br />
}}<br />
<br />
Obtain the UUID of your LUKS drive via the following command:<br />
<br />
{{bc|<br />
blkid -s UUID -o value /dev/nvme0n1p2<br />
}}<br />
<br />
Create the following files with the listed content. Be sure to replace UUIDs with what you actually need. The extraneous {{ic:rd.luks.options}} should not cause an issue, but will be used once we've enabled secure boot. See {{man|5|dracut.conf}} for more information on what these commands do.<br />
<br />
A good portion of the kernel command line was as generated by dracut. Many are extraneous or you may wish to change some of the block device names.<br />
<br />
{{hc|/etc/dracut.conf.d/cmdline.conf|2=<br />
kernel_cmdline="rd.luks.uuid=luks-17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02 rd.luks.options=17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02=tpm2-device=auto rd.lvm.lv=CryptRoot/root rd.lvm.lv=CryptRoot/swap resume=/dev/mapper/CryptRoot-swap root=/dev/mapper/CryptRoot-root rootfstype=ext4 rootflags=rw,relatime"<br />
}}<br />
<br />
{{hc|/etc/dracut.conf.d/flags.conf|2=<br />
compress="zstd"<br />
hostonly="yes"<br />
}}<br />
<br />
Run the following command to generate your EFI stub kernels.<br />
<br />
dracut --uefi<br />
<br />
=== Secure boot ===<br />
<br />
==== Dual Booting Windows ====<br />
<br />
{{warning|This section is still being written}}<br />
<br />
Review [[Unified Extensible Firmware Interface/Secure Boot#shim]] to get a rough understanding of how it's going to work. Install {{aur|shim-signed}}. Perform the following commands to place files where both the UEFI boot entry and shim will load them.<br />
<br />
# mv /efi/EFI/BOOT/BOOTx64.EFI /efi/EFI/BOOT/grubx64.efi<br />
# cp /usr/share/shim-signed/shimx64.efi esp/EFI/BOOT/BOOTx64.EFI<br />
# cp /usr/share/shim-signed/mmx64.efi esp/EFI/BOOT/<br />
<br />
Install {{Pkg|sbctl}}. Use the following command to check that secure boot is in the right status. Your output should be similar.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✘ Sbctl is not installed<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/BOOT/grubx64.efi is not signed<br />
<br />
✘ /efi/EFI/BOOT/mmx64.efi is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
}}<br />
<br />
Note that shim and MOKManager (mmx) is included in this list, even though we will not be signing it.<br />
<br />
{{bc|<br />
# sbctl sign -s /efi/EFI/BOOT/ grubx64.efi <br />
<br />
✔ Signed /efi/EFI/BOOT/grubx64.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi <br />
<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi <br />
<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi<br />
# sbctl verify<br />
<br />
Verifying file database and EFI images in /efi...<br />
✔� /efi/EFI/BOOT/grubx64.efi is signed<br />
✔ /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi is signed<br />
✔ /efi/EFI/systemd/systemd-bootx64.efi is signed<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/BOOT/mmx64.efi is not signed<br />
}}<br />
<br />
You can validate that {{ic|BOOTx64.EFI}} and {{ic|mmx64.efi}} have signatures with {{man|1|sbverify}} from the {{Pkg|sbsigntools}} package.<br />
<br />
Next, we need to create the DER format certificate to load into ''MokManager''.<br />
<br />
# openssl x509 -outform DER -in /usr/share/secureboot/keys/db/db.pem -out /efi/signing.cer<br />
<br />
Use {{Pkg|efibootmgr}} ({{man|8|efibootmgr}}) to adjust your boot entries. Primarily, you will want to remove the {{ic|Linux Boot Manager}} entry.<br />
<br />
{{bc|<br />
# efibootmgr<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0001,0000,0002,0003,0004<br />
Boot0000* Windows Boot Manager<br />
Boot0001* Linux Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
}}<br />
<br />
In this example, we see that {{ic|0000}} is the Windows boot manager. {{ic|0001}} is the Linux Boot Manager and also the first in line to boot. {{ic|0001}} needs to be deleted and optionally the boot order modified so {{ic|0004}} is the default boot entry.<br />
<br />
{{bc|<br />
# efibootmgr --bootnum 0001 --delete-bootnum<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0000,0002,0003,0004<br />
Boot0000* Windows Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
<br />
# efibootmgr --bootorder 0004,0000,0002,0003<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0004,0000,0002,0003<br />
Boot0000* Windows Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Now reboot. You should get an error from your motherboard's UEFI BIOS that secure boot checks failed. Your computer should restart directly into ''MokManager'', if you rearranged the boot order. If not, you will need to select {{ic|UEFI OS}} from your UEFI boot menu. Navigate to the {{ic|signing.cer}} file we placed on the EFI partition and enroll the key. Select reboot, and the system should boot directly into linux with no problem.<br />
<br />
==== Booting only Linux ====<br />
<br />
{{note|The very newly developed [https://github.com/Foxboron/sbctl sbctl], availble via {{aur|sbctl-git}} has completely revamped this process and will only get better as they approach 1.0. From here on out, as of October 2021, this process should greatly simplify.}}<br />
<br />
{{note|Credit to this [https://lunaryorn.com/secure-boot-on-arch-linux-with-sbctl-and-dracut blog post by lunaryorn] for the inspiration.}}<br />
<br />
Install {{Pkg|sbctl}}. At this point you will likely need to reboot and adjust your secure boot settings. You want secure boot in '''setup mode'''. <br />
<br />
{{bc|<br />
$ sbctl status<br />
Installed: X Sbctl is not installed<br />
Setup Mode: X Enabled<br />
Secure Boot: X Disabled<br />
}}<br />
<br />
Run the following commands as root. See {{man|8|sbctl}} for more information on their function. Of particular note is the {{ic|-s}} flag which indicates {{ic|sbctl}} should remember the file for future verification and signing.<br />
<br />
Note your Linux EFI binary name may be slightly different.<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
<br />
# sbctl sign -s /efi/EFI/BOOT/BOOTx64.EFI<br />
✔ Signed /efi/EFI/BOOT/BOOTx64.EFI<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Finally, enroll the Secure Boot keys.<br />
<br />
{{bc|<br />
# sbctl enroll-keys<br />
Enrolling keys to EFI variables...✔<br />
Enrolled keys to the EFI variables!<br />
}}<br />
<br />
Verify that secure boot now has an owner GUID and setup mode is disabled.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✔ Sbctl is installed<br />
Owner GUID: a2ee3d08-725a-408b-9d95-28026a44611c<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
Now reboot. This reboot is required so we can get the TPM measurements into their (hopefully) permanent state.<br />
<br />
=== Enroll LUKS key in TPM ===<br />
{{warning|Yes, this will cause a system to automatically unlock it's encrypted root volume without any interaction from a human. Yes, this exposes it to any sufficently advanced Evil Maid attacks. If sealed against the appropriate registers (especially register 8 with the kernel arguments), the TPM measurements should force systemd to ask for your LUKS passphrase in almost any attempt to access the encrypted volume from outside your normal boot process.}}<br />
<br />
We are fortunate that in our shift to dracut includes utilizing systemd and sd-encrypt, as we can use systemd's native support for enrolling LUKS keys. A review of [[Trusted Platform Module#Using TPM 2.0]] is recommended but not very clear.<br />
<br />
First, be sure to install {{Pkg|tpm2-tools}}. Alternatively {{aur|ibm-tss}} can be used per [[Trusted Platform Module]], however this guide is not tested against those.<br />
<br />
{{note|A reboot may be required to convince {{ic|systemd-cryptenroll}} that TPM 2.0 devices now exist on the machine.}}<br />
<br />
There are several decisions to be made here. The table at [[Trusted Platform Module#Accessing PCR registers]] is accurate as of October 2021. Essentially, once you seal your LUKS key, if any of the registers you've sealed against change, then you will be asked for your LUKS passphrase. This is equivalent to when Windows 10 makes you enter your BitLocker recovery key after a hardware change or changing BIOS settings.<br />
<br />
Your mileage may vary, based on UEFI vendors. For my laptop, I went with 0+1+2+3+4+5+7+8 and have been able to invalidate my TPM. Unfortunately, if you change your system BACK the volume will unlock. I'm investigating how to disable that.<br />
<br />
Other options on {{man|1|systemd-cryptenroll}} will reveal that several hardware tokens can also be enrolled to allow unlocking the root LUKS volume automatically, but only if a key is present. Further testing is requried.<br />
<br />
To enroll your LUKS volume, simply run the following command as root<br />
<br />
# systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/nvme0n1p2<br />
<br />
To remove your key, run this command:<br />
<br />
# systemd-cryptenroll --wipe-slot=tpm2 /dev/nvme0n1p2<br />
<br />
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:<br />
<br />
{{hc|~/bin/luks_reenroll_tpm|2=<br />
sudo systemd-cryptenroll --wipe-slot=tpm2 /dev/disk/by-uuid/{UUID_HERE}<br />
systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/disk/by-uuid/{UUID_HERE}<br />
}}<br />
<br />
== Justifications ==<br />
<br />
=== LVM on LUKS vs other dm-crypt approaches ===<br />
<br />
LVM on LUKS was selected becasue it is simply the easiest to manage while conferring both encrypted swap and disk. The other approaches required much more tooling and manual fussing to utilize. This selection also gives room change freely between {{ic|busybox}} and {{ic|systemd}} initrds.<br />
<br />
=== Using dracut ===<br />
<br />
{{Pkg|dracut}} just makes it easier to build full unified kernels that {{man|7|systemd-boot}} can launch as EFI binaries. There is also available tooling in the [[AUR]] for automating the creation of these binaries. Finally, {{ic|dracut}} will sign the binaries it creates automatically when configured to do so.<br />
<br />
=== Unified kernel images ===<br />
<br />
While UKI's could be problematic on other distributions, they fit right in with an Arch Linux install. The automation is there through pacman hooks and {{Pkg|sbctl}} to sign our UKIs as they're created. Furthermore, you can only sign and create a new signed UKI while booted into a properly signed UKI. It creates a chain of trust, which means it's important to never disable Secure Boot once you've set it up.<br />
<br />
The UKI encompasses all of the following items inside the signature, which means you can't change any of them without invalidating the signature.<br />
<br />
* Kernel arguments<br />
* Initrd/Initramfs<br />
* Kernel<br />
<br />
In particular, all other flavors of secureboot do not sign or validate the initramfs. This is a big attack area and can be relatively trivialized that a semi-decent pawn shop owner with Google could likely find an image that would grant him access and make the TPM none the wiser the system has changed. One can prevent this with encrypted /boot, but that would limit you to GRUB2 and LUKS version 1 devices only. This also doesn't include the work to keep GRUB2's files signed with a PGP key by root.<br />
<br />
== Miscellaneous discussions ==<br />
<br />
=== Filesystem Selection ===<br />
<br />
Most examples on Arch utilize {{ic|ext4}}, but other file systems such as {{ic|brtfs}} can work equally well. As for performance or issues with being inside LVM, [https://btrfs.wiki.kernel.org/index.php/FAQ#Btrfs_has_subvolumes.2C_does_this_mean_I_don.27t_need_a_logical_volume_manager_and_I_can_create_a_big_Btrfs_filesystem_on_a_raw_partition.3F this question in the brtfs FAQ] implie that there is some performance loss but no other issues.<br />
<br />
=== LUKS TPM enrollment and managing luks keys ===<br />
<br />
Note that using {{man|1|systemd-cryptenroll}} will add a key to your LUKS volume. It's not clear how exactly the option {{ic|1=--wipe-slot=tpm2}} is able to identify which slot it needs to wipe, but it does. This even works if your TPM has changed.<br />
<br />
You can see the effects by comparing the output of {{ic|cryptsetup luksDump /dev/nvme0n1p2}} before and after you enroll or wipe a TPM based key. You can identify what slot your own passphrase is in with {{ic|cryptsetup --verbose open --test-passphrase /dev/nvme0n1p2}} and entering your passphrase. The output will inform you which key slot was unlocked.<br />
<br />
Finally, your passphrase may be changed with {{ic|cryptsetup luksChangeKey /dev/nvme0n1p2 -S 0}}.<br />
<br />
== Planned TODOs ==<br />
A panic command that can dump the TPM and shutdown the computer (without requiring the time of entering a password in sudo) forcing an adversary to resort to [https://en.wikipedia.org/wiki/Rubber-hose_cryptanalysis rubber-hose cryptanalysis] to get to the encrypted data.</div>Krinhttps://wiki.archlinux.org/index.php?title=User:Krin/Secure_Boot,_full_disk_encryption,_and_TPM2_unlocking_install&diff=697929User:Krin/Secure Boot, full disk encryption, and TPM2 unlocking install2021-10-01T02:09:45Z<p>Krin: /* Bootloader */ Tested section.</p>
<hr />
<div>{{Unsupported|30 September 2021}}<br />
{{Expansion|Work In Progress, Draft from Installation Notes, Needs Testing}}<br />
<br />
== Introduction ==<br />
<br />
This installation is based on my installing Arch on an Asus ROG Strix G G531 I got second hand and a desktop computer made of second hand parts that had to share space with Windows. The primary goals were to replace Windows 10 Pro with Bitlocker encryption and maintain the convienence and security balance of that original operating system.<br />
<br />
My requirements boiled down to:<br />
<br />
* A fully encrypted disk<br />
* Full Secure Boot validation of all UEFI components.<br />
* Use of the TPM to facilitate unlocking of the disk.<br />
* Hibernate/Suspend working.<br />
<br />
My primary use case here is to make it difficult enough for a baggage handler with sticky hands to get at my data that they just wipe the drive. A state level actor with the expertise and equipment to hot swap my ram in my hotel room is not something that I'm defending this ''particular'' laptop against. This is more for gaming and web browsing and uploading photos while traveling.<br />
<br />
I'll continue to update these notes as I develop further solutions.<br />
<br />
== Disclaimers ==<br />
<br />
This article is primarily for the author's own notes. It is assumed that the reader is familiar with the [[Installation guide]] and will refer to it often. Reading linked articles is recommended.<br />
<br />
== Dual Booting Modifications ==<br />
<br />
For computers that will have to dual boot with windows, the easiest solution is to use two different physical drives and utilize your motherboard's UEFI boot menu to select which one to boot. This guide will follow that assumption. You can also attempt to have everything live on one EFI partition. Windows's 100 MiB EFI partition is especially problematic to this approach for secure boot, as Unified Kernel Images can approach 80 MiB and Windows 10 regularly uses up to 30 MiB.<br />
<br />
There are two changes that will be made and will be noted in the relevant sections:<br />
<br />
* Do not clear your Secure Boot keys. Merely disable Secure Boot for the installation.<br />
* Use {{ic|shim}} to boot systemd-bootloader<br />
* Load your db.cer file into the MOKManager application.<br />
<br />
All remaining steps should remain the same, except your system will still be dependent on the factory provided Microsoft Certificates. But you can boot Windows 10 in Secure Boot, which will be important for Windows 11.<br />
<br />
== Initial setup ==<br />
<br />
=== Pre-installation ===<br />
<br />
If you will only boot linux, reset your Secure Boot settings in BIOS to enable setup mode. Usually this means you set Secure Boot to Enabled and then select the option to wipe out the keys.<br />
<br />
If you will be dual booting Windows, disable secure boot.<br />
<br />
Follow the [[Installation_guide#Pre-installation]] up to Paritioning the Disks.<br />
<br />
=== Disk preparation ===<br />
<br />
If you have data on your disks you want to overwrite, utilize [[Dm-crypt/Drive_preparation#dm-crypt_wipe_on_an_empty_disk_or_partition]] to wipe it. If this disk was previously encrypted, utilize [[Dm-crypt/Drive_preparation#Wipe_LUKS_header]] instead for a much faster disposal. Finally, use [[Dm-crypt/Encrypting_an_entire_system#LVM_on_LUKS]] to parition your drive with two differences.<br />
<br />
{{tip|Using a memorable LUKS passphrase until you've completed the install process can be helpful. It will take several reboots to finish setup.}}<br />
<br />
First, the partition layout will be similar to here. You may wish to break out the /home directory into it's own partition. The primary requirement is that only your EFI partition be unencrypted.<br />
<br />
{{hc|Partiton Layout|<br />
┌────────────────────┬──────────────────────────┬─────────────────────────────┐<br />
│ │ │ │<br />
│ EFI Boot Partition │ Logical Volume 1 │ Logical Volume 2 │<br />
│ │ │ │<br />
│ /efi │ [SWAP] │ / │<br />
│ │ │ │<br />
│ /dev/nvme0n1p1 │ /dev/CryptRootVG/swap │ /dev/CryptRootVG/root │<br />
│ │ │ │<br />
│ 512 MB │ 16 GB (Or RAM size) │ Remaining Free Space │<br />
│ │ │ │<br />
│ │ │ │<br />
│ ├──────────────────────────┴─────────────────────────────┤<br />
│ │ │<br />
│ │ LUKS and LVM Physical Volume │<br />
│ │ │<br />
│ │ /dev/nvme0n1p2 │<br />
│ │ │<br />
└────────────────────┴────────────────────────────────────────────────────────┘<br />
}}<br />
<br />
Second, if your hard drive is an SSD like this laptop, use the following command to open your LUKS volume.<br />
<br />
# cryptsetup open --perf-no_read_workqueue --perf-no_write_workqueue --persistent /dev/nvme0n1p2 cryptroot<br />
<br />
After completing your LUKS on LVM setup, format your EFI partition per [[EFI system partition]].<br />
<br />
# mkfs.fat -F32 /dev/nvme0n1p1<br />
<br />
Mount this partition at {{ic|/mnt/efi}}. It is very important to leave {{ic|/boot}} on your encrypted root partition.<br />
<br />
== Installation ==<br />
<br />
Continue with [[Installation_guide#Installation]]. Be sure to flesh out your {{man|8|pacstrap}} with the following list of packages:<br />
<br />
* {{Pkg|dracut}}<br />
* {{Pkg|intel-ucode}}<br />
* {{Pkg|lvm2}}<br />
* {{Pkg|openssh}}<br />
* {{Pkg|ansible}}<br />
* {{Pkg|git}}<br />
* {{Pkg|iwd}}<br />
* {{Pkg|efibootmgr}}<br />
<br />
<br />
We are going to leave off the installation guide at the initramfs section, so go ahead and reset your root password. <br />
<br />
# passwd<br />
<br />
=== Bootloader ===<br />
<br />
First, install {{ic|systemd-boot}} by following [[Systemd-boot#Installing_the_EFI_boot_manager]]. Next, install {{aur|dracut-hook-uefi}}.<br />
<br />
Ensure you drop in a systemd-boot hook to update your bootctl any time it's updated.<br />
<br />
{{hc|/etc/pacman.d/hooks/998-systemd-boot.hook|2=<br />
[Trigger]<br />
Type = Package<br />
Operation = Install<br />
Operation = Upgrade<br />
Target = systemd<br />
<br />
[Action]<br />
Description = Updating systemd-boot<br />
When = PostTransaction<br />
Exec = /usr/bin/bootctl update; <br />
}}<br />
<br />
Obtain the UUID of your LUKS drive via the following command:<br />
<br />
{{bc|<br />
blkid -s UUID -o value /dev/nvme0n1p2<br />
}}<br />
<br />
Create the following files with the listed content. Be sure to replace UUIDs with what you actually need. The extraneous {{ic:rd.luks.options}} should not cause an issue, but will be used once we've enabled secure boot. See {{man|5|dracut.conf}} for more information on what these commands do.<br />
<br />
A good portion of the kernel command line was as generated by dracut. Many are extraneous or you may wish to change some of the block device names.<br />
<br />
{{hc|/etc/dracut.conf.d/cmdline.conf|2=<br />
kernel_cmdline="rd.luks.uuid=luks-17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02 rd.luks.options=17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02=tpm2-device=auto rd.lvm.lv=CryptRoot/root rd.lvm.lv=CryptRoot/swap resume=/dev/mapper/CryptRoot-swap root=/dev/mapper/CryptRoot-root rootfstype=ext4 rootflags=rw,relatime"<br />
}}<br />
<br />
{{hc|/etc/dracut.conf.d/flags.conf|2=<br />
compress="zstd"<br />
hostonly="yes"<br />
}}<br />
<br />
Run the following command to generate your EFI stub kernels.<br />
<br />
dracut --uefi<br />
<br />
=== Secure boot ===<br />
<br />
==== Dual Booting Windows ====<br />
<br />
{{warning|This section is still being written}}<br />
<br />
Review [[Unified Extensible Firmware Interface/Secure Boot#shim]] to get a rough understanding of how it's going to work. Install {{aur|shim-signed}}. Perform the following commands to place files where both the UEFI boot entry and shim will load them.<br />
<br />
# mv /efi/EFI/BOOT/BOOTx64.EFI /efi/EFI/BOOT/grubx64.efi<br />
# cp /usr/share/shim-signed/shimx64.efi esp/EFI/BOOT/BOOTx64.EFI<br />
# cp /usr/share/shim-signed/mmx64.efi esp/EFI/BOOT/<br />
<br />
Install {{Pkg|sbctl}}. Use the following command to check that secure boot is in the right status. Your output should be similar.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✘ Sbctl is not installed<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/BOOT/grubx64.efi is not signed<br />
<br />
✘ /efi/EFI/BOOT/mmx64.efi is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
}}<br />
<br />
Note that shim and MOKManager (mmx) is included in this list, even though we will not be signing it.<br />
<br />
{{bc|<br />
# sbctl sign -s /efi/EFI/BOOT/ grubx64.efi <br />
<br />
✔ Signed /efi/EFI/BOOT/grubx64.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi <br />
<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi <br />
<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi<br />
# sbctl verify<br />
<br />
Verifying file database and EFI images in /efi...<br />
✔� /efi/EFI/BOOT/grubx64.efi is signed<br />
✔ /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi is signed<br />
✔ /efi/EFI/systemd/systemd-bootx64.efi is signed<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/BOOT/mmx64.efi is not signed<br />
}}<br />
<br />
You can validate that {{ic|BOOTx64.EFI}} and {{ic|mmx64.efi}} have signatures with {{man|1|sbverify}} from the {{Pkg|sbsigntools}} package.<br />
<br />
Next, we need to create the DER format certificate to load into ''MokManager''.<br />
<br />
# openssl x509 -outform DER -in /usr/share/secureboot/keys/db/db.pem -out /efi/signing.cer<br />
<br />
Use {{Pkg|efibootmgr}} ({{man|8|efibootmgr}}) to adjust your boot entries. Primarily, you will want to remove the {{ic|Linux Boot Manager}} entry.<br />
<br />
{{bc|<br />
# efibootmgr<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0001,0000,0002,0003,0004<br />
Boot0000* Windows Boot Manager<br />
Boot0001* Linux Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
}}<br />
<br />
In this example, we see that {{ic|0000}} is the Windows boot manager. {{ic|0001}} is the Linux Boot Manager and also the first in line to boot. {{ic|0001}} needs to be deleted and optionally the boot order modified so {{ic|0004}} is the default boot entry.<br />
<br />
{{bc|<br />
# efibootmgr --bootnum 0001 --delete-bootnum<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0000,0002,0003,0004<br />
Boot0000* Windows Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
<br />
# efibootmgr --bootorder 0004,0000,0002,0003<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0004,0000,0002,0003<br />
Boot0000* Windows Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
==== Booting only Linux ====<br />
<br />
{{note|The very newly developed [https://github.com/Foxboron/sbctl sbctl], availble via {{aur|sbctl-git}} has completely revamped this process and will only get better as they approach 1.0. From here on out, as of October 2021, this process should greatly simplify.}}<br />
<br />
{{note|Credit to this [https://lunaryorn.com/secure-boot-on-arch-linux-with-sbctl-and-dracut blog post by lunaryorn] for the inspiration.}}<br />
<br />
Install {{Pkg|sbctl}}. At this point you will likely need to reboot and adjust your secure boot settings. You want secure boot in '''setup mode'''. <br />
<br />
{{bc|<br />
$ sbctl status<br />
Installed: X Sbctl is not installed<br />
Setup Mode: X Enabled<br />
Secure Boot: X Disabled<br />
}}<br />
<br />
Run the following commands as root. See {{man|8|sbctl}} for more information on their function. Of particular note is the {{ic|-s}} flag which indicates {{ic|sbctl}} should remember the file for future verification and signing.<br />
<br />
Note your Linux EFI binary name may be slightly different.<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
<br />
# sbctl sign -s /efi/EFI/BOOT/BOOTx64.EFI<br />
✔ Signed /efi/EFI/BOOT/BOOTx64.EFI<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Finally, enroll the Secure Boot keys.<br />
<br />
{{bc|<br />
# sbctl enroll-keys<br />
Enrolling keys to EFI variables...✔<br />
Enrolled keys to the EFI variables!<br />
}}<br />
<br />
Verify that secure boot now has an owner GUID and setup mode is disabled.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✔ Sbctl is installed<br />
Owner GUID: a2ee3d08-725a-408b-9d95-28026a44611c<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
Now reboot. This reboot is required so we can get the TPM measurements into their (hopefully) permanent state.<br />
<br />
=== Enroll LUKS key in TPM ===<br />
{{warning|Yes, this will cause a system to automatically unlock it's encrypted root volume without any interaction from a human. Yes, this exposes it to any sufficently advanced Evil Maid attacks. If sealed against the appropriate registers (especially register 8 with the kernel arguments), the TPM measurements should force systemd to ask for your LUKS passphrase in almost any attempt to access the encrypted volume from outside your normal boot process.}}<br />
<br />
We are fortunate that in our shift to dracut includes utilizing systemd and sd-encrypt, as we can use systemd's native support for enrolling LUKS keys. A review of [[Trusted Platform Module#Using TPM 2.0]] is recommended but not very clear.<br />
<br />
First, be sure to install {{Pkg|tpm2-tools}}. Alternatively {{aur|ibm-tss}} can be used per [[Trusted Platform Module]], however this guide is not tested against those.<br />
<br />
{{note|A reboot may be required to convince {{ic|systemd-cryptenroll}} that TPM 2.0 devices now exist on the machine.}}<br />
<br />
There are several decisions to be made here. The table at [[Trusted Platform Module#Accessing PCR registers]] is accurate as of October 2021. Essentially, once you seal your LUKS key, if any of the registers you've sealed against change, then you will be asked for your LUKS passphrase. This is equivalent to when Windows 10 makes you enter your BitLocker recovery key after a hardware change or changing BIOS settings.<br />
<br />
Your mileage may vary, based on UEFI vendors. For my laptop, I went with 0+1+2+3+4+5+7+8 and have been able to invalidate my TPM. Unfortunately, if you change your system BACK the volume will unlock. I'm investigating how to disable that.<br />
<br />
Other options on {{man|1|systemd-cryptenroll}} will reveal that several hardware tokens can also be enrolled to allow unlocking the root LUKS volume automatically, but only if a key is present. Further testing is requried.<br />
<br />
To enroll your LUKS volume, simply run the following command as root<br />
<br />
# systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/nvme0n1p2<br />
<br />
To remove your key, run this command:<br />
<br />
# systemd-cryptenroll --wipe-slot=tpm2 /dev/nvme0n1p2<br />
<br />
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:<br />
<br />
{{hc|~/bin/luks_reenroll_tpm|2=<br />
sudo systemd-cryptenroll --wipe-slot=tpm2 /dev/disk/by-uuid/{UUID_HERE}<br />
systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/disk/by-uuid/{UUID_HERE}<br />
}}<br />
<br />
== Justifications ==<br />
<br />
=== LVM on LUKS vs other dm-crypt approaches ===<br />
<br />
LVM on LUKS was selected becasue it is simply the easiest to manage while conferring both encrypted swap and disk. The other approaches required much more tooling and manual fussing to utilize. This selection also gives room change freely between {{ic|busybox}} and {{ic|systemd}} initrds.<br />
<br />
=== Using dracut ===<br />
<br />
{{Pkg|dracut}} just makes it easier to build full unified kernels that {{man|7|systemd-boot}} can launch as EFI binaries. There is also available tooling in the [[AUR]] for automating the creation of these binaries. Finally, {{ic|dracut}} will sign the binaries it creates automatically when configured to do so.<br />
<br />
=== Unified kernel images ===<br />
<br />
While UKI's could be problematic on other distributions, they fit right in with an Arch Linux install. The automation is there through pacman hooks and {{Pkg|sbctl}} to sign our UKIs as they're created. Furthermore, you can only sign and create a new signed UKI while booted into a properly signed UKI. It creates a chain of trust, which means it's important to never disable Secure Boot once you've set it up.<br />
<br />
The UKI encompasses all of the following items inside the signature, which means you can't change any of them without invalidating the signature.<br />
<br />
* Kernel arguments<br />
* Initrd/Initramfs<br />
* Kernel<br />
<br />
In particular, all other flavors of secureboot do not sign or validate the initramfs. This is a big attack area and can be relatively trivialized that a semi-decent pawn shop owner with Google could likely find an image that would grant him access and make the TPM none the wiser the system has changed. One can prevent this with encrypted /boot, but that would limit you to GRUB2 and LUKS version 1 devices only. This also doesn't include the work to keep GRUB2's files signed with a PGP key by root.<br />
<br />
== Miscellaneous discussions ==<br />
<br />
=== Filesystem Selection ===<br />
<br />
Most examples on Arch utilize {{ic|ext4}}, but other file systems such as {{ic|brtfs}} can work equally well. As for performance or issues with being inside LVM, [https://btrfs.wiki.kernel.org/index.php/FAQ#Btrfs_has_subvolumes.2C_does_this_mean_I_don.27t_need_a_logical_volume_manager_and_I_can_create_a_big_Btrfs_filesystem_on_a_raw_partition.3F this question in the brtfs FAQ] implie that there is some performance loss but no other issues.<br />
<br />
=== LUKS TPM enrollment and managing luks keys ===<br />
<br />
Note that using {{man|1|systemd-cryptenroll}} will add a key to your LUKS volume. It's not clear how exactly the option {{ic|1=--wipe-slot=tpm2}} is able to identify which slot it needs to wipe, but it does. This even works if your TPM has changed.<br />
<br />
You can see the effects by comparing the output of {{ic|cryptsetup luksDump /dev/nvme0n1p2}} before and after you enroll or wipe a TPM based key. You can identify what slot your own passphrase is in with {{ic|cryptsetup --verbose open --test-passphrase /dev/nvme0n1p2}} and entering your passphrase. The output will inform you which key slot was unlocked.<br />
<br />
Finally, your passphrase may be changed with {{ic|cryptsetup luksChangeKey /dev/nvme0n1p2 -S 0}}.<br />
<br />
== Planned TODOs ==<br />
A panic command that can dump the TPM and shutdown the computer (without requiring the time of entering a password in sudo) forcing an adversary to resort to [https://en.wikipedia.org/wiki/Rubber-hose_cryptanalysis rubber-hose cryptanalysis] to get to the encrypted data.</div>Krinhttps://wiki.archlinux.org/index.php?title=User:Krin/Secure_Boot,_full_disk_encryption,_and_TPM2_unlocking_install&diff=697928User:Krin/Secure Boot, full disk encryption, and TPM2 unlocking install2021-10-01T02:08:17Z<p>Krin: /* Dual Booting Windows */ Completing Windows Dual Boot Secure Boot</p>
<hr />
<div>{{Unsupported|30 September 2021}}<br />
{{Expansion|Work In Progress, Draft from Installation Notes, Needs Testing}}<br />
<br />
== Introduction ==<br />
<br />
This installation is based on my installing Arch on an Asus ROG Strix G G531 I got second hand and a desktop computer made of second hand parts that had to share space with Windows. The primary goals were to replace Windows 10 Pro with Bitlocker encryption and maintain the convienence and security balance of that original operating system.<br />
<br />
My requirements boiled down to:<br />
<br />
* A fully encrypted disk<br />
* Full Secure Boot validation of all UEFI components.<br />
* Use of the TPM to facilitate unlocking of the disk.<br />
* Hibernate/Suspend working.<br />
<br />
My primary use case here is to make it difficult enough for a baggage handler with sticky hands to get at my data that they just wipe the drive. A state level actor with the expertise and equipment to hot swap my ram in my hotel room is not something that I'm defending this ''particular'' laptop against. This is more for gaming and web browsing and uploading photos while traveling.<br />
<br />
I'll continue to update these notes as I develop further solutions.<br />
<br />
== Disclaimers ==<br />
<br />
This article is primarily for the author's own notes. It is assumed that the reader is familiar with the [[Installation guide]] and will refer to it often. Reading linked articles is recommended.<br />
<br />
== Dual Booting Modifications ==<br />
<br />
For computers that will have to dual boot with windows, the easiest solution is to use two different physical drives and utilize your motherboard's UEFI boot menu to select which one to boot. This guide will follow that assumption. You can also attempt to have everything live on one EFI partition. Windows's 100 MiB EFI partition is especially problematic to this approach for secure boot, as Unified Kernel Images can approach 80 MiB and Windows 10 regularly uses up to 30 MiB.<br />
<br />
There are two changes that will be made and will be noted in the relevant sections:<br />
<br />
* Do not clear your Secure Boot keys. Merely disable Secure Boot for the installation.<br />
* Use {{ic|shim}} to boot systemd-bootloader<br />
* Load your db.cer file into the MOKManager application.<br />
<br />
All remaining steps should remain the same, except your system will still be dependent on the factory provided Microsoft Certificates. But you can boot Windows 10 in Secure Boot, which will be important for Windows 11.<br />
<br />
== Initial setup ==<br />
<br />
=== Pre-installation ===<br />
<br />
If you will only boot linux, reset your Secure Boot settings in BIOS to enable setup mode. Usually this means you set Secure Boot to Enabled and then select the option to wipe out the keys.<br />
<br />
If you will be dual booting Windows, disable secure boot.<br />
<br />
Follow the [[Installation_guide#Pre-installation]] up to Paritioning the Disks.<br />
<br />
=== Disk preparation ===<br />
<br />
If you have data on your disks you want to overwrite, utilize [[Dm-crypt/Drive_preparation#dm-crypt_wipe_on_an_empty_disk_or_partition]] to wipe it. If this disk was previously encrypted, utilize [[Dm-crypt/Drive_preparation#Wipe_LUKS_header]] instead for a much faster disposal. Finally, use [[Dm-crypt/Encrypting_an_entire_system#LVM_on_LUKS]] to parition your drive with two differences.<br />
<br />
{{tip|Using a memorable LUKS passphrase until you've completed the install process can be helpful. It will take several reboots to finish setup.}}<br />
<br />
First, the partition layout will be similar to here. You may wish to break out the /home directory into it's own partition. The primary requirement is that only your EFI partition be unencrypted.<br />
<br />
{{hc|Partiton Layout|<br />
┌────────────────────┬──────────────────────────┬─────────────────────────────┐<br />
│ │ │ │<br />
│ EFI Boot Partition │ Logical Volume 1 │ Logical Volume 2 │<br />
│ │ │ │<br />
│ /efi │ [SWAP] │ / │<br />
│ │ │ │<br />
│ /dev/nvme0n1p1 │ /dev/CryptRootVG/swap │ /dev/CryptRootVG/root │<br />
│ │ │ │<br />
│ 512 MB │ 16 GB (Or RAM size) │ Remaining Free Space │<br />
│ │ │ │<br />
│ │ │ │<br />
│ ├──────────────────────────┴─────────────────────────────┤<br />
│ │ │<br />
│ │ LUKS and LVM Physical Volume │<br />
│ │ │<br />
│ │ /dev/nvme0n1p2 │<br />
│ │ │<br />
└────────────────────┴────────────────────────────────────────────────────────┘<br />
}}<br />
<br />
Second, if your hard drive is an SSD like this laptop, use the following command to open your LUKS volume.<br />
<br />
# cryptsetup open --perf-no_read_workqueue --perf-no_write_workqueue --persistent /dev/nvme0n1p2 cryptroot<br />
<br />
After completing your LUKS on LVM setup, format your EFI partition per [[EFI system partition]].<br />
<br />
# mkfs.fat -F32 /dev/nvme0n1p1<br />
<br />
Mount this partition at {{ic|/mnt/efi}}. It is very important to leave {{ic|/boot}} on your encrypted root partition.<br />
<br />
== Installation ==<br />
<br />
Continue with [[Installation_guide#Installation]]. Be sure to flesh out your {{man|8|pacstrap}} with the following list of packages:<br />
<br />
* {{Pkg|dracut}}<br />
* {{Pkg|intel-ucode}}<br />
* {{Pkg|lvm2}}<br />
* {{Pkg|openssh}}<br />
* {{Pkg|ansible}}<br />
* {{Pkg|git}}<br />
* {{Pkg|iwd}}<br />
* {{Pkg|efibootmgr}}<br />
<br />
<br />
We are going to leave off the installation guide at the initramfs section, so go ahead and reset your root password. <br />
<br />
# passwd<br />
<br />
=== Bootloader ===<br />
<br />
{{warning|This section needs testing.}}<br />
<br />
First, install {{ic|systemd-boot}} by following [[Systemd-boot#Installing_the_EFI_boot_manager]]. Next, install {{aur|dracut-hook-uefi}}.<br />
<br />
Ensure you drop in a systemd-boot hook to update your bootctl any time it's updated.<br />
<br />
{{hc|/etc/pacman.d/hooks/998-systemd-boot.hook|2=<br />
[Trigger]<br />
Type = Package<br />
Operation = Install<br />
Operation = Upgrade<br />
Target = systemd<br />
<br />
[Action]<br />
Description = Updating systemd-boot<br />
When = PostTransaction<br />
Exec = /usr/bin/bootctl update; <br />
}}<br />
<br />
Obtain the UUID of your LUKS drive via the following command:<br />
<br />
{{bc|<br />
blkid -s UUID -o value /dev/nvme0n1p2<br />
}}<br />
<br />
Create the following files with the listed content. Be sure to replace UUIDs with what you actually need. The extraneous {{ic:rd.luks.options}} should not cause an issue, but will be used once we've enabled secure boot. See {{man|5|dracut.conf}} for more information on what these commands do.<br />
<br />
A good portion of the kernel command line was as generated by dracut. Many are extraneous or you may wish to change some of the block device names.<br />
<br />
{{hc|/etc/dracut.conf.d/cmdline.conf|2=<br />
kernel_cmdline="rd.luks.uuid=luks-17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02 rd.luks.options=17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02=tpm2-device=auto rd.lvm.lv=CryptRoot/root rd.lvm.lv=CryptRoot/swap resume=/dev/mapper/CryptRoot-swap root=/dev/mapper/CryptRoot-root rootfstype=ext4 rootflags=rw,relatime"<br />
}}<br />
<br />
{{hc|/etc/dracut.conf.d/flags.conf|2=<br />
compress="zstd"<br />
hostonly="yes"<br />
}}<br />
<br />
Run the following command to generate your EFI stub kernels.<br />
<br />
dracut --uefi<br />
<br />
=== Secure boot ===<br />
<br />
==== Dual Booting Windows ====<br />
<br />
{{warning|This section is still being written}}<br />
<br />
Review [[Unified Extensible Firmware Interface/Secure Boot#shim]] to get a rough understanding of how it's going to work. Install {{aur|shim-signed}}. Perform the following commands to place files where both the UEFI boot entry and shim will load them.<br />
<br />
# mv /efi/EFI/BOOT/BOOTx64.EFI /efi/EFI/BOOT/grubx64.efi<br />
# cp /usr/share/shim-signed/shimx64.efi esp/EFI/BOOT/BOOTx64.EFI<br />
# cp /usr/share/shim-signed/mmx64.efi esp/EFI/BOOT/<br />
<br />
Install {{Pkg|sbctl}}. Use the following command to check that secure boot is in the right status. Your output should be similar.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✘ Sbctl is not installed<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/BOOT/grubx64.efi is not signed<br />
<br />
✘ /efi/EFI/BOOT/mmx64.efi is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
}}<br />
<br />
Note that shim and MOKManager (mmx) is included in this list, even though we will not be signing it.<br />
<br />
{{bc|<br />
# sbctl sign -s /efi/EFI/BOOT/ grubx64.efi <br />
<br />
✔ Signed /efi/EFI/BOOT/grubx64.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi <br />
<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi <br />
<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi<br />
# sbctl verify<br />
<br />
Verifying file database and EFI images in /efi...<br />
✔� /efi/EFI/BOOT/grubx64.efi is signed<br />
✔ /efi/EFI/Linux/linux-5.14.8-arch1-1-df10c5e79c5444b78ef1b154eef3ca32-rolling.efi is signed<br />
✔ /efi/EFI/systemd/systemd-bootx64.efi is signed<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/BOOT/mmx64.efi is not signed<br />
}}<br />
<br />
You can validate that {{ic|BOOTx64.EFI}} and {{ic|mmx64.efi}} have signatures with {{man|1|sbverify}} from the {{Pkg|sbsigntools}} package.<br />
<br />
Next, we need to create the DER format certificate to load into ''MokManager''.<br />
<br />
# openssl x509 -outform DER -in /usr/share/secureboot/keys/db/db.pem -out /efi/signing.cer<br />
<br />
Use {{Pkg|efibootmgr}} ({{man|8|efibootmgr}}) to adjust your boot entries. Primarily, you will want to remove the {{ic|Linux Boot Manager}} entry.<br />
<br />
{{bc|<br />
# efibootmgr<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0001,0000,0002,0003,0004<br />
Boot0000* Windows Boot Manager<br />
Boot0001* Linux Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
}}<br />
<br />
In this example, we see that {{ic|0000}} is the Windows boot manager. {{ic|0001}} is the Linux Boot Manager and also the first in line to boot. {{ic|0001}} needs to be deleted and optionally the boot order modified so {{ic|0004}} is the default boot entry.<br />
<br />
{{bc|<br />
# efibootmgr --bootnum 0001 --delete-bootnum<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0000,0002,0003,0004<br />
Boot0000* Windows Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
<br />
# efibootmgr --bootorder 0004,0000,0002,0003<br />
BootCurrent: 0004<br />
Timeout: 1 seconds<br />
BootOrder: 0004,0000,0002,0003<br />
Boot0000* Windows Boot Manager<br />
Boot0002* UEFI: Samsung Flash Drive FIT 1100<br />
Boot0003* UEFI: Samsung Flash Drive FIT 1100, Partition 2<br />
Boot0004* UEFI OS<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
==== Booting only Linux ====<br />
<br />
{{note|The very newly developed [https://github.com/Foxboron/sbctl sbctl], availble via {{aur|sbctl-git}} has completely revamped this process and will only get better as they approach 1.0. From here on out, as of October 2021, this process should greatly simplify.}}<br />
<br />
{{note|Credit to this [https://lunaryorn.com/secure-boot-on-arch-linux-with-sbctl-and-dracut blog post by lunaryorn] for the inspiration.}}<br />
<br />
Install {{Pkg|sbctl}}. At this point you will likely need to reboot and adjust your secure boot settings. You want secure boot in '''setup mode'''. <br />
<br />
{{bc|<br />
$ sbctl status<br />
Installed: X Sbctl is not installed<br />
Setup Mode: X Enabled<br />
Secure Boot: X Disabled<br />
}}<br />
<br />
Run the following commands as root. See {{man|8|sbctl}} for more information on their function. Of particular note is the {{ic|-s}} flag which indicates {{ic|sbctl}} should remember the file for future verification and signing.<br />
<br />
Note your Linux EFI binary name may be slightly different.<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
<br />
# sbctl sign -s /efi/EFI/BOOT/BOOTx64.EFI<br />
✔ Signed /efi/EFI/BOOT/BOOTx64.EFI<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Finally, enroll the Secure Boot keys.<br />
<br />
{{bc|<br />
# sbctl enroll-keys<br />
Enrolling keys to EFI variables...✔<br />
Enrolled keys to the EFI variables!<br />
}}<br />
<br />
Verify that secure boot now has an owner GUID and setup mode is disabled.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✔ Sbctl is installed<br />
Owner GUID: a2ee3d08-725a-408b-9d95-28026a44611c<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
Now reboot. This reboot is required so we can get the TPM measurements into their (hopefully) permanent state.<br />
<br />
=== Enroll LUKS key in TPM ===<br />
{{warning|Yes, this will cause a system to automatically unlock it's encrypted root volume without any interaction from a human. Yes, this exposes it to any sufficently advanced Evil Maid attacks. If sealed against the appropriate registers (especially register 8 with the kernel arguments), the TPM measurements should force systemd to ask for your LUKS passphrase in almost any attempt to access the encrypted volume from outside your normal boot process.}}<br />
<br />
We are fortunate that in our shift to dracut includes utilizing systemd and sd-encrypt, as we can use systemd's native support for enrolling LUKS keys. A review of [[Trusted Platform Module#Using TPM 2.0]] is recommended but not very clear.<br />
<br />
First, be sure to install {{Pkg|tpm2-tools}}. Alternatively {{aur|ibm-tss}} can be used per [[Trusted Platform Module]], however this guide is not tested against those.<br />
<br />
{{note|A reboot may be required to convince {{ic|systemd-cryptenroll}} that TPM 2.0 devices now exist on the machine.}}<br />
<br />
There are several decisions to be made here. The table at [[Trusted Platform Module#Accessing PCR registers]] is accurate as of October 2021. Essentially, once you seal your LUKS key, if any of the registers you've sealed against change, then you will be asked for your LUKS passphrase. This is equivalent to when Windows 10 makes you enter your BitLocker recovery key after a hardware change or changing BIOS settings.<br />
<br />
Your mileage may vary, based on UEFI vendors. For my laptop, I went with 0+1+2+3+4+5+7+8 and have been able to invalidate my TPM. Unfortunately, if you change your system BACK the volume will unlock. I'm investigating how to disable that.<br />
<br />
Other options on {{man|1|systemd-cryptenroll}} will reveal that several hardware tokens can also be enrolled to allow unlocking the root LUKS volume automatically, but only if a key is present. Further testing is requried.<br />
<br />
To enroll your LUKS volume, simply run the following command as root<br />
<br />
# systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/nvme0n1p2<br />
<br />
To remove your key, run this command:<br />
<br />
# systemd-cryptenroll --wipe-slot=tpm2 /dev/nvme0n1p2<br />
<br />
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:<br />
<br />
{{hc|~/bin/luks_reenroll_tpm|2=<br />
sudo systemd-cryptenroll --wipe-slot=tpm2 /dev/disk/by-uuid/{UUID_HERE}<br />
systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/disk/by-uuid/{UUID_HERE}<br />
}}<br />
<br />
== Justifications ==<br />
<br />
=== LVM on LUKS vs other dm-crypt approaches ===<br />
<br />
LVM on LUKS was selected becasue it is simply the easiest to manage while conferring both encrypted swap and disk. The other approaches required much more tooling and manual fussing to utilize. This selection also gives room change freely between {{ic|busybox}} and {{ic|systemd}} initrds.<br />
<br />
=== Using dracut ===<br />
<br />
{{Pkg|dracut}} just makes it easier to build full unified kernels that {{man|7|systemd-boot}} can launch as EFI binaries. There is also available tooling in the [[AUR]] for automating the creation of these binaries. Finally, {{ic|dracut}} will sign the binaries it creates automatically when configured to do so.<br />
<br />
=== Unified kernel images ===<br />
<br />
While UKI's could be problematic on other distributions, they fit right in with an Arch Linux install. The automation is there through pacman hooks and {{Pkg|sbctl}} to sign our UKIs as they're created. Furthermore, you can only sign and create a new signed UKI while booted into a properly signed UKI. It creates a chain of trust, which means it's important to never disable Secure Boot once you've set it up.<br />
<br />
The UKI encompasses all of the following items inside the signature, which means you can't change any of them without invalidating the signature.<br />
<br />
* Kernel arguments<br />
* Initrd/Initramfs<br />
* Kernel<br />
<br />
In particular, all other flavors of secureboot do not sign or validate the initramfs. This is a big attack area and can be relatively trivialized that a semi-decent pawn shop owner with Google could likely find an image that would grant him access and make the TPM none the wiser the system has changed. One can prevent this with encrypted /boot, but that would limit you to GRUB2 and LUKS version 1 devices only. This also doesn't include the work to keep GRUB2's files signed with a PGP key by root.<br />
<br />
== Miscellaneous discussions ==<br />
<br />
=== Filesystem Selection ===<br />
<br />
Most examples on Arch utilize {{ic|ext4}}, but other file systems such as {{ic|brtfs}} can work equally well. As for performance or issues with being inside LVM, [https://btrfs.wiki.kernel.org/index.php/FAQ#Btrfs_has_subvolumes.2C_does_this_mean_I_don.27t_need_a_logical_volume_manager_and_I_can_create_a_big_Btrfs_filesystem_on_a_raw_partition.3F this question in the brtfs FAQ] implie that there is some performance loss but no other issues.<br />
<br />
=== LUKS TPM enrollment and managing luks keys ===<br />
<br />
Note that using {{man|1|systemd-cryptenroll}} will add a key to your LUKS volume. It's not clear how exactly the option {{ic|1=--wipe-slot=tpm2}} is able to identify which slot it needs to wipe, but it does. This even works if your TPM has changed.<br />
<br />
You can see the effects by comparing the output of {{ic|cryptsetup luksDump /dev/nvme0n1p2}} before and after you enroll or wipe a TPM based key. You can identify what slot your own passphrase is in with {{ic|cryptsetup --verbose open --test-passphrase /dev/nvme0n1p2}} and entering your passphrase. The output will inform you which key slot was unlocked.<br />
<br />
Finally, your passphrase may be changed with {{ic|cryptsetup luksChangeKey /dev/nvme0n1p2 -S 0}}.<br />
<br />
== Planned TODOs ==<br />
A panic command that can dump the TPM and shutdown the computer (without requiring the time of entering a password in sudo) forcing an adversary to resort to [https://en.wikipedia.org/wiki/Rubber-hose_cryptanalysis rubber-hose cryptanalysis] to get to the encrypted data.</div>Krinhttps://wiki.archlinux.org/index.php?title=User:Krin/Secure_Boot,_full_disk_encryption,_and_TPM2_unlocking_install&diff=697927User:Krin/Secure Boot, full disk encryption, and TPM2 unlocking install2021-10-01T01:14:30Z<p>Krin: /* Bootloader */ Correct error in kernel command line.</p>
<hr />
<div>{{Unsupported|30 September 2021}}<br />
{{Expansion|Work In Progress, Draft from Installation Notes, Needs Testing}}<br />
<br />
== Introduction ==<br />
<br />
This installation is based on my installing Arch on an Asus ROG Strix G G531 I got second hand and a desktop computer made of second hand parts that had to share space with Windows. The primary goals were to replace Windows 10 Pro with Bitlocker encryption and maintain the convienence and security balance of that original operating system.<br />
<br />
My requirements boiled down to:<br />
<br />
* A fully encrypted disk<br />
* Full Secure Boot validation of all UEFI components.<br />
* Use of the TPM to facilitate unlocking of the disk.<br />
* Hibernate/Suspend working.<br />
<br />
My primary use case here is to make it difficult enough for a baggage handler with sticky hands to get at my data that they just wipe the drive. A state level actor with the expertise and equipment to hot swap my ram in my hotel room is not something that I'm defending this ''particular'' laptop against. This is more for gaming and web browsing and uploading photos while traveling.<br />
<br />
I'll continue to update these notes as I develop further solutions.<br />
<br />
== Disclaimers ==<br />
<br />
This article is primarily for the author's own notes. It is assumed that the reader is familiar with the [[Installation guide]] and will refer to it often. Reading linked articles is recommended.<br />
<br />
== Dual Booting Modifications ==<br />
<br />
For computers that will have to dual boot with windows, the easiest solution is to use two different physical drives and utilize your motherboard's UEFI boot menu to select which one to boot. This guide will follow that assumption. You can also attempt to have everything live on one EFI partition. Windows's 100 MiB EFI partition is especially problematic to this approach for secure boot, as Unified Kernel Images can approach 80 MiB and Windows 10 regularly uses up to 30 MiB.<br />
<br />
There are two changes that will be made and will be noted in the relevant sections:<br />
<br />
* Do not clear your Secure Boot keys. Merely disable Secure Boot for the installation.<br />
* Use {{ic|shim}} to boot systemd-bootloader<br />
* Load your db.cer file into the MOKManager application.<br />
<br />
All remaining steps should remain the same, except your system will still be dependent on the factory provided Microsoft Certificates. But you can boot Windows 10 in Secure Boot, which will be important for Windows 11.<br />
<br />
== Initial setup ==<br />
<br />
=== Pre-installation ===<br />
<br />
If you will only boot linux, reset your Secure Boot settings in BIOS to enable setup mode. Usually this means you set Secure Boot to Enabled and then select the option to wipe out the keys.<br />
<br />
If you will be dual booting Windows, disable secure boot.<br />
<br />
Follow the [[Installation_guide#Pre-installation]] up to Paritioning the Disks.<br />
<br />
=== Disk preparation ===<br />
<br />
If you have data on your disks you want to overwrite, utilize [[Dm-crypt/Drive_preparation#dm-crypt_wipe_on_an_empty_disk_or_partition]] to wipe it. If this disk was previously encrypted, utilize [[Dm-crypt/Drive_preparation#Wipe_LUKS_header]] instead for a much faster disposal. Finally, use [[Dm-crypt/Encrypting_an_entire_system#LVM_on_LUKS]] to parition your drive with two differences.<br />
<br />
{{tip|Using a memorable LUKS passphrase until you've completed the install process can be helpful. It will take several reboots to finish setup.}}<br />
<br />
First, the partition layout will be similar to here. You may wish to break out the /home directory into it's own partition. The primary requirement is that only your EFI partition be unencrypted.<br />
<br />
{{hc|Partiton Layout|<br />
┌────────────────────┬──────────────────────────┬─────────────────────────────┐<br />
│ │ │ │<br />
│ EFI Boot Partition │ Logical Volume 1 │ Logical Volume 2 │<br />
│ │ │ │<br />
│ /efi │ [SWAP] │ / │<br />
│ │ │ │<br />
│ /dev/nvme0n1p1 │ /dev/CryptRootVG/swap │ /dev/CryptRootVG/root │<br />
│ │ │ │<br />
│ 512 MB │ 16 GB (Or RAM size) │ Remaining Free Space │<br />
│ │ │ │<br />
│ │ │ │<br />
│ ├──────────────────────────┴─────────────────────────────┤<br />
│ │ │<br />
│ │ LUKS and LVM Physical Volume │<br />
│ │ │<br />
│ │ /dev/nvme0n1p2 │<br />
│ │ │<br />
└────────────────────┴────────────────────────────────────────────────────────┘<br />
}}<br />
<br />
Second, if your hard drive is an SSD like this laptop, use the following command to open your LUKS volume.<br />
<br />
# cryptsetup open --perf-no_read_workqueue --perf-no_write_workqueue --persistent /dev/nvme0n1p2 cryptroot<br />
<br />
After completing your LUKS on LVM setup, format your EFI partition per [[EFI system partition]].<br />
<br />
# mkfs.fat -F32 /dev/nvme0n1p1<br />
<br />
Mount this partition at {{ic|/mnt/efi}}. It is very important to leave {{ic|/boot}} on your encrypted root partition.<br />
<br />
== Installation ==<br />
<br />
Continue with [[Installation_guide#Installation]]. Be sure to flesh out your {{man|8|pacstrap}} with the following list of packages:<br />
<br />
* {{Pkg|dracut}}<br />
* {{Pkg|intel-ucode}}<br />
* {{Pkg|lvm2}}<br />
* {{Pkg|openssh}}<br />
* {{Pkg|ansible}}<br />
* {{Pkg|git}}<br />
* {{Pkg|iwd}}<br />
* {{Pkg|efibootmgr}}<br />
<br />
<br />
We are going to leave off the installation guide at the initramfs section, so go ahead and reset your root password. <br />
<br />
# passwd<br />
<br />
=== Bootloader ===<br />
<br />
{{warning|This section needs testing.}}<br />
<br />
First, install {{ic|systemd-boot}} by following [[Systemd-boot#Installing_the_EFI_boot_manager]]. Next, install {{aur|dracut-hook-uefi}}.<br />
<br />
Ensure you drop in a systemd-boot hook to update your bootctl any time it's updated.<br />
<br />
{{hc|/etc/pacman.d/hooks/998-systemd-boot.hook|2=<br />
[Trigger]<br />
Type = Package<br />
Operation = Install<br />
Operation = Upgrade<br />
Target = systemd<br />
<br />
[Action]<br />
Description = Updating systemd-boot<br />
When = PostTransaction<br />
Exec = /usr/bin/bootctl update; <br />
}}<br />
<br />
Obtain the UUID of your LUKS drive via the following command:<br />
<br />
{{bc|<br />
blkid -s UUID -o value /dev/nvme0n1p2<br />
}}<br />
<br />
Create the following files with the listed content. Be sure to replace UUIDs with what you actually need. The extraneous {{ic:rd.luks.options}} should not cause an issue, but will be used once we've enabled secure boot. See {{man|5|dracut.conf}} for more information on what these commands do.<br />
<br />
A good portion of the kernel command line was as generated by dracut. Many are extraneous or you may wish to change some of the block device names.<br />
<br />
{{hc|/etc/dracut.conf.d/cmdline.conf|2=<br />
kernel_cmdline="rd.luks.uuid=luks-17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02 rd.luks.options=17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02=tpm2-device=auto rd.lvm.lv=CryptRoot/root rd.lvm.lv=CryptRoot/swap resume=/dev/mapper/CryptRoot-swap root=/dev/mapper/CryptRoot-root rootfstype=ext4 rootflags=rw,relatime"<br />
}}<br />
<br />
{{hc|/etc/dracut.conf.d/flags.conf|2=<br />
compress="zstd"<br />
hostonly="yes"<br />
}}<br />
<br />
Run the following command to generate your EFI stub kernels.<br />
<br />
dracut --uefi<br />
<br />
=== Secure boot ===<br />
<br />
==== Dual Booting Windows ====<br />
<br />
{{warning|This section is still being written}}<br />
<br />
Review [[Unified Extensible Firmware Interface/Secure Boot#shim]] to get a rough understanding of how it's going to work. Install {{aur|shim-signed}}. Perform the following commands to place files where both the UEFI boot entry and shim will load them.<br />
<br />
# mv /efi/EFI/BOOT/BOOTx64.EFI /efi/EFI/BOOT/grubx64.efi<br />
# cp /usr/share/shim-signed/shimx64.efi esp/EFI/BOOT/BOOTx64.EFI<br />
# cp /usr/share/shim-signed/mmx64.efi esp/EFI/BOOT/<br />
<br />
Install {{Pkg|sbctl}}. Use the following command to check that secure boot is in the right status. Your output should be similar.<br />
<br />
{{bc|<br />
}}<br />
<br />
==== Booting only Linux ====<br />
<br />
{{note|The very newly developed [https://github.com/Foxboron/sbctl sbctl], availble via {{aur|sbctl-git}} has completely revamped this process and will only get better as they approach 1.0. From here on out, as of October 2021, this process should greatly simplify.}}<br />
<br />
{{note|Credit to this [https://lunaryorn.com/secure-boot-on-arch-linux-with-sbctl-and-dracut blog post by lunaryorn] for the inspiration.}}<br />
<br />
Install {{Pkg|sbctl}}. At this point you will likely need to reboot and adjust your secure boot settings. You want secure boot in '''setup mode'''. <br />
<br />
{{bc|<br />
$ sbctl status<br />
Installed: X Sbctl is not installed<br />
Setup Mode: X Enabled<br />
Secure Boot: X Disabled<br />
}}<br />
<br />
Run the following commands as root. See {{man|8|sbctl}} for more information on their function. Of particular note is the {{ic|-s}} flag which indicates {{ic|sbctl}} should remember the file for future verification and signing.<br />
<br />
Note your Linux EFI binary name may be slightly different.<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
<br />
# sbctl sign -s /efi/EFI/BOOT/BOOTx64.EFI<br />
✔ Signed /efi/EFI/BOOT/BOOTx64.EFI<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Finally, enroll the Secure Boot keys.<br />
<br />
{{bc|<br />
# sbctl enroll-keys<br />
Enrolling keys to EFI variables...✔<br />
Enrolled keys to the EFI variables!<br />
}}<br />
<br />
Verify that secure boot now has an owner GUID and setup mode is disabled.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✔ Sbctl is installed<br />
Owner GUID: a2ee3d08-725a-408b-9d95-28026a44611c<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
Now reboot. This reboot is required so we can get the TPM measurements into their (hopefully) permanent state.<br />
<br />
=== Enroll LUKS key in TPM ===<br />
{{warning|Yes, this will cause a system to automatically unlock it's encrypted root volume without any interaction from a human. Yes, this exposes it to any sufficently advanced Evil Maid attacks. If sealed against the appropriate registers (especially register 8 with the kernel arguments), the TPM measurements should force systemd to ask for your LUKS passphrase in almost any attempt to access the encrypted volume from outside your normal boot process.}}<br />
<br />
We are fortunate that in our shift to dracut includes utilizing systemd and sd-encrypt, as we can use systemd's native support for enrolling LUKS keys. A review of [[Trusted Platform Module#Using TPM 2.0]] is recommended but not very clear.<br />
<br />
First, be sure to install {{Pkg|tpm2-tools}}. Alternatively {{aur|ibm-tss}} can be used per [[Trusted Platform Module]], however this guide is not tested against those.<br />
<br />
{{note|A reboot may be required to convince {{ic|systemd-cryptenroll}} that TPM 2.0 devices now exist on the machine.}}<br />
<br />
There are several decisions to be made here. The table at [[Trusted Platform Module#Accessing PCR registers]] is accurate as of October 2021. Essentially, once you seal your LUKS key, if any of the registers you've sealed against change, then you will be asked for your LUKS passphrase. This is equivalent to when Windows 10 makes you enter your BitLocker recovery key after a hardware change or changing BIOS settings.<br />
<br />
Your mileage may vary, based on UEFI vendors. For my laptop, I went with 0+1+2+3+4+5+7+8 and have been able to invalidate my TPM. Unfortunately, if you change your system BACK the volume will unlock. I'm investigating how to disable that.<br />
<br />
Other options on {{man|1|systemd-cryptenroll}} will reveal that several hardware tokens can also be enrolled to allow unlocking the root LUKS volume automatically, but only if a key is present. Further testing is requried.<br />
<br />
To enroll your LUKS volume, simply run the following command as root<br />
<br />
# systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/nvme0n1p2<br />
<br />
To remove your key, run this command:<br />
<br />
# systemd-cryptenroll --wipe-slot=tpm2 /dev/nvme0n1p2<br />
<br />
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:<br />
<br />
{{hc|~/bin/luks_reenroll_tpm|2=<br />
sudo systemd-cryptenroll --wipe-slot=tpm2 /dev/disk/by-uuid/{UUID_HERE}<br />
systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/disk/by-uuid/{UUID_HERE}<br />
}}<br />
<br />
== Justifications ==<br />
<br />
=== LVM on LUKS vs other dm-crypt approaches ===<br />
<br />
LVM on LUKS was selected becasue it is simply the easiest to manage while conferring both encrypted swap and disk. The other approaches required much more tooling and manual fussing to utilize. This selection also gives room change freely between {{ic|busybox}} and {{ic|systemd}} initrds.<br />
<br />
=== Using dracut ===<br />
<br />
{{Pkg|dracut}} just makes it easier to build full unified kernels that {{man|7|systemd-boot}} can launch as EFI binaries. There is also available tooling in the [[AUR]] for automating the creation of these binaries. Finally, {{ic|dracut}} will sign the binaries it creates automatically when configured to do so.<br />
<br />
=== Unified kernel images ===<br />
<br />
While UKI's could be problematic on other distributions, they fit right in with an Arch Linux install. The automation is there through pacman hooks and {{Pkg|sbctl}} to sign our UKIs as they're created. Furthermore, you can only sign and create a new signed UKI while booted into a properly signed UKI. It creates a chain of trust, which means it's important to never disable Secure Boot once you've set it up.<br />
<br />
The UKI encompasses all of the following items inside the signature, which means you can't change any of them without invalidating the signature.<br />
<br />
* Kernel arguments<br />
* Initrd/Initramfs<br />
* Kernel<br />
<br />
In particular, all other flavors of secureboot do not sign or validate the initramfs. This is a big attack area and can be relatively trivialized that a semi-decent pawn shop owner with Google could likely find an image that would grant him access and make the TPM none the wiser the system has changed. One can prevent this with encrypted /boot, but that would limit you to GRUB2 and LUKS version 1 devices only. This also doesn't include the work to keep GRUB2's files signed with a PGP key by root.<br />
<br />
== Miscellaneous discussions ==<br />
<br />
=== Filesystem Selection ===<br />
<br />
Most examples on Arch utilize {{ic|ext4}}, but other file systems such as {{ic|brtfs}} can work equally well. As for performance or issues with being inside LVM, [https://btrfs.wiki.kernel.org/index.php/FAQ#Btrfs_has_subvolumes.2C_does_this_mean_I_don.27t_need_a_logical_volume_manager_and_I_can_create_a_big_Btrfs_filesystem_on_a_raw_partition.3F this question in the brtfs FAQ] implie that there is some performance loss but no other issues.<br />
<br />
=== LUKS TPM enrollment and managing luks keys ===<br />
<br />
Note that using {{man|1|systemd-cryptenroll}} will add a key to your LUKS volume. It's not clear how exactly the option {{ic|1=--wipe-slot=tpm2}} is able to identify which slot it needs to wipe, but it does. This even works if your TPM has changed.<br />
<br />
You can see the effects by comparing the output of {{ic|cryptsetup luksDump /dev/nvme0n1p2}} before and after you enroll or wipe a TPM based key. You can identify what slot your own passphrase is in with {{ic|cryptsetup --verbose open --test-passphrase /dev/nvme0n1p2}} and entering your passphrase. The output will inform you which key slot was unlocked.<br />
<br />
Finally, your passphrase may be changed with {{ic|cryptsetup luksChangeKey /dev/nvme0n1p2 -S 0}}.<br />
<br />
== Planned TODOs ==<br />
A panic command that can dump the TPM and shutdown the computer (without requiring the time of entering a password in sudo) forcing an adversary to resort to [https://en.wikipedia.org/wiki/Rubber-hose_cryptanalysis rubber-hose cryptanalysis] to get to the encrypted data.</div>Krinhttps://wiki.archlinux.org/index.php?title=User:Krin/Secure_Boot,_full_disk_encryption,_and_TPM2_unlocking_install&diff=697926User:Krin/Secure Boot, full disk encryption, and TPM2 unlocking install2021-10-01T01:09:37Z<p>Krin: /* Bootloader */ Correct typo</p>
<hr />
<div>{{Unsupported|30 September 2021}}<br />
{{Expansion|Work In Progress, Draft from Installation Notes, Needs Testing}}<br />
<br />
== Introduction ==<br />
<br />
This installation is based on my installing Arch on an Asus ROG Strix G G531 I got second hand and a desktop computer made of second hand parts that had to share space with Windows. The primary goals were to replace Windows 10 Pro with Bitlocker encryption and maintain the convienence and security balance of that original operating system.<br />
<br />
My requirements boiled down to:<br />
<br />
* A fully encrypted disk<br />
* Full Secure Boot validation of all UEFI components.<br />
* Use of the TPM to facilitate unlocking of the disk.<br />
* Hibernate/Suspend working.<br />
<br />
My primary use case here is to make it difficult enough for a baggage handler with sticky hands to get at my data that they just wipe the drive. A state level actor with the expertise and equipment to hot swap my ram in my hotel room is not something that I'm defending this ''particular'' laptop against. This is more for gaming and web browsing and uploading photos while traveling.<br />
<br />
I'll continue to update these notes as I develop further solutions.<br />
<br />
== Disclaimers ==<br />
<br />
This article is primarily for the author's own notes. It is assumed that the reader is familiar with the [[Installation guide]] and will refer to it often. Reading linked articles is recommended.<br />
<br />
== Dual Booting Modifications ==<br />
<br />
For computers that will have to dual boot with windows, the easiest solution is to use two different physical drives and utilize your motherboard's UEFI boot menu to select which one to boot. This guide will follow that assumption. You can also attempt to have everything live on one EFI partition. Windows's 100 MiB EFI partition is especially problematic to this approach for secure boot, as Unified Kernel Images can approach 80 MiB and Windows 10 regularly uses up to 30 MiB.<br />
<br />
There are two changes that will be made and will be noted in the relevant sections:<br />
<br />
* Do not clear your Secure Boot keys. Merely disable Secure Boot for the installation.<br />
* Use {{ic|shim}} to boot systemd-bootloader<br />
* Load your db.cer file into the MOKManager application.<br />
<br />
All remaining steps should remain the same, except your system will still be dependent on the factory provided Microsoft Certificates. But you can boot Windows 10 in Secure Boot, which will be important for Windows 11.<br />
<br />
== Initial setup ==<br />
<br />
=== Pre-installation ===<br />
<br />
If you will only boot linux, reset your Secure Boot settings in BIOS to enable setup mode. Usually this means you set Secure Boot to Enabled and then select the option to wipe out the keys.<br />
<br />
If you will be dual booting Windows, disable secure boot.<br />
<br />
Follow the [[Installation_guide#Pre-installation]] up to Paritioning the Disks.<br />
<br />
=== Disk preparation ===<br />
<br />
If you have data on your disks you want to overwrite, utilize [[Dm-crypt/Drive_preparation#dm-crypt_wipe_on_an_empty_disk_or_partition]] to wipe it. If this disk was previously encrypted, utilize [[Dm-crypt/Drive_preparation#Wipe_LUKS_header]] instead for a much faster disposal. Finally, use [[Dm-crypt/Encrypting_an_entire_system#LVM_on_LUKS]] to parition your drive with two differences.<br />
<br />
{{tip|Using a memorable LUKS passphrase until you've completed the install process can be helpful. It will take several reboots to finish setup.}}<br />
<br />
First, the partition layout will be similar to here. You may wish to break out the /home directory into it's own partition. The primary requirement is that only your EFI partition be unencrypted.<br />
<br />
{{hc|Partiton Layout|<br />
┌────────────────────┬──────────────────────────┬─────────────────────────────┐<br />
│ │ │ │<br />
│ EFI Boot Partition │ Logical Volume 1 │ Logical Volume 2 │<br />
│ │ │ │<br />
│ /efi │ [SWAP] │ / │<br />
│ │ │ │<br />
│ /dev/nvme0n1p1 │ /dev/CryptRootVG/swap │ /dev/CryptRootVG/root │<br />
│ │ │ │<br />
│ 512 MB │ 16 GB (Or RAM size) │ Remaining Free Space │<br />
│ │ │ │<br />
│ │ │ │<br />
│ ├──────────────────────────┴─────────────────────────────┤<br />
│ │ │<br />
│ │ LUKS and LVM Physical Volume │<br />
│ │ │<br />
│ │ /dev/nvme0n1p2 │<br />
│ │ │<br />
└────────────────────┴────────────────────────────────────────────────────────┘<br />
}}<br />
<br />
Second, if your hard drive is an SSD like this laptop, use the following command to open your LUKS volume.<br />
<br />
# cryptsetup open --perf-no_read_workqueue --perf-no_write_workqueue --persistent /dev/nvme0n1p2 cryptroot<br />
<br />
After completing your LUKS on LVM setup, format your EFI partition per [[EFI system partition]].<br />
<br />
# mkfs.fat -F32 /dev/nvme0n1p1<br />
<br />
Mount this partition at {{ic|/mnt/efi}}. It is very important to leave {{ic|/boot}} on your encrypted root partition.<br />
<br />
== Installation ==<br />
<br />
Continue with [[Installation_guide#Installation]]. Be sure to flesh out your {{man|8|pacstrap}} with the following list of packages:<br />
<br />
* {{Pkg|dracut}}<br />
* {{Pkg|intel-ucode}}<br />
* {{Pkg|lvm2}}<br />
* {{Pkg|openssh}}<br />
* {{Pkg|ansible}}<br />
* {{Pkg|git}}<br />
* {{Pkg|iwd}}<br />
* {{Pkg|efibootmgr}}<br />
<br />
<br />
We are going to leave off the installation guide at the initramfs section, so go ahead and reset your root password. <br />
<br />
# passwd<br />
<br />
=== Bootloader ===<br />
<br />
{{warning|This section needs testing.}}<br />
<br />
First, install {{ic|systemd-boot}} by following [[Systemd-boot#Installing_the_EFI_boot_manager]]. Next, install {{aur|dracut-hook-uefi}}.<br />
<br />
Ensure you drop in a systemd-boot hook to update your bootctl any time it's updated.<br />
<br />
{{hc|/etc/pacman.d/hooks/998-systemd-boot.hook|2=<br />
[Trigger]<br />
Type = Package<br />
Operation = Install<br />
Operation = Upgrade<br />
Target = systemd<br />
<br />
[Action]<br />
Description = Updating systemd-boot<br />
When = PostTransaction<br />
Exec = /usr/bin/bootctl update; <br />
}}<br />
<br />
Obtain the UUID of your LUKS drive via the following command:<br />
<br />
{{bc|<br />
blkid -s UUID -o value /dev/nvme0n1p2<br />
}}<br />
<br />
Create the following files with the listed content. Be sure to replace UUIDs with what you actually need. The extraneous {{ic:rd.luks.options}} should not cause an issue, but will be used once we've enabled secure boot. See {{man|5|dracut.conf}} for more information on what these commands do.<br />
<br />
A good portion of the kernel command line was as generated by dracut. Many are extraneous or you may wish to change some of the block device names.<br />
<br />
{{hc|/etc/dracut.conf.d/cmdline.conf|2=<br />
kernel_cmdline="rd.luks.uuid=luks-17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02 rd.luks.options=17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02 rd.lvm.lv=CryptRoot/root rd.lvm.lv=CryptRoot/swap resume=/dev/mapper/CryptRoot-swap root=/dev/mapper/CryptRoot-root rootfstype=ext4 rootflags=rw,relatime"<br />
}}<br />
<br />
{{hc|/etc/dracut.conf.d/flags.conf|2=<br />
compress="zstd"<br />
hostonly="yes"<br />
}}<br />
<br />
Run the following command to generate your EFI stub kernels.<br />
<br />
dracut --uefi<br />
<br />
=== Secure boot ===<br />
<br />
==== Dual Booting Windows ====<br />
<br />
{{warning|This section is still being written}}<br />
<br />
Review [[Unified Extensible Firmware Interface/Secure Boot#shim]] to get a rough understanding of how it's going to work. Install {{aur|shim-signed}}. Perform the following commands to place files where both the UEFI boot entry and shim will load them.<br />
<br />
# mv /efi/EFI/BOOT/BOOTx64.EFI /efi/EFI/BOOT/grubx64.efi<br />
# cp /usr/share/shim-signed/shimx64.efi esp/EFI/BOOT/BOOTx64.EFI<br />
# cp /usr/share/shim-signed/mmx64.efi esp/EFI/BOOT/<br />
<br />
Install {{Pkg|sbctl}}. Use the following command to check that secure boot is in the right status. Your output should be similar.<br />
<br />
{{bc|<br />
}}<br />
<br />
==== Booting only Linux ====<br />
<br />
{{note|The very newly developed [https://github.com/Foxboron/sbctl sbctl], availble via {{aur|sbctl-git}} has completely revamped this process and will only get better as they approach 1.0. From here on out, as of October 2021, this process should greatly simplify.}}<br />
<br />
{{note|Credit to this [https://lunaryorn.com/secure-boot-on-arch-linux-with-sbctl-and-dracut blog post by lunaryorn] for the inspiration.}}<br />
<br />
Install {{Pkg|sbctl}}. At this point you will likely need to reboot and adjust your secure boot settings. You want secure boot in '''setup mode'''. <br />
<br />
{{bc|<br />
$ sbctl status<br />
Installed: X Sbctl is not installed<br />
Setup Mode: X Enabled<br />
Secure Boot: X Disabled<br />
}}<br />
<br />
Run the following commands as root. See {{man|8|sbctl}} for more information on their function. Of particular note is the {{ic|-s}} flag which indicates {{ic|sbctl}} should remember the file for future verification and signing.<br />
<br />
Note your Linux EFI binary name may be slightly different.<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
<br />
# sbctl sign -s /efi/EFI/BOOT/BOOTx64.EFI<br />
✔ Signed /efi/EFI/BOOT/BOOTx64.EFI<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Finally, enroll the Secure Boot keys.<br />
<br />
{{bc|<br />
# sbctl enroll-keys<br />
Enrolling keys to EFI variables...✔<br />
Enrolled keys to the EFI variables!<br />
}}<br />
<br />
Verify that secure boot now has an owner GUID and setup mode is disabled.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✔ Sbctl is installed<br />
Owner GUID: a2ee3d08-725a-408b-9d95-28026a44611c<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
Now reboot. This reboot is required so we can get the TPM measurements into their (hopefully) permanent state.<br />
<br />
=== Enroll LUKS key in TPM ===<br />
{{warning|Yes, this will cause a system to automatically unlock it's encrypted root volume without any interaction from a human. Yes, this exposes it to any sufficently advanced Evil Maid attacks. If sealed against the appropriate registers (especially register 8 with the kernel arguments), the TPM measurements should force systemd to ask for your LUKS passphrase in almost any attempt to access the encrypted volume from outside your normal boot process.}}<br />
<br />
We are fortunate that in our shift to dracut includes utilizing systemd and sd-encrypt, as we can use systemd's native support for enrolling LUKS keys. A review of [[Trusted Platform Module#Using TPM 2.0]] is recommended but not very clear.<br />
<br />
First, be sure to install {{Pkg|tpm2-tools}}. Alternatively {{aur|ibm-tss}} can be used per [[Trusted Platform Module]], however this guide is not tested against those.<br />
<br />
{{note|A reboot may be required to convince {{ic|systemd-cryptenroll}} that TPM 2.0 devices now exist on the machine.}}<br />
<br />
There are several decisions to be made here. The table at [[Trusted Platform Module#Accessing PCR registers]] is accurate as of October 2021. Essentially, once you seal your LUKS key, if any of the registers you've sealed against change, then you will be asked for your LUKS passphrase. This is equivalent to when Windows 10 makes you enter your BitLocker recovery key after a hardware change or changing BIOS settings.<br />
<br />
Your mileage may vary, based on UEFI vendors. For my laptop, I went with 0+1+2+3+4+5+7+8 and have been able to invalidate my TPM. Unfortunately, if you change your system BACK the volume will unlock. I'm investigating how to disable that.<br />
<br />
Other options on {{man|1|systemd-cryptenroll}} will reveal that several hardware tokens can also be enrolled to allow unlocking the root LUKS volume automatically, but only if a key is present. Further testing is requried.<br />
<br />
To enroll your LUKS volume, simply run the following command as root<br />
<br />
# systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/nvme0n1p2<br />
<br />
To remove your key, run this command:<br />
<br />
# systemd-cryptenroll --wipe-slot=tpm2 /dev/nvme0n1p2<br />
<br />
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:<br />
<br />
{{hc|~/bin/luks_reenroll_tpm|2=<br />
sudo systemd-cryptenroll --wipe-slot=tpm2 /dev/disk/by-uuid/{UUID_HERE}<br />
systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/disk/by-uuid/{UUID_HERE}<br />
}}<br />
<br />
== Justifications ==<br />
<br />
=== LVM on LUKS vs other dm-crypt approaches ===<br />
<br />
LVM on LUKS was selected becasue it is simply the easiest to manage while conferring both encrypted swap and disk. The other approaches required much more tooling and manual fussing to utilize. This selection also gives room change freely between {{ic|busybox}} and {{ic|systemd}} initrds.<br />
<br />
=== Using dracut ===<br />
<br />
{{Pkg|dracut}} just makes it easier to build full unified kernels that {{man|7|systemd-boot}} can launch as EFI binaries. There is also available tooling in the [[AUR]] for automating the creation of these binaries. Finally, {{ic|dracut}} will sign the binaries it creates automatically when configured to do so.<br />
<br />
=== Unified kernel images ===<br />
<br />
While UKI's could be problematic on other distributions, they fit right in with an Arch Linux install. The automation is there through pacman hooks and {{Pkg|sbctl}} to sign our UKIs as they're created. Furthermore, you can only sign and create a new signed UKI while booted into a properly signed UKI. It creates a chain of trust, which means it's important to never disable Secure Boot once you've set it up.<br />
<br />
The UKI encompasses all of the following items inside the signature, which means you can't change any of them without invalidating the signature.<br />
<br />
* Kernel arguments<br />
* Initrd/Initramfs<br />
* Kernel<br />
<br />
In particular, all other flavors of secureboot do not sign or validate the initramfs. This is a big attack area and can be relatively trivialized that a semi-decent pawn shop owner with Google could likely find an image that would grant him access and make the TPM none the wiser the system has changed. One can prevent this with encrypted /boot, but that would limit you to GRUB2 and LUKS version 1 devices only. This also doesn't include the work to keep GRUB2's files signed with a PGP key by root.<br />
<br />
== Miscellaneous discussions ==<br />
<br />
=== Filesystem Selection ===<br />
<br />
Most examples on Arch utilize {{ic|ext4}}, but other file systems such as {{ic|brtfs}} can work equally well. As for performance or issues with being inside LVM, [https://btrfs.wiki.kernel.org/index.php/FAQ#Btrfs_has_subvolumes.2C_does_this_mean_I_don.27t_need_a_logical_volume_manager_and_I_can_create_a_big_Btrfs_filesystem_on_a_raw_partition.3F this question in the brtfs FAQ] implie that there is some performance loss but no other issues.<br />
<br />
=== LUKS TPM enrollment and managing luks keys ===<br />
<br />
Note that using {{man|1|systemd-cryptenroll}} will add a key to your LUKS volume. It's not clear how exactly the option {{ic|1=--wipe-slot=tpm2}} is able to identify which slot it needs to wipe, but it does. This even works if your TPM has changed.<br />
<br />
You can see the effects by comparing the output of {{ic|cryptsetup luksDump /dev/nvme0n1p2}} before and after you enroll or wipe a TPM based key. You can identify what slot your own passphrase is in with {{ic|cryptsetup --verbose open --test-passphrase /dev/nvme0n1p2}} and entering your passphrase. The output will inform you which key slot was unlocked.<br />
<br />
Finally, your passphrase may be changed with {{ic|cryptsetup luksChangeKey /dev/nvme0n1p2 -S 0}}.<br />
<br />
== Planned TODOs ==<br />
A panic command that can dump the TPM and shutdown the computer (without requiring the time of entering a password in sudo) forcing an adversary to resort to [https://en.wikipedia.org/wiki/Rubber-hose_cryptanalysis rubber-hose cryptanalysis] to get to the encrypted data.</div>Krinhttps://wiki.archlinux.org/index.php?title=User:Krin/Secure_Boot,_full_disk_encryption,_and_TPM2_unlocking_install&diff=697925User:Krin/Secure Boot, full disk encryption, and TPM2 unlocking install2021-10-01T00:49:28Z<p>Krin: /* Disk preparation */ Correct which disk mkfs.fat targeted.</p>
<hr />
<div>{{Unsupported|30 September 2021}}<br />
{{Expansion|Work In Progress, Draft from Installation Notes, Needs Testing}}<br />
<br />
== Introduction ==<br />
<br />
This installation is based on my installing Arch on an Asus ROG Strix G G531 I got second hand and a desktop computer made of second hand parts that had to share space with Windows. The primary goals were to replace Windows 10 Pro with Bitlocker encryption and maintain the convienence and security balance of that original operating system.<br />
<br />
My requirements boiled down to:<br />
<br />
* A fully encrypted disk<br />
* Full Secure Boot validation of all UEFI components.<br />
* Use of the TPM to facilitate unlocking of the disk.<br />
* Hibernate/Suspend working.<br />
<br />
My primary use case here is to make it difficult enough for a baggage handler with sticky hands to get at my data that they just wipe the drive. A state level actor with the expertise and equipment to hot swap my ram in my hotel room is not something that I'm defending this ''particular'' laptop against. This is more for gaming and web browsing and uploading photos while traveling.<br />
<br />
I'll continue to update these notes as I develop further solutions.<br />
<br />
== Disclaimers ==<br />
<br />
This article is primarily for the author's own notes. It is assumed that the reader is familiar with the [[Installation guide]] and will refer to it often. Reading linked articles is recommended.<br />
<br />
== Dual Booting Modifications ==<br />
<br />
For computers that will have to dual boot with windows, the easiest solution is to use two different physical drives and utilize your motherboard's UEFI boot menu to select which one to boot. This guide will follow that assumption. You can also attempt to have everything live on one EFI partition. Windows's 100 MiB EFI partition is especially problematic to this approach for secure boot, as Unified Kernel Images can approach 80 MiB and Windows 10 regularly uses up to 30 MiB.<br />
<br />
There are two changes that will be made and will be noted in the relevant sections:<br />
<br />
* Do not clear your Secure Boot keys. Merely disable Secure Boot for the installation.<br />
* Use {{ic|shim}} to boot systemd-bootloader<br />
* Load your db.cer file into the MOKManager application.<br />
<br />
All remaining steps should remain the same, except your system will still be dependent on the factory provided Microsoft Certificates. But you can boot Windows 10 in Secure Boot, which will be important for Windows 11.<br />
<br />
== Initial setup ==<br />
<br />
=== Pre-installation ===<br />
<br />
If you will only boot linux, reset your Secure Boot settings in BIOS to enable setup mode. Usually this means you set Secure Boot to Enabled and then select the option to wipe out the keys.<br />
<br />
If you will be dual booting Windows, disable secure boot.<br />
<br />
Follow the [[Installation_guide#Pre-installation]] up to Paritioning the Disks.<br />
<br />
=== Disk preparation ===<br />
<br />
If you have data on your disks you want to overwrite, utilize [[Dm-crypt/Drive_preparation#dm-crypt_wipe_on_an_empty_disk_or_partition]] to wipe it. If this disk was previously encrypted, utilize [[Dm-crypt/Drive_preparation#Wipe_LUKS_header]] instead for a much faster disposal. Finally, use [[Dm-crypt/Encrypting_an_entire_system#LVM_on_LUKS]] to parition your drive with two differences.<br />
<br />
{{tip|Using a memorable LUKS passphrase until you've completed the install process can be helpful. It will take several reboots to finish setup.}}<br />
<br />
First, the partition layout will be similar to here. You may wish to break out the /home directory into it's own partition. The primary requirement is that only your EFI partition be unencrypted.<br />
<br />
{{hc|Partiton Layout|<br />
┌────────────────────┬──────────────────────────┬─────────────────────────────┐<br />
│ │ │ │<br />
│ EFI Boot Partition │ Logical Volume 1 │ Logical Volume 2 │<br />
│ │ │ │<br />
│ /efi │ [SWAP] │ / │<br />
│ │ │ │<br />
│ /dev/nvme0n1p1 │ /dev/CryptRootVG/swap │ /dev/CryptRootVG/root │<br />
│ │ │ │<br />
│ 512 MB │ 16 GB (Or RAM size) │ Remaining Free Space │<br />
│ │ │ │<br />
│ │ │ │<br />
│ ├──────────────────────────┴─────────────────────────────┤<br />
│ │ │<br />
│ │ LUKS and LVM Physical Volume │<br />
│ │ │<br />
│ │ /dev/nvme0n1p2 │<br />
│ │ │<br />
└────────────────────┴────────────────────────────────────────────────────────┘<br />
}}<br />
<br />
Second, if your hard drive is an SSD like this laptop, use the following command to open your LUKS volume.<br />
<br />
# cryptsetup open --perf-no_read_workqueue --perf-no_write_workqueue --persistent /dev/nvme0n1p2 cryptroot<br />
<br />
After completing your LUKS on LVM setup, format your EFI partition per [[EFI system partition]].<br />
<br />
# mkfs.fat -F32 /dev/nvme0n1p1<br />
<br />
Mount this partition at {{ic|/mnt/efi}}. It is very important to leave {{ic|/boot}} on your encrypted root partition.<br />
<br />
== Installation ==<br />
<br />
Continue with [[Installation_guide#Installation]]. Be sure to flesh out your {{man|8|pacstrap}} with the following list of packages:<br />
<br />
* {{Pkg|dracut}}<br />
* {{Pkg|intel-ucode}}<br />
* {{Pkg|lvm2}}<br />
* {{Pkg|openssh}}<br />
* {{Pkg|ansible}}<br />
* {{Pkg|git}}<br />
* {{Pkg|iwd}}<br />
* {{Pkg|efibootmgr}}<br />
<br />
<br />
We are going to leave off the installation guide at the initramfs section, so go ahead and reset your root password. <br />
<br />
# passwd<br />
<br />
=== Bootloader ===<br />
<br />
{{warning|This section needs testing.}}<br />
<br />
First, install {{ic|systemd-boot}} by following [[Systemd-boot#Installing_the_EFI_boot_manager]]. Next, install {{aur|dracut-hook-uefi}}.<br />
<br />
Ensure you drop in a systemd-boot hook to update your bootctl any time it's updated.<br />
<br />
{{hc|/etc/pacman.d/hooks/998-systemd-boot.hook|2=<br />
[Trigger]<br />
Type = Package<br />
Operation = Install<br />
Operation = Upgrade<br />
Target = systemd<br />
<br />
[Action]<br />
Description = Updating systemd-boot<br />
When = PostTransation<br />
Exec = /usr/bin/bootctl update; <br />
}}<br />
<br />
Obtain the UUID of your LUKS drive via the following command:<br />
<br />
{{bc|<br />
blkid -s UUID -o value /dev/nvme0n1p2<br />
}}<br />
<br />
Create the following files with the listed content. Be sure to replace UUIDs with what you actually need. The extraneous {{ic:rd.luks.options}} should not cause an issue, but will be used once we've enabled secure boot. See {{man|5|dracut.conf}} for more information on what these commands do.<br />
<br />
A good portion of the kernel command line was as generated by dracut. Many are extraneous or you may wish to change some of the block device names.<br />
<br />
{{hc|/etc/dracut.conf.d/cmdline.conf|2=<br />
kernel_cmdline="rd.luks.uuid=luks-17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02 rd.luks.options=17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02 rd.lvm.lv=CryptRoot/root rd.lvm.lv=CryptRoot/swap resume=/dev/mapper/CryptRoot-swap root=/dev/mapper/CryptRoot-root rootfstype=ext4 rootflags=rw,relatime"<br />
}}<br />
<br />
{{hc|/etc/dracut.conf.d/flags.conf|2=<br />
compress="zstd"<br />
hostonly="yes"<br />
}}<br />
<br />
Run the following command to generate your EFI stub kernels.<br />
<br />
dracut --uefi<br />
<br />
=== Secure boot ===<br />
<br />
==== Dual Booting Windows ====<br />
<br />
{{warning|This section is still being written}}<br />
<br />
Review [[Unified Extensible Firmware Interface/Secure Boot#shim]] to get a rough understanding of how it's going to work. Install {{aur|shim-signed}}. Perform the following commands to place files where both the UEFI boot entry and shim will load them.<br />
<br />
# mv /efi/EFI/BOOT/BOOTx64.EFI /efi/EFI/BOOT/grubx64.efi<br />
# cp /usr/share/shim-signed/shimx64.efi esp/EFI/BOOT/BOOTx64.EFI<br />
# cp /usr/share/shim-signed/mmx64.efi esp/EFI/BOOT/<br />
<br />
Install {{Pkg|sbctl}}. Use the following command to check that secure boot is in the right status. Your output should be similar.<br />
<br />
{{bc|<br />
}}<br />
<br />
==== Booting only Linux ====<br />
<br />
{{note|The very newly developed [https://github.com/Foxboron/sbctl sbctl], availble via {{aur|sbctl-git}} has completely revamped this process and will only get better as they approach 1.0. From here on out, as of October 2021, this process should greatly simplify.}}<br />
<br />
{{note|Credit to this [https://lunaryorn.com/secure-boot-on-arch-linux-with-sbctl-and-dracut blog post by lunaryorn] for the inspiration.}}<br />
<br />
Install {{Pkg|sbctl}}. At this point you will likely need to reboot and adjust your secure boot settings. You want secure boot in '''setup mode'''. <br />
<br />
{{bc|<br />
$ sbctl status<br />
Installed: X Sbctl is not installed<br />
Setup Mode: X Enabled<br />
Secure Boot: X Disabled<br />
}}<br />
<br />
Run the following commands as root. See {{man|8|sbctl}} for more information on their function. Of particular note is the {{ic|-s}} flag which indicates {{ic|sbctl}} should remember the file for future verification and signing.<br />
<br />
Note your Linux EFI binary name may be slightly different.<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
<br />
# sbctl sign -s /efi/EFI/BOOT/BOOTx64.EFI<br />
✔ Signed /efi/EFI/BOOT/BOOTx64.EFI<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Finally, enroll the Secure Boot keys.<br />
<br />
{{bc|<br />
# sbctl enroll-keys<br />
Enrolling keys to EFI variables...✔<br />
Enrolled keys to the EFI variables!<br />
}}<br />
<br />
Verify that secure boot now has an owner GUID and setup mode is disabled.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✔ Sbctl is installed<br />
Owner GUID: a2ee3d08-725a-408b-9d95-28026a44611c<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
Now reboot. This reboot is required so we can get the TPM measurements into their (hopefully) permanent state.<br />
<br />
=== Enroll LUKS key in TPM ===<br />
{{warning|Yes, this will cause a system to automatically unlock it's encrypted root volume without any interaction from a human. Yes, this exposes it to any sufficently advanced Evil Maid attacks. If sealed against the appropriate registers (especially register 8 with the kernel arguments), the TPM measurements should force systemd to ask for your LUKS passphrase in almost any attempt to access the encrypted volume from outside your normal boot process.}}<br />
<br />
We are fortunate that in our shift to dracut includes utilizing systemd and sd-encrypt, as we can use systemd's native support for enrolling LUKS keys. A review of [[Trusted Platform Module#Using TPM 2.0]] is recommended but not very clear.<br />
<br />
First, be sure to install {{Pkg|tpm2-tools}}. Alternatively {{aur|ibm-tss}} can be used per [[Trusted Platform Module]], however this guide is not tested against those.<br />
<br />
{{note|A reboot may be required to convince {{ic|systemd-cryptenroll}} that TPM 2.0 devices now exist on the machine.}}<br />
<br />
There are several decisions to be made here. The table at [[Trusted Platform Module#Accessing PCR registers]] is accurate as of October 2021. Essentially, once you seal your LUKS key, if any of the registers you've sealed against change, then you will be asked for your LUKS passphrase. This is equivalent to when Windows 10 makes you enter your BitLocker recovery key after a hardware change or changing BIOS settings.<br />
<br />
Your mileage may vary, based on UEFI vendors. For my laptop, I went with 0+1+2+3+4+5+7+8 and have been able to invalidate my TPM. Unfortunately, if you change your system BACK the volume will unlock. I'm investigating how to disable that.<br />
<br />
Other options on {{man|1|systemd-cryptenroll}} will reveal that several hardware tokens can also be enrolled to allow unlocking the root LUKS volume automatically, but only if a key is present. Further testing is requried.<br />
<br />
To enroll your LUKS volume, simply run the following command as root<br />
<br />
# systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/nvme0n1p2<br />
<br />
To remove your key, run this command:<br />
<br />
# systemd-cryptenroll --wipe-slot=tpm2 /dev/nvme0n1p2<br />
<br />
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:<br />
<br />
{{hc|~/bin/luks_reenroll_tpm|2=<br />
sudo systemd-cryptenroll --wipe-slot=tpm2 /dev/disk/by-uuid/{UUID_HERE}<br />
systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/disk/by-uuid/{UUID_HERE}<br />
}}<br />
<br />
== Justifications ==<br />
<br />
=== LVM on LUKS vs other dm-crypt approaches ===<br />
<br />
LVM on LUKS was selected becasue it is simply the easiest to manage while conferring both encrypted swap and disk. The other approaches required much more tooling and manual fussing to utilize. This selection also gives room change freely between {{ic|busybox}} and {{ic|systemd}} initrds.<br />
<br />
=== Using dracut ===<br />
<br />
{{Pkg|dracut}} just makes it easier to build full unified kernels that {{man|7|systemd-boot}} can launch as EFI binaries. There is also available tooling in the [[AUR]] for automating the creation of these binaries. Finally, {{ic|dracut}} will sign the binaries it creates automatically when configured to do so.<br />
<br />
=== Unified kernel images ===<br />
<br />
While UKI's could be problematic on other distributions, they fit right in with an Arch Linux install. The automation is there through pacman hooks and {{Pkg|sbctl}} to sign our UKIs as they're created. Furthermore, you can only sign and create a new signed UKI while booted into a properly signed UKI. It creates a chain of trust, which means it's important to never disable Secure Boot once you've set it up.<br />
<br />
The UKI encompasses all of the following items inside the signature, which means you can't change any of them without invalidating the signature.<br />
<br />
* Kernel arguments<br />
* Initrd/Initramfs<br />
* Kernel<br />
<br />
In particular, all other flavors of secureboot do not sign or validate the initramfs. This is a big attack area and can be relatively trivialized that a semi-decent pawn shop owner with Google could likely find an image that would grant him access and make the TPM none the wiser the system has changed. One can prevent this with encrypted /boot, but that would limit you to GRUB2 and LUKS version 1 devices only. This also doesn't include the work to keep GRUB2's files signed with a PGP key by root.<br />
<br />
== Miscellaneous discussions ==<br />
<br />
=== Filesystem Selection ===<br />
<br />
Most examples on Arch utilize {{ic|ext4}}, but other file systems such as {{ic|brtfs}} can work equally well. As for performance or issues with being inside LVM, [https://btrfs.wiki.kernel.org/index.php/FAQ#Btrfs_has_subvolumes.2C_does_this_mean_I_don.27t_need_a_logical_volume_manager_and_I_can_create_a_big_Btrfs_filesystem_on_a_raw_partition.3F this question in the brtfs FAQ] implie that there is some performance loss but no other issues.<br />
<br />
=== LUKS TPM enrollment and managing luks keys ===<br />
<br />
Note that using {{man|1|systemd-cryptenroll}} will add a key to your LUKS volume. It's not clear how exactly the option {{ic|1=--wipe-slot=tpm2}} is able to identify which slot it needs to wipe, but it does. This even works if your TPM has changed.<br />
<br />
You can see the effects by comparing the output of {{ic|cryptsetup luksDump /dev/nvme0n1p2}} before and after you enroll or wipe a TPM based key. You can identify what slot your own passphrase is in with {{ic|cryptsetup --verbose open --test-passphrase /dev/nvme0n1p2}} and entering your passphrase. The output will inform you which key slot was unlocked.<br />
<br />
Finally, your passphrase may be changed with {{ic|cryptsetup luksChangeKey /dev/nvme0n1p2 -S 0}}.<br />
<br />
== Planned TODOs ==<br />
A panic command that can dump the TPM and shutdown the computer (without requiring the time of entering a password in sudo) forcing an adversary to resort to [https://en.wikipedia.org/wiki/Rubber-hose_cryptanalysis rubber-hose cryptanalysis] to get to the encrypted data.</div>Krinhttps://wiki.archlinux.org/index.php?title=User:Krin/Secure_Boot,_full_disk_encryption,_and_TPM2_unlocking_install&diff=697924User:Krin/Secure Boot, full disk encryption, and TPM2 unlocking install2021-10-01T00:48:41Z<p>Krin: /* Disk preparation */ Correct command.</p>
<hr />
<div>{{Unsupported|30 September 2021}}<br />
{{Expansion|Work In Progress, Draft from Installation Notes, Needs Testing}}<br />
<br />
== Introduction ==<br />
<br />
This installation is based on my installing Arch on an Asus ROG Strix G G531 I got second hand and a desktop computer made of second hand parts that had to share space with Windows. The primary goals were to replace Windows 10 Pro with Bitlocker encryption and maintain the convienence and security balance of that original operating system.<br />
<br />
My requirements boiled down to:<br />
<br />
* A fully encrypted disk<br />
* Full Secure Boot validation of all UEFI components.<br />
* Use of the TPM to facilitate unlocking of the disk.<br />
* Hibernate/Suspend working.<br />
<br />
My primary use case here is to make it difficult enough for a baggage handler with sticky hands to get at my data that they just wipe the drive. A state level actor with the expertise and equipment to hot swap my ram in my hotel room is not something that I'm defending this ''particular'' laptop against. This is more for gaming and web browsing and uploading photos while traveling.<br />
<br />
I'll continue to update these notes as I develop further solutions.<br />
<br />
== Disclaimers ==<br />
<br />
This article is primarily for the author's own notes. It is assumed that the reader is familiar with the [[Installation guide]] and will refer to it often. Reading linked articles is recommended.<br />
<br />
== Dual Booting Modifications ==<br />
<br />
For computers that will have to dual boot with windows, the easiest solution is to use two different physical drives and utilize your motherboard's UEFI boot menu to select which one to boot. This guide will follow that assumption. You can also attempt to have everything live on one EFI partition. Windows's 100 MiB EFI partition is especially problematic to this approach for secure boot, as Unified Kernel Images can approach 80 MiB and Windows 10 regularly uses up to 30 MiB.<br />
<br />
There are two changes that will be made and will be noted in the relevant sections:<br />
<br />
* Do not clear your Secure Boot keys. Merely disable Secure Boot for the installation.<br />
* Use {{ic|shim}} to boot systemd-bootloader<br />
* Load your db.cer file into the MOKManager application.<br />
<br />
All remaining steps should remain the same, except your system will still be dependent on the factory provided Microsoft Certificates. But you can boot Windows 10 in Secure Boot, which will be important for Windows 11.<br />
<br />
== Initial setup ==<br />
<br />
=== Pre-installation ===<br />
<br />
If you will only boot linux, reset your Secure Boot settings in BIOS to enable setup mode. Usually this means you set Secure Boot to Enabled and then select the option to wipe out the keys.<br />
<br />
If you will be dual booting Windows, disable secure boot.<br />
<br />
Follow the [[Installation_guide#Pre-installation]] up to Paritioning the Disks.<br />
<br />
=== Disk preparation ===<br />
<br />
If you have data on your disks you want to overwrite, utilize [[Dm-crypt/Drive_preparation#dm-crypt_wipe_on_an_empty_disk_or_partition]] to wipe it. If this disk was previously encrypted, utilize [[Dm-crypt/Drive_preparation#Wipe_LUKS_header]] instead for a much faster disposal. Finally, use [[Dm-crypt/Encrypting_an_entire_system#LVM_on_LUKS]] to parition your drive with two differences.<br />
<br />
{{tip|Using a memorable LUKS passphrase until you've completed the install process can be helpful. It will take several reboots to finish setup.}}<br />
<br />
First, the partition layout will be similar to here. You may wish to break out the /home directory into it's own partition. The primary requirement is that only your EFI partition be unencrypted.<br />
<br />
{{hc|Partiton Layout|<br />
┌────────────────────┬──────────────────────────┬─────────────────────────────┐<br />
│ │ │ │<br />
│ EFI Boot Partition │ Logical Volume 1 │ Logical Volume 2 │<br />
│ │ │ │<br />
│ /efi │ [SWAP] │ / │<br />
│ │ │ │<br />
│ /dev/nvme0n1p1 │ /dev/CryptRootVG/swap │ /dev/CryptRootVG/root │<br />
│ │ │ │<br />
│ 512 MB │ 16 GB (Or RAM size) │ Remaining Free Space │<br />
│ │ │ │<br />
│ │ │ │<br />
│ ├──────────────────────────┴─────────────────────────────┤<br />
│ │ │<br />
│ │ LUKS and LVM Physical Volume │<br />
│ │ │<br />
│ │ /dev/nvme0n1p2 │<br />
│ │ │<br />
└────────────────────┴────────────────────────────────────────────────────────┘<br />
}}<br />
<br />
Second, if your hard drive is an SSD like this laptop, use the following command to open your LUKS volume.<br />
<br />
# cryptsetup open --perf-no_read_workqueue --perf-no_write_workqueue --persistent /dev/nvme0n1p2 cryptroot<br />
<br />
After completing your LUKS on LVM setup, format your EFI partition per [[EFI system partition]].<br />
<br />
# mkfs.fat -F32 /dev/nvme0n1p2<br />
<br />
Mount this partition at {{ic|/mnt/efi}}. It is very important to leave {{ic|/boot}} on your encrypted root partition.<br />
<br />
== Installation ==<br />
<br />
Continue with [[Installation_guide#Installation]]. Be sure to flesh out your {{man|8|pacstrap}} with the following list of packages:<br />
<br />
* {{Pkg|dracut}}<br />
* {{Pkg|intel-ucode}}<br />
* {{Pkg|lvm2}}<br />
* {{Pkg|openssh}}<br />
* {{Pkg|ansible}}<br />
* {{Pkg|git}}<br />
* {{Pkg|iwd}}<br />
* {{Pkg|efibootmgr}}<br />
<br />
<br />
We are going to leave off the installation guide at the initramfs section, so go ahead and reset your root password. <br />
<br />
# passwd<br />
<br />
=== Bootloader ===<br />
<br />
{{warning|This section needs testing.}}<br />
<br />
First, install {{ic|systemd-boot}} by following [[Systemd-boot#Installing_the_EFI_boot_manager]]. Next, install {{aur|dracut-hook-uefi}}.<br />
<br />
Ensure you drop in a systemd-boot hook to update your bootctl any time it's updated.<br />
<br />
{{hc|/etc/pacman.d/hooks/998-systemd-boot.hook|2=<br />
[Trigger]<br />
Type = Package<br />
Operation = Install<br />
Operation = Upgrade<br />
Target = systemd<br />
<br />
[Action]<br />
Description = Updating systemd-boot<br />
When = PostTransation<br />
Exec = /usr/bin/bootctl update; <br />
}}<br />
<br />
Obtain the UUID of your LUKS drive via the following command:<br />
<br />
{{bc|<br />
blkid -s UUID -o value /dev/nvme0n1p2<br />
}}<br />
<br />
Create the following files with the listed content. Be sure to replace UUIDs with what you actually need. The extraneous {{ic:rd.luks.options}} should not cause an issue, but will be used once we've enabled secure boot. See {{man|5|dracut.conf}} for more information on what these commands do.<br />
<br />
A good portion of the kernel command line was as generated by dracut. Many are extraneous or you may wish to change some of the block device names.<br />
<br />
{{hc|/etc/dracut.conf.d/cmdline.conf|2=<br />
kernel_cmdline="rd.luks.uuid=luks-17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02 rd.luks.options=17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02 rd.lvm.lv=CryptRoot/root rd.lvm.lv=CryptRoot/swap resume=/dev/mapper/CryptRoot-swap root=/dev/mapper/CryptRoot-root rootfstype=ext4 rootflags=rw,relatime"<br />
}}<br />
<br />
{{hc|/etc/dracut.conf.d/flags.conf|2=<br />
compress="zstd"<br />
hostonly="yes"<br />
}}<br />
<br />
Run the following command to generate your EFI stub kernels.<br />
<br />
dracut --uefi<br />
<br />
=== Secure boot ===<br />
<br />
==== Dual Booting Windows ====<br />
<br />
{{warning|This section is still being written}}<br />
<br />
Review [[Unified Extensible Firmware Interface/Secure Boot#shim]] to get a rough understanding of how it's going to work. Install {{aur|shim-signed}}. Perform the following commands to place files where both the UEFI boot entry and shim will load them.<br />
<br />
# mv /efi/EFI/BOOT/BOOTx64.EFI /efi/EFI/BOOT/grubx64.efi<br />
# cp /usr/share/shim-signed/shimx64.efi esp/EFI/BOOT/BOOTx64.EFI<br />
# cp /usr/share/shim-signed/mmx64.efi esp/EFI/BOOT/<br />
<br />
Install {{Pkg|sbctl}}. Use the following command to check that secure boot is in the right status. Your output should be similar.<br />
<br />
{{bc|<br />
}}<br />
<br />
==== Booting only Linux ====<br />
<br />
{{note|The very newly developed [https://github.com/Foxboron/sbctl sbctl], availble via {{aur|sbctl-git}} has completely revamped this process and will only get better as they approach 1.0. From here on out, as of October 2021, this process should greatly simplify.}}<br />
<br />
{{note|Credit to this [https://lunaryorn.com/secure-boot-on-arch-linux-with-sbctl-and-dracut blog post by lunaryorn] for the inspiration.}}<br />
<br />
Install {{Pkg|sbctl}}. At this point you will likely need to reboot and adjust your secure boot settings. You want secure boot in '''setup mode'''. <br />
<br />
{{bc|<br />
$ sbctl status<br />
Installed: X Sbctl is not installed<br />
Setup Mode: X Enabled<br />
Secure Boot: X Disabled<br />
}}<br />
<br />
Run the following commands as root. See {{man|8|sbctl}} for more information on their function. Of particular note is the {{ic|-s}} flag which indicates {{ic|sbctl}} should remember the file for future verification and signing.<br />
<br />
Note your Linux EFI binary name may be slightly different.<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
<br />
# sbctl sign -s /efi/EFI/BOOT/BOOTx64.EFI<br />
✔ Signed /efi/EFI/BOOT/BOOTx64.EFI<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Finally, enroll the Secure Boot keys.<br />
<br />
{{bc|<br />
# sbctl enroll-keys<br />
Enrolling keys to EFI variables...✔<br />
Enrolled keys to the EFI variables!<br />
}}<br />
<br />
Verify that secure boot now has an owner GUID and setup mode is disabled.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✔ Sbctl is installed<br />
Owner GUID: a2ee3d08-725a-408b-9d95-28026a44611c<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
Now reboot. This reboot is required so we can get the TPM measurements into their (hopefully) permanent state.<br />
<br />
=== Enroll LUKS key in TPM ===<br />
{{warning|Yes, this will cause a system to automatically unlock it's encrypted root volume without any interaction from a human. Yes, this exposes it to any sufficently advanced Evil Maid attacks. If sealed against the appropriate registers (especially register 8 with the kernel arguments), the TPM measurements should force systemd to ask for your LUKS passphrase in almost any attempt to access the encrypted volume from outside your normal boot process.}}<br />
<br />
We are fortunate that in our shift to dracut includes utilizing systemd and sd-encrypt, as we can use systemd's native support for enrolling LUKS keys. A review of [[Trusted Platform Module#Using TPM 2.0]] is recommended but not very clear.<br />
<br />
First, be sure to install {{Pkg|tpm2-tools}}. Alternatively {{aur|ibm-tss}} can be used per [[Trusted Platform Module]], however this guide is not tested against those.<br />
<br />
{{note|A reboot may be required to convince {{ic|systemd-cryptenroll}} that TPM 2.0 devices now exist on the machine.}}<br />
<br />
There are several decisions to be made here. The table at [[Trusted Platform Module#Accessing PCR registers]] is accurate as of October 2021. Essentially, once you seal your LUKS key, if any of the registers you've sealed against change, then you will be asked for your LUKS passphrase. This is equivalent to when Windows 10 makes you enter your BitLocker recovery key after a hardware change or changing BIOS settings.<br />
<br />
Your mileage may vary, based on UEFI vendors. For my laptop, I went with 0+1+2+3+4+5+7+8 and have been able to invalidate my TPM. Unfortunately, if you change your system BACK the volume will unlock. I'm investigating how to disable that.<br />
<br />
Other options on {{man|1|systemd-cryptenroll}} will reveal that several hardware tokens can also be enrolled to allow unlocking the root LUKS volume automatically, but only if a key is present. Further testing is requried.<br />
<br />
To enroll your LUKS volume, simply run the following command as root<br />
<br />
# systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/nvme0n1p2<br />
<br />
To remove your key, run this command:<br />
<br />
# systemd-cryptenroll --wipe-slot=tpm2 /dev/nvme0n1p2<br />
<br />
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:<br />
<br />
{{hc|~/bin/luks_reenroll_tpm|2=<br />
sudo systemd-cryptenroll --wipe-slot=tpm2 /dev/disk/by-uuid/{UUID_HERE}<br />
systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/disk/by-uuid/{UUID_HERE}<br />
}}<br />
<br />
== Justifications ==<br />
<br />
=== LVM on LUKS vs other dm-crypt approaches ===<br />
<br />
LVM on LUKS was selected becasue it is simply the easiest to manage while conferring both encrypted swap and disk. The other approaches required much more tooling and manual fussing to utilize. This selection also gives room change freely between {{ic|busybox}} and {{ic|systemd}} initrds.<br />
<br />
=== Using dracut ===<br />
<br />
{{Pkg|dracut}} just makes it easier to build full unified kernels that {{man|7|systemd-boot}} can launch as EFI binaries. There is also available tooling in the [[AUR]] for automating the creation of these binaries. Finally, {{ic|dracut}} will sign the binaries it creates automatically when configured to do so.<br />
<br />
=== Unified kernel images ===<br />
<br />
While UKI's could be problematic on other distributions, they fit right in with an Arch Linux install. The automation is there through pacman hooks and {{Pkg|sbctl}} to sign our UKIs as they're created. Furthermore, you can only sign and create a new signed UKI while booted into a properly signed UKI. It creates a chain of trust, which means it's important to never disable Secure Boot once you've set it up.<br />
<br />
The UKI encompasses all of the following items inside the signature, which means you can't change any of them without invalidating the signature.<br />
<br />
* Kernel arguments<br />
* Initrd/Initramfs<br />
* Kernel<br />
<br />
In particular, all other flavors of secureboot do not sign or validate the initramfs. This is a big attack area and can be relatively trivialized that a semi-decent pawn shop owner with Google could likely find an image that would grant him access and make the TPM none the wiser the system has changed. One can prevent this with encrypted /boot, but that would limit you to GRUB2 and LUKS version 1 devices only. This also doesn't include the work to keep GRUB2's files signed with a PGP key by root.<br />
<br />
== Miscellaneous discussions ==<br />
<br />
=== Filesystem Selection ===<br />
<br />
Most examples on Arch utilize {{ic|ext4}}, but other file systems such as {{ic|brtfs}} can work equally well. As for performance or issues with being inside LVM, [https://btrfs.wiki.kernel.org/index.php/FAQ#Btrfs_has_subvolumes.2C_does_this_mean_I_don.27t_need_a_logical_volume_manager_and_I_can_create_a_big_Btrfs_filesystem_on_a_raw_partition.3F this question in the brtfs FAQ] implie that there is some performance loss but no other issues.<br />
<br />
=== LUKS TPM enrollment and managing luks keys ===<br />
<br />
Note that using {{man|1|systemd-cryptenroll}} will add a key to your LUKS volume. It's not clear how exactly the option {{ic|1=--wipe-slot=tpm2}} is able to identify which slot it needs to wipe, but it does. This even works if your TPM has changed.<br />
<br />
You can see the effects by comparing the output of {{ic|cryptsetup luksDump /dev/nvme0n1p2}} before and after you enroll or wipe a TPM based key. You can identify what slot your own passphrase is in with {{ic|cryptsetup --verbose open --test-passphrase /dev/nvme0n1p2}} and entering your passphrase. The output will inform you which key slot was unlocked.<br />
<br />
Finally, your passphrase may be changed with {{ic|cryptsetup luksChangeKey /dev/nvme0n1p2 -S 0}}.<br />
<br />
== Planned TODOs ==<br />
A panic command that can dump the TPM and shutdown the computer (without requiring the time of entering a password in sudo) forcing an adversary to resort to [https://en.wikipedia.org/wiki/Rubber-hose_cryptanalysis rubber-hose cryptanalysis] to get to the encrypted data.</div>Krinhttps://wiki.archlinux.org/index.php?title=User:Krin/Secure_Boot,_full_disk_encryption,_and_TPM2_unlocking_install&diff=697923User:Krin/Secure Boot, full disk encryption, and TPM2 unlocking install2021-10-01T00:43:20Z<p>Krin: /* Dual Booting Windows */ Instructions for installing shim</p>
<hr />
<div>{{Unsupported|30 September 2021}}<br />
{{Expansion|Work In Progress, Draft from Installation Notes, Needs Testing}}<br />
<br />
== Introduction ==<br />
<br />
This installation is based on my installing Arch on an Asus ROG Strix G G531 I got second hand and a desktop computer made of second hand parts that had to share space with Windows. The primary goals were to replace Windows 10 Pro with Bitlocker encryption and maintain the convienence and security balance of that original operating system.<br />
<br />
My requirements boiled down to:<br />
<br />
* A fully encrypted disk<br />
* Full Secure Boot validation of all UEFI components.<br />
* Use of the TPM to facilitate unlocking of the disk.<br />
* Hibernate/Suspend working.<br />
<br />
My primary use case here is to make it difficult enough for a baggage handler with sticky hands to get at my data that they just wipe the drive. A state level actor with the expertise and equipment to hot swap my ram in my hotel room is not something that I'm defending this ''particular'' laptop against. This is more for gaming and web browsing and uploading photos while traveling.<br />
<br />
I'll continue to update these notes as I develop further solutions.<br />
<br />
== Disclaimers ==<br />
<br />
This article is primarily for the author's own notes. It is assumed that the reader is familiar with the [[Installation guide]] and will refer to it often. Reading linked articles is recommended.<br />
<br />
== Dual Booting Modifications ==<br />
<br />
For computers that will have to dual boot with windows, the easiest solution is to use two different physical drives and utilize your motherboard's UEFI boot menu to select which one to boot. This guide will follow that assumption. You can also attempt to have everything live on one EFI partition. Windows's 100 MiB EFI partition is especially problematic to this approach for secure boot, as Unified Kernel Images can approach 80 MiB and Windows 10 regularly uses up to 30 MiB.<br />
<br />
There are two changes that will be made and will be noted in the relevant sections:<br />
<br />
* Do not clear your Secure Boot keys. Merely disable Secure Boot for the installation.<br />
* Use {{ic|shim}} to boot systemd-bootloader<br />
* Load your db.cer file into the MOKManager application.<br />
<br />
All remaining steps should remain the same, except your system will still be dependent on the factory provided Microsoft Certificates. But you can boot Windows 10 in Secure Boot, which will be important for Windows 11.<br />
<br />
== Initial setup ==<br />
<br />
=== Pre-installation ===<br />
<br />
If you will only boot linux, reset your Secure Boot settings in BIOS to enable setup mode. Usually this means you set Secure Boot to Enabled and then select the option to wipe out the keys.<br />
<br />
If you will be dual booting Windows, disable secure boot.<br />
<br />
Follow the [[Installation_guide#Pre-installation]] up to Paritioning the Disks.<br />
<br />
=== Disk preparation ===<br />
<br />
If you have data on your disks you want to overwrite, utilize [[Dm-crypt/Drive_preparation#dm-crypt_wipe_on_an_empty_disk_or_partition]] to wipe it. If this disk was previously encrypted, utilize [[Dm-crypt/Drive_preparation#Wipe_LUKS_header]] instead for a much faster disposal. Finally, use [[Dm-crypt/Encrypting_an_entire_system#LVM_on_LUKS]] to parition your drive with two differences.<br />
<br />
{{tip|Using a memorable LUKS passphrase until you've completed the install process can be helpful. It will take several reboots to finish setup.}}<br />
<br />
First, the partition layout will be similar to here. You may wish to break out the /home directory into it's own partition. The primary requirement is that only your EFI partition be unencrypted.<br />
<br />
{{hc|Partiton Layout|<br />
┌────────────────────┬──────────────────────────┬─────────────────────────────┐<br />
│ │ │ │<br />
│ EFI Boot Partition │ Logical Volume 1 │ Logical Volume 2 │<br />
│ │ │ │<br />
│ /efi │ [SWAP] │ / │<br />
│ │ │ │<br />
│ /dev/nvme0n1p1 │ /dev/CryptRootVG/swap │ /dev/CryptRootVG/root │<br />
│ │ │ │<br />
│ 512 MB │ 16 GB (Or RAM size) │ Remaining Free Space │<br />
│ │ │ │<br />
│ │ │ │<br />
│ ├──────────────────────────┴─────────────────────────────┤<br />
│ │ │<br />
│ │ LUKS and LVM Physical Volume │<br />
│ │ │<br />
│ │ /dev/nvme0n1p2 │<br />
│ │ │<br />
└────────────────────┴────────────────────────────────────────────────────────┘<br />
}}<br />
<br />
Second, if your hard drive is an SSD like this laptop, use the following command to open your LUKS volume.<br />
<br />
# cryptsetup open --perf-no_read_workqueue --perf-no_write_workqueue --persistent /dev/nvme0n1p2 cryptroot<br />
<br />
After completing your LUKS on LVM setup, format your EFI partition per [[EFI system partition]].<br />
<br />
# mkfs ext.vfat -F32 /dev/nvme0n1p2<br />
<br />
Mount this partition at {{ic|/mnt/efi}}. It is very important to leave {{ic|/boot}} on your encrypted root partition.<br />
<br />
== Installation ==<br />
<br />
Continue with [[Installation_guide#Installation]]. Be sure to flesh out your {{man|8|pacstrap}} with the following list of packages:<br />
<br />
* {{Pkg|dracut}}<br />
* {{Pkg|intel-ucode}}<br />
* {{Pkg|lvm2}}<br />
* {{Pkg|openssh}}<br />
* {{Pkg|ansible}}<br />
* {{Pkg|git}}<br />
* {{Pkg|iwd}}<br />
* {{Pkg|efibootmgr}}<br />
<br />
<br />
We are going to leave off the installation guide at the initramfs section, so go ahead and reset your root password. <br />
<br />
# passwd<br />
<br />
=== Bootloader ===<br />
<br />
{{warning|This section needs testing.}}<br />
<br />
First, install {{ic|systemd-boot}} by following [[Systemd-boot#Installing_the_EFI_boot_manager]]. Next, install {{aur|dracut-hook-uefi}}.<br />
<br />
Ensure you drop in a systemd-boot hook to update your bootctl any time it's updated.<br />
<br />
{{hc|/etc/pacman.d/hooks/998-systemd-boot.hook|2=<br />
[Trigger]<br />
Type = Package<br />
Operation = Install<br />
Operation = Upgrade<br />
Target = systemd<br />
<br />
[Action]<br />
Description = Updating systemd-boot<br />
When = PostTransation<br />
Exec = /usr/bin/bootctl update; <br />
}}<br />
<br />
Obtain the UUID of your LUKS drive via the following command:<br />
<br />
{{bc|<br />
blkid -s UUID -o value /dev/nvme0n1p2<br />
}}<br />
<br />
Create the following files with the listed content. Be sure to replace UUIDs with what you actually need. The extraneous {{ic:rd.luks.options}} should not cause an issue, but will be used once we've enabled secure boot. See {{man|5|dracut.conf}} for more information on what these commands do.<br />
<br />
A good portion of the kernel command line was as generated by dracut. Many are extraneous or you may wish to change some of the block device names.<br />
<br />
{{hc|/etc/dracut.conf.d/cmdline.conf|2=<br />
kernel_cmdline="rd.luks.uuid=luks-17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02 rd.luks.options=17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02 rd.lvm.lv=CryptRoot/root rd.lvm.lv=CryptRoot/swap resume=/dev/mapper/CryptRoot-swap root=/dev/mapper/CryptRoot-root rootfstype=ext4 rootflags=rw,relatime"<br />
}}<br />
<br />
{{hc|/etc/dracut.conf.d/flags.conf|2=<br />
compress="zstd"<br />
hostonly="yes"<br />
}}<br />
<br />
Run the following command to generate your EFI stub kernels.<br />
<br />
dracut --uefi<br />
<br />
=== Secure boot ===<br />
<br />
==== Dual Booting Windows ====<br />
<br />
{{warning|This section is still being written}}<br />
<br />
Review [[Unified Extensible Firmware Interface/Secure Boot#shim]] to get a rough understanding of how it's going to work. Install {{aur|shim-signed}}. Perform the following commands to place files where both the UEFI boot entry and shim will load them.<br />
<br />
# mv /efi/EFI/BOOT/BOOTx64.EFI /efi/EFI/BOOT/grubx64.efi<br />
# cp /usr/share/shim-signed/shimx64.efi esp/EFI/BOOT/BOOTx64.EFI<br />
# cp /usr/share/shim-signed/mmx64.efi esp/EFI/BOOT/<br />
<br />
Install {{Pkg|sbctl}}. Use the following command to check that secure boot is in the right status. Your output should be similar.<br />
<br />
{{bc|<br />
}}<br />
<br />
==== Booting only Linux ====<br />
<br />
{{note|The very newly developed [https://github.com/Foxboron/sbctl sbctl], availble via {{aur|sbctl-git}} has completely revamped this process and will only get better as they approach 1.0. From here on out, as of October 2021, this process should greatly simplify.}}<br />
<br />
{{note|Credit to this [https://lunaryorn.com/secure-boot-on-arch-linux-with-sbctl-and-dracut blog post by lunaryorn] for the inspiration.}}<br />
<br />
Install {{Pkg|sbctl}}. At this point you will likely need to reboot and adjust your secure boot settings. You want secure boot in '''setup mode'''. <br />
<br />
{{bc|<br />
$ sbctl status<br />
Installed: X Sbctl is not installed<br />
Setup Mode: X Enabled<br />
Secure Boot: X Disabled<br />
}}<br />
<br />
Run the following commands as root. See {{man|8|sbctl}} for more information on their function. Of particular note is the {{ic|-s}} flag which indicates {{ic|sbctl}} should remember the file for future verification and signing.<br />
<br />
Note your Linux EFI binary name may be slightly different.<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
<br />
# sbctl sign -s /efi/EFI/BOOT/BOOTx64.EFI<br />
✔ Signed /efi/EFI/BOOT/BOOTx64.EFI<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Finally, enroll the Secure Boot keys.<br />
<br />
{{bc|<br />
# sbctl enroll-keys<br />
Enrolling keys to EFI variables...✔<br />
Enrolled keys to the EFI variables!<br />
}}<br />
<br />
Verify that secure boot now has an owner GUID and setup mode is disabled.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✔ Sbctl is installed<br />
Owner GUID: a2ee3d08-725a-408b-9d95-28026a44611c<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
Now reboot. This reboot is required so we can get the TPM measurements into their (hopefully) permanent state.<br />
<br />
=== Enroll LUKS key in TPM ===<br />
{{warning|Yes, this will cause a system to automatically unlock it's encrypted root volume without any interaction from a human. Yes, this exposes it to any sufficently advanced Evil Maid attacks. If sealed against the appropriate registers (especially register 8 with the kernel arguments), the TPM measurements should force systemd to ask for your LUKS passphrase in almost any attempt to access the encrypted volume from outside your normal boot process.}}<br />
<br />
We are fortunate that in our shift to dracut includes utilizing systemd and sd-encrypt, as we can use systemd's native support for enrolling LUKS keys. A review of [[Trusted Platform Module#Using TPM 2.0]] is recommended but not very clear.<br />
<br />
First, be sure to install {{Pkg|tpm2-tools}}. Alternatively {{aur|ibm-tss}} can be used per [[Trusted Platform Module]], however this guide is not tested against those.<br />
<br />
{{note|A reboot may be required to convince {{ic|systemd-cryptenroll}} that TPM 2.0 devices now exist on the machine.}}<br />
<br />
There are several decisions to be made here. The table at [[Trusted Platform Module#Accessing PCR registers]] is accurate as of October 2021. Essentially, once you seal your LUKS key, if any of the registers you've sealed against change, then you will be asked for your LUKS passphrase. This is equivalent to when Windows 10 makes you enter your BitLocker recovery key after a hardware change or changing BIOS settings.<br />
<br />
Your mileage may vary, based on UEFI vendors. For my laptop, I went with 0+1+2+3+4+5+7+8 and have been able to invalidate my TPM. Unfortunately, if you change your system BACK the volume will unlock. I'm investigating how to disable that.<br />
<br />
Other options on {{man|1|systemd-cryptenroll}} will reveal that several hardware tokens can also be enrolled to allow unlocking the root LUKS volume automatically, but only if a key is present. Further testing is requried.<br />
<br />
To enroll your LUKS volume, simply run the following command as root<br />
<br />
# systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/nvme0n1p2<br />
<br />
To remove your key, run this command:<br />
<br />
# systemd-cryptenroll --wipe-slot=tpm2 /dev/nvme0n1p2<br />
<br />
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:<br />
<br />
{{hc|~/bin/luks_reenroll_tpm|2=<br />
sudo systemd-cryptenroll --wipe-slot=tpm2 /dev/disk/by-uuid/{UUID_HERE}<br />
systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/disk/by-uuid/{UUID_HERE}<br />
}}<br />
<br />
== Justifications ==<br />
<br />
=== LVM on LUKS vs other dm-crypt approaches ===<br />
<br />
LVM on LUKS was selected becasue it is simply the easiest to manage while conferring both encrypted swap and disk. The other approaches required much more tooling and manual fussing to utilize. This selection also gives room change freely between {{ic|busybox}} and {{ic|systemd}} initrds.<br />
<br />
=== Using dracut ===<br />
<br />
{{Pkg|dracut}} just makes it easier to build full unified kernels that {{man|7|systemd-boot}} can launch as EFI binaries. There is also available tooling in the [[AUR]] for automating the creation of these binaries. Finally, {{ic|dracut}} will sign the binaries it creates automatically when configured to do so.<br />
<br />
=== Unified kernel images ===<br />
<br />
While UKI's could be problematic on other distributions, they fit right in with an Arch Linux install. The automation is there through pacman hooks and {{Pkg|sbctl}} to sign our UKIs as they're created. Furthermore, you can only sign and create a new signed UKI while booted into a properly signed UKI. It creates a chain of trust, which means it's important to never disable Secure Boot once you've set it up.<br />
<br />
The UKI encompasses all of the following items inside the signature, which means you can't change any of them without invalidating the signature.<br />
<br />
* Kernel arguments<br />
* Initrd/Initramfs<br />
* Kernel<br />
<br />
In particular, all other flavors of secureboot do not sign or validate the initramfs. This is a big attack area and can be relatively trivialized that a semi-decent pawn shop owner with Google could likely find an image that would grant him access and make the TPM none the wiser the system has changed. One can prevent this with encrypted /boot, but that would limit you to GRUB2 and LUKS version 1 devices only. This also doesn't include the work to keep GRUB2's files signed with a PGP key by root.<br />
<br />
== Miscellaneous discussions ==<br />
<br />
=== Filesystem Selection ===<br />
<br />
Most examples on Arch utilize {{ic|ext4}}, but other file systems such as {{ic|brtfs}} can work equally well. As for performance or issues with being inside LVM, [https://btrfs.wiki.kernel.org/index.php/FAQ#Btrfs_has_subvolumes.2C_does_this_mean_I_don.27t_need_a_logical_volume_manager_and_I_can_create_a_big_Btrfs_filesystem_on_a_raw_partition.3F this question in the brtfs FAQ] implie that there is some performance loss but no other issues.<br />
<br />
=== LUKS TPM enrollment and managing luks keys ===<br />
<br />
Note that using {{man|1|systemd-cryptenroll}} will add a key to your LUKS volume. It's not clear how exactly the option {{ic|1=--wipe-slot=tpm2}} is able to identify which slot it needs to wipe, but it does. This even works if your TPM has changed.<br />
<br />
You can see the effects by comparing the output of {{ic|cryptsetup luksDump /dev/nvme0n1p2}} before and after you enroll or wipe a TPM based key. You can identify what slot your own passphrase is in with {{ic|cryptsetup --verbose open --test-passphrase /dev/nvme0n1p2}} and entering your passphrase. The output will inform you which key slot was unlocked.<br />
<br />
Finally, your passphrase may be changed with {{ic|cryptsetup luksChangeKey /dev/nvme0n1p2 -S 0}}.<br />
<br />
== Planned TODOs ==<br />
A panic command that can dump the TPM and shutdown the computer (without requiring the time of entering a password in sudo) forcing an adversary to resort to [https://en.wikipedia.org/wiki/Rubber-hose_cryptanalysis rubber-hose cryptanalysis] to get to the encrypted data.</div>Krinhttps://wiki.archlinux.org/index.php?title=User:Krin/Secure_Boot,_full_disk_encryption,_and_TPM2_unlocking_install&diff=697922User:Krin/Secure Boot, full disk encryption, and TPM2 unlocking install2021-10-01T00:27:18Z<p>Krin: /* Secure boot */ Restructure to support Windows Dual Boot documentation upcoming.</p>
<hr />
<div>{{Unsupported|30 September 2021}}<br />
{{Expansion|Work In Progress, Draft from Installation Notes, Needs Testing}}<br />
<br />
== Introduction ==<br />
<br />
This installation is based on my installing Arch on an Asus ROG Strix G G531 I got second hand and a desktop computer made of second hand parts that had to share space with Windows. The primary goals were to replace Windows 10 Pro with Bitlocker encryption and maintain the convienence and security balance of that original operating system.<br />
<br />
My requirements boiled down to:<br />
<br />
* A fully encrypted disk<br />
* Full Secure Boot validation of all UEFI components.<br />
* Use of the TPM to facilitate unlocking of the disk.<br />
* Hibernate/Suspend working.<br />
<br />
My primary use case here is to make it difficult enough for a baggage handler with sticky hands to get at my data that they just wipe the drive. A state level actor with the expertise and equipment to hot swap my ram in my hotel room is not something that I'm defending this ''particular'' laptop against. This is more for gaming and web browsing and uploading photos while traveling.<br />
<br />
I'll continue to update these notes as I develop further solutions.<br />
<br />
== Disclaimers ==<br />
<br />
This article is primarily for the author's own notes. It is assumed that the reader is familiar with the [[Installation guide]] and will refer to it often. Reading linked articles is recommended.<br />
<br />
== Dual Booting Modifications ==<br />
<br />
For computers that will have to dual boot with windows, the easiest solution is to use two different physical drives and utilize your motherboard's UEFI boot menu to select which one to boot. This guide will follow that assumption. You can also attempt to have everything live on one EFI partition. Windows's 100 MiB EFI partition is especially problematic to this approach for secure boot, as Unified Kernel Images can approach 80 MiB and Windows 10 regularly uses up to 30 MiB.<br />
<br />
There are two changes that will be made and will be noted in the relevant sections:<br />
<br />
* Do not clear your Secure Boot keys. Merely disable Secure Boot for the installation.<br />
* Use {{ic|shim}} to boot systemd-bootloader<br />
* Load your db.cer file into the MOKManager application.<br />
<br />
All remaining steps should remain the same, except your system will still be dependent on the factory provided Microsoft Certificates. But you can boot Windows 10 in Secure Boot, which will be important for Windows 11.<br />
<br />
== Initial setup ==<br />
<br />
=== Pre-installation ===<br />
<br />
If you will only boot linux, reset your Secure Boot settings in BIOS to enable setup mode. Usually this means you set Secure Boot to Enabled and then select the option to wipe out the keys.<br />
<br />
If you will be dual booting Windows, disable secure boot.<br />
<br />
Follow the [[Installation_guide#Pre-installation]] up to Paritioning the Disks.<br />
<br />
=== Disk preparation ===<br />
<br />
If you have data on your disks you want to overwrite, utilize [[Dm-crypt/Drive_preparation#dm-crypt_wipe_on_an_empty_disk_or_partition]] to wipe it. If this disk was previously encrypted, utilize [[Dm-crypt/Drive_preparation#Wipe_LUKS_header]] instead for a much faster disposal. Finally, use [[Dm-crypt/Encrypting_an_entire_system#LVM_on_LUKS]] to parition your drive with two differences.<br />
<br />
{{tip|Using a memorable LUKS passphrase until you've completed the install process can be helpful. It will take several reboots to finish setup.}}<br />
<br />
First, the partition layout will be similar to here. You may wish to break out the /home directory into it's own partition. The primary requirement is that only your EFI partition be unencrypted.<br />
<br />
{{hc|Partiton Layout|<br />
┌────────────────────┬──────────────────────────┬─────────────────────────────┐<br />
│ │ │ │<br />
│ EFI Boot Partition │ Logical Volume 1 │ Logical Volume 2 │<br />
│ │ │ │<br />
│ /efi │ [SWAP] │ / │<br />
│ │ │ │<br />
│ /dev/nvme0n1p1 │ /dev/CryptRootVG/swap │ /dev/CryptRootVG/root │<br />
│ │ │ │<br />
│ 512 MB │ 16 GB (Or RAM size) │ Remaining Free Space │<br />
│ │ │ │<br />
│ │ │ │<br />
│ ├──────────────────────────┴─────────────────────────────┤<br />
│ │ │<br />
│ │ LUKS and LVM Physical Volume │<br />
│ │ │<br />
│ │ /dev/nvme0n1p2 │<br />
│ │ │<br />
└────────────────────┴────────────────────────────────────────────────────────┘<br />
}}<br />
<br />
Second, if your hard drive is an SSD like this laptop, use the following command to open your LUKS volume.<br />
<br />
# cryptsetup open --perf-no_read_workqueue --perf-no_write_workqueue --persistent /dev/nvme0n1p2 cryptroot<br />
<br />
After completing your LUKS on LVM setup, format your EFI partition per [[EFI system partition]].<br />
<br />
# mkfs ext.vfat -F32 /dev/nvme0n1p2<br />
<br />
Mount this partition at {{ic|/mnt/efi}}. It is very important to leave {{ic|/boot}} on your encrypted root partition.<br />
<br />
== Installation ==<br />
<br />
Continue with [[Installation_guide#Installation]]. Be sure to flesh out your {{man|8|pacstrap}} with the following list of packages:<br />
<br />
* {{Pkg|dracut}}<br />
* {{Pkg|intel-ucode}}<br />
* {{Pkg|lvm2}}<br />
* {{Pkg|openssh}}<br />
* {{Pkg|ansible}}<br />
* {{Pkg|git}}<br />
* {{Pkg|iwd}}<br />
* {{Pkg|efibootmgr}}<br />
<br />
<br />
We are going to leave off the installation guide at the initramfs section, so go ahead and reset your root password. <br />
<br />
# passwd<br />
<br />
=== Bootloader ===<br />
<br />
{{warning|This section needs testing.}}<br />
<br />
First, install {{ic|systemd-boot}} by following [[Systemd-boot#Installing_the_EFI_boot_manager]]. Next, install {{aur|dracut-hook-uefi}}.<br />
<br />
Ensure you drop in a systemd-boot hook to update your bootctl any time it's updated.<br />
<br />
{{hc|/etc/pacman.d/hooks/998-systemd-boot.hook|2=<br />
[Trigger]<br />
Type = Package<br />
Operation = Install<br />
Operation = Upgrade<br />
Target = systemd<br />
<br />
[Action]<br />
Description = Updating systemd-boot<br />
When = PostTransation<br />
Exec = /usr/bin/bootctl update; <br />
}}<br />
<br />
Obtain the UUID of your LUKS drive via the following command:<br />
<br />
{{bc|<br />
blkid -s UUID -o value /dev/nvme0n1p2<br />
}}<br />
<br />
Create the following files with the listed content. Be sure to replace UUIDs with what you actually need. The extraneous {{ic:rd.luks.options}} should not cause an issue, but will be used once we've enabled secure boot. See {{man|5|dracut.conf}} for more information on what these commands do.<br />
<br />
A good portion of the kernel command line was as generated by dracut. Many are extraneous or you may wish to change some of the block device names.<br />
<br />
{{hc|/etc/dracut.conf.d/cmdline.conf|2=<br />
kernel_cmdline="rd.luks.uuid=luks-17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02 rd.luks.options=17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02 rd.lvm.lv=CryptRoot/root rd.lvm.lv=CryptRoot/swap resume=/dev/mapper/CryptRoot-swap root=/dev/mapper/CryptRoot-root rootfstype=ext4 rootflags=rw,relatime"<br />
}}<br />
<br />
{{hc|/etc/dracut.conf.d/flags.conf|2=<br />
compress="zstd"<br />
hostonly="yes"<br />
}}<br />
<br />
Run the following command to generate your EFI stub kernels.<br />
<br />
dracut --uefi<br />
<br />
=== Secure boot ===<br />
<br />
==== Dual Booting Windows ====<br />
<br />
==== Booting only Linux ====<br />
<br />
{{note|The very newly developed [https://github.com/Foxboron/sbctl sbctl], availble via {{aur|sbctl-git}} has completely revamped this process and will only get better as they approach 1.0. From here on out, as of October 2021, this process should greatly simplify.}}<br />
<br />
{{note|Credit to this [https://lunaryorn.com/secure-boot-on-arch-linux-with-sbctl-and-dracut blog post by lunaryorn] for the inspiration.}}<br />
<br />
Install {{Pkg|sbctl}}. At this point you will likely need to reboot and adjust your secure boot settings. You want secure boot in '''setup mode'''. <br />
<br />
{{bc|<br />
$ sbctl status<br />
Installed: X Sbctl is not installed<br />
Setup Mode: X Enabled<br />
Secure Boot: X Disabled<br />
}}<br />
<br />
Run the following commands as root. See {{man|8|sbctl}} for more information on their function. Of particular note is the {{ic|-s}} flag which indicates {{ic|sbctl}} should remember the file for future verification and signing.<br />
<br />
Note your Linux EFI binary name may be slightly different.<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
<br />
# sbctl sign -s /efi/EFI/BOOT/BOOTx64.EFI<br />
✔ Signed /efi/EFI/BOOT/BOOTx64.EFI<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Finally, enroll the Secure Boot keys.<br />
<br />
{{bc|<br />
# sbctl enroll-keys<br />
Enrolling keys to EFI variables...✔<br />
Enrolled keys to the EFI variables!<br />
}}<br />
<br />
Verify that secure boot now has an owner GUID and setup mode is disabled.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✔ Sbctl is installed<br />
Owner GUID: a2ee3d08-725a-408b-9d95-28026a44611c<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
Now reboot. This reboot is required so we can get the TPM measurements into their (hopefully) permanent state.<br />
<br />
=== Enroll LUKS key in TPM ===<br />
{{warning|Yes, this will cause a system to automatically unlock it's encrypted root volume without any interaction from a human. Yes, this exposes it to any sufficently advanced Evil Maid attacks. If sealed against the appropriate registers (especially register 8 with the kernel arguments), the TPM measurements should force systemd to ask for your LUKS passphrase in almost any attempt to access the encrypted volume from outside your normal boot process.}}<br />
<br />
We are fortunate that in our shift to dracut includes utilizing systemd and sd-encrypt, as we can use systemd's native support for enrolling LUKS keys. A review of [[Trusted Platform Module#Using TPM 2.0]] is recommended but not very clear.<br />
<br />
First, be sure to install {{Pkg|tpm2-tools}}. Alternatively {{aur|ibm-tss}} can be used per [[Trusted Platform Module]], however this guide is not tested against those.<br />
<br />
{{note|A reboot may be required to convince {{ic|systemd-cryptenroll}} that TPM 2.0 devices now exist on the machine.}}<br />
<br />
There are several decisions to be made here. The table at [[Trusted Platform Module#Accessing PCR registers]] is accurate as of October 2021. Essentially, once you seal your LUKS key, if any of the registers you've sealed against change, then you will be asked for your LUKS passphrase. This is equivalent to when Windows 10 makes you enter your BitLocker recovery key after a hardware change or changing BIOS settings.<br />
<br />
Your mileage may vary, based on UEFI vendors. For my laptop, I went with 0+1+2+3+4+5+7+8 and have been able to invalidate my TPM. Unfortunately, if you change your system BACK the volume will unlock. I'm investigating how to disable that.<br />
<br />
Other options on {{man|1|systemd-cryptenroll}} will reveal that several hardware tokens can also be enrolled to allow unlocking the root LUKS volume automatically, but only if a key is present. Further testing is requried.<br />
<br />
To enroll your LUKS volume, simply run the following command as root<br />
<br />
# systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/nvme0n1p2<br />
<br />
To remove your key, run this command:<br />
<br />
# systemd-cryptenroll --wipe-slot=tpm2 /dev/nvme0n1p2<br />
<br />
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:<br />
<br />
{{hc|~/bin/luks_reenroll_tpm|2=<br />
sudo systemd-cryptenroll --wipe-slot=tpm2 /dev/disk/by-uuid/{UUID_HERE}<br />
systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/disk/by-uuid/{UUID_HERE}<br />
}}<br />
<br />
== Justifications ==<br />
<br />
=== LVM on LUKS vs other dm-crypt approaches ===<br />
<br />
LVM on LUKS was selected becasue it is simply the easiest to manage while conferring both encrypted swap and disk. The other approaches required much more tooling and manual fussing to utilize. This selection also gives room change freely between {{ic|busybox}} and {{ic|systemd}} initrds.<br />
<br />
=== Using dracut ===<br />
<br />
{{Pkg|dracut}} just makes it easier to build full unified kernels that {{man|7|systemd-boot}} can launch as EFI binaries. There is also available tooling in the [[AUR]] for automating the creation of these binaries. Finally, {{ic|dracut}} will sign the binaries it creates automatically when configured to do so.<br />
<br />
=== Unified kernel images ===<br />
<br />
While UKI's could be problematic on other distributions, they fit right in with an Arch Linux install. The automation is there through pacman hooks and {{Pkg|sbctl}} to sign our UKIs as they're created. Furthermore, you can only sign and create a new signed UKI while booted into a properly signed UKI. It creates a chain of trust, which means it's important to never disable Secure Boot once you've set it up.<br />
<br />
The UKI encompasses all of the following items inside the signature, which means you can't change any of them without invalidating the signature.<br />
<br />
* Kernel arguments<br />
* Initrd/Initramfs<br />
* Kernel<br />
<br />
In particular, all other flavors of secureboot do not sign or validate the initramfs. This is a big attack area and can be relatively trivialized that a semi-decent pawn shop owner with Google could likely find an image that would grant him access and make the TPM none the wiser the system has changed. One can prevent this with encrypted /boot, but that would limit you to GRUB2 and LUKS version 1 devices only. This also doesn't include the work to keep GRUB2's files signed with a PGP key by root.<br />
<br />
== Miscellaneous discussions ==<br />
<br />
=== Filesystem Selection ===<br />
<br />
Most examples on Arch utilize {{ic|ext4}}, but other file systems such as {{ic|brtfs}} can work equally well. As for performance or issues with being inside LVM, [https://btrfs.wiki.kernel.org/index.php/FAQ#Btrfs_has_subvolumes.2C_does_this_mean_I_don.27t_need_a_logical_volume_manager_and_I_can_create_a_big_Btrfs_filesystem_on_a_raw_partition.3F this question in the brtfs FAQ] implie that there is some performance loss but no other issues.<br />
<br />
=== LUKS TPM enrollment and managing luks keys ===<br />
<br />
Note that using {{man|1|systemd-cryptenroll}} will add a key to your LUKS volume. It's not clear how exactly the option {{ic|1=--wipe-slot=tpm2}} is able to identify which slot it needs to wipe, but it does. This even works if your TPM has changed.<br />
<br />
You can see the effects by comparing the output of {{ic|cryptsetup luksDump /dev/nvme0n1p2}} before and after you enroll or wipe a TPM based key. You can identify what slot your own passphrase is in with {{ic|cryptsetup --verbose open --test-passphrase /dev/nvme0n1p2}} and entering your passphrase. The output will inform you which key slot was unlocked.<br />
<br />
Finally, your passphrase may be changed with {{ic|cryptsetup luksChangeKey /dev/nvme0n1p2 -S 0}}.<br />
<br />
== Planned TODOs ==<br />
A panic command that can dump the TPM and shutdown the computer (without requiring the time of entering a password in sudo) forcing an adversary to resort to [https://en.wikipedia.org/wiki/Rubber-hose_cryptanalysis rubber-hose cryptanalysis] to get to the encrypted data.</div>Krinhttps://wiki.archlinux.org/index.php?title=User:Krin/Secure_Boot,_full_disk_encryption,_and_TPM2_unlocking_install&diff=697921User:Krin/Secure Boot, full disk encryption, and TPM2 unlocking install2021-10-01T00:14:18Z<p>Krin: Add dual boot differences.</p>
<hr />
<div>{{Unsupported|30 September 2021}}<br />
{{Expansion|Work In Progress, Draft from Installation Notes, Needs Testing}}<br />
<br />
== Introduction ==<br />
<br />
This installation is based on my installing Arch on an Asus ROG Strix G G531 I got second hand and a desktop computer made of second hand parts that had to share space with Windows. The primary goals were to replace Windows 10 Pro with Bitlocker encryption and maintain the convienence and security balance of that original operating system.<br />
<br />
My requirements boiled down to:<br />
<br />
* A fully encrypted disk<br />
* Full Secure Boot validation of all UEFI components.<br />
* Use of the TPM to facilitate unlocking of the disk.<br />
* Hibernate/Suspend working.<br />
<br />
My primary use case here is to make it difficult enough for a baggage handler with sticky hands to get at my data that they just wipe the drive. A state level actor with the expertise and equipment to hot swap my ram in my hotel room is not something that I'm defending this ''particular'' laptop against. This is more for gaming and web browsing and uploading photos while traveling.<br />
<br />
I'll continue to update these notes as I develop further solutions.<br />
<br />
== Disclaimers ==<br />
<br />
This article is primarily for the author's own notes. It is assumed that the reader is familiar with the [[Installation guide]] and will refer to it often. Reading linked articles is recommended.<br />
<br />
== Dual Booting Modifications ==<br />
<br />
For computers that will have to dual boot with windows, the easiest solution is to use two different physical drives and utilize your motherboard's UEFI boot menu to select which one to boot. This guide will follow that assumption. You can also attempt to have everything live on one EFI partition. Windows's 100 MiB EFI partition is especially problematic to this approach for secure boot, as Unified Kernel Images can approach 80 MiB and Windows 10 regularly uses up to 30 MiB.<br />
<br />
There are two changes that will be made and will be noted in the relevant sections:<br />
<br />
* Do not clear your Secure Boot keys. Merely disable Secure Boot for the installation.<br />
* Use {{ic|shim}} to boot systemd-bootloader<br />
* Load your db.cer file into the MOKManager application.<br />
<br />
All remaining steps should remain the same, except your system will still be dependent on the factory provided Microsoft Certificates. But you can boot Windows 10 in Secure Boot, which will be important for Windows 11.<br />
<br />
== Initial setup ==<br />
<br />
=== Pre-installation ===<br />
<br />
If you will only boot linux, reset your Secure Boot settings in BIOS to enable setup mode. Usually this means you set Secure Boot to Enabled and then select the option to wipe out the keys.<br />
<br />
If you will be dual booting Windows, disable secure boot.<br />
<br />
Follow the [[Installation_guide#Pre-installation]] up to Paritioning the Disks.<br />
<br />
=== Disk preparation ===<br />
<br />
If you have data on your disks you want to overwrite, utilize [[Dm-crypt/Drive_preparation#dm-crypt_wipe_on_an_empty_disk_or_partition]] to wipe it. If this disk was previously encrypted, utilize [[Dm-crypt/Drive_preparation#Wipe_LUKS_header]] instead for a much faster disposal. Finally, use [[Dm-crypt/Encrypting_an_entire_system#LVM_on_LUKS]] to parition your drive with two differences.<br />
<br />
{{tip|Using a memorable LUKS passphrase until you've completed the install process can be helpful. It will take several reboots to finish setup.}}<br />
<br />
First, the partition layout will be similar to here. You may wish to break out the /home directory into it's own partition. The primary requirement is that only your EFI partition be unencrypted.<br />
<br />
{{hc|Partiton Layout|<br />
┌────────────────────┬──────────────────────────┬─────────────────────────────┐<br />
│ │ │ │<br />
│ EFI Boot Partition │ Logical Volume 1 │ Logical Volume 2 │<br />
│ │ │ │<br />
│ /efi │ [SWAP] │ / │<br />
│ │ │ │<br />
│ /dev/nvme0n1p1 │ /dev/CryptRootVG/swap │ /dev/CryptRootVG/root │<br />
│ │ │ │<br />
│ 512 MB │ 16 GB (Or RAM size) │ Remaining Free Space │<br />
│ │ │ │<br />
│ │ │ │<br />
│ ├──────────────────────────┴─────────────────────────────┤<br />
│ │ │<br />
│ │ LUKS and LVM Physical Volume │<br />
│ │ │<br />
│ │ /dev/nvme0n1p2 │<br />
│ │ │<br />
└────────────────────┴────────────────────────────────────────────────────────┘<br />
}}<br />
<br />
Second, if your hard drive is an SSD like this laptop, use the following command to open your LUKS volume.<br />
<br />
# cryptsetup open --perf-no_read_workqueue --perf-no_write_workqueue --persistent /dev/nvme0n1p2 cryptroot<br />
<br />
After completing your LUKS on LVM setup, format your EFI partition per [[EFI system partition]].<br />
<br />
# mkfs ext.vfat -F32 /dev/nvme0n1p2<br />
<br />
Mount this partition at {{ic|/mnt/efi}}. It is very important to leave {{ic|/boot}} on your encrypted root partition.<br />
<br />
== Installation ==<br />
<br />
Continue with [[Installation_guide#Installation]]. Be sure to flesh out your {{man|8|pacstrap}} with the following list of packages:<br />
<br />
* {{Pkg|dracut}}<br />
* {{Pkg|intel-ucode}}<br />
* {{Pkg|lvm2}}<br />
* {{Pkg|openssh}}<br />
* {{Pkg|ansible}}<br />
* {{Pkg|git}}<br />
* {{Pkg|iwd}}<br />
* {{Pkg|efibootmgr}}<br />
<br />
<br />
We are going to leave off the installation guide at the initramfs section, so go ahead and reset your root password. <br />
<br />
# passwd<br />
<br />
=== Bootloader ===<br />
<br />
{{warning|This section needs testing.}}<br />
<br />
First, install {{ic|systemd-boot}} by following [[Systemd-boot#Installing_the_EFI_boot_manager]]. Next, install {{aur|dracut-hook-uefi}}.<br />
<br />
Ensure you drop in a systemd-boot hook to update your bootctl any time it's updated.<br />
<br />
{{hc|/etc/pacman.d/hooks/998-systemd-boot.hook|2=<br />
[Trigger]<br />
Type = Package<br />
Operation = Install<br />
Operation = Upgrade<br />
Target = systemd<br />
<br />
[Action]<br />
Description = Updating systemd-boot<br />
When = PostTransation<br />
Exec = /usr/bin/bootctl update; <br />
}}<br />
<br />
Obtain the UUID of your LUKS drive via the following command:<br />
<br />
{{bc|<br />
blkid -s UUID -o value /dev/nvme0n1p2<br />
}}<br />
<br />
Create the following files with the listed content. Be sure to replace UUIDs with what you actually need. The extraneous {{ic:rd.luks.options}} should not cause an issue, but will be used once we've enabled secure boot. See {{man|5|dracut.conf}} for more information on what these commands do.<br />
<br />
A good portion of the kernel command line was as generated by dracut. Many are extraneous or you may wish to change some of the block device names.<br />
<br />
{{hc|/etc/dracut.conf.d/cmdline.conf|2=<br />
kernel_cmdline="rd.luks.uuid=luks-17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02 rd.luks.options=17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02 rd.lvm.lv=CryptRoot/root rd.lvm.lv=CryptRoot/swap resume=/dev/mapper/CryptRoot-swap root=/dev/mapper/CryptRoot-root rootfstype=ext4 rootflags=rw,relatime"<br />
}}<br />
<br />
{{hc|/etc/dracut.conf.d/flags.conf|2=<br />
compress="zstd"<br />
hostonly="yes"<br />
}}<br />
<br />
Run the following command to generate your EFI stub kernels.<br />
<br />
dracut --uefi<br />
<br />
=== Secure boot ===<br />
<br />
{{note|The very newly developed [https://github.com/Foxboron/sbctl sbctl], availble via {{aur|sbctl-git}} has completely revamped this process and will only get better as they approach 1.0. From here on out, as of October 2021, this process should greatly simplify.}}<br />
<br />
{{note|Credit to this [https://lunaryorn.com/secure-boot-on-arch-linux-with-sbctl-and-dracut blog post by lunaryorn] for the inspiration.}}<br />
<br />
{{warning|This section is INCOMPLETE untested.}}<br />
<br />
Install {{Pkg|sbctl}}. At this point you will likely need to reboot and adjust your secure boot settings. You want secure boot in '''setup mode'''. <br />
<br />
{{bc|<br />
$ sbctl status<br />
Installed: X Sbctl is not installed<br />
Setup Mode: X Enabled<br />
Secure Boot: X Disabled<br />
}}<br />
<br />
Run the following commands as root. See {{man|8|sbctl}} for more information on their function. Of particular note is the {{ic|-s}} flag which indicates {{ic|sbctl}} should remember the file for future verification and signing.<br />
<br />
Note your Linux EFI binary name may be slightly different.<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
<br />
# sbctl sign -s /efi/EFI/BOOT/BOOTx64.EFI<br />
✔ Signed /efi/EFI/BOOT/BOOTx64.EFI<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Finally, enroll the Secure Boot keys.<br />
<br />
{{bc|<br />
# sbctl enroll-keys<br />
Enrolling keys to EFI variables...✔<br />
Enrolled keys to the EFI variables!<br />
}}<br />
<br />
Verify that secure boot now has an owner GUID and setup mode is disabled.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✔ Sbctl is installed<br />
Owner GUID: a2ee3d08-725a-408b-9d95-28026a44611c<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
Now reboot. This reboot is required so we can get the TPM measurements into their (hopefully) permanent state.<br />
<br />
=== Enroll LUKS key in TPM ===<br />
{{warning|Yes, this will cause a system to automatically unlock it's encrypted root volume without any interaction from a human. Yes, this exposes it to any sufficently advanced Evil Maid attacks. If sealed against the appropriate registers (especially register 8 with the kernel arguments), the TPM measurements should force systemd to ask for your LUKS passphrase in almost any attempt to access the encrypted volume from outside your normal boot process.}}<br />
<br />
We are fortunate that in our shift to dracut includes utilizing systemd and sd-encrypt, as we can use systemd's native support for enrolling LUKS keys. A review of [[Trusted Platform Module#Using TPM 2.0]] is recommended but not very clear.<br />
<br />
First, be sure to install {{Pkg|tpm2-tools}}. Alternatively {{aur|ibm-tss}} can be used per [[Trusted Platform Module]], however this guide is not tested against those.<br />
<br />
{{note|A reboot may be required to convince {{ic|systemd-cryptenroll}} that TPM 2.0 devices now exist on the machine.}}<br />
<br />
There are several decisions to be made here. The table at [[Trusted Platform Module#Accessing PCR registers]] is accurate as of October 2021. Essentially, once you seal your LUKS key, if any of the registers you've sealed against change, then you will be asked for your LUKS passphrase. This is equivalent to when Windows 10 makes you enter your BitLocker recovery key after a hardware change or changing BIOS settings.<br />
<br />
Your mileage may vary, based on UEFI vendors. For my laptop, I went with 0+1+2+3+4+5+7+8 and have been able to invalidate my TPM. Unfortunately, if you change your system BACK the volume will unlock. I'm investigating how to disable that.<br />
<br />
Other options on {{man|1|systemd-cryptenroll}} will reveal that several hardware tokens can also be enrolled to allow unlocking the root LUKS volume automatically, but only if a key is present. Further testing is requried.<br />
<br />
To enroll your LUKS volume, simply run the following command as root<br />
<br />
# systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/nvme0n1p2<br />
<br />
To remove your key, run this command:<br />
<br />
# systemd-cryptenroll --wipe-slot=tpm2 /dev/nvme0n1p2<br />
<br />
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:<br />
<br />
{{hc|~/bin/luks_reenroll_tpm|2=<br />
sudo systemd-cryptenroll --wipe-slot=tpm2 /dev/disk/by-uuid/{UUID_HERE}<br />
systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/disk/by-uuid/{UUID_HERE}<br />
}}<br />
<br />
== Justifications ==<br />
<br />
=== LVM on LUKS vs other dm-crypt approaches ===<br />
<br />
LVM on LUKS was selected becasue it is simply the easiest to manage while conferring both encrypted swap and disk. The other approaches required much more tooling and manual fussing to utilize. This selection also gives room change freely between {{ic|busybox}} and {{ic|systemd}} initrds.<br />
<br />
=== Using dracut ===<br />
<br />
{{Pkg|dracut}} just makes it easier to build full unified kernels that {{man|7|systemd-boot}} can launch as EFI binaries. There is also available tooling in the [[AUR]] for automating the creation of these binaries. Finally, {{ic|dracut}} will sign the binaries it creates automatically when configured to do so.<br />
<br />
=== Unified kernel images ===<br />
<br />
While UKI's could be problematic on other distributions, they fit right in with an Arch Linux install. The automation is there through pacman hooks and {{Pkg|sbctl}} to sign our UKIs as they're created. Furthermore, you can only sign and create a new signed UKI while booted into a properly signed UKI. It creates a chain of trust, which means it's important to never disable Secure Boot once you've set it up.<br />
<br />
The UKI encompasses all of the following items inside the signature, which means you can't change any of them without invalidating the signature.<br />
<br />
* Kernel arguments<br />
* Initrd/Initramfs<br />
* Kernel<br />
<br />
In particular, all other flavors of secureboot do not sign or validate the initramfs. This is a big attack area and can be relatively trivialized that a semi-decent pawn shop owner with Google could likely find an image that would grant him access and make the TPM none the wiser the system has changed. One can prevent this with encrypted /boot, but that would limit you to GRUB2 and LUKS version 1 devices only. This also doesn't include the work to keep GRUB2's files signed with a PGP key by root.<br />
<br />
== Miscellaneous discussions ==<br />
<br />
=== Filesystem Selection ===<br />
<br />
Most examples on Arch utilize {{ic|ext4}}, but other file systems such as {{ic|brtfs}} can work equally well. As for performance or issues with being inside LVM, [https://btrfs.wiki.kernel.org/index.php/FAQ#Btrfs_has_subvolumes.2C_does_this_mean_I_don.27t_need_a_logical_volume_manager_and_I_can_create_a_big_Btrfs_filesystem_on_a_raw_partition.3F this question in the brtfs FAQ] implie that there is some performance loss but no other issues.<br />
<br />
=== LUKS TPM enrollment and managing luks keys ===<br />
<br />
Note that using {{man|1|systemd-cryptenroll}} will add a key to your LUKS volume. It's not clear how exactly the option {{ic|1=--wipe-slot=tpm2}} is able to identify which slot it needs to wipe, but it does. This even works if your TPM has changed.<br />
<br />
You can see the effects by comparing the output of {{ic|cryptsetup luksDump /dev/nvme0n1p2}} before and after you enroll or wipe a TPM based key. You can identify what slot your own passphrase is in with {{ic|cryptsetup --verbose open --test-passphrase /dev/nvme0n1p2}} and entering your passphrase. The output will inform you which key slot was unlocked.<br />
<br />
Finally, your passphrase may be changed with {{ic|cryptsetup luksChangeKey /dev/nvme0n1p2 -S 0}}.<br />
<br />
== Planned TODOs ==<br />
A panic command that can dump the TPM and shutdown the computer (without requiring the time of entering a password in sudo) forcing an adversary to resort to [https://en.wikipedia.org/wiki/Rubber-hose_cryptanalysis rubber-hose cryptanalysis] to get to the encrypted data.</div>Krinhttps://wiki.archlinux.org/index.php?title=User:Krin/Secure_Boot,_full_disk_encryption,_and_TPM2_unlocking_install&diff=697920User:Krin/Secure Boot, full disk encryption, and TPM2 unlocking install2021-10-01T00:13:18Z<p>Krin: Beginning to mark dual boot windows differences</p>
<hr />
<div>{{Unsupported|30 September 2021}}<br />
{{Expansion|Work In Progress, Draft from Installation Notes, Needs Testing}}<br />
<br />
== Introduction ==<br />
<br />
This installation is based on my installing Arch on an Asus ROG Strix G G531 I got second hand and a desktop computer made of second hand parts that had to share space with Windows. The primary goals were to replace Windows 10 Pro with Bitlocker encryption and maintain the convienence and security balance of that original operating system.<br />
<br />
My requirements boiled down to:<br />
<br />
* A fully encrypted disk<br />
* Full Secure Boot validation of all UEFI components.<br />
* Use of the TPM to facilitate unlocking of the disk.<br />
* Hibernate/Suspend working.<br />
<br />
My primary use case here is to make it difficult enough for a baggage handler with sticky hands to get at my data that they just wipe the drive. A state level actor with the expertise and equipment to hot swap my ram in my hotel room is not something that I'm defending this ''particular'' laptop against. This is more for gaming and web browsing and uploading photos while traveling.<br />
<br />
I'll continue to update these notes as I develop further solutions.<br />
<br />
== Disclaimers ==<br />
<br />
This article is primarily for the author's own notes. It is assumed that the reader is familiar with the [[Installation guide]] and will refer to it often. Reading linked articles is recommended.<br />
<br />
== Dual Booting Modifications ==<br />
<br />
For computers that will have to dual boot with windows, the easiest solution is to use two different physical drives and utilize your motherboard's UEFI boot menu to select which one to boot. This guide will follow that assumption. You can also attempt to have everything live on one EFI partition. Windows's 100 MiB EFI partition is especially problematic to this approach for secure boot, as Unified Kernel Images can approach 80 MiB and Windows 10 regularly uses up to 30 MiB.<br />
<br />
There are two changes that will be made and will be noted in the relevant sections:<br />
<br />
* Do not clear your Secure Boot keys. Merely disable Secure Boot for the installation.<br />
* Use {{ic|shim}} to boot systemd-bootloader<br />
* Load your db.cer file into the MOKManager application.<br />
<br />
All remaining steps should remain the same, except your system will still be dependent on the factory provided Microsoft Certificates. But you can boot Windows 10 in Secure Boot, which will be important for Windows 11.<br />
<br />
== Initial setup ==<br />
<br />
=== Pre-installation ===<br />
<br />
Reset your Secure Boot settings in BIOS to enable setup mode. Usually this means you set Secure Boot to Enabled and then select the option to wipe out the keys.<br />
<br />
Follow the [[Installation_guide#Pre-installation]] up to Paritioning the Disks.<br />
<br />
=== Disk preparation ===<br />
<br />
If you have data on your disks you want to overwrite, utilize [[Dm-crypt/Drive_preparation#dm-crypt_wipe_on_an_empty_disk_or_partition]] to wipe it. If this disk was previously encrypted, utilize [[Dm-crypt/Drive_preparation#Wipe_LUKS_header]] instead for a much faster disposal. Finally, use [[Dm-crypt/Encrypting_an_entire_system#LVM_on_LUKS]] to parition your drive with two differences.<br />
<br />
{{tip|Using a memorable LUKS passphrase until you've completed the install process can be helpful. It will take several reboots to finish setup.}}<br />
<br />
First, the partition layout will be similar to here. You may wish to break out the /home directory into it's own partition. The primary requirement is that only your EFI partition be unencrypted.<br />
<br />
{{hc|Partiton Layout|<br />
┌────────────────────┬──────────────────────────┬─────────────────────────────┐<br />
│ │ │ │<br />
│ EFI Boot Partition │ Logical Volume 1 │ Logical Volume 2 │<br />
│ │ │ │<br />
│ /efi │ [SWAP] │ / │<br />
│ │ │ │<br />
│ /dev/nvme0n1p1 │ /dev/CryptRootVG/swap │ /dev/CryptRootVG/root │<br />
│ │ │ │<br />
│ 512 MB │ 16 GB (Or RAM size) │ Remaining Free Space │<br />
│ │ │ │<br />
│ │ │ │<br />
│ ├──────────────────────────┴─────────────────────────────┤<br />
│ │ │<br />
│ │ LUKS and LVM Physical Volume │<br />
│ │ │<br />
│ │ /dev/nvme0n1p2 │<br />
│ │ │<br />
└────────────────────┴────────────────────────────────────────────────────────┘<br />
}}<br />
<br />
Second, if your hard drive is an SSD like this laptop, use the following command to open your LUKS volume.<br />
<br />
# cryptsetup open --perf-no_read_workqueue --perf-no_write_workqueue --persistent /dev/nvme0n1p2 cryptroot<br />
<br />
After completing your LUKS on LVM setup, format your EFI partition per [[EFI system partition]].<br />
<br />
# mkfs ext.vfat -F32 /dev/nvme0n1p2<br />
<br />
Mount this partition at {{ic|/mnt/efi}}. It is very important to leave {{ic|/boot}} on your encrypted root partition.<br />
<br />
== Installation ==<br />
<br />
Continue with [[Installation_guide#Installation]]. Be sure to flesh out your {{man|8|pacstrap}} with the following list of packages:<br />
<br />
* {{Pkg|dracut}}<br />
* {{Pkg|intel-ucode}}<br />
* {{Pkg|lvm2}}<br />
* {{Pkg|openssh}}<br />
* {{Pkg|ansible}}<br />
* {{Pkg|git}}<br />
* {{Pkg|iwd}}<br />
* {{Pkg|efibootmgr}}<br />
<br />
<br />
We are going to leave off the installation guide at the initramfs section, so go ahead and reset your root password. <br />
<br />
# passwd<br />
<br />
=== Bootloader ===<br />
<br />
{{warning|This section needs testing.}}<br />
<br />
First, install {{ic|systemd-boot}} by following [[Systemd-boot#Installing_the_EFI_boot_manager]]. Next, install {{aur|dracut-hook-uefi}}.<br />
<br />
Ensure you drop in a systemd-boot hook to update your bootctl any time it's updated.<br />
<br />
{{hc|/etc/pacman.d/hooks/998-systemd-boot.hook|2=<br />
[Trigger]<br />
Type = Package<br />
Operation = Install<br />
Operation = Upgrade<br />
Target = systemd<br />
<br />
[Action]<br />
Description = Updating systemd-boot<br />
When = PostTransation<br />
Exec = /usr/bin/bootctl update; <br />
}}<br />
<br />
Obtain the UUID of your LUKS drive via the following command:<br />
<br />
{{bc|<br />
blkid -s UUID -o value /dev/nvme0n1p2<br />
}}<br />
<br />
Create the following files with the listed content. Be sure to replace UUIDs with what you actually need. The extraneous {{ic:rd.luks.options}} should not cause an issue, but will be used once we've enabled secure boot. See {{man|5|dracut.conf}} for more information on what these commands do.<br />
<br />
A good portion of the kernel command line was as generated by dracut. Many are extraneous or you may wish to change some of the block device names.<br />
<br />
{{hc|/etc/dracut.conf.d/cmdline.conf|2=<br />
kernel_cmdline="rd.luks.uuid=luks-17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02 rd.luks.options=17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02 rd.lvm.lv=CryptRoot/root rd.lvm.lv=CryptRoot/swap resume=/dev/mapper/CryptRoot-swap root=/dev/mapper/CryptRoot-root rootfstype=ext4 rootflags=rw,relatime"<br />
}}<br />
<br />
{{hc|/etc/dracut.conf.d/flags.conf|2=<br />
compress="zstd"<br />
hostonly="yes"<br />
}}<br />
<br />
Run the following command to generate your EFI stub kernels.<br />
<br />
dracut --uefi<br />
<br />
=== Secure boot ===<br />
<br />
{{note|The very newly developed [https://github.com/Foxboron/sbctl sbctl], availble via {{aur|sbctl-git}} has completely revamped this process and will only get better as they approach 1.0. From here on out, as of October 2021, this process should greatly simplify.}}<br />
<br />
{{note|Credit to this [https://lunaryorn.com/secure-boot-on-arch-linux-with-sbctl-and-dracut blog post by lunaryorn] for the inspiration.}}<br />
<br />
{{warning|This section is INCOMPLETE untested.}}<br />
<br />
Install {{Pkg|sbctl}}. At this point you will likely need to reboot and adjust your secure boot settings. You want secure boot in '''setup mode'''. <br />
<br />
{{bc|<br />
$ sbctl status<br />
Installed: X Sbctl is not installed<br />
Setup Mode: X Enabled<br />
Secure Boot: X Disabled<br />
}}<br />
<br />
Run the following commands as root. See {{man|8|sbctl}} for more information on their function. Of particular note is the {{ic|-s}} flag which indicates {{ic|sbctl}} should remember the file for future verification and signing.<br />
<br />
Note your Linux EFI binary name may be slightly different.<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
<br />
# sbctl sign -s /efi/EFI/BOOT/BOOTx64.EFI<br />
✔ Signed /efi/EFI/BOOT/BOOTx64.EFI<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Finally, enroll the Secure Boot keys.<br />
<br />
{{bc|<br />
# sbctl enroll-keys<br />
Enrolling keys to EFI variables...✔<br />
Enrolled keys to the EFI variables!<br />
}}<br />
<br />
Verify that secure boot now has an owner GUID and setup mode is disabled.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✔ Sbctl is installed<br />
Owner GUID: a2ee3d08-725a-408b-9d95-28026a44611c<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
Now reboot. This reboot is required so we can get the TPM measurements into their (hopefully) permanent state.<br />
<br />
=== Enroll LUKS key in TPM ===<br />
{{warning|Yes, this will cause a system to automatically unlock it's encrypted root volume without any interaction from a human. Yes, this exposes it to any sufficently advanced Evil Maid attacks. If sealed against the appropriate registers (especially register 8 with the kernel arguments), the TPM measurements should force systemd to ask for your LUKS passphrase in almost any attempt to access the encrypted volume from outside your normal boot process.}}<br />
<br />
We are fortunate that in our shift to dracut includes utilizing systemd and sd-encrypt, as we can use systemd's native support for enrolling LUKS keys. A review of [[Trusted Platform Module#Using TPM 2.0]] is recommended but not very clear.<br />
<br />
First, be sure to install {{Pkg|tpm2-tools}}. Alternatively {{aur|ibm-tss}} can be used per [[Trusted Platform Module]], however this guide is not tested against those.<br />
<br />
{{note|A reboot may be required to convince {{ic|systemd-cryptenroll}} that TPM 2.0 devices now exist on the machine.}}<br />
<br />
There are several decisions to be made here. The table at [[Trusted Platform Module#Accessing PCR registers]] is accurate as of October 2021. Essentially, once you seal your LUKS key, if any of the registers you've sealed against change, then you will be asked for your LUKS passphrase. This is equivalent to when Windows 10 makes you enter your BitLocker recovery key after a hardware change or changing BIOS settings.<br />
<br />
Your mileage may vary, based on UEFI vendors. For my laptop, I went with 0+1+2+3+4+5+7+8 and have been able to invalidate my TPM. Unfortunately, if you change your system BACK the volume will unlock. I'm investigating how to disable that.<br />
<br />
Other options on {{man|1|systemd-cryptenroll}} will reveal that several hardware tokens can also be enrolled to allow unlocking the root LUKS volume automatically, but only if a key is present. Further testing is requried.<br />
<br />
To enroll your LUKS volume, simply run the following command as root<br />
<br />
# systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/nvme0n1p2<br />
<br />
To remove your key, run this command:<br />
<br />
# systemd-cryptenroll --wipe-slot=tpm2 /dev/nvme0n1p2<br />
<br />
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:<br />
<br />
{{hc|~/bin/luks_reenroll_tpm|2=<br />
sudo systemd-cryptenroll --wipe-slot=tpm2 /dev/disk/by-uuid/{UUID_HERE}<br />
systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/disk/by-uuid/{UUID_HERE}<br />
}}<br />
<br />
== Justifications ==<br />
<br />
=== LVM on LUKS vs other dm-crypt approaches ===<br />
<br />
LVM on LUKS was selected becasue it is simply the easiest to manage while conferring both encrypted swap and disk. The other approaches required much more tooling and manual fussing to utilize. This selection also gives room change freely between {{ic|busybox}} and {{ic|systemd}} initrds.<br />
<br />
=== Using dracut ===<br />
<br />
{{Pkg|dracut}} just makes it easier to build full unified kernels that {{man|7|systemd-boot}} can launch as EFI binaries. There is also available tooling in the [[AUR]] for automating the creation of these binaries. Finally, {{ic|dracut}} will sign the binaries it creates automatically when configured to do so.<br />
<br />
=== Unified kernel images ===<br />
<br />
While UKI's could be problematic on other distributions, they fit right in with an Arch Linux install. The automation is there through pacman hooks and {{Pkg|sbctl}} to sign our UKIs as they're created. Furthermore, you can only sign and create a new signed UKI while booted into a properly signed UKI. It creates a chain of trust, which means it's important to never disable Secure Boot once you've set it up.<br />
<br />
The UKI encompasses all of the following items inside the signature, which means you can't change any of them without invalidating the signature.<br />
<br />
* Kernel arguments<br />
* Initrd/Initramfs<br />
* Kernel<br />
<br />
In particular, all other flavors of secureboot do not sign or validate the initramfs. This is a big attack area and can be relatively trivialized that a semi-decent pawn shop owner with Google could likely find an image that would grant him access and make the TPM none the wiser the system has changed. One can prevent this with encrypted /boot, but that would limit you to GRUB2 and LUKS version 1 devices only. This also doesn't include the work to keep GRUB2's files signed with a PGP key by root.<br />
<br />
== Miscellaneous discussions ==<br />
<br />
=== Filesystem Selection ===<br />
<br />
Most examples on Arch utilize {{ic|ext4}}, but other file systems such as {{ic|brtfs}} can work equally well. As for performance or issues with being inside LVM, [https://btrfs.wiki.kernel.org/index.php/FAQ#Btrfs_has_subvolumes.2C_does_this_mean_I_don.27t_need_a_logical_volume_manager_and_I_can_create_a_big_Btrfs_filesystem_on_a_raw_partition.3F this question in the brtfs FAQ] implie that there is some performance loss but no other issues.<br />
<br />
=== LUKS TPM enrollment and managing luks keys ===<br />
<br />
Note that using {{man|1|systemd-cryptenroll}} will add a key to your LUKS volume. It's not clear how exactly the option {{ic|1=--wipe-slot=tpm2}} is able to identify which slot it needs to wipe, but it does. This even works if your TPM has changed.<br />
<br />
You can see the effects by comparing the output of {{ic|cryptsetup luksDump /dev/nvme0n1p2}} before and after you enroll or wipe a TPM based key. You can identify what slot your own passphrase is in with {{ic|cryptsetup --verbose open --test-passphrase /dev/nvme0n1p2}} and entering your passphrase. The output will inform you which key slot was unlocked.<br />
<br />
Finally, your passphrase may be changed with {{ic|cryptsetup luksChangeKey /dev/nvme0n1p2 -S 0}}.<br />
<br />
== Planned TODOs ==<br />
A panic command that can dump the TPM and shutdown the computer (without requiring the time of entering a password in sudo) forcing an adversary to resort to [https://en.wikipedia.org/wiki/Rubber-hose_cryptanalysis rubber-hose cryptanalysis] to get to the encrypted data.</div>Krinhttps://wiki.archlinux.org/index.php?title=User:Krin/Secure_Boot,_full_disk_encryption,_and_TPM2_unlocking_install&diff=697915User:Krin/Secure Boot, full disk encryption, and TPM2 unlocking install2021-09-30T22:03:53Z<p>Krin: Add information about LUKS TPM enrollment and managing keys.</p>
<hr />
<div>{{Unsupported|30 September 2021}}<br />
{{Expansion|Work In Progress, Draft from Installation Notes, Needs Testing}}<br />
<br />
== Introduction ==<br />
<br />
This installation is based on my installing Arch on an Asus ROG Strix G G531 I got second hand. The primary goals were to replace Windows 10 Pro with Bitlocker encryption and maintain the convienence and security balance of that original operating system.<br />
<br />
My requirements boiled down to:<br />
<br />
* A fully encrypted disk<br />
* Full Secure Boot validation of all UEFI components.<br />
* Use of the TPM to facilitate unlocking of the disk.<br />
* Hibernate/Suspend working.<br />
<br />
My primary use case here is to make it difficult enough for a baggage handler with sticky hands to get at my data that they just wipe the drive. A state level actor with the expertise and equipment to hot swap my ram in my hotel room is not something that I'm defending this ''particular'' laptop against. This is more for gaming and web browsing and uploading photos while traveling.<br />
<br />
I'll continue to update these notes as I develop further solutions.<br />
<br />
== Disclaimers ==<br />
<br />
This article is primarily for the author's own notes. It is assumed that the reader is familiar with the [[Installation guide]] and will refer to it often. Reading linked articles is recommended.<br />
<br />
== Initial setup ==<br />
<br />
=== Pre-installation ===<br />
<br />
Reset your Secure Boot settings in BIOS to enable setup mode. Usually this means you set Secure Boot to Enabled and then select the option to wipe out the keys.<br />
<br />
Follow the [[Installation_guide#Pre-installation]] up to Paritioning the Disks.<br />
<br />
=== Disk preparation ===<br />
<br />
If you have data on your disks you want to overwrite, utilize [[Dm-crypt/Drive_preparation#dm-crypt_wipe_on_an_empty_disk_or_partition]] to wipe it. If this disk was previously encrypted, utilize [[Dm-crypt/Drive_preparation#Wipe_LUKS_header]] instead for a much faster disposal. Finally, use [[Dm-crypt/Encrypting_an_entire_system#LVM_on_LUKS]] to parition your drive with two differences.<br />
<br />
{{tip|Using a memorable LUKS passphrase until you've completed the install process can be helpful. It will take several reboots to finish setup.}}<br />
<br />
First, the partition layout will be as follows:<br />
<br />
{{hc|Partiton Layout|<br />
┌────────────────────┬──────────────────────────┬─────────────────────────────┐<br />
│ │ │ │<br />
│ EFI Boot Partition │ Logical Volume 1 │ Logical Volume 2 │<br />
│ │ │ │<br />
│ /efi │ [SWAP] │ / │<br />
│ │ │ │<br />
│ /dev/nvme0n1p1 │ /dev/CryptRootVG/swap │ /dev/CryptRootVG/root │<br />
│ │ │ │<br />
│ 512 MB │ 16 GB (Or RAM size) │ Remaining Free Space │<br />
│ │ │ │<br />
│ │ │ │<br />
│ ├──────────────────────────┴─────────────────────────────┤<br />
│ │ │<br />
│ │ LUKS and LVM Physical Volume │<br />
│ │ │<br />
│ │ /dev/nvme0n1p2 │<br />
│ │ │<br />
└────────────────────┴────────────────────────────────────────────────────────┘<br />
}}<br />
<br />
Second, if your hard drive is an SSD like this laptop, use the following command to open your LUKS volume.<br />
<br />
# cryptsetup open --perf-no_read_workqueue --perf-no_write_workqueue --persistent /dev/nvme0n1p2 cryptroot<br />
<br />
After completing your LUKS on LVM setup, format your EFI partition per [[EFI system partition]].<br />
<br />
# mkfs ext.vfat -F32 /dev/nvme0n1p2<br />
<br />
Mount this partition at {{ic|/mnt/efi}}. It is very important to leave {{ic|/boot}} on your encrypted root partition.<br />
<br />
== Installation ==<br />
<br />
Continue with [[Installation_guide#Installation]]. Be sure to flesh out your {{man|8|pacstrap}} with the following list of packages:<br />
<br />
* {{Pkg|dracut}}<br />
* {{Pkg|intel-ucode}}<br />
* {{Pkg|lvm2}}<br />
* {{Pkg|openssh}}<br />
* {{Pkg|ansible}}<br />
* {{Pkg|git}}<br />
* {{Pkg|iwd}}<br />
* {{Pkg|efibootmgr}}<br />
<br />
<br />
We are going to leave off the installation guide at the initramfs section, so go ahead and reset your root password. <br />
<br />
# passwd<br />
<br />
=== Bootloader ===<br />
<br />
{{warning|This section needs testing.}}<br />
<br />
First, install {{ic|systemd-boot}} by following [[Systemd-boot#Installing_the_EFI_boot_manager]]. Next, install {{aur|dracut-hook-uefi}}.<br />
<br />
Ensure you drop in a systemd-boot hook to update your bootctl any time it's updated.<br />
<br />
{{hc|/etc/pacman.d/hooks/998-systemd-boot.hook|2=<br />
[Trigger]<br />
Type = Package<br />
Operation = Install<br />
Operation = Upgrade<br />
Target = systemd<br />
<br />
[Action]<br />
Description = Updating systemd-boot<br />
When = PostTransation<br />
Exec = /usr/bin/bootctl update; <br />
}}<br />
<br />
Obtain the UUID of your LUKS drive via the following command:<br />
<br />
{{bc|<br />
blkid -s UUID -o value /dev/nvme0n1p2<br />
}}<br />
<br />
Create the following files with the listed content. Be sure to replace UUIDs with what you actually need. The extraneous {{ic:rd.luks.options}} should not cause an issue, but will be used once we've enabled secure boot. See {{man|5|dracut.conf}} for more information on what these commands do.<br />
<br />
A good portion of the kernel command line was as generated by dracut. Many are extraneous or you may wish to change some of the block device names.<br />
<br />
{{hc|/etc/dracut.conf.d/cmdline.conf|2=<br />
kernel_cmdline="rd.luks.uuid=luks-17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02 rd.luks.options=17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02 rd.lvm.lv=CryptRoot/root rd.lvm.lv=CryptRoot/swap resume=/dev/mapper/CryptRoot-swap root=/dev/mapper/CryptRoot-root rootfstype=ext4 rootflags=rw,relatime"<br />
}}<br />
<br />
{{hc|/etc/dracut.conf.d/flags.conf|2=<br />
compress="zstd"<br />
hostonly="yes"<br />
}}<br />
<br />
Run the following command to generate your EFI stub kernels.<br />
<br />
dracut --uefi<br />
<br />
=== Secure boot ===<br />
<br />
{{note|The very newly developed [https://github.com/Foxboron/sbctl sbctl], availble via {{aur|sbctl-git}} has completely revamped this process and will only get better as they approach 1.0. From here on out, as of October 2021, this process should greatly simplify.}}<br />
<br />
{{note|Credit to this [https://lunaryorn.com/secure-boot-on-arch-linux-with-sbctl-and-dracut blog post by lunaryorn] for the inspiration.}}<br />
<br />
{{warning|This section is INCOMPLETE untested.}}<br />
<br />
Install {{Pkg|sbctl}}. At this point you will likely need to reboot and adjust your secure boot settings. You want secure boot in '''setup mode'''. <br />
<br />
{{bc|<br />
$ sbctl status<br />
Installed: X Sbctl is not installed<br />
Setup Mode: X Enabled<br />
Secure Boot: X Disabled<br />
}}<br />
<br />
Run the following commands as root. See {{man|8|sbctl}} for more information on their function. Of particular note is the {{ic|-s}} flag which indicates {{ic|sbctl}} should remember the file for future verification and signing.<br />
<br />
Note your Linux EFI binary name may be slightly different.<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
<br />
# sbctl sign -s /efi/EFI/BOOT/BOOTx64.EFI<br />
✔ Signed /efi/EFI/BOOT/BOOTx64.EFI<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Finally, enroll the Secure Boot keys.<br />
<br />
{{bc|<br />
# sbctl enroll-keys<br />
Enrolling keys to EFI variables...✔<br />
Enrolled keys to the EFI variables!<br />
}}<br />
<br />
Verify that secure boot now has an owner GUID and setup mode is disabled.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✔ Sbctl is installed<br />
Owner GUID: a2ee3d08-725a-408b-9d95-28026a44611c<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
Now reboot. This reboot is required so we can get the TPM measurements into their (hopefully) permanent state.<br />
<br />
=== Enroll LUKS key in TPM ===<br />
{{warning|Yes, this will cause a system to automatically unlock it's encrypted root volume without any interaction from a human. Yes, this exposes it to any sufficently advanced Evil Maid attacks. If sealed against the appropriate registers (especially register 8 with the kernel arguments), the TPM measurements should force systemd to ask for your LUKS passphrase in almost any attempt to access the encrypted volume from outside your normal boot process.}}<br />
<br />
We are fortunate that in our shift to dracut includes utilizing systemd and sd-encrypt, as we can use systemd's native support for enrolling LUKS keys. A review of [[Trusted Platform Module#Using TPM 2.0]] is recommended but not very clear.<br />
<br />
First, be sure to install {{Pkg|tpm2-tools}}. Alternatively {{aur|ibm-tss}} can be used per [[Trusted Platform Module]], however this guide is not tested against those.<br />
<br />
{{note|A reboot may be required to convince {{ic|systemd-cryptenroll}} that TPM 2.0 devices now exist on the machine.}}<br />
<br />
There are several decisions to be made here. The table at [[Trusted Platform Module#Accessing PCR registers]] is accurate as of October 2021. Essentially, once you seal your LUKS key, if any of the registers you've sealed against change, then you will be asked for your LUKS passphrase. This is equivalent to when Windows 10 makes you enter your BitLocker recovery key after a hardware change or changing BIOS settings.<br />
<br />
Your mileage may vary, based on UEFI vendors. For my laptop, I went with 0+1+2+3+4+5+7+8 and have been able to invalidate my TPM. Unfortunately, if you change your system BACK the volume will unlock. I'm investigating how to disable that.<br />
<br />
Other options on {{man|1|systemd-cryptenroll}} will reveal that several hardware tokens can also be enrolled to allow unlocking the root LUKS volume automatically, but only if a key is present. Further testing is requried.<br />
<br />
To enroll your LUKS volume, simply run the following command as root<br />
<br />
# systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/nvme0n1p2<br />
<br />
To remove your key, run this command:<br />
<br />
# systemd-cryptenroll --wipe-slot=tpm2 /dev/nvme0n1p2<br />
<br />
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:<br />
<br />
{{hc|~/bin/luks_reenroll_tpm|2=<br />
sudo systemd-cryptenroll --wipe-slot=tpm2 /dev/disk/by-uuid/{UUID_HERE}<br />
systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/disk/by-uuid/{UUID_HERE}<br />
}}<br />
<br />
== Justifications ==<br />
<br />
=== LVM on LUKS vs other dm-crypt approaches ===<br />
<br />
LVM on LUKS was selected becasue it is simply the easiest to manage while conferring both encrypted swap and disk. The other approaches required much more tooling and manual fussing to utilize. This selection also gives room change freely between {{ic|busybox}} and {{ic|systemd}} initrds.<br />
<br />
=== Using dracut ===<br />
<br />
{{Pkg|dracut}} just makes it easier to build full unified kernels that {{man|7|systemd-boot}} can launch as EFI binaries. There is also available tooling in the [[AUR]] for automating the creation of these binaries. Finally, {{ic|dracut}} will sign the binaries it creates automatically when configured to do so.<br />
<br />
=== Unified kernel images ===<br />
<br />
While UKI's could be problematic on other distributions, they fit right in with an Arch Linux install. The automation is there through pacman hooks and {{Pkg|sbctl}} to sign our UKIs as they're created. Furthermore, you can only sign and create a new signed UKI while booted into a properly signed UKI. It creates a chain of trust, which means it's important to never disable Secure Boot once you've set it up.<br />
<br />
The UKI encompasses all of the following items inside the signature, which means you can't change any of them without invalidating the signature.<br />
<br />
* Kernel arguments<br />
* Initrd/Initramfs<br />
* Kernel<br />
<br />
In particular, all other flavors of secureboot do not sign or validate the initramfs. This is a big attack area and can be relatively trivialized that a semi-decent pawn shop owner with Google could likely find an image that would grant him access and make the TPM none the wiser the system has changed. One can prevent this with encrypted /boot, but that would limit you to GRUB2 and LUKS version 1 devices only. This also doesn't include the work to keep GRUB2's files signed with a PGP key by root.<br />
<br />
== Miscellaneous discussions ==<br />
<br />
=== Filesystem Selection ===<br />
<br />
Most examples on Arch utilize {{ic|ext4}}, but other file systems such as {{ic|brtfs}} can work equally well. As for performance or issues with being inside LVM, [https://btrfs.wiki.kernel.org/index.php/FAQ#Btrfs_has_subvolumes.2C_does_this_mean_I_don.27t_need_a_logical_volume_manager_and_I_can_create_a_big_Btrfs_filesystem_on_a_raw_partition.3F this question in the brtfs FAQ] implie that there is some performance loss but no other issues.<br />
<br />
=== LUKS TPM enrollment and managing luks keys ===<br />
<br />
Note that using {{man|1|systemd-cryptenroll}} will add a key to your LUKS volume. It's not clear how exactly the option {{ic|1=--wipe-slot=tpm2}} is able to identify which slot it needs to wipe, but it does. This even works if your TPM has changed.<br />
<br />
You can see the effects by comparing the output of {{ic|cryptsetup luksDump /dev/nvme0n1p2}} before and after you enroll or wipe a TPM based key. You can identify what slot your own passphrase is in with {{ic|cryptsetup --verbose open --test-passphrase /dev/nvme0n1p2}} and entering your passphrase. The output will inform you which key slot was unlocked.<br />
<br />
Finally, your passphrase may be changed with {{ic|cryptsetup luksChangeKey /dev/nvme0n1p2 -S 0}}.<br />
<br />
== Planned TODOs ==<br />
A panic command that can dump the TPM and shutdown the computer (without requiring the time of entering a password in sudo) forcing an adversary to resort to [https://en.wikipedia.org/wiki/Rubber-hose_cryptanalysis rubber-hose cryptanalysis] to get to the encrypted data.</div>Krinhttps://wiki.archlinux.org/index.php?title=User:Krin/Secure_Boot,_full_disk_encryption,_and_TPM2_unlocking_install&diff=697913User:Krin/Secure Boot, full disk encryption, and TPM2 unlocking install2021-09-30T21:53:29Z<p>Krin: Minor edits to clean up formatting and depersonalize warnings.</p>
<hr />
<div>{{Unsupported|30 September 2021}}<br />
{{Expansion|Work In Progress, Draft from Installation Notes, Needs Testing}}<br />
<br />
== Introduction ==<br />
<br />
This installation is based on my installing Arch on an Asus ROG Strix G G531 I got second hand. The primary goals were to replace Windows 10 Pro with Bitlocker encryption and maintain the convienence and security balance of that original operating system.<br />
<br />
My requirements boiled down to:<br />
<br />
* A fully encrypted disk<br />
* Full Secure Boot validation of all UEFI components.<br />
* Use of the TPM to facilitate unlocking of the disk.<br />
* Hibernate/Suspend working.<br />
<br />
My primary use case here is to make it difficult enough for a baggage handler with sticky hands to get at my data that they just wipe the drive. A state level actor with the expertise and equipment to hot swap my ram in my hotel room is not something that I'm defending this ''particular'' laptop against. This is more for gaming and web browsing and uploading photos while traveling.<br />
<br />
I'll continue to update these notes as I develop further solutions.<br />
<br />
== Disclaimers ==<br />
<br />
This article is primarily for the author's own notes. It is assumed that the reader is familiar with the [[Installation guide]] and will refer to it often. Reading linked articles is recommended.<br />
<br />
== Initial setup ==<br />
<br />
=== Pre-installation ===<br />
<br />
Reset your Secure Boot settings in BIOS to enable setup mode. Usually this means you set Secure Boot to Enabled and then select the option to wipe out the keys.<br />
<br />
Follow the [[Installation_guide#Pre-installation]] up to Paritioning the Disks.<br />
<br />
=== Disk preparation ===<br />
<br />
If you have data on your disks you want to overwrite, utilize [[Dm-crypt/Drive_preparation#dm-crypt_wipe_on_an_empty_disk_or_partition]] to wipe it. If this disk was previously encrypted, utilize [[Dm-crypt/Drive_preparation#Wipe_LUKS_header]] instead for a much faster disposal. Finally, use [[Dm-crypt/Encrypting_an_entire_system#LVM_on_LUKS]] to parition your drive with two differences.<br />
<br />
{{tip|Using a memorable LUKS passphrase until you've completed the install process can be helpful. It will take several reboots to finish setup.}}<br />
<br />
First, the partition layout will be as follows:<br />
<br />
{{hc|Partiton Layout|<br />
┌────────────────────┬──────────────────────────┬─────────────────────────────┐<br />
│ │ │ │<br />
│ EFI Boot Partition │ Logical Volume 1 │ Logical Volume 2 │<br />
│ │ │ │<br />
│ /efi │ [SWAP] │ / │<br />
│ │ │ │<br />
│ /dev/nvme0n1p1 │ /dev/CryptRootVG/swap │ /dev/CryptRootVG/root │<br />
│ │ │ │<br />
│ 512 MB │ 16 GB (Or RAM size) │ Remaining Free Space │<br />
│ │ │ │<br />
│ │ │ │<br />
│ ├──────────────────────────┴─────────────────────────────┤<br />
│ │ │<br />
│ │ LUKS and LVM Physical Volume │<br />
│ │ │<br />
│ │ /dev/nvme0n1p2 │<br />
│ │ │<br />
└────────────────────┴────────────────────────────────────────────────────────┘<br />
}}<br />
<br />
Second, if your hard drive is an SSD like this laptop, use the following command to open your LUKS volume.<br />
<br />
# cryptsetup open --perf-no_read_workqueue --perf-no_write_workqueue --persistent /dev/nvme0n1p2 cryptroot<br />
<br />
After completing your LUKS on LVM setup, format your EFI partition per [[EFI system partition]].<br />
<br />
# mkfs ext.vfat -F32 /dev/nvme0n1p2<br />
<br />
Mount this partition at {{ic|/mnt/efi}}. It is very important to leave {{ic|/boot}} on your encrypted root partition.<br />
<br />
== Installation ==<br />
<br />
Continue with [[Installation_guide#Installation]]. Be sure to flesh out your {{man|8|pacstrap}} with the following list of packages:<br />
<br />
* {{Pkg|dracut}}<br />
* {{Pkg|intel-ucode}}<br />
* {{Pkg|lvm2}}<br />
* {{Pkg|openssh}}<br />
* {{Pkg|ansible}}<br />
* {{Pkg|git}}<br />
* {{Pkg|iwd}}<br />
* {{Pkg|efibootmgr}}<br />
<br />
<br />
We are going to leave off the installation guide at the initramfs section, so go ahead and reset your root password. <br />
<br />
# passwd<br />
<br />
=== Bootloader ===<br />
<br />
{{warning|This section needs testing.}}<br />
<br />
First, install {{ic|systemd-boot}} by following [[Systemd-boot#Installing_the_EFI_boot_manager]]. Next, install {{aur|dracut-hook-uefi}}.<br />
<br />
Ensure you drop in a systemd-boot hook to update your bootctl any time it's updated.<br />
<br />
{{hc|/etc/pacman.d/hooks/998-systemd-boot.hook|2=<br />
[Trigger]<br />
Type = Package<br />
Operation = Install<br />
Operation = Upgrade<br />
Target = systemd<br />
<br />
[Action]<br />
Description = Updating systemd-boot<br />
When = PostTransation<br />
Exec = /usr/bin/bootctl update; <br />
}}<br />
<br />
Obtain the UUID of your LUKS drive via the following command:<br />
<br />
{{bc|<br />
blkid -s UUID -o value /dev/nvme0n1p2<br />
}}<br />
<br />
Create the following files with the listed content. Be sure to replace UUIDs with what you actually need. The extraneous {{ic:rd.luks.options}} should not cause an issue, but will be used once we've enabled secure boot. See {{man|5|dracut.conf}} for more information on what these commands do.<br />
<br />
A good portion of the kernel command line was as generated by dracut. Many are extraneous or you may wish to change some of the block device names.<br />
<br />
{{hc|/etc/dracut.conf.d/cmdline.conf|2=<br />
kernel_cmdline="rd.luks.uuid=luks-17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02 rd.luks.options=17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02 rd.lvm.lv=CryptRoot/root rd.lvm.lv=CryptRoot/swap resume=/dev/mapper/CryptRoot-swap root=/dev/mapper/CryptRoot-root rootfstype=ext4 rootflags=rw,relatime"<br />
}}<br />
<br />
{{hc|/etc/dracut.conf.d/flags.conf|2=<br />
compress="zstd"<br />
hostonly="yes"<br />
}}<br />
<br />
Run the following command to generate your EFI stub kernels.<br />
<br />
dracut --uefi<br />
<br />
=== Secure boot ===<br />
<br />
{{note|The very newly developed [https://github.com/Foxboron/sbctl sbctl], availble via {{aur|sbctl-git}} has completely revamped this process and will only get better as they approach 1.0. From here on out, as of October 2021, this process should greatly simplify.}}<br />
<br />
{{note|Credit to this [https://lunaryorn.com/secure-boot-on-arch-linux-with-sbctl-and-dracut blog post by lunaryorn] for the inspiration.}}<br />
<br />
{{warning|This section is INCOMPLETE untested.}}<br />
<br />
Install {{Pkg|sbctl}}. At this point you will likely need to reboot and adjust your secure boot settings. You want secure boot in '''setup mode'''. <br />
<br />
{{bc|<br />
$ sbctl status<br />
Installed: X Sbctl is not installed<br />
Setup Mode: X Enabled<br />
Secure Boot: X Disabled<br />
}}<br />
<br />
Run the following commands as root. See {{man|8|sbctl}} for more information on their function. Of particular note is the {{ic|-s}} flag which indicates {{ic|sbctl}} should remember the file for future verification and signing.<br />
<br />
Note your Linux EFI binary name may be slightly different.<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
<br />
# sbctl sign -s /efi/EFI/BOOT/BOOTx64.EFI<br />
✔ Signed /efi/EFI/BOOT/BOOTx64.EFI<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Finally, enroll the Secure Boot keys.<br />
<br />
{{bc|<br />
# sbctl enroll-keys<br />
Enrolling keys to EFI variables...✔<br />
Enrolled keys to the EFI variables!<br />
}}<br />
<br />
Verify that secure boot now has an owner GUID and setup mode is disabled.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✔ Sbctl is installed<br />
Owner GUID: a2ee3d08-725a-408b-9d95-28026a44611c<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
Now reboot. This reboot is required so we can get the TPM measurements into their (hopefully) permanent state.<br />
<br />
=== Enroll LUKS key in TPM ===<br />
{{warning|Yes, this will cause a system to automatically unlock it's encrypted root volume without any interaction from a human. Yes, this exposes it to any sufficently advanced Evil Maid attacks. If sealed against the appropriate registers (especially register 8 with the kernel arguments), the TPM measurements should force systemd to ask for your LUKS passphrase in almost any attempt to access the encrypted volume from outside your normal boot process.}}<br />
<br />
We are fortunate that in our shift to dracut includes utilizing systemd and sd-encrypt, as we can use systemd's native support for enrolling LUKS keys. A review of [[Trusted Platform Module#Using TPM 2.0]] is recommended but not very clear.<br />
<br />
First, be sure to install {{Pkg|tpm2-tools}}. Alternatively {{aur|ibm-tss}} can be used per [[Trusted Platform Module]], however this guide is not tested against those.<br />
<br />
{{note|A reboot may be required to convince {{ic|systemd-cryptenroll}} that TPM 2.0 devices now exist on the machine.}}<br />
<br />
There are several decisions to be made here. The table at [[Trusted Platform Module#Accessing PCR registers]] is accurate as of October 2021. Essentially, once you seal your LUKS key, if any of the registers you've sealed against change, then you will be asked for your LUKS passphrase. This is equivalent to when Windows 10 makes you enter your BitLocker recovery key after a hardware change or changing BIOS settings.<br />
<br />
Your mileage may vary, based on UEFI vendors. For my laptop, I went with 0+1+2+3+4+5+7+8 and have been able to invalidate my TPM. Unfortunately, if you change your system BACK the volume will unlock. I'm investigating how to disable that.<br />
<br />
Other options on {{man|1|systemd-cryptenroll}} will reveal that several hardware tokens can also be enrolled to allow unlocking the root LUKS volume automatically, but only if a key is present. Further testing is requried.<br />
<br />
To enroll your LUKS volume, simply run the following command as root<br />
<br />
# systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/nvme0n1p2<br />
<br />
To remove your key, run this command:<br />
<br />
# systemd-cryptenroll --wipe-slot=tpm2 /dev/nvme0n1p2<br />
<br />
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:<br />
<br />
{{hc|~/bin/luks_reenroll_tpm|2=<br />
sudo systemd-cryptenroll --wipe-slot=tpm2 /dev/disk/by-uuid/{UUID_HERE}<br />
systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/disk/by-uuid/{UUID_HERE}<br />
}}<br />
<br />
== Justifications ==<br />
<br />
=== LVM on LUKS vs other dm-crypt approaches ===<br />
<br />
LVM on LUKS was selected becasue it is simply the easiest to manage while conferring both encrypted swap and disk. The other approaches required much more tooling and manual fussing to utilize. This selection also gives room change freely between {{ic|busybox}} and {{ic|systemd}} initrds.<br />
<br />
=== Using dracut ===<br />
<br />
{{Pkg|dracut}} just makes it easier to build full unified kernels that {{man|7|systemd-boot}} can launch as EFI binaries. There is also available tooling in the [[AUR]] for automating the creation of these binaries. Finally, {{ic|dracut}} will sign the binaries it creates automatically when configured to do so.<br />
<br />
=== Unified kernel images ===<br />
<br />
While UKI's could be problematic on other distributions, they fit right in with an Arch Linux install. The automation is there through pacman hooks and {{Pkg|sbctl}} to sign our UKIs as they're created. Furthermore, you can only sign and create a new signed UKI while booted into a properly signed UKI. It creates a chain of trust, which means it's important to never disable Secure Boot once you've set it up.<br />
<br />
The UKI encompasses all of the following items inside the signature, which means you can't change any of them without invalidating the signature.<br />
<br />
* Kernel arguments<br />
* Initrd/Initramfs<br />
* Kernel<br />
<br />
In particular, all other flavors of secureboot do not sign or validate the initramfs. This is a big attack area and can be relatively trivialized that a semi-decent pawn shop owner with Google could likely find an image that would grant him access and make the TPM none the wiser the system has changed. One can prevent this with encrypted /boot, but that would limit you to GRUB2 and LUKS version 1 devices only. This also doesn't include the work to keep GRUB2's files signed with a PGP key by root.<br />
<br />
== Miscellaneous discussions ==<br />
<br />
=== Filesystem Selection ===<br />
<br />
Most examples on Arch utilize {{ic|ext4}}, but other file systems such as {{ic|brtfs}} can work equally well. As for performance or issues with being inside LVM, [https://btrfs.wiki.kernel.org/index.php/FAQ#Btrfs_has_subvolumes.2C_does_this_mean_I_don.27t_need_a_logical_volume_manager_and_I_can_create_a_big_Btrfs_filesystem_on_a_raw_partition.3F this question in the brtfs FAQ] implie that there is some performance loss but no other issues.<br />
<br />
== Planned TODOs ==<br />
A panic command that can dump the TPM and shutdown the computer (without requiring the time of entering a password in sudo) forcing an adversary to resort to [https://en.wikipedia.org/wiki/Rubber-hose_cryptanalysis rubber-hose cryptanalysis] to get to the encrypted data.</div>Krinhttps://wiki.archlinux.org/index.php?title=User:Krin/Secure_Boot,_full_disk_encryption,_and_TPM2_unlocking_install&diff=697912User:Krin/Secure Boot, full disk encryption, and TPM2 unlocking install2021-09-30T21:46:56Z<p>Krin: Seal LUKS against TPM section. Formatting.</p>
<hr />
<div>{{Unsupported|30 September 2021}}<br />
{{Expansion|Work In Progress, Draft from Installation Notes, Needs Testing}}<br />
{{Related articles start}}<br />
{{Related|Unified Extensible Firmware Interface/Secure Boot}}<br />
{{Related|Trusted Platform Module}}<br />
{{Related articles end}}<br />
<br />
== Introduction ==<br />
<br />
This installation is based on my installing Arch on an Asus ROG Strix G G531 I got second hand. The primary goals were to replace Windows 10 Pro with Bitlocker encryption and maintain the convienence and security balance of that original operating system.<br />
<br />
My requirements boiled down to:<br />
<br />
* A fully encrypted disk<br />
* Full Secure Boot validation of all UEFI components.<br />
* Use of the TPM to facilitate unlocking of the disk.<br />
* Hibernate/Suspend working.<br />
<br />
My primary use case here is to make it difficult enough for a baggage handler with sticky hands to get at my data that they just wipe the drive. A state level actor with the expertise and equipment to hot swap my ram in my hotel room is not something that I'm defending this ''particular'' laptop against. This is more for gaming and web browsing and uploading photos while traveling.<br />
<br />
I'll continue to update these notes as I develop further solutions.<br />
<br />
== Disclaimers ==<br />
<br />
This article is primarily for the author's own notes. It is assumed that the reader is familiar with the [[Installation guide]] and will refer to it often. Reading linked articles is recommended.<br />
<br />
== Initial Setup ==<br />
<br />
=== Pre-Installation ===<br />
<br />
Reset your Secure Boot settings in BIOS to enable setup mode. Usually this means you set Secure Boot to Enabled and then select the option to wipe out the keys.<br />
<br />
Follow the [[Installation_guide#Pre-installation]] up to Paritioning the Disks.<br />
<br />
=== Disk Preparation ===<br />
<br />
If you have data on your disks you want to overwrite, utilize [[Dm-crypt/Drive_preparation#dm-crypt_wipe_on_an_empty_disk_or_partition]] to wipe it. If this disk was previously encrypted, utilize [[Dm-crypt/Drive_preparation#Wipe_LUKS_header]] instead for a much faster disposal. Finally, use [[Dm-crypt/Encrypting_an_entire_system#LVM_on_LUKS]] to parition your drive with two differences.<br />
<br />
{{tip|Using a memorable LUKS passphrase until you've completed the install process can be helpful. It will take several reboots to finish setup.}}<br />
<br />
First, the partition layout will be as follows:<br />
<br />
{{hc|Partiton Layout|<br />
┌────────────────────┬──────────────────────────┬─────────────────────────────┐<br />
│ │ │ │<br />
│ EFI Boot Partition │ Logical Volume 1 │ Logical Volume 2 │<br />
│ │ │ │<br />
│ /efi │ [SWAP] │ / │<br />
│ │ │ │<br />
│ /dev/nvme0n1p1 │ /dev/CryptRootVG/swap │ /dev/CryptRootVG/root │<br />
│ │ │ │<br />
│ 512 MB │ 16 GB (Or RAM size) │ Remaining Free Space │<br />
│ │ │ │<br />
│ │ │ │<br />
│ ├──────────────────────────┴─────────────────────────────┤<br />
│ │ │<br />
│ │ LUKS and LVM Physical Volume │<br />
│ │ │<br />
│ │ /dev/nvme0n1p2 │<br />
│ │ │<br />
└────────────────────┴────────────────────────────────────────────────────────┘<br />
}}<br />
<br />
Second, if your hard drive is an SSD like this laptop, use the following command to open your LUKS volume.<br />
<br />
# cryptsetup open --perf-no_read_workqueue --perf-no_write_workqueue --persistent /dev/nvme0n1p2 cryptroot<br />
<br />
After completing your LUKS on LVM setup, format your EFI partition per [[EFI system partition]].<br />
<br />
# mkfs ext.vfat -F32 /dev/nvme0n1p2<br />
<br />
Mount this partition at {{ic|/mnt/efi}}. It is very important to leave {{ic|/boot}} on your encrypted root partition.<br />
<br />
== Installation ==<br />
<br />
Continue with [[Installation_guide#Installation]]. Be sure to flesh out your {{man|8|pacstrap}} with the following list of packages:<br />
<br />
* {{Pkg|dracut}}<br />
* {{Pkg|intel-ucode}}<br />
* {{Pkg|lvm2}}<br />
* {{Pkg|openssh}}<br />
* {{Pkg|ansible}}<br />
* {{Pkg|git}}<br />
* {{Pkg|iwd}}<br />
* {{Pkg|efibootmgr}}<br />
<br />
<br />
We are going to leave off the installation guide at the initramfs section, so go ahead and reset your root password. <br />
<br />
# passwd<br />
<br />
=== Bootloader ===<br />
<br />
{{warning|This section needs testing.}}<br />
<br />
First, install {{ic|systemd-boot}} by following [[Systemd-boot#Installing_the_EFI_boot_manager]]. Next, install {{aur|dracut-hook-uefi}}.<br />
<br />
Ensure you drop in a systemd-boot hook to update your bootctl any time it's updated.<br />
<br />
{{hc|/etc/pacman.d/hooks/998-systemd-boot.hook|2=<br />
[Trigger]<br />
Type = Package<br />
Operation = Install<br />
Operation = Upgrade<br />
Target = systemd<br />
<br />
[Action]<br />
Description = Updating systemd-boot<br />
When = PostTransation<br />
Exec = /usr/bin/bootctl update; <br />
}}<br />
<br />
Obtain the UUID of your LUKS drive via the following command:<br />
<br />
{{bc|<br />
blkid -s UUID -o value /dev/nvme0n1p2<br />
}}<br />
<br />
Create the following files with the listed content. Be sure to replace UUIDs with what you actually need. The extraneous {{ic:rd.luks.options}} should not cause an issue, but will be used once we've enabled secure boot. See {{man|5|dracut.conf}} for more information on what these commands do.<br />
<br />
A good portion of the kernel command line was as generated by dracut. Many are extraneous or you may wish to change some of the block device names.<br />
<br />
{{hc|/etc/dracut.conf.d/cmdline.conf|2=<br />
kernel_cmdline="rd.luks.uuid=luks-17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02 rd.luks.options=17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02 rd.lvm.lv=CryptRoot/root rd.lvm.lv=CryptRoot/swap resume=/dev/mapper/CryptRoot-swap root=/dev/mapper/CryptRoot-root rootfstype=ext4 rootflags=rw,relatime"<br />
}}<br />
<br />
{{hc|/etc/dracut.conf.d/flags.conf|2=<br />
compress="zstd"<br />
hostonly="yes"<br />
}}<br />
<br />
Run the following command to generate your EFI stub kernels.<br />
<br />
dracut --uefi<br />
<br />
=== Secure Boot ===<br />
<br />
{{note|The very newly developed [https://github.com/Foxboron/sbctl sbctl], availble via {{aur|sbctl-git}} has completely revamped this process and will only get better as they approach 1.0. From here on out, as of October 2021, this process should greatly simplify.}}<br />
<br />
{{note|Credit to this [https://lunaryorn.com/secure-boot-on-arch-linux-with-sbctl-and-dracut blog post by lunaryorn] for the inspiration.}}<br />
<br />
{{warning|This section is INCOMPLETE untested.}}<br />
<br />
Install {{Pkg|sbctl}}. At this point you will likely need to reboot and adjust your secure boot settings. You want secure boot in '''setup mode'''. <br />
<br />
{{bc|<br />
$ sbctl status<br />
Installed: X Sbctl is not installed<br />
Setup Mode: X Enabled<br />
Secure Boot: X Disabled<br />
}}<br />
<br />
Run the following commands as root. See {{man|8|sbctl}} for more information on their function. Of particular note is the {{ic|-s}} flag which indicates {{ic|sbctl}} should remember the file for future verification and signing.<br />
<br />
Note your Linux EFI binary name may be slightly different.<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
<br />
# sbctl sign -s /efi/EFI/BOOT/BOOTx64.EFI<br />
✔ Signed /efi/EFI/BOOT/BOOTx64.EFI<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Finally, enroll the Secure Boot keys.<br />
<br />
{{bc|<br />
# sbctl enroll-keys<br />
Enrolling keys to EFI variables...✔<br />
Enrolled keys to the EFI variables!<br />
}}<br />
<br />
Verify that secure boot now has an owner GUID and setup mode is disabled.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✔ Sbctl is installed<br />
Owner GUID: a2ee3d08-725a-408b-9d95-28026a44611c<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
Now reboot. This reboot is required so we can get the TPM measurements into their (hopefully) permanent state.<br />
<br />
=== Seal LUKS Against TPM ===<br />
{{warning|Yes, this will cause your system to automatically unlock your encrypted volume without any interaction from you. Yes, this exposes you to sufficently advanced Evil Maid attacks. Almost every person I've met who tells me this is horrible also runs the linux-zen kernel and ustilizes suspend, so keep the salt handy.}}<br />
<br />
We are fortunate that in our shift to dracut includes utilizing systemd and sd-encrypt, as we can use systemd's native support for enrolling LUKS keys. A review of [[Trusted Platform Module#Using TPM 2.0]] is recommended but not very clear.<br />
<br />
First, be sure to install {{Pkg|tpm2-tools}}. Alternatively {{aur|ibm-tss}} can be used per [[Trusted Platform Module]], however this guide is not tested against those.<br />
<br />
{{note|A reboot may be required to convince {{ic|systemd-cryptenroll}} that TPM 2.0 devices now exist on the machine.}}<br />
<br />
There are several decisions to be made here. The table at [[Trusted Platform Module#Accessing PCR registers]] is accurate as of October 2021. Essentially, once you seal your LUKS key, if any of the registers you've sealed against change, then you will be asked for your LUKS passphrase. This is equivalent to when Windows 10 makes you enter your BitLocker recovery key after a hardware change or changing BIOS settings.<br />
<br />
Your mileage may vary, based on UEFI vendors. For my laptop, I went with 0+1+2+3+4+5+7+8 and have been able to invalidate my TPM. Unfortunately, if you change your system BACK the volume will unlock. I'm investigating how to disable that.<br />
<br />
Other options on {{man|1|systemd-cryptenroll}} will reveal that several hardware tokens can also be enrolled to allow unlocking the root LUKS volume automatically, but only if a key is present. Further testing is requried.<br />
<br />
To enroll your LUKS volume, simply run the following command as root<br />
<br />
# systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/nvme0n1p2<br />
<br />
To remove your key, run this command:<br />
<br />
# systemd-cryptenroll --wipe-slot=tpm2 /dev/nvme0n1p2<br />
<br />
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:<br />
<br />
{{hc|~/bin/luks_reenroll_tpm|2=<br />
sudo systemd-cryptenroll --wipe-slot=tpm2 /dev/disk/by-uuid/{UUID_HERE}<br />
systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+1+2+3+4+5+7+8 /dev/disk/by-uuid/{UUID_HERE}<br />
}}<br />
<br />
== Justifications ==<br />
<br />
=== LVM on LUKS vs other dm-crypt approaches ===<br />
<br />
LVM on LUKS was selected becasue it is simply the easiest to manage while conferring both encrypted swap and disk. The other approaches required much more tooling and manual fussing to utilize. This selection also gives room change freely between {{ic|busybox}} and {{ic|systemd}} initrds.<br />
<br />
=== Using dracut ===<br />
<br />
{{Pkg|dracut}} just makes it easier to build full unified kernels that {{man|7|systemd-boot}} can launch as EFI binaries. There is also available tooling in the [[AUR]] for automating the creation of these binaries. Finally, {{ic|dracut}} will sign the binaries it creates automatically when configured to do so.<br />
<br />
=== Unified kernel images ===<br />
<br />
While UKI's could be problematic on other distributions, they fit right in with an Arch Linux install. The automation is there through pacman hooks and {{Pkg|sbctl}} to sign our UKIs as they're created. Furthermore, you can only sign and create a new signed UKI while booted into a properly signed UKI. It creates a chain of trust, which means it's important to never disable Secure Boot once you've set it up.<br />
<br />
The UKI encompasses all of the following items inside the signature, which means you can't change any of them without invalidating the signature.<br />
<br />
* Kernel arguments<br />
* Initrd/Initramfs<br />
* Kernel<br />
<br />
In particular, all other flavors of secureboot do not sign or validate the initramfs. This is a big attack area and can be relatively trivialized that a semi-decent pawn shop owner with Google could likely find an image that would grant him access and make the TPM none the wiser the system has changed. One can prevent this with encrypted /boot, but that would limit you to GRUB2 and LUKS version 1 devices only. This also doesn't include the work to keep GRUB2's files signed with a PGP key by root.<br />
<br />
== Miscellaneous discussions ==<br />
<br />
=== Filesystem Selection ===<br />
<br />
Most examples on Arch utilize {{ic|ext4}}, but other file systems such as {{ic|brtfs}} can work equally well. As for performance or issues with being inside LVM, [https://btrfs.wiki.kernel.org/index.php/FAQ#Btrfs_has_subvolumes.2C_does_this_mean_I_don.27t_need_a_logical_volume_manager_and_I_can_create_a_big_Btrfs_filesystem_on_a_raw_partition.3F this question in the brtfs FAQ] implie that there is some performance loss but no other issues.<br />
<br />
== Planned TODOs ==<br />
A panic command that can dump the TPM and shutdown the computer (without requiring the time of entering a password in sudo) forcing your adversary to resort to [https://en.wikipedia.org/wiki/Rubber-hose_cryptanalysis rubber-hose cryptanalysis] to get to your data</div>Krinhttps://wiki.archlinux.org/index.php?title=User:Krin/Secure_Boot,_full_disk_encryption,_and_TPM2_unlocking_install&diff=697911User:Krin/Secure Boot, full disk encryption, and TPM2 unlocking install2021-09-30T20:57:07Z<p>Krin: Complete secure boot section. Move some tips to earlier to be more useful.</p>
<hr />
<div>{{Unsupported|30 September 2021}}<br />
{{Expansion|Work In Progress, Draft from Installation Notes, Needs Testing}}<br />
{{Related articles start}}<br />
{{Related|Unified Extensible Firmware Interface/Secure Boot}}<br />
{{Related|Trusted Platform Module}}<br />
{{Related articles end}}<br />
<br />
== Introduction ==<br />
<br />
This installation is based on my installing Arch on an Asus ROG Strix G G531 I got second hand. The primary goals were to replace Windows 10 Pro with Bitlocker encryption and maintain the convienence and security balance of that original operating system.<br />
<br />
My requirements boiled down to:<br />
<br />
* A fully encrypted disk<br />
* Full Secure Boot validation of all UEFI components.<br />
* Use of the TPM to facilitate unlocking of the disk.<br />
* Hibernate/Suspend working.<br />
<br />
My primary use case here is to make it difficult enough for a baggage handler with sticky hands to get at my data that they just wipe the drive. A state level actor with the expertise and equipment to hot swap my ram in my hotel room is not something that I'm defending this ''particular'' laptop against. This is more for gaming and web browsing and uploading photos while traveling.<br />
<br />
I'll continue to update these notes as I develop further solutions.<br />
<br />
== Disclaimers ==<br />
<br />
This article is primarily for the author's own notes. It is assumed that the reader is familiar with the [[Installation guide]] and will refer to it often. Reading linked articles is recommended.<br />
<br />
== Initial Setup ==<br />
<br />
=== Pre-Installation ===<br />
<br />
Reset your Secure Boot settings in BIOS to enable setup mode. Usually this means you set Secure Boot to Enabled and then select the option to wipe out the keys.<br />
<br />
Follow the [[Installation_guide#Pre-installation]] up to Paritioning the Disks.<br />
<br />
=== Disk Preparation ===<br />
<br />
If you have data on your disks you want to overwrite, utilize [[Dm-crypt/Drive_preparation#dm-crypt_wipe_on_an_empty_disk_or_partition]] to wipe it. If this disk was previously encrypted, utilize [[Dm-crypt/Drive_preparation#Wipe_LUKS_header]] instead for a much faster disposal. Finally, use [[Dm-crypt/Encrypting_an_entire_system#LVM_on_LUKS]] to parition your drive with two differences.<br />
<br />
{{tip|Using a memorable LUKS passphrase until you've completed the install process can be helpful. It will take several reboots to finish setup.}}<br />
<br />
First, the partition layout will be as follows:<br />
<br />
{{hc|Partiton Layout|<br />
┌────────────────────┬──────────────────────────┬─────────────────────────────┐<br />
│ │ │ │<br />
│ EFI Boot Partition │ Logical Volume 1 │ Logical Volume 2 │<br />
│ │ │ │<br />
│ /efi │ [SWAP] │ / │<br />
│ │ │ │<br />
│ /dev/nvme0n1p1 │ /dev/CryptRootVG/swap │ /dev/CryptRootVG/root │<br />
│ │ │ │<br />
│ 512 MB │ 16 GB (Or RAM size) │ Remaining Free Space │<br />
│ │ │ │<br />
│ │ │ │<br />
│ ├──────────────────────────┴─────────────────────────────┤<br />
│ │ │<br />
│ │ LUKS and LVM Physical Volume │<br />
│ │ │<br />
│ │ /dev/nvme0n1p2 │<br />
│ │ │<br />
└────────────────────┴────────────────────────────────────────────────────────┘<br />
}}<br />
<br />
Second, if your hard drive is an SSD like this laptop, use the following command to open your LUKS volume.<br />
<br />
# cryptsetup open --perf-no_read_workqueue --perf-no_write_workqueue --persistent /dev/nvme0n1p2 cryptroot<br />
<br />
After completing your LUKS on LVM setup, format your EFI partition per [[EFI system partition]].<br />
<br />
# mkfs ext.vfat -F32 /dev/nvme0n1p2<br />
<br />
Mount this partition at {{ic|/mnt/efi}}. It is very important to leave {{ic|/boot}} on your encrypted root partition.<br />
<br />
== Installation ==<br />
<br />
Continue with [[Installation_guide#Installation]]. Be sure to flesh out your {{man|8|pacstrap}} with the following list of packages:<br />
<br />
* {{Pkg|dracut}}<br />
* {{Pkg|intel-ucode}}<br />
* {{Pkg|lvm2}}<br />
* {{Pkg|openssh}}<br />
* {{Pkg|ansible}}<br />
* {{Pkg|git}}<br />
* {{Pkg|iwd}}<br />
* {{Pkg|efibootmgr}}<br />
<br />
<br />
We are going to leave off the installation guide at the initramfs section, so go ahead and reset your root password. <br />
<br />
# passwd<br />
<br />
=== Bootloader ===<br />
<br />
{{warning|This section needs testing.}}<br />
<br />
First, install {{ic|systemd-boot}} by following [[Systemd-boot#Installing_the_EFI_boot_manager]]. Next, install {{aur|dracut-hook-uefi}}.<br />
<br />
Ensure you drop in a systemd-boot hook to update your bootctl any time it's updated.<br />
<br />
{{hc|/etc/pacman.d/hooks/998-systemd-boot.hook|2=<br />
[Trigger]<br />
Type = Package<br />
Operation = Install<br />
Operation = Upgrade<br />
Target = systemd<br />
<br />
[Action]<br />
Description = Updating systemd-boot<br />
When = PostTransation<br />
Exec = /usr/bin/bootctl update; <br />
}}<br />
<br />
Obtain the UUID of your LUKS drive via the following command:<br />
<br />
{{bc|<br />
blkid -s UUID -o value /dev/nvme0n1p2<br />
}}<br />
<br />
Create the following files with the listed content. Be sure to replace UUIDs with what you actually need. The extraneous {{ic:rd.luks.options}} should not cause an issue, but will be used once we've enabled secure boot. See {{man|5|dracut.conf}} for more information on what these commands do.<br />
<br />
A good portion of the kernel command line was as generated by dracut. Many are extraneous or you may wish to change some of the block device names.<br />
<br />
{{hc|/etc/dracut.conf.d/cmdline.conf|2=<br />
kernel_cmdline="rd.luks.uuid=luks-17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02 rd.luks.options=17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02 rd.lvm.lv=CryptRoot/root rd.lvm.lv=CryptRoot/swap resume=/dev/mapper/CryptRoot-swap root=/dev/mapper/CryptRoot-root rootfstype=ext4 rootflags=rw,relatime"<br />
}}<br />
<br />
{{hc|/etc/dracut.conf.d/flags.conf|2=<br />
compress="zstd"<br />
hostonly="yes"<br />
}}<br />
<br />
Run the following command to generate your EFI stub kernels.<br />
<br />
dracut --uefi<br />
<br />
=== Secure Boot ===<br />
<br />
{{note|The very newly developed [https://github.com/Foxboron/sbctl sbctl], availble via {{aur|sbctl-git}} has completely revamped this process and will only get better as they approach 1.0. From here on out, as of October 2021, this process should greatly simplify.}}<br />
<br />
{{note|Credit to this [https://lunaryorn.com/secure-boot-on-arch-linux-with-sbctl-and-dracut blog post by lunaryorn] for the inspiration.}}<br />
<br />
{{warning|This section is INCOMPLETE untested.}}<br />
<br />
Install {{Pkg|sbctl}}. At this point you will likely need to reboot and adjust your secure boot settings. You want secure boot in '''setup mode'''. <br />
<br />
{{bc|<br />
$ sbctl status<br />
Installed: X Sbctl is not installed<br />
Setup Mode: X Enabled<br />
Secure Boot: X Disabled<br />
}}<br />
<br />
Run the following commands as root. See {{man|8|sbctl}} for more information on their function. Of particular note is the {{ic|-s}} flag which indicates {{ic|sbctl}} should remember the file for future verification and signing.<br />
<br />
Note your Linux EFI binary name may be slightly different.<br />
<br />
{{bc|<br />
# sbctl create-keys<br />
Created Owner UUID a2ee3d08-725a-408b-9d95-28026a44611c<br />
Creating secure boot keys...✔<br />
Secure boot keys created!<br />
# sbctl verify<br />
Verifying file database and EFI images in /efi...<br />
✘ /efi/EFI/BOOT/BOOTx64.EFI is not signed<br />
<br />
✘ /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi is not signed<br />
<br />
✘ /efi/EFI/systemd/systemd-bootx64.efi is not signed<br />
<br />
# sbctl sign -s /efi/EFI/BOOT/BOOTx64.EFI<br />
✔ Signed /efi/EFI/BOOT/BOOTx64.EFI<br />
# sbctl sign -s /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
✔ Signed /efi/EFI/Linux/linux-5.14.8-arch1-1-8ac4653b867643879835f2c25c0d0cd7-rolling.efi<br />
# sbctl sign -s /efi/EFI/systemd/systemd-bootx64.efi<br />
✔ Signed /efi/EFI/systemd/systemd-bootx64.efi<br />
}}<br />
<br />
Finally, we need to let dracut know to sign it's unified kernel images when it creates them. Create the following file:<br />
<br />
{{hc|/etc/dracut.conf.d/secureboot.conf|2=<br />
uefi_secureboot_cert="/usr/share/secureboot/keys/db/db.pem"<br />
uefi_secureboot_key="/usr/share/secureboot/keys/db/db.key"<br />
}}<br />
<br />
Finally, enroll the Secure Boot keys.<br />
<br />
{{bc|<br />
# sbctl enroll-keys<br />
Enrolling keys to EFI variables...✔<br />
Enrolled keys to the EFI variables!<br />
}}<br />
<br />
Verify that secure boot now has an owner GUID and setup mode is disabled.<br />
<br />
{{bc|<br />
# sbctl status<br />
Installed: ✔ Sbctl is installed<br />
Owner GUID: a2ee3d08-725a-408b-9d95-28026a44611c<br />
Setup Mode: ✔ Disabled<br />
Secure Boot: ✘ Disabled<br />
}}<br />
<br />
Now reboot. This reboot is required so we can get the TPM measurements into their (hopefully) permanent state.<br />
== Justifications ==<br />
<br />
=== LVM on LUKS vs other dm-crypt approaches ===<br />
<br />
LVM on LUKS was selected becasue it is simply the easiest to manage while conferring both encrypted swap and disk. The other approaches required much more tooling and manual fussing to utilize. This selection also gives room change freely between {{ic|busybox}} and {{ic|systemd}} initrds.<br />
<br />
=== Using dracut ===<br />
<br />
{{Pkg|dracut}} just makes it easier to build full unified kernels that {{man|7|systemd-boot}} can launch as EFI binaries. There is also available tooling in the [[AUR]] for automating the creation of these binaries. Finally, {{ic|dracut}} will sign the binaries it creates automatically when configured to do so.<br />
<br />
=== Unified Kernel Images ===<br />
<br />
While UKI's could be problematic on other distributions, they fit right in with an Arch Linux install. The automation is there through pacman hooks and {{Pkg|sbctl}} to sign our UKIs as they're created. Furthermore, you can only sign and create a new signed UKI while booted into a properly signed UKI. It creates a chain of trust, which means it's important to never disable Secure Boot once you've set it up.<br />
<br />
The UKI encompasses all of the following items inside the signature, which means you can't change any of them without invalidating the signature.<br />
<br />
* Kernel arguments<br />
* Initrd/Initramfs<br />
* Kernel<br />
<br />
In particular, all other flavors of secureboot do not sign or validate the initramfs. This is a big attack area and can be relatively trivialized that a semi-decent pawn shop owner with Google could likely find an image that would grant him access and make the TPM none the wiser the system has changed.<br />
<br />
== Miscellaneous Discussions ==<br />
<br />
=== Filesystem Selection ===<br />
<br />
Most examples on Arch utilize {{ic|ext4}}, but other file systems such as {{ic|brtfs}} can work equally well. As for performance or issues with being inside LVM, [https://btrfs.wiki.kernel.org/index.php/FAQ#Btrfs_has_subvolumes.2C_does_this_mean_I_don.27t_need_a_logical_volume_manager_and_I_can_create_a_big_Btrfs_filesystem_on_a_raw_partition.3F this question in the brtfs FAQ] implie that there is some performance loss but no other issues.<br />
<br />
== Planned TODOs ==<br />
A panic command that can dump the TPM and shutdown the computer (without requiring the time of entering a password in sudo) forcing your adversary to resort to [https://en.wikipedia.org/wiki/Rubber-hose_cryptanalysis rubber-hose cryptanalysis] to get to your data</div>Krinhttps://wiki.archlinux.org/index.php?title=User:Krin/Secure_Boot,_full_disk_encryption,_and_TPM2_unlocking_install&diff=697908User:Krin/Secure Boot, full disk encryption, and TPM2 unlocking install2021-09-30T20:30:31Z<p>Krin: Rearrange when we create the systemd-boot update hook. Remove unneeded hook now we’ve moved to sbctl.</p>
<hr />
<div>{{Unsupported|30 September 2021}}<br />
{{Expansion|Work In Progress, Draft from Installation Notes, Needs Testing}}<br />
{{Related articles start}}<br />
{{Related|Unified Extensible Firmware Interface/Secure Boot}}<br />
{{Related|Trusted Platform Module}}<br />
{{Related articles end}}<br />
<br />
== Introduction ==<br />
<br />
This installation is based on my installing Arch on an Asus ROG Strix G G531 I got second hand. The primary goals were to replace Windows 10 Pro with Bitlocker encryption and maintain the convienence and security balance of that original operating system.<br />
<br />
My requirements boiled down to:<br />
<br />
* A fully encrypted disk<br />
* Full Secure Boot validation of all UEFI components.<br />
* Use of the TPM to facilitate unlocking of the disk.<br />
* Hibernate/Suspend working.<br />
<br />
My primary use case here is to make it difficult enough for a baggage handler with sticky hands to get at my data that they just wipe the drive. A state level actor with the expertise and equipment to hot swap my ram in my hotel room is not something that I'm defending this ''particular'' laptop against. This is more for gaming and web browsing and uploading photos while traveling.<br />
<br />
I'll continue to update these notes as I develop further solutions.<br />
<br />
== Disclaimers ==<br />
<br />
This article is primarily for the author's own notes. It is assumed that the reader is familiar with the [[Installation guide]] and will refer to it often. Reading linked articles is recommended.<br />
<br />
== Initial Setup ==<br />
<br />
=== Pre-Installation ===<br />
<br />
Disable Secure Boot in your BIOS. Follow the [[Installation_guide#Pre-installation]] up to Paritioning the Disks.<br />
<br />
=== Disk Preparation ===<br />
<br />
If you have data on your disks you want to overwrite, utilize [[Dm-crypt/Drive_preparation#dm-crypt_wipe_on_an_empty_disk_or_partition]] to wipe it. If this disk was previously encrypted, utilize [[Dm-crypt/Drive_preparation#Wipe_LUKS_header]] instead for a much faster disposal. Finally, use [[Dm-crypt/Encrypting_an_entire_system#LVM_on_LUKS]] to parition your drive with two differences.<br />
<br />
{{tip|Using a memorable LUKS passphrase until you've completed the install process can be helpful. It will take several reboots to finish setup.}}<br />
<br />
First, the partition layout will be as follows:<br />
<br />
{{hc|Partiton Layout|<br />
┌────────────────────┬──────────────────────────┬─────────────────────────────┐<br />
│ │ │ │<br />
│ EFI Boot Partition │ Logical Volume 1 │ Logical Volume 2 │<br />
│ │ │ │<br />
│ /efi │ [SWAP] │ / │<br />
│ │ │ │<br />
│ /dev/nvme0n1p1 │ /dev/CryptRootVG/swap │ /dev/CryptRootVG/root │<br />
│ │ │ │<br />
│ 512 MB │ 16 GB (Or RAM size) │ Remaining Free Space │<br />
│ │ │ │<br />
│ │ │ │<br />
│ ├──────────────────────────┴─────────────────────────────┤<br />
│ │ │<br />
│ │ LUKS and LVM Physical Volume │<br />
│ │ │<br />
│ │ /dev/nvme0n1p2 │<br />
│ │ │<br />
└────────────────────┴────────────────────────────────────────────────────────┘<br />
}}<br />
<br />
Second, if your hard drive is an SSD like this laptop, use the following command to open your LUKS volume.<br />
<br />
# cryptsetup open --perf-no_read_workqueue --perf-no_write_workqueue --persistent /dev/nvme0n1p2 cryptroot<br />
<br />
After completing your LUKS on LVM setup, format your EFI partition per [[EFI system partition]].<br />
<br />
# mkfs ext.vfat -F32 /dev/nvme0n1p2<br />
<br />
Mount this partition at {{ic|/mnt/efi}}. It is very important to leave {{ic|/boot}} on your encrypted root partition.<br />
<br />
== Installation ==<br />
<br />
Continue with [[Installation_guide#Installation]]. Be sure to flesh out your {{man|8|pacstrap}} with the following list of packages:<br />
<br />
* {{Pkg|dracut}}<br />
* {{Pkg|intel-ucode}}<br />
* {{Pkg|lvm2}}<br />
* {{Pkg|openssh}}<br />
* {{Pkg|ansible}}<br />
* {{Pkg|git}}<br />
* {{Pkg|iwd}}<br />
* {{Pkg|efibootmgr}}<br />
<br />
<br />
We are going to leave off the installation guide at the initramfs section, so go ahead and reset your root password. <br />
<br />
# passwd<br />
<br />
=== Bootloader ===<br />
<br />
{{warning|This section needs testing.}}<br />
<br />
First, install {{ic|systemd-boot}} by following [[Systemd-boot#Installing_the_EFI_boot_manager]]. Next, install {{aur|dracut-hook-uefi}}.<br />
<br />
Ensure you drop in a systemd-boot hook to update your bootctl any time it's updated.<br />
<br />
{{hc|/etc/pacman.d/hooks/998-systemd-boot.hook|2=<br />
[Trigger]<br />
Type = Package<br />
Operation = Install<br />
Operation = Upgrade<br />
Target = systemd<br />
<br />
[Action]<br />
Description = Updating systemd-boot<br />
When = PostTransation<br />
Exec = /usr/bin/bootctl update; <br />
}}<br />
<br />
Obtain the UUID of your LUKS drive via the following command:<br />
<br />
{{bc|<br />
blkid -s UUID -o value /dev/nvme0n1p2<br />
}}<br />
<br />
Create the following files with the listed content. Be sure to replace UUIDs with what you actually need. The extraneous {{ic:rd.luks.options}} should not cause an issue, but will be used once we've enabled secure boot. See {{man|5|dracut.conf}} for more information on what these commands do.<br />
<br />
A good portion of the kernel command line was as generated by dracut. Many are extraneous or you may wish to change some of the block device names.<br />
<br />
{{hc|/etc/dracut.conf.d/cmdline.conf|2=<br />
kernel_cmdline="rd.luks.uuid=luks-17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02 rd.luks.options=17eb0a1e-0e1a-4d06-9bf0-a4f8c5eebb02 rd.lvm.lv=CryptRoot/root rd.lvm.lv=CryptRoot/swap resume=/dev/mapper/CryptRoot-swap root=/dev/mapper/CryptRoot-root rootfstype=ext4 rootflags=rw,relatime"<br />
}}<br />
<br />
{{hc|/etc/dracut.conf.d/flags.conf|2=<br />
compress="zstd"<br />
hostonly="yes"<br />
}}<br />
<br />
Run the following command to generate your EFI stub kernels.<br />
<br />
dracut --uefi<br />
<br />
=== Secure Boot ===<br />
<br />
{{note|The very newly developed [https://github.com/Foxboron/sbctl sbctl], availble via {{aur|sbctl-git}} has completely revamped this process and will only get better as they approach 1.0. From here on out, as of October 2021, this process should greatly simplify.}}<br />
<br />
{{note|Credit to this [https://lunaryorn.com/secure-boot-on-arch-linux-with-sbctl-and-dracut blog post by lunaryorn] for the inspiration.}}<br />
<br />
{{warning|This section is INCOMPLETE untested.}}<br />
<br />
Install {{Pkg|sbctl}}. At this point you will likely need to reboot and adjust your secure boot settings. You want secure boot in '''setup mode'''. The verbiage in various UEFI software differs, but it generally involves enabling Secure Boot and erasing all keys or resetting the key database. If you get the following output, you're in the right state.<br />
<br />
{{bc|<br />
$ sbctl status<br />
Installed: X Sbctl is not installed<br />
Setup Mode: X Enabled<br />
Secure Boot: X Disabled<br />
}}<br />
<br />
== Justifications ==<br />
<br />
=== LVM on LUKS vs other dm-crypt approaches ===<br />
<br />
LVM on LUKS was selected becasue it is simply the easiest to manage while conferring both encrypted swap and disk. The other approaches required much more tooling and manual fussing to utilize. This selection also gives room change freely between {{ic|busybox}} and {{ic|systemd}} initrds.<br />
<br />
=== Using dracut ===<br />
<br />
{{Pkg|dracut}} just makes it easier to build full unified kernels that {{man|7|systemd-boot}} can launch as EFI binaries. There is also available tooling in the [[AUR]] for automating the creation of these binaries. Finally, {{ic|dracut}} will sign the binaries it creates automatically when configured to do so.<br />
<br />
== Miscellaneous Discussions ==<br />
<br />
=== Filesystem Selection ===<br />
<br />
Most examples on Arch utilize {{ic|ext4}}, but other file systems such as {{ic|brtfs}} can work equally well. As for performance or issues with being inside LVM, [https://btrfs.wiki.kernel.org/index.php/FAQ#Btrfs_has_subvolumes.2C_does_this_mean_I_don.27t_need_a_logical_volume_manager_and_I_can_create_a_big_Btrfs_filesystem_on_a_raw_partition.3F this question in the brtfs FAQ] implie that there is some performance loss but no other issues.<br />
<br />
== Planned TODOs ==<br />
A panic command that can dump the TPM and shutdown the computer (without requiring the time of entering a password in sudo) forcing your adversary to resort to [https://en.wikipedia.org/wiki/Rubber-hose_cryptanalysis rubber-hose cryptanalysis] to get to your data</div>Krin