On Mon, Mar 30, 2026 at 03:45:31AM -0500, Andrea Bolognani wrote:
> On Mon, Mar 30, 2026 at 12:24:06PM +0530, Arun Menon wrote:
> > Hi Andrea,
> >
> > Thank you for finding this.
> >
> > On Sun, Mar 29, 2026 at 03:12:25PM -0500, Andrea Bolognani wrote:
> > > On Tue, Feb 10, 2026 at 11:26:39PM +0530, Arun Menon via Devel wrote:
> > > > This commit sets the foundation for encrypting the libvirt secrets by 
> > > > providing a
> > > > secure way to pass a secret encryption key to the virtsecretd service.
> > > >
> > > > A random secret key is generated using the new 
> > > > virt-secret-init-encryption
> > > > service. This key can be consumed by the virtsecretd service.
> > > >
> > > > By using the "Before=" directive in the new virt-secret-init-encryption
> > > > service and using "Requires=" directive in the virtsecretd service,
> > > > we make sure that the daemon is run only after we have an encrypted
> > > > secret key file generated and placed in /var/lib/libvirt/secrets.
> > > > The virtsecretd service can then read the key from 
> > > > CREDENTIALS_DIRECTORY. [1]
> > >
> > > [...]
> > >
> > > > +++ b/src/remote/libvirtd.service.in
> > > > @@ -12,6 +12,8 @@ After=libvirtd.socket
> > > >  After=libvirtd-ro.socket
> > > >  After=libvirtd-admin.socket
> > > >  Requires=virtlogd.socket
> > > > +Requires=virt-secret-init-encryption.service
> > > > +After=virt-secret-init-encryption.service
> > > >  Wants=virtlockd.socket
> > > >  After=virtlogd.socket
> > > >  After=virtlockd.socket
> > > > @@ -29,6 +31,8 @@ Conflicts=xendomains.service
> > > >  Type=notify-reload
> > > >  Environment=LIBVIRTD_ARGS="--timeout 120"
> > > >  EnvironmentFile=-@initconfdir@/libvirtd
> > > > +Environment=SECRETS_ENCRYPTION_KEY=%d/secrets-encryption-key
> > > > +LoadCredentialEncrypted=secrets-encryption-key:@localstatedir@/lib/libvirt/secrets/secrets-encryption-key
> > >
> > > A bit late to the party, sorry.
> > >
> > > This change breaks the scenario in which the monolithic daemon is in
> > > use and the secret driver is not installed. The error messages is
> > > quite clear about what's wrong:
> > >
> > >   $ sudo systemctl start libvirtd.service
> > >   Failed to start libvirtd.service: Unit
> > > virt-secret-init-encryption.service not found.
> > >
> > > I thought I could fix things by weakening the Requires= into a Want=,
> > > which would feel appropriate for an optional component, however that
> > > doesn't work either:
> > >
> > >   systemd[1]: Starting libvirtd.service - libvirt legacy monolithic 
> > > daemon...
> > >   (libvirtd)[20437]: libvirtd.service: Failed to set up credentials:
> > > No such file or directory
> > >   (libvirtd)[20437]: libvirtd.service: Failed at step CREDENTIALS
> > > spawning /usr/sbin/libvirtd: No such file or directory
> > >   systemd[1]: libvirtd.service: Main process exited, code=exited,
> > > status=243/CREDENTIALS
> > >   systemd[1]: libvirtd.service: Failed with result 'exit-code'.
> > >
> > > Based on my reading of systemd.exec(5), there doesn't seem to be a
> > > way to make this conditional. ImportCredential= is supposed to behave
> > > gracefully when the credential doesn't exist, but I don't think it
> > > suits our needs otherwise.
> >
> > We can change the Requires= to Wants=, like you mentioned, it will
> > gracefully skip if the encryption service is not found.
>
> Yeah, this part is easy.
>
> > Can we move the LoadCredentialEncrypted= and Environment= out of
> > libvirtd.service.in in to a separate file, and then use meson.build to
> > optionally install the new file to the configuration directory
> > systemd/system/libvirtd.service.d/ if conf.has('WITH_SECRETS') is set?
>
> That won't work, because when building distro packages all features
> get enabled at compile time. The decision about whether the
> rpm/deb/whatever containing the secret driver gets installed is made
> later, by the local admin, and is completely out of our control.

We could, however, ship that override snippet as part of the
libvirt-daemon-driver-secret package. That seems to work:

  $ grep -i secret /usr/lib/systemd/system/libvirtd.service

  $ cat /usr/lib/systemd/system/libvirtd.service.d/secret.conf
  [Unit]
  Requires=virt-secret-init-encryption.service
  After=virt-secret-init-encryption.service

  [Service]
  Environment=SECRETS_ENCRYPTION_KEY=%d/secrets-encryption-key
  
LoadCredentialEncrypted=secrets-encryption-key:/var/lib/libvirt/secrets/secrets-encryption-key

  $ sudo systemctl start libvirtd
  Failed to start libvirtd.service: Unit
virt-secret-init-encryption.service not found.

Not the most elegant solution perhaps, but I can't come up with
anything better. I wonder how many system packages ship systemd unit
overrides this way. The mechanism clearly exists though...

-- 
Andrea Bolognani / Red Hat / Virtualization

Reply via email to