Here's the 6th installment of my series of posts highlighting key new features of the upcoming v256 release of systemd.
In the 2nd installment of this series we have already discussed system and service credentials in systemd a bit. Quick recap: these are smallish blobs of data that can be passed into a service in a secure way, to parameterize, configure it, and in particular to pass secrets to it (passwords, PINs, private keys, …).
They are acquired (and if necessary: decrypted and authenticated) at the moment a service consuming them is started, and are then accessible to the service through the file system, in a private tmpfs instance with swapping disabled that is destroyed when the service goes down again.
Service credentials are supposed to be a more secure, more restricted alternative to passing secrets via environment variables, which is unfortunately relatively common in the cloud world I guess.
Environment variables after all suck for passing secrets, since they are by default inherited down the process tree, even across privilege changes, are placed in swappable memory, cannot be recalled, have no access control concept (i.e. not locked to the UID/GID) and so on.
There's one particularly nice facet of systemd's credentials concept: they are not just *service* credentials, but also *system* credentials.
i.e in pretty much the same way you can securely parameterize a service with them, you can also parameterize the whole system with them. Of course, it's ultimately the system's services that consume them, hence there's a propagation scheme in place: you can pass credentials into the system, and then selectively propagate these into individual services that they are supposed to be consumed in. And not just that you can actually propagate them further down the tree, …
… , into guest containers, guest VMs, and from there into their services, and so on.
How do you get system credentials into the system? There are various mechanisms in place. The two most interesting ones are: for VMs you can pass them via SMBIOS Type 11 strings, i.e. directly from the qemu command line for example. And for (full OS) containers the container manager can pass them in via a special mount in /run/host/.
Of course, systemd-nspawn and systemd-vmspawn both support these schemes. For physical systems you can also pass them in via files in the UEFI ESP. And then there's an interface for augmenting them from the initrd – which is intended for use by deployment tools such as cloud-init.
So far so good, this all has already been available in the past releases, so what precisely is new in v256 on this (besides the concept of user-scoped credentials discussed in the 2nd installment)?
Well, I think we finally closed the last major gaps in the various system services shipped by systemd that consume credentials, so that all relevant facets of the system can now be configured via credentials. The last major gap was also the most relevant one: there's finally a way how you can pass .network, .link and .netdev files into a system via credentials, or in other words: configure the network in all details, just by providing a nice .network file into the system when you start it.
Thus, a regular systemd system will now allow you to configure via credentials: keymap, locale, timezone, issue file, motd file, hosts file, .link files, .network files, .netdev files, DNS servers, DNS search domains, root passwords, root shell, SSH key of root, additional SSH address/port to listen on, sysuser.d/ additions, tmpfiles.d/ additions, sysctl.d/ additions, fstab additions, console font, additional TTYs to spawn gettys on, socket to forward journal data to, …
…, socket for sd_notify() messages from the system, machine ID, hostname, systemd-homed users to create, cryptsetup passwords and pins, additional unit files and drop-ins for unit files, udev rules, and more.
For further details see the relevant man page that lists them: https://www.freedesktop.org/software/systemd/man/devel/systemd.system-credentials.html
Or in other words: there's a lot now, covering pretty much all facets of the basic OS. Or in other words: I am pretty sure this is ready for prime-time.
And that's all for today, I hope to post installment #7 soon.
@pid_eins thank you very much for these posts. It's a really nice way for me to learn about recent changes
@pid_eins yeh we should add `/run/host` virtiofs support to vmspawn at some point. It's still on my list of things I want to add
@pid_eins can this be used to pass secrets to applications? Eg if you're currently hosting some service, you usually pass secrets through it by using the .env file or the env section in docker-compose or whatever.
Can systemd credentials replace this and offer a better way to pass secrets to podman containers or arbitrary applications? Or is it only intended for system services?
@flexagoon For now the focus was privileged services, but we laid some groundwork in v256 to eventually make this available to user services too. (i.e. there are user-scoped encrypted credential's now, see 2nd installment of this series)
I have no experience with podman. I doubt they support credentials though, the OCI container world is generally a bit "laissez faire" on security topics. i.e. env vars, because yolo.
@pid_eins I asked specifically about Podman and not Docker because unlike Docker, Podman actually tries to work with existing standards and for example supports orchestration using systemd services. So there's a chance they'll add credential support some day!