Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add service for root disk unlocking #90

Merged
merged 2 commits into from
Mar 27, 2024

Conversation

simoncampion
Copy link

@simoncampion simoncampion commented Mar 16, 2024

Add service for root disk unlocking

Currently, root disk unlocking in the initramfs has to be triggered by setting a kernel argument rd.luks... in the Ignition config. This has two disadvantages. First, it would be nicer for the users if they did not have to set a kernel argument to make root disk unlocking work. Second, during first boot, it leads to an unnecessary systemd-cryptsetup unit that (at least sometimes) fails. While this failing unit causes no harm, it does make the tests fail and might confuse users.

The systemd-cryptsetup-generator does not generate because we don't have appropriate entries in /etc/crypttab in the initramfs. This PR adds a service that works around this issue by generating a crypttab file, calling systemd-cryptsetup-generator on that crypttab file to generate a systemd-cryptsetup service to decrypt the root, and then starting that service.

How to use

Root disk decryption set up with storage.luks in Ignition should work without passing special kernel arguments in the Ignition config.

Testing done

I built the amd64 image based on this scripts PR and ran the TPM and Tang tests as modified in this bootengine PR.

mantle on remove-luks-cmdline ❯ sudo ./bin/kola run -k cl -p qemu --board amd64-usr --qemu-image ./root-unlock-service.img cl.tpm.* cl.tang.*
2024-03-24T12:54:24Z kola: Using "3916.0.0+nightly-20240321-2100-1-gee375fb003" as version to filter tests...
=== RUN   cl.tpm.root
=== RUN   cl.tpm.nonroot
=== RUN   cl.tang.root
=== RUN   cl.tang.nonroot
--- PASS: cl.tpm.root (61.14s)
--- PASS: cl.tang.nonroot (54.54s)
        tang.go:149: Started tang on 10.0.0.1:44339
--- PASS: cl.tang.root (68.06s)
        tang.go:149: Started tang on 10.0.0.1:43983
--- PASS: cl.tpm.nonroot (54.53s)
PASS, output in _kola_temp/qemu-2024-03-24-1354-761048

I failed to get cross-compilation to work and hence have not run the arm64 tests yet. Running CI on the scripts PR will build the arm64 image and I can then run the updated tests against that image.

  • Changelog entries added in the respective changelog/ directory (user-facing change, bug fix, security fix, update)
  • Inspected CI output for image differences: /boot and /usr size, packages, list files for any missing binaries, kernel modules, config files, kernel modules, etc.

@simoncampion
Copy link
Author

It turns out that the systemd-generators in the initramfs run very early, even before device files for block devices are created in /dev/. So far, I couldn't come up with a way for the generator to figure out the UUID of the ROOT partition under these circumstances. Any ideas would be very welcome.

If we decide that it's not feasible to implement this generator, we could instead implement a systemd service that runs in the initramfs or even during late user space boot. That service would determines the UUID of the ROOT partition and add rd.luks.uuid=$uuid to the kernel cmdline parameters in grub.cfg. It would bring the same benefits as the generator: the user would not need to specify the rd.luks parameter in their Ignition config, and we would ensure that the cmdline parameter is not yet present during the first boot.

@pothos
Copy link
Member

pothos commented Mar 17, 2024

About the timing; generators may run multiple times. We could also have a look at how the systemd gpt auto generator manages to "wait" for the device.

@simoncampion
Copy link
Author

simoncampion commented Mar 18, 2024

We could also have a look at how the systemd gpt auto generator manages to "wait" for the device.

I might be reading the code wrong, but I think the systemd-gpt-auto-generator does not itself wait for device files to appear. Instead, it generates a cryptsetup service that waits for a device file to appear, which is later created by udev (see here). We could adapt that strategy by adding a systemd service that decrypts the ROOT partition once it's available, but the whole idea was to just piggy-back on the cryptsetup-generator rather than writing our own decryption service.

About the timing; generators may run multiple times.

What did you have in mind here? One option that might work (not sure whether that's what you thought of) is to trigger re-running of generators by adding a service that runs systemctl daemon-reload. If we do this after udev, the generator I wrote would probably work because all the device files are present. However, I'm not sure running systemctl daemon-reload is a good idea, since this is a global operation and might have unintended side-effects.

@pothos
Copy link
Member

pothos commented Mar 22, 2024

Thanks, thinking about this I guess we can try to define a helper service that runs the logic to invoke the generator. Since we know what service the generator will write out, we can explicitly start this generated service with systemctl start. It's best to avoid the daemon-reload and we can do so by calling the generator with /etc/systemd/system/ as directory to write to.

@simoncampion simoncampion force-pushed the root-unlock-generator branch from fa49847 to b9f3b12 Compare March 24, 2024 10:43
@simoncampion
Copy link
Author

Thanks, thinking about this I guess we can try to define a helper service that runs the logic to invoke the generator. Since we know what service the generator will write out, we can explicitly start this generated service with systemctl start. It's best to avoid the daemon-reload and we can do so by calling the generator with /etc/systemd/system/ as directory to write to.

Sounds good 👍 I implemented this approach. Let me know what you think.

@simoncampion simoncampion changed the title Add generator for root disk unlocking Add service for root disk unlocking Mar 24, 2024
@simoncampion simoncampion marked this pull request as ready for review March 24, 2024 11:11
@simoncampion simoncampion force-pushed the root-unlock-generator branch from b9f3b12 to 66145c3 Compare March 25, 2024 14:17
@simoncampion
Copy link
Author

I added the service under 31decrypt-root/ but I'm uncertain whether 31 is the most appropriate number here because I'm uncertain about what the logic behind the names of the various dracut modules in dracut/ is. Let me know if a different number prefix would be more fitting.

@ader1990
Copy link
Contributor

ader1990 commented Mar 26, 2024

I added the service under 31decrypt-root/ but I'm uncertain whether 31 is the most appropriate number here because I'm uncertain about what the logic behind the names of the various dracut modules in dracut/ is. Let me know if a different number prefix would be more fitting.

Hello @simoncampion, the only usable systemd command for this scenario is systemd-analyze plot. I used it succesfully during my kmod static nodes PR, to be able to see properly the systemd execution tree during initrd and after switch root.

Should look like this and is very helpful to see the order
plot-base

@pothos pothos merged commit 357ca18 into flatcar:flatcar-master Mar 27, 2024
@simoncampion
Copy link
Author

@ader1990 Thanks for the hint! That's a neat command.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants