-
Notifications
You must be signed in to change notification settings - Fork 97
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
feat: Implement measurement and policy generation/luks unlock of sysextensions for UKI #2608
feat: Implement measurement and policy generation/luks unlock of sysextensions for UKI #2608
Comments
I'm sorry, but your issue does not have enough information to be triaged. Could you please provide steps to reproduce, relevant versions of artifacts and a clear description of the issue? I will label your issue with 'add_label_to_github_issue' and 'question' until I have more information to triage it. I am a bot, an experiment of @mudler and @jimmykarily. |
Useful links:https://www.freedesktop.org/software/systemd/man/latest/systemd-repart.html# StatusSupport is there and working out of the box mainly. Create a verity+signed sysext image:
Copy it into So we would need to copy it to Then reboot, systemd-stub will read those raw extensions and pass it to the initramfs inside the That dir is only read during initramfs, which is set via a file in Call sysext with a strict policy Things magically appear!
Things that we need to do to support this out of the boxDecide if we are gonna support initrd or initrd/early means that we can enable the sysext really early. Like just after mounting the main system mounts. This is a bit dangerous as we still havent mounted anything else from persistent so there is an overlap issue here. i.e. a sysext mounts something on /usr/local/X and then the persistent mounts over it as well. It also means that we have to force the loading as sysext are not supported during initrd, only confext, and forcing them could work but we are skipping a few sanity checks. So this becomes prone to failure IMO, we should wait until persistent is loaded, then immediately afterwards run sysext so we load things over the persistent stuff. That makes more sense to me due to the posibility of upgrading existing things on persistent, like k3s via sysext and less moving parts. As we cannot use the initrd env var without breaking a lot of stuff, the idea would be to copy the In fact I would recommend using the EFI sysext method only for generic things (k3s for example) as for troubleshooting its easier and breaking it and cleaning its easier via recovery and dont need to unlock the persistent partition. sysext on /var/lib/extensions should be done for extensions that contains private code and need to be locked out of easy access (contains private code, credentials and such) as they are more difficult to access from the outside (booting livecd, recovery) Decide if we are gonna to make the strict policy the default via overriding the service file Currently the image policy (verity+signed or absent or more, see Disk Image Dissection Policy seems to be a bad default as it basically accepts everything. IMO, we should override the default sysext service to add the Notice that is still possible to manually run sysext as root and skip the policy or set a more relaxed one, but at that point, with root you can basically do anything (download a binary into persistent for example?) so this is expected. We just want to be able to load extensions during boot via immucore and fail if they dont conform to our strcit policy before giving a shell. Decide what are we doing when finding unsigned sysext We have 2 possibilities. Either warn and continue or directly fail booting. As the sysext are PER efi file, even if we add them to active+passive we still have recovery NOT loading them, so if something goes wrong, a user can still boot in recovery and manually delete the sysextensions from the EFI partition directly, which should make it work again. IMO, we should default to Decide how are we gonna deal with 1 broken/unsigned sysext Currently there is an issue that if you got 10 sysext and just one doesnt fill the policy, it stops loading them all.
Im not sure this covers our use case as it seems to only check for invalid images (do not match the system ID and such) but its a real pain in the ass. Ideally, as we are in control of the process and we copy them into place, we should be able to verify them before copying them but its a laborious process. Another way would be much more simpler but slower. We copy 1 extension, call sysext refresh and if the return code is not zero, we remove that extension and keep going. Decide how to sign the extensions for documentation purposes For signing the extensions we need a key and cert. I been using the secureboot ones to do it and they work as expected (either PK, KEK or DB work) BUT due to a configuration not enabled in the kernel by default the MOK keys are not available in the kernel keyring, which means if we are using those keys for the sysext signing we need to manually extract them and put them under More problematic is if the user decides to sign them with a different key+cert, then we need a way of producing the public cert and storing it somewhere. Probably via config file as usual?
This is trivial IMO, we should recommend signing this stuff with the DB key in the same process that sings the EFI files, but Im sure somone is gonna ask for this, so we better have an alternative ready. Kind of makes sense to have a different key for this as you can keep your DB key secure, but may need to sign sysexts more frequently (k3s patch versions for example) Final notesThis is pretty much ready for consumption and only minor things around. We should be ok to have it ready for 3.1.x maybe on beta status as we polish it around. |
That's great! awesome finds @Itxaka !
this might have sense if we let sysext to overlay directories also outside of
That makes most of sense indeed
that's going to be tricky, would be nice to expose for the user that down the line (for instance, picking up extensions from the LiveCD and installing them in the persistent portion which is mapped to
definetly, otherwise an open policy would let anyone to drop a file in there and get loaded and overlaying part of the system (? to be tested ?) - better safe then sorry.
One of the major problem about this approach is that there is no manual intervention in most cases - so it would be better to be conservative here and do not default to a strict policy. This allows a downstream component (e.g. a provider or a system agent) to take over and decide to recover in other ways automatically without breaking the box. however, this should be configurable during installation via cloud config.
Let's stick to the simple case here - default is good. If even one of the sysext is broken, we should ignore all of them or fatal ( as in the question earlier above) - it means that either the machine is being compromised, or there is a bug that must be resolved when installing sysext or building installable mediums.
We can think about iterating later, let's keep very simple now and document to use the same keys for signing the EFI files. To me it makes sense to use the same keys used for the UKI in any case - because if the key mismatch the system (UKI) is not going to boot at all , as would mismatch SB signatures.
👍 |
shoot and I assume there are no soft links at this level then, but for keeping track of which extensions there are on different images this might actually be good Amazing work @Itxaka 👏 |
No :( But at least it gives us some fine grained control for users? Like maybe they want to deploy a new version of X only to active and keep the old one at passive so if it fails they can go back easily? |
Indeed, but in that case, only confext are supported. We can force other stuff to be loaded but we are skipping some sanity checks so we would need to be careful in there
Yes, Im currently testing that because otherwise is boring as f to test this. Currently copying them into the efi partition, but its one toggle away from putting in a different place as part of the install kairos-io/kairos-agent#372
Well, only root can do that (dir permissions+sysext run permissions) so its not a big issue IMO. If you are root you can do anything :D
Yes, indeed. For the first versions we could go with default permissive, let users choose enforce. Would be nice if we could hook systemd into this to crash so the boot assesment can kick in maybe? Anyway for future versions.
Ok, sounds good. Current test implementation goes by copying one extension, trying to refresh the extensions and if it fails to load, remove the extension and continue with the others.
Yes, to me it also makes sense, but if the OS build and sysext build go at different paces (you update OS every 6 months or more, but want to update sysext with patch releases every I dunno, month) then it makes sense to have another key for this. Mainly because its easier to reroll that key, and use a new one. And if it gets exposed becuase you keep taking it out of cold storage to sign stuff, then its a minor issue more or less, you update your public key in the configs and old sysext are invalidated immediately. Both use cases have pros and cons, we should explain this carefully in the documentation! |
ok, good news here, there is a tool to check if a image is valid before mounting it and covers the policy so we should be ok to do this by:
Very nice! This would require to install an extra package on ubuntu
|
Tested and works as expected.
Files that dont match are ignored and not copied. |
ok, mostly done, the only thing missing is to add the bits and bobs for further configuration, but I think we could merge this first iteration, start adding end2end tests in kairos to verify it further and then start expanding it with more config Configs to add:
Or the other way around:
And anything that doesn't match goes into both? And we support any custom entries there in the efi stuff. |
One this stuff is merged, Ill open cards for the above things |
Also, Im gonna try to do a sysext with the contents of |
I see the examples refer to k3s/rke/etc. Is it possible that we also make the provider-kairos a sysext? I think we-ve discussed it in the past but after doing the research, do you think it would be possible to only produce "core" images and spice them up with providers in the form of sys extensions? This would also allow us to test new provider versions without having to build full images. If that's possible, we would need to find a way to do the same in the non-UKI case (without the signing and all probably). |
Oh yes, there is still the question in the air. Currently immucore on the fly sets the sysext timeout/policy on each boot but ideally we could move that to the cloud-config default files for UKI only. thoughts @mauromorales @mudler @jimmykarily ? |
Yes, there should be no issues with the provider or anything else as long as it goes under /usr or /opt I would say that this feature might be uki-exclusive. We dont have the kind of issues in non-uki with sizes that we would need to do this, and we have bundles for extending the system which cover this no? |
ah just saw that the provider is currently using |
maybe we could expand the plugin system to look both on |
After all the work, we hit an issue. Currently the system works but as soon as sysext finds any extensions it creates an overlayfs on /usr This means that our current /usr/local with all the state and such gets lost. Lots of things have been tried but not much seems to work. One of the things that work is:
That way you get a proper merge between the systemd-sysext AND we can mount our mountpoint in there
This implies changing the actual boot process on immucore to do this instead of the usual direct mount under /usr/local Or we could just go and do our own thing.
And thats it. |
we can fix this by overriding the Here we can see our existing /usr/local dirs like .state AND the overlayed extension
something to notice here is that the overlayed extension went into the proper dir! so that means that its merging at the /usr/local level
Still this looks good! |
Follow up on #2117
This is the implementation part as the spike revealed that there is nothing to do this currently.
The objective would be to treat sysextensions like an UKI and be able to generate a policy and attach it to them than we can use to unlock the system. Policy/signatures should be able to be done offline as to generate them outside of the node.
This way we would be able to extend a UKI system via sysext without opening a hole in the security.
Like k3s deployed via sysextension or stylus.
The reason for the policy would be to be able to upgrade those sysextensions while not breaking the measurements.
The reson for needing sysextensions would be to keep the size of the system to a minimum as EFI firmware usually cant deal with big EFI files and bundling everything in the EFI file blows the size.
Refer to original spike for more info on whats currently on the market for this.
The text was updated successfully, but these errors were encountered: