Skip to content

Commit

Permalink
feat: add bootloader and UKI instructions
Browse files Browse the repository at this point in the history
This adds instructions on how to configure systemd-boot and dracut to
create a UKI kernel image as a EFI executable which is able to boot
the LUKS encrypted filesystems.

Refs: #4, $5, #11
Signed-off-by: Jaremy Hatler <hatler.jaremy@gmail.com>
  • Loading branch information
jhatler committed Jan 3, 2024
1 parent 204990f commit 71f1320
Showing 1 changed file with 123 additions and 78 deletions.
201 changes: 123 additions & 78 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -667,93 +667,138 @@ find / -type d -path /boot/efi -prune -o -path /proc -prune -o -type f -executab
find / -type d -path /boot/efi -prune -o -path /proc -prune -o -type f -not -executable -not -newer /tmp/prebuild_checkpoint -print0 2>/dev/null | xargs -0 file --no-pad --separator="@@@" | grep '@@@.*\( ELF\| ar archive\)'
```

### Bootloader and Other System Configuration

The non-tivial issues encountered were:
- app-shells/fish needs the usersandbox feature disabled for tests to pass.
- [Gentoo Bug 838187](https://bugs.gentoo.org/838187)
- The betamax python package was [forked](https://github.com/jhatler/betamax) until the following issues are resolved. The fork was placed in a local repository called ```local```.
- [betamax#200](https://github.com/betamaxpy/betamax/issues/200)
- [betamax#203](https://github.com/betamaxpy/betamax/issues/203)
- [betamax#204](https://github.com/betamaxpy/betamax/issues/204)
- The ```dev-python/uvloop``` package was copied to the ```local``` repository and the patch found in the below issue was added. The dependency on a pre-v3 version of ```cython``` was removed.
- [uvloop#586](https://github.com/MagicStack/uvloop/issues/586)
- The ```dev-python/autocommand``` package needed patched with the below PR due to the below bug.
- [autocommand#31](https://github.com/Lucretiel/autocommand/pull/31)
- [Gentoo Bug 917754](https://bugs.gentoo.org/917754)
- The ```dev-python/cython``` tests failed to pass due to a path traversal error. This was resolved with the patch prodived to the below Gentoo bug.
- [Gentoo Bug 912814](https://bugs.gentoo.org/912814)
- The ```dev-python/inflect``` package had a failing test which was fixed with the patch from the below PR submitted upstream.
- [inflect#205](https://github.com/jaraco/inflect/pull/205)
- The ```dev-python/pytest-mock``` package had failing tests fixed in the below commits which were added as patches to my portage.
- [pytest-mock#403](https://github.com/pytest-dev/pytest-mock/pull/403)
- [pytest-mock#404](https://github.com/pytest-dev/pytest-mock/pull/404)
- The ```dev-python/send2trash``` package fails its tests due to bad cross-platform support. The package was copied to the ```local``` repository and a patch was added to add additional checks before importing the mac and windows support.
- The ```dev-python/terminado``` package had a missing BDEPEND on ```dev-python/pytest-timeout``` needed for testing.
- The ```dev-python/pytest-virtualenv``` test called ```test_installed_packages``` had to be disabled due to a deprecation warning not expected by the test.
- The ```dev-python/Faker``` package was copied to the ```local``` repository so the ```test_ssn_without_age_range``` test could be disabled. This test fails due to a bug in the upstream package.
- [Faker#1956](https://github.com/joke2k/faker/issues/1956)
- The ```dev-vcs/mercurial``` package has flaky tests under parallelism, so they were disabled.
- The tests of the following packages failed in non-concerning ways so I disabled them until I had the energy/time to dig in further.
- ```sys-libs/glibc```
- ```dev-python/cryptography```
- ```dev-python/pypiserver```
- ```dev-python/pycurl```
- ```curl``` needs downgraded to 8.3.0
- The tests of ```sys-devel/gcc``` can be idealistic and some failures seem to be commonplace, per the Gentoo Buzilla. A baseline of the test results was prepared using the below command.
- ```GCC_TESTS_NO_IGNORE_BASELINE=1 emerge -v1 sys-devel/gcc```
- ```dev-python/html5lib``` needed the patch in the below PR to be applied for the tests to complete.
- [html5lib#570](https://github.com/html5lib/html5lib-python/pull/570/)
- ```dev-libs/glib``` requires ```dev-util/desktop-file-utils``` to be installed to bypass an ebuild bug which doesn't properly disable the dependent tests.
- This command must be used to bypass the circular dependency ```FEATURES="-test" emerge -av dev-util/desktop-file-utils```
- ```systemd-machine-id-setup``` must be run before trying the ```dev-libs/glib``` tests.
- ```dev-python/Pillow``` needs the following commit applied as a patch for the tests to pass.
- [Pillow#7594](https://github.com/python-pillow/Pillow/pull/7594)
- ```app-accessibility/at-spi2-core``` requires ```app-editors/gedit``` to be installed for the tests to pass.
- [Gentoo Bug 678372](https://bugs.gentoo.org/678372)
- ```dev-util/umockdev``` needs ```x11-apps/xinput``` and ```x11-drivers/xf86-input-synaptics``` for the tests to pass.
- The below patch from Debian was applied to ```net-libs/libsoup-2.74.3``` to resolve a testing failure recorded in the below bug.
- [skip-tls_interaction-test.patch](https://sources.debian.org/data/main/libs/libsoup2.4/2.74.3-2/debian/patches/skip-tls_interaction-test.patch)
- [libsoup#120](https://gitlab.gnome.org/GNOME/libsoup/-/issues/120)
- The ```gnome-base/dconf``` packages is needed for the ```net-libs/uhttpmock``` tests to work.
- A single test, listed below, was failing on ```dev-python/matplotlib```. It was disabled for now given that package had to disable many tests to work.
- ```tests/test_image.py::test_imshow_masked_interpolation[png]```

Once the package testing was complete, the gentoo repository was updated to use git instead of rsync for syncing.

The /var/db/repos/gentoo directory was deleted. Then the ```/etc/portage/repos.conf/gentoo.conf``` file was updated to the below:
The timezone was set to UTC:

```bash
ln -sf ../usr/share/zoneinfo/UTC /etc/localtime
```

A hostname was configured using [the instructions here.](https://wiki.gentoo.org/wiki/Systemd#Hostname)

The journal was made peristent by updating ```/etc/systemd/journald.conf``` on the following lines:

```text
[DEFAULT]
main-repo = gentoo
[gentoo]
location = /var/db/repos/gentoo
sync-type = git
sync-uri = https://github.com/gentoo/gentoo.git
auto-sync = yes
clone-depth = 0
sync-depth = 0
sync-openpgp-key-path = /usr/share/openpgp-keys/gentoo-release.asc
sync-openpgp-keyserver = hkps://keys.gentoo.org
sync-openpgp-key-refresh-retry-count = 40
sync-openpgp-key-refresh-retry-overall-timeout = 1200
sync-openpgp-key-refresh-retry-delay-exp-base = 2
sync-openpgp-key-refresh-retry-delay-max = 60
sync-openpgp-key-refresh-retry-delay-mult = 4
```

A new sync was done by running ```emerge --sync```.
...
Storage=auto
Compress=yes
...
```

### GCC Optimization
A root password was set using ```passwd```.

Now that a baseline copy of the GCC tests had been created, the gcc use flags were updated to updated to optimize the build
and support graphite (isl). This was done by creating the file ```/etc/portage/package.use/gcc``` with the following line:
sshd was enabled using the command ```systemctl enable sshd```. Root logins were allowed by updating
```/etc/ssh/sshd_config``` on the below line.

```text
>=sys-devel/gcc-13 graphite lto pgo zstd
...
PermitRootLogin yes
...
```

The ```systemd-networkd-wait-online``` was masked using the below command:

```bash
systemctl mask systemd-networkd-wait-online.service
```

```/etc/fstab``` was updated to the following:

```text
/dev/mapper/cryptboot /boot ext4 defaults 0 0
/dev/disk/by-label/esp0 /boot/efi vfat defaults 0 0
/dev/disk/by-label/esp1 /boot/efi.nvme1n1 vfat defaults 0 0
/dev/disk/by-label/esp2 /boot/efi.nvme2n1 vfat defaults 0 0
/dev/mapper/cryptswap0 none swap sw 0 0
/dev/mapper/cryptswap1 none swap sw 0 0
/dev/mapper/cryptswap2 none swap sw 0 0
/dev/mapper/vg0-root0 / btrfs compress=zstd,discard=async,max_inline=0,space_cache=v2,ssd,commit=120,user_subvol_rm_allowed,subvol=@gentoo 0 0
/dev/mapper/vg0-data0 /home btrfs compress=zstd,discard=async,max_inline=0,space_cache=v2,ssd,commit=120,user_subvol_rm_allowed,subvol=@gentoo-home 0 0
/dev/mapper/vg0-data0 /var/cache btrfs compress=zstd,discard=async,max_inline=0,space_cache=v2,ssd,commit=120,user_subvol_rm_allowed,subvol=@gentoo-var-cache 0 0
/dev/mapper/vg0-data0 /var/db btrfs compress=zstd,discard=async,max_inline=0,space_cache=v2,ssd,commit=120,user_subvol_rm_allowed,subvol=@gentoo-var-db 0 0
/dev/mapper/vg0-data0 /var/log btrfs compress=zstd,discard=async,max_inline=0,space_cache=v2,ssd,commit=120,user_subvol_rm_allowed,subvol=@gentoo-var-log 0 0
/dev/mapper/vg0-data0 /var/tmp btrfs compress=zstd,discard=async,max_inline=0,space_cache=v2,ssd,commit=120,user_subvol_rm_allowed,subvol=@gentoo-var-tmp 0 0
/dev/mapper/vg0-root0 /mnt/btrfs/root btrfs compress=zstd,discard=async,max_inline=0,space_cache=v2,ssd,commit=120,user_subvol_rm_allowed 0 0
/dev/mapper/vg0-data0 /mnt/btrfs/data btrfs compress=zstd,discard=async,max_inline=0,space_cache=v2,ssd,commit=120,user_subvol_rm_allowed 0 0
```

LVM was configured to allow discards by updating ```/etc/lvm/lvm.conf``` to uncomment the below line:

```text
...
issue_discards = 1
...
```

systemd-boot was installed using the below command.

```bash
bootctl install
```

#### Dracut Setup and UKI Generation

Dracut needs configured to support the secure booting of the system.

The ```/etc/dracut.conf``` file was cleared and the below two lines were added initially.

```text
uefi="yes"
add_dracutmodules+=" bash btrfs crypt dm lvm mdraid systemd rescue rootfs-block "
```

The file needs the ```kernel_cmdline``` parameter added still.

This requires the UUIDs of each of the LUKS partitions. These can be found using the below commands:

```bash
blkid /dev/md127 /dev/nvme{0,1,2}n1p{3,4}
```

The cmdline should begin with: ```rd.auto rd.lvm=1 rd.dm=1 rd.md=1 rd.luks=1 rd.luks.allow-discards```

Then each LUKS volume needs added to the cmdline separated by spaces. The format is below and separated by newlines to make reading it easier.
The portions in [] should be replaced with the specified value from the above ```blkid``` command.

```text
rd.luks.uuid=[UUID of /dev/nvme0n1p3]
rd.luks.name=[UUID of /dev/nvme0n1p3]=cryptswap0
rd.luks.uuid=[UUID of /dev/nvme1n1p3]
rd.luks.name=[UUID of /dev/nvme1n1p3]=cryptswap1
rd.luks.uuid=[UUID of /dev/nvme2n1p3]
rd.luks.name=[UUID of /dev/nvme2n1p3]=cryptswap2
rd.luks.uuid=[UUID of /dev/md127]
rd.luks.name=[UUID of /dev/md127]=cryptboot
rd.luks.uuid=[UUID of /dev/nvme0n1p4]
rd.luks.name=[UUID of /dev/nvme0n1p4]=cryptdata0
rd.luks.uuid=[UUID of /dev/nvme1n1p4]
rd.luks.name=[UUID of /dev/nvme1n1p4]=cryptdata1
rd.luks.uuid=[UUID of /dev/nvme2n1p4]
rd.luks.name=[UUID of /dev/nvme2n1p4]=cryptdata2
```

Finally, the cmdline should be ended with the following settings to specify the root filesystem location and mount flags.

```
root=/dev/mapper/vg0-root0 rootflags=compress=zstd,discard=async,max_inline=0,space_cache=v2,ssd,commit=120,user_subvol_rm_allowed,subvol=@gentoo
```

The complete string comprising of the above three sections needs to be on a single line in quotes and added to the end of the
```/etc/dracut.conf``` file. That file should look like this when complete:

```text
uefi="yes"
add_dracutmodules+=" bash btrfs crypt dm lvm mdraid systemd rescue rootfs-block "
kernel_cmdline="[COMBINDED CMDLINE]"
```

Now that dracut is configured, a UKI image can be created using the command below:

```bash
emerge --config sys-kernel/gentoo-kernel-bin
```

The the systemd was updated using this command:

```bash
emerge -avuDU --with-bdeps=y @world
Expand Down

0 comments on commit 71f1320

Please sign in to comment.