Bare Metal Arch Linux Installation
Table of Contents
This page provides a guide to the configuration, installation, and set up, of all the various components for new bare-metal systems, including UEFI, Secure Boot, Boot Loaders, the Operating System, and Ansible plays, to prepare a new or wiped system back to full operation.
Initial Configuration #
The first steps are to boot the system using an Arch Linux USB or ISO image, and
prepare it to receive remote connections over SSH so that Ansible can run the
bootstrap
.
Given Secure Boot is disabled in the UEFI for this system, simply plug in the USB to the host, along with a keyboard and monitor, and power on. The USB will normally be the only bootable device, and the UEFI will therefore select this by default, booting into the Arch Linux installation environment.
If this is not the case, press
Ctrl
+F10
during the first second of power on to select the boot device menu from the UEFI (entering the Supervisor password when asked) and select the USB device from the available list.Once booted and logged into the
root
console, set the hostname for the device usinghostnamectl
:$ hostnamectl hostname {hostname}
Configure the initial networking with
ip
to provide the node with access to thekub3-node
VLAN and default routing for access for installation:$ ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host noprefixroute valid_lft forever preferred_lft forever 2: enp86s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9000 qdisc mq state UP group default qlen 1000 link/ether 48:21:eb:55:83:7b brd ff:ff:ff:ff:ff:ff inet6 fe80::4821:ebff:fe55:837b/64 scope link proto kernel_ll valid_lft forever preferred_lft forever
Take note of the link-local (
scope link
) address on theenp86s0
interface above, and specifically anything after thefe80::
prefix. This part of the address is the EUI64 address for the interface and will need to be appended to the network prefix (see below). It will be important to get both the IPv4 and IPv6 addresses are correct to ensure that the network settings are correctly configured by Ansible in all future runs.Once ready, then add all IPv4 and IPv6 settings as follows:
$ ip link add link {dev} name {dev}.32 type vlan id 32 $ ip -4 addr add 172.23.32.{number}/24 dev {dev}.32 $ ip -4 route add 0.0.0.0/0 via 172.23.32.1 $ ip -6 addr add 2a02:8010:8006:3a32:{eui64-address}/64 dev {dev}.32
The IPv6 route will automatically received any processed by the Router Advertisements sent byrouter-lan-01
and can be verified by checking with the following command:$ ip -6 route ::/64 dev wlan0 proto ra metric 256 expires 2591909sec pref medium default via fe80::7a9a:18ff:fe49:b230 dev wlan0 proto ra metric 256 expires 3509sec pref high
Set the
root
user password on the live installation image to allow remove access for configuration using Ansible:$ passwd New password: {password} Retype new password: {password} password: password updated successfully
Bootstrapping #
The bootstrapping of the system is the biggest part of the configuration of the host and is fully automated. It should take about 2-3 minutes to complete on each host and will set up all filesystems, bootstrap the operating system, and pre-configure the host ready to be rebooted into itself.
Start an SSH session to the
root
user on the host to be installed, but ensure that the Host Key is neither saved nor verified for this host as it will be using a temporary one generated by the installation image:$ ssh \ -o StrictHostKeyChecking=no \ -o UserKnownHostsFile=/dev/null \ {hostname} root@{hostname} ~ #
Taking a clone of the Ansible repository, run the
bootstrap
using theTaskfile.yaml
. If this system is new to the n3tuk Lab, then ensure that the host is listed in theinventory.yaml
file, as well as having it’s own variables file underhosts_vars
.$ task bootstrap SSH password: {password} PLAY [Bootstrap new physical and virtual machines with Arch Linux] *************
If the
bootstrap
play only needs to be focused on a single host, or selected hosts, then thelimit=
argument can be provided on the command-line to only run on those hosts:$ task baseline limit=node-01.s.cym-south-1.kub3.uk BECOME password: {password}
Secure Booting #
To optimise the security of the system, Secure Boot should be enabled to verify that the kernel and initial images have not been tampered with, and as such allow the encrypted filesystem to be unlocked automatically (especially important as this is a remotely-managed server).
Although the bootstrapping steps above ensure that the keys are configured, and the kernels are set up and signed with them, we need to prepare the system to accept the public keys and then enable Secure Boot.
Once successfully run, reboot the system and press
Ctrl
andF2
to access the UEFI interface, entering in the required password for the Supervisor on this system.Press
Tab
until Boot is highlighted, and pressEnter
, then godown
and select Reset to Setup Mode, confirming with Yes on the pop-up. This will allow the Secure Boot keys to be enrolled into the UEFI BIOS and validate signed kernels for booting. PressCtrl
+F10
then select Yes to save the settings and reboot.Once the system has been rebooted, unlock the storage partition (locally), log in as the
root
account (either directly via the console, or remotely via a user account who cansudo
into theroot
account. From there, runsbctl
to verify Secure Boot is ready to be loaded with our custom keys:$ sbctl status Installed: ✓ sbctl is installed Owner GUID: 00000000-0000-0000-0000-000000000000 Setup Mode: ✗ Enabled Secure Boot: ✗ Disabled Vendor Keys: none
So long as Setup Mode is showing as Enabled, run the
sbctl enroll-keys
command to load the locally generated keys into the database, ensuring that the Microsoft keys are enrolled too:$ sbctl enroll-keys --microsoft Enrolling keys to EFI variables... With vendor keys from microsoft...✓ Enrolled keys to the EFI variables!
To verify this has worked as expected, again reboot the system and press
Ctrl
andF2
to access the UEFI interface, entering in the required password for the Supervisor on this system.Press
Tab
until Boot is highlighted, and pressEnter
, then godown
and select Secure Boot, changing Secure Boot in the following screen to Enabled. PressCtrl
+F10
then select Yes to save the settings and reboot.The system should boot as normal, but with Secure Boot enabled. If there is a warning message about the authenticity of the boot loader or kernels, then disable Secure Boot in the UEFI following the above steps, and then reboot in the system and run:
$ sbctl sign-all ✓ Signed /efi/EFI/Linux/linux-hardened.efi ✓ Signed /efi/EFI/Linux/linux-lts.efi
To verify that Secure Boot is fully operational and the signed kernels are loaded correctly, and that Setup Mode has been disabled (so no new keys can be added), run
sbctl status
:$ sbctl status Installed: ✓ sbctl is installed Owner GUID: 00000000-0000-0000-0000-000000000000 Setup Mode: ✓ Disabled Secure Boot: ✓ Enabled Vendor Keys: microsoft
TPM Enrollment #
Once we are booting with Secure Boot enabled, the system is ready to enroll the TPM chip into the boot process by storing an encrypted key to unlock the encrypted filesystem, so long as nothing has been tampered. The following steps will accomplish this.
The next step is to enroll the encrypted filesystem into the TPM module on the system, which allows the UEFI/TPM module to provided the decryption key for the filesystem, so long as the system has not been tampered and the kernels are signed.
First, verify that the TPM device is available to be configured:
$ systemd-cryptenroll --tpm2-device=list PATH DEVICE DRIVER /dev/tpmrm0 MSFT0101:00 tpm_crb
$ systemd-cryptenroll \ --tpm2-device=auto \ --tpm2-pcrs=0+7 \ /dev/nvme0n1p2 Please enter current passphrase for disk /dev/nvme0n1p2: {passphrase} New TPM2 token enrolled as key slot 1.
The TPM2 should now be enrolled and the system can boot with a signed kernel only and decrypt the filesystem provided there’s been no change to the UEFI firmware and Secure Boot remains enabled. The
/etc/crypttab
files already support TPM2 unlocking, so no further configuration is required.
Baselining #
Once a system has been bootstrapped and configured for secure booting, we can
run the baseline
play against the server. This ensures that
all final configurations are made and anything which should not be installed
during bootstrapping is installed now.
The final step is to run the
baseline
play from the Ansible repository using theTaskfile.yaml
:$ task baseline BECOME password: {password} PLAY [Baseline all physical machines] ******************************************
Like with the
bootstrap
play above, ifbaseline
only needs to be focused on a single host, or selected hosts, then thelimit=
argument can be provided on the command-line to only run on those hosts:$ task baseline limit=node-01.s.cym-south-1.kub3.uk BECOME password: {password}
This will ensure that the final utilities and configurations are installed (such as
firewalld
), and then that the system is ready to operate as required (running the appropriate plays for the specific services and configurations needed).
- Reboot the system to verify everything operates as expected.