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

WIP: Enable initramfs-etc.img as an appended initramfs #364

Closed
wants to merge 1 commit into from
Closed

WIP: Enable initramfs-etc.img as an appended initramfs #364

wants to merge 1 commit into from

Conversation

darkmuggle
Copy link
Contributor

@darkmuggle darkmuggle commented Apr 23, 2020

The idea here is to enable configuration needed during the initramfs
without requiring the re-generation of it.

Previous models including [1] were considered. As counter-idea, it was
suggested to add to Dracut the ability to source in a signed CPIO
archive or at least checksum it (e.g. boot-etc=/boot/foo.cpio:sha256) and then
rely on signed kargs. The chief concerns is that we need to ensure that
the content is machine specific and not enable an easy boot-foot gun.

This solution used Grub as the enforcement mechanism for both
authenticity and authentication of the change and bypasses Dracut
all-together. The core advantage is that admin could enable secure boot,
set the Grub password (to prevent menu editing) and then Grub would only
set "initramfs-etc='...'" if the file checked out.

[1] dracutdevs/dracut#792

@darkmuggle
Copy link
Contributor Author

darkmuggle commented Apr 23, 2020

Note: this is missing updating the blsconfig.

Throwing this up for an early review. I can see strong arguments against this, and I can see strong arguments to having Dracut as the enforcement mechanism. This is a bit more complicated than I'd like.

To support this we'll need to change:

  • rpm-ostree to add $initramfs_etc to the loader line
  • COSA will need the default grub2.cfg to support it

The envisioned user story is:

  • files are dropped in /etc
  • the user runs initramfs-etc --create

Finally, this is in rough shape, so it needs more work.

/cc @jlebon @ashcrow @cgwalters

@ashcrow ashcrow requested review from ashcrow, cgwalters and jlebon April 23, 2020 19:57
@ashcrow
Copy link
Member

ashcrow commented Apr 23, 2020

I can see promise in this. Thank you for putting this together @darkmuggle. My initial question is around how kmods-via-containers would change to support this if we are trying to get to first boot kmods. Would we move kmods-via-containers to be a build once, and then provide a machine-kmods-container, which housed the cpio, and drop after networking is up in initramfs but before we switch to real root?

@ashcrow ashcrow requested a review from miabbott April 23, 2020 20:08
@ashcrow
Copy link
Member

ashcrow commented Apr 23, 2020

/cc @imcleod too :-)

@cgwalters
Copy link
Member

It still seems a lot simpler to me to have as a kernel argument:
rd.initrdconfig=/initrdconfig-v1.cpio@sha256:a96c2a54a95b52b17d87da72c19247ed41a4f829678e9dfba0449284a224f40d

And all our dracut module does is verify the checksum and unpack that file early on in boot.

Today we're not verifying the kernel arguments, but we need to do so as part of securing the boot process, and there are already tools to do that. Inventing our own signing system seems like a large burden to carry.

I guess to me what's important is that we come up a model where we think we can come by later and add signing, not that we do it right now. Having a separate "bootconfig.cpio" file that's separate from our code that we sign is part of ensuring we lay the groundwork for a future design there - it means e.g. that when we ship an OS update, the initramfs only needs to be verified with our key, any configuration (kargs, bootconfig.cpio) needs to be verified with the user key.

Though in practice maybe we will end up with a model where we do something like this: https://systemd.io/BOOT_LOADER_SPECIFICATION/#type-2-efi-unified-kernel-images
where it's all rolled together and signed with the user key.

@cgwalters
Copy link
Member

A tricky aspect to this is when we talk about signing, that is only relevant for UEFI, and we could e.g. actually use UEFI variables as Lennart was suggesting. But...we need a model for configuring multipath without signing since I am sure we need that for multipath/s390x which I am sure has something totally not UEFI.

@cgwalters
Copy link
Member

cgwalters commented Apr 23, 2020

My initial question is around how kmods-via-containers would change to support this if we are trying to get to first boot kmods.

OK so we're rolling together the discussion on multipath (which is configuration) with kernel modules (which is code).

I don't think most people will need to change the multipath config after install. But it's highly likely kernel modules will need to change - at least if they're not fully covered by kABI.

We can clearly use an "overlay a cpio blob stored in /boot on the initramfs" model for both...I guess I'd hope that we at least make it harder for people to inject completely arbitrary code into our initramfs in the first case (e.g. I was imagining a whitelisted set of files so they don't inject /etc/systemd/system or /usr/bin/foo). But with kmods all bets are off, so maybe it's rd.initrdcode or something which wouldn't have any whitelist and would clearly show it's injecting not-configuration.

It gets tricky if we want to cleanly support an "overlay initramfs" that's per kernel version in a clean fashion. Today ostree creates a /boot/ostree/$stateroot-$bootchecksum - something could come by and drop an overlay initramfs there but it wouldn't be transactional (ostree would have already written the bootloader config) - although maybe it could be if we rely on staged deployments, I would need to look.

@cgwalters
Copy link
Member

Or to say this another way; the initramfs config and "rootfs kmods" are clearly related but also differ a lot in scope.

For example, one can do a multipath install without caring at all about what the kernel version of the target OS is. But...trying to do early kmods for OpenShift will quickly get into the early OS upgrade and the fact there are (potentially) two kernel versions involved. The necessary code to inject for that is just much more complex - at least as long as one has a module not covered by kABI.

@darkmuggle
Copy link
Contributor Author

darkmuggle commented Apr 23, 2020

It still seems a lot simpler to me to have as a kernel argument:
rd.initrdconfig=/initrdconfig-v1.cpio@sha256:a96c2a54a95b52b17d87da72c19247ed41a4f829678e9dfba0449284a224f40d
And all our dracut module does is verify the checksum and unpack that file early on in boot.

Conceptually, I don't have a strong opinion about this either way. But there's a really interesting argument that if you're going to change the karg to rd.initconfg=... that just adding another initrd is easier. Or why not just enable rpm-ostree initramfs generation?

The strongest argument for this approach is that there is no logic in Dracut -- the config is just there to start and there is no logic. And if we provide the sugar to make it, then we have a bit more control to drive the user behavior that we recommend. By using signed archives, we make it a bit harder for arbitrary code changes.

Though in practice maybe we will end up with a model where we do something like this: https://systemd.io/BOOT_LOADER_SPECIFICATION/#type-2-efi-unified-kernel-images
where it's all rolled together and signed with the user key.

I think that's really orthogonal. If we're going to roll it all up and sign with their key, then this model can be easily adapted to support that and might be superior since the whole payload is there and signed by the user key.

We can clearly use an "overlay a cpio blob stored in /boot on the initramfs" model for both...I guess I'd hope that we at least make it harder for people to inject completely arbitrary code into our initramfs in the first case (e.g. I was imagining a whitelisted set of files so they don't inject /etc/systemd/system or /usr/bin/foo). But with kmods all bets are off, so maybe it's rd.initrdcode or something which wouldn't have any whitelist and would clearly show it's injecting not-configuration.

The POC for initramfs-etc only produces a filtered etc, so /etc/systemd is stripped out. That's a concern that I took into consideration. For the kmod use-case I envision a world only /lib/modules... and /lib/firmware are included.

Or to say this another way; the initramfs config and "rootfs kmods" are clearly related but also differ a lot in scope.

I started with Config only. But it quickly became apparent that it's extensible. I definitely think the two should be treated separately. With kmods on everyone's mind, thinking about this generally with two distinct implementations is in order.

The necessary code to inject for that is just much more complex - at least as long as one has a module not covered by kABI.

For kmods, I 💯 think that we need to have a binding to it per OSTree Commit. I envision for RHCOS use-cases that we could use the SRO to drop the cpio file and then something else comes along and updates the blsconfig to use it.

It gets tricky if we want to cleanly support an "overlay initramfs" that's per kernel version in a clean fashion. Today ostree creates a /boot/ostree/$stateroot-$bootchecksum - something could come by and drop an overlay initramfs there but it wouldn't be transactional (ostree would have already written the bootloader config) - although maybe it could be if we rely on staged deployments, I would need to look.

For config only (as this PR demonstrates) it can be version-less. For kmods, I think that it might be a bit easier -- we drop the kmod.cpio in /boot as <ostree>.cpio and then update the BLS config for that OS Tree (we have precedence for doing this).

# Generate a real initrd, but we'll throw it away later
# This ensures that we get a "filtered" config, plus the
# extra's that we need.
dracut "${work_d}/work.img" $(uname -r) \
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cgwalters I specifically use Dracut here to limit the arbitrary logic and just get the configuration that was needed. We get a config cpio that's going to be compatible with the machine and the major series.

Notice, the rm -rf /etc/systemd to clean out the logic.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note, this will break if/when we enable coreos/rpm-ostree#1789 - would need to directly invoke /usr/libexec/rpm-ostree/wrapped/dracut.

@jlebon
Copy link
Member

jlebon commented Apr 24, 2020

Today we're not verifying the kernel arguments, but we need to do so as part of securing the boot process, and there are already tools to do that. Inventing our own signing system seems like a large burden to carry.

I guess to me what's important is that we come up a model where we think we can come by later and add signing, not that we do it right now.

Definitely agreed with this. We should be re-using the infrastructure in place for trusted booting when we get there.

It still seems a lot simpler to me to have as a kernel argument:
rd.initrdconfig=/initrdconfig-v1.cpio@sha256:a96c2a54a95b52b17d87da72c19247ed41a4f829678e9dfba0449284a224f40d

And all our dracut module does is verify the checksum and unpack that file early on in boot.

Hmm, this seems to be leaning in the opposite direction though, no? We're taking on the responsibility of checking the payload instead of re-using existing mechanisms to do that.

For example, GRUB uses check_signatures=enforce; with this, GRUB will automatically know to verify the signature of every file it tries to load (see also https://fedoraproject.org/wiki/Changes/Include_security_modules_in_efi_Grub2). That includes the kernel and AFAICT all initrds.

The strongest argument for this approach is that there is no logic in Dracut -- the config is just there to start and there is no logic.

I agree this is a strong argument for this approach. It may be multipath today, but there are lots more configs in there, and systemctl try-restart might not always do the trick. One example offhand is /etc/systemd/system.conf.d/foo.conf; which directly configures pid 1 itself (and we had requests about this recently where users want to be able to set CPU affinity).

If we had to have only one mechanism for adding things without rebuilding the initrd, then IMO something transparent to dracut/systemd is cleanest. This is exactly what Ignition solves for the real root case too, so there's some beauty in symmetry there. ;)

Re. /usr/sbin/initramfs-etc, I think we'd want rpm-ostree to own this instead? Then (1) it stays transactional, (2) it can ensure a strong binding between the deployment and the overlay (so e.g. the real root /etc can remain the source of truth, and users can just edit that, and e.g. rolling back rolls back both the initrd and the overlay), and (3) it shows up prominently in rpm-ostree status.

@darkmuggle
Copy link
Contributor Author

darkmuggle commented Apr 24, 2020

Inventing our own signing system seems like a large burden to carry.

Its worth noting that we're A) not inventing our own signing system. Grub has the support already for this; B) there are plenty of examples in the wild where people are doing secure boot signed Grub with GPG validation on the initrd. (https://wiki.archlinux.org/index.php/Secure_Boot#shim_with_key_and_GRUB)

Switching to using a hash validation is trivial. https://www.gnu.org/software/grub/manual/grub/html_node/hashsum.html

@cgwalters
Copy link
Member

Its worth noting that we're A) not inventing our own signing system. Grub has the support already for this;

Ah thanks, I missed that! Definitely worth adding that Linux Arch wiki link into the commit message. The fact that there is an existing mechanism for this signing/verification definitely addresses my main concern with that.

Hmm, this seems to be leaning in the opposite direction though, no? We're taking on the responsibility of checking the payload instead of re-using existing mechanisms to do that.

With the checksum we're not taking responsibility for any signing or key management - those are hard problems. Computing a checksum isn't.

One aspect to this I'm thinking is that the later in the operating system boot we load any 3rd party code, the easier it is for us to e.g. report failures. If we use GRUB to check signatures, when it fails...what happens? The machine just stays dead at the console? Whereas if e.g. we can delay loading 3rd party initramfs config/code until the middle of our initramfs, ideally we have networking and can report failures to the cluster.

@darkmuggle
Copy link
Contributor Author

darkmuggle commented Apr 26, 2020

One aspect to this I'm thinking is that the later in the operating system boot we load any 3rd party code, the easier it is for us to e.g. report failures. If we use GRUB to check signatures, when it fails...what happens

In the WIP code here, here the user will see a message about the checksum failure. If we add set checkum=enforcing then boot will halt. As written on https://github.com/coreos/fedora-coreos-config/pull/364/files#diff-306b7a9e42fcd7f8e16823fa070a2c07R25 the variable of initramfs_etc is empty until after the checksum.

Whereas if e.g. we can delay loading 3rd party initramfs config/code until the middle of our initramfs, ideally we have networking and can report failures to the cluster.

This is an interesting idea, but without precedence in the initramfs. And it's moving the goalposts. Today we don't have a clear secure boot story, we don't have networking except on the second boot, and we don't have an initramfs module for reporting back to the cluster failures. The linked issue would only apply to first boot for reporting failures. That's not to say that we can't move towards those goals, but they are orthogonal to this problem.

For the 3rd part initramfs config/code, we could have a "failure" cpio that handles reporting back. For example, checksum fails, failure handler cpio is loaded and reports it back to the cluster.

@cgwalters
Copy link
Member

and systemctl try-restart might not always do the trick. One example offhand is /etc/systemd/system.conf.d/foo.conf; which directly configures pid 1 itself (and we had requests about this recently where users want to be able to set CPU affinity).

https://bugzilla.redhat.com/show_bug.cgi?id=1812894

@darkmuggle darkmuggle closed this Apr 27, 2020
@ashcrow
Copy link
Member

ashcrow commented Apr 27, 2020

I see discussion, a link, and then closure. What is the outcome of this discussion?

@darkmuggle darkmuggle reopened this Apr 27, 2020
@cgwalters
Copy link
Member

and we don't have an initramfs module for reporting back to the cluster failures.

We did land coreos/ignition-dracut#146 and it's already useful in our CI and locally, and does set precedent for this.

I wouldn't say the failure discussion is completely orthogonal once we talk about signing; today e.g. the UEFI Secure Boot failure scenario sucks. See also this tech-list thread. Now one can't easily have UEFI report failures somewhere because that gets into e.g. how you configure it to report somewhere. But if we can at least boot our verified kernel and initrd without user customizations, we can easily load a file in /boot that tells us where to report failures and has a full HTTP and network stack, etc.

One further argument against doing this with GRUB is that we need to handle !GRUB bootloaders, namely zipl.

But to counter that, I think it's also perfectly fine by me if our signing story only works on UEFI to start and we think about porting later.

@cgwalters
Copy link
Member

Back to the top though, I am trying to understand the expected flow here for the multipath case.

All we need for multipath is the multipath.conf file, right? We already have all the code loaded in our initrd already. Or to rephrase, after you run this, what is in the initramfs-etc.img except the multipath config?

What I'm uncertain about here is how initrd-etc gets run during the coreos-installer flow, at least if we want to even try to handle the case where coreos-installer is run from a !CoreOS system.

What if this logic lived in coreos-installer - something like coreos-installer initramfs-config --from-dir /path/to/temp/etc and /path/to/temp/etc/multipath.conf exists.

@cgwalters
Copy link
Member

Let's keep the signing code but make it optional or commented out or something? When I first looked at this PR I just had difficulty thinking through the ramifications of the signing from the UX perspective; basically I don't think we can force everyone who wants to do a multipath install to deal with GPG key/passphrase management, particularly if we're not signing anything else.
But it's great to have that and know we can turn it on!

(I also went down a rabbit hole for a bit of understanding the signing infrastructure - it seems like the linked GRUB design requires re-generating the GRUB binary with the user key and enrolling it in the Secure Boot chain, which is basically AIUI how it has to work - e.g. with this code nothing stops someone from replacing both the /boot/.machine_key.gpg and the /boot/initramfs-etc.img and signing with their own key right? But, the questions about security of this specific signature chain I think are a bit of a distraction from the point that we probably can't enable it by default right now)

@darkmuggle
Copy link
Contributor Author

Back to the top though, I am trying to understand the expected flow here for the multipath case.

All we need for multipath is the multipath.conf file, right? We already have all the code loaded in our initrd already. Or to rephrase, after you run this, what is in the initramfs-etc.img except the multipath config?

In previous discussions there was concern for too much being in the initrd. Per https://github.com/coreos/fedora-coreos-config/pull/364/files#diff-ab205697e5620ab84e4e269a5708e943R41-R51 a currated white-list is added to support additional things.

[core@cosa-devsh ~]$ sudo su
[root@cosa-devsh core]# initramfs-etc --create
gpg: keybox '/root/.initramfs-etc/pubring.kbx' created
gpg: Generating machine signing key
gpg: /root/.initramfs-etc/trustdb.gpg: trustdb created
gpg: key 2EEC4A30687FA948 marked as ultimately trusted
gpg: directory '/root/.initramfs-etc/openpgp-revocs.d' created
gpg: revocation certificate stored as '/root/.initramfs-etc/openpgp-revocs.d/1E920C0DD1C339B6ABF01E292EEC4A30687FA948.rev'
gpg:
gpg: WARNING: please keep /root/.initramfs-etc safe
gpg: This key will be used for signing initramfs to aide
gpg: with Grub2 validation
gpg:
Generating new /boot/initramfs-etc.img using Dracut
/boot/initramfs-etc.img will only contain configuration data, no logic
Failed to add dependency on unit, unit systemd-ask-password-plymouth.service does not exist.
/usr/lib/dracut/modules.d/45url-lib/module-setup.sh: line 33: warning: command substitution: ignored null byte in input
/usr/lib/dracut/modules.d/45url-lib/module-setup.sh: line 33: warning: command substitution: ignored null byte in input
/usr/lib/dracut/modules.d/45url-lib/module-setup.sh: line 33: warning: command substitution: ignored null byte in input
/usr/lib/dracut/modules.d/45url-lib/module-setup.sh: line 33: warning: command substitution: ignored null byte in input
189390 blocks
672 blocks
[root@cosa-devsh core]# lsinitrd /boot/initramfs-etc.img
initrd in UEFI: : 337K
========================================================================

========================================================================
Version:

Arguments:
dracut modules:
========================================================================
drwxr-xr-x   9 root     root            0 Apr 27 22:04 etc
drwx------   2 root     root            0 Apr 27 22:04 etc/cmdline.d
drwx------   2 root     root            0 Apr 27 22:04 etc/conf.d
-rw-------   1 root     root          124 Apr 27 22:04 etc/conf.d/systemd.conf
-rw-------   1 root     root            0 Apr 27 22:04 etc/fstab.empty
-rw-------   1 root     root          116 Apr 27 22:04 etc/group
lrwxrwxrwx   1 root     root           25 Apr 27 22:04 etc/initrd-release -> ../usr/lib/initrd-release
-rw-r--r--   1 root     root         8755 Apr 27 22:04 etc/ld.so.cache
-rw-r--r--   1 root     root           28 Apr 27 22:04 etc/ld.so.conf
drwxr-xr-x   2 root     root            0 Apr 27 22:04 etc/lvm
-rw-r--r--   1 root     root       102343 Apr 27 22:04 etc/lvm/lvm.conf
-rw-r--r--   1 root     root         2301 Apr 27 22:04 etc/lvm/lvmlocal.conf
-r--r--r--   1 root     root           33 Apr 27 22:04 etc/machine-id
drwxr-xr-x   2 root     root            0 Apr 27 22:04 etc/modprobe.d
-rw-rw-r--   1 root     root           76 Apr 27 22:04 etc/modprobe.d/blacklist-nouveau.conf
lrwxrwxrwx   1 root     root           17 Apr 27 22:04 etc/mtab -> /proc/self/mounts
lrwxrwxrwx   1 root     root           14 Apr 27 22:04 etc/os-release -> initrd-release
-rw-------   1 root     root           26 Apr 27 22:04 etc/passwd
drwxr-xr-x   4 root     root            0 Apr 27 22:04 etc/pki
drwxr-xr-x   3 root     root            0 Apr 27 22:04 etc/pki/ca-trust
drwxr-xr-x   3 root     root            0 Apr 27 22:04 etc/pki/ca-trust/extracted
drwxr-xr-x   2 root     root            0 Apr 27 22:04 etc/pki/ca-trust/extracted/pem
-r--r--r--   1 root     root       219744 Apr 27 22:04 etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem
drwxr-xr-x   3 root     root            0 Apr 27 22:04 etc/pki/tls
drwxr-xr-x   2 root     root            0 Apr 27 22:04 etc/pki/tls/certs
lrwxrwxrwx   1 root     root           46 Apr 27 22:04 etc/pki/tls/certs/ca-bundle.crt -> ../../ca-trust/extracted/pem/tls-ca-bundle.pem
-rw-------   1 root     root           26 Apr 27 22:04 etc/shadow
-rw-r--r--   1 root     root          449 Apr 27 22:04 etc/sysctl.conf
drwxr-xr-x   2 root     root            0 Apr 27 22:04 etc/sysctl.d
-rw-------   1 root     root           27 Apr 27 22:04 etc/sysctl.d/10-dont-ratelimit-kmsg.conf
lrwxrwxrwx   1 root     root           14 Apr 27 22:04 etc/sysctl.d/99-sysctl.conf -> ../sysctl.conf
drwxr-xr-x   3 root     root            0 Apr 27 22:04 etc/udev
drwxr-xr-x   2 root     root            0 Apr 27 22:04 etc/udev/rules.d
-rw-r--r--   1 root     root          142 Apr 27 22:04 etc/udev/rules.d/11-dm.rules
-rw-------   1 root     root          680 Apr 27 22:04 etc/udev/rules.d/59-persistent-storage-dm.rules
-rw-------   1 root     root          297 Apr 27 22:04 etc/udev/rules.d/59-persistent-storage.rules
-rw-------   1 root     root         1030 Apr 27 22:04 etc/udev/rules.d/61-persistent-storage.rules
-rw-r--r--   1 root     root          775 Apr 27 22:04 etc/udev/rules.d/64-lvm.rules
-rw-r--r--   1 root     root          281 Apr 27 22:04 etc/udev/udev.conf
-rw-r--r--   1 root     root         1204 Apr 27 22:04 etc/virc
========================================================================

What I'm uncertain about here is how initrd-etc gets run during the coreos-installer flow, at least if we want to even try to handle the case where coreos-installer is run from a !CoreOS system.

From the live ISO, the user would:

  • configure Multipath and check that everything works
  • run `initramfs-etc --create
  • run the installer

The open question is whether or not the installer would pick up /boot/.machine_key and /boot/initramfs-etc.img

What if this logic lived in coreos-installer - something like coreos-installer initramfs-config --from-dir /path/to/temp/etc and /path/to/temp/etc/multipath.conf exists.

There are three paths that have been proposed:

  • putting in CoreOS
  • putting in rpm-ostree
  • punting to the installer

IMO, I would rather see it go into rpm-ostree since then it could be used transactionally and to ensure that the blsconfig gets updated. I had initially put it in the Fedora Config branch since its sans logic.

@darkmuggle
Copy link
Contributor Author

Let's keep the signing code but make it optional or commented out or something? When I first looked at this PR I just had difficulty thinking through the ramifications of the signing from the UX perspective; basically I don't think we can force everyone who wants to do a multipath install to deal with GPG key/passphrase management, particularly if we're not signing anything else.
But it's great to have that and know we can turn it on!

The tension from previous feedback is that we don't want to make it too easy for the user to use this, and @haraldh had suggested that we bind to the resulting configuration to the machine.

Switching over hashes is trivial. Or we don't do anything.

I'd just rather kill the code if there is no utility.

(I also went down a rabbit hole for a bit of understanding the signing infrastructure - it seems like the linked GRUB design requires re-generating the GRUB binary with the user key and enrolling it in the Secure Boot chain, which is basically AIUI how it has to work - e.g. with this code nothing stops someone from replacing both the /boot/.machine_key.gpg and the /boot/initramfs-etc.img and signing with their own key right? But, the questions about security of this specific signature chain I think are a bit of a distraction from the point that we probably can't enable it by default right now)

https://github.com/coreos/fedora-coreos-config/pull/364/files#diff-306b7a9e42fcd7f8e16823fa070a2c07R20 is the bit that results in trust.

The idea here is to enable configuration needed during the initramfs
without requiring the re-generation of it.

Previous models including [1] were considered. As counter-idea, it was
suggested to add to Dracut the ability to source in a signed CPIO
archive or at least checksum it (e.g. boot-etc=<file>:sha256) and then
rely on signed kargs. The chief concerns is that we need to ensure that
the content is machine specific and not enable an easy boot-foot gun.

This solution used Grub as the enforcement mechanism for both
authenticity and authentication of the change and bypasses Dracut
all-together. The core advantage is that admin could enable secure boot,
set the Grub password (to prevent menu editing) and then Grub would only
set "initramfs-etc='...'" if the file checked out.

[1] dracutdevs/dracut#792

Signed-off-by: Ben Howard <[email protected]>
@darkmuggle
Copy link
Contributor Author

darkmuggle commented Apr 27, 2020

Repushed with changes for using checksumming instead. This is untested, though

@jlebon
Copy link
Member

jlebon commented Apr 28, 2020

One random thought I had about this yesterday was that we could punt on this entirely and instead solve a different problem, which is to make it easier to run rpm-ostree to target the freshly installed system after doing an install but before reboot. That way, one can still use rpm-ostree initramfs --enable or whatever before firstboot, we reuse existing functionality, it still shows up in rpm-ostree status, we (mostly) maintain the same UX across day-1 and day-2, etc...

For example, coreos-installer could learn to mount the deployment root at /install (and mount the root and boot partitions at /install/sysroot and /install/boot). Then the workflow would just be:

  • boot live ISO/PXE
  • run coreos-installer install ...
  • edit /install/etc/multipath.conf
  • run rpm-ostree initramfs --enable --sysroot /install

(And of course, this can be extended for whatever other firstboot thing one really needs.)

@cgwalters
Copy link
Member

Which is to make it easier to run rpm-ostree to target the freshly installed system after doing an install but before reboot.

Right, Ben mentioned that option above in passing too. To be clear I'm not opposed to it...but regenerating the initramfs locally feels like a step "backwards" towards being less of an image system by default.

We went to some effort to get systemd patched to add a karg for the CPU affinity thing so we didn't need to regenerate the initramfs for that.

On the flip side if we go the initramfs-etc.img route here it would be nice if rpm-ostree status learned to display it which would mostly just be parsing the karg.

@cgwalters
Copy link
Member

The tension from previous feedback is that we don't want to make it too easy for the user to use this, and @haraldh had suggested that we bind to the resulting configuration to the machine.

Ah hmm...I see. There may be some disconnect with what Harald is thinking here because we need to support multipath/iSCSI - it can't be too hard to use right?

@darkmuggle
Copy link
Contributor Author

We did a video chat about this topic and the decision is was to satisfy the needs of the generic case (i.e. DASD) by using the rd.multipath=default karg. In the ignition-generator for Dracut-Ignition, we trigger new /dev/disk/by-* symlinks by restarting systemd-udev-trigger; the effect will be the by-labels of boot and root will just continue to work and will use the device mapper paths.

The tricky part, though is that the growpart code needs to become device mapper aware in at least two places.

In parallel we're going to look at doing the appended initramfs's in rpm-ostree to ensure the transactional nature and look at teaching the coreos-installer about updating the initramfs (maybe).

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.

4 participants