On Tue, Dec 09, 2025 at 01:22:28 +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]
>
> This setup therefore provides a default key out-of-the-box for initial use.
> A subsequent commit will introduce the logic for virtsecretd
> to access and use this key via the $CREDENTIALS_DIRECTORY environment
> variable. [2]
>
> [1] https://www.freedesktop.org/software/systemd/man/latest/systemd-creds.html
> [2] https://systemd.io/CREDENTIALS/
>
> Signed-off-by: Arun Menon <[email protected]>
> ---
> libvirt.spec.in | 4 ++++
> src/meson.build | 1 +
> src/remote/libvirtd.service.in | 2 ++
> src/secret/meson.build | 15 +++++++++++++++
> src/secret/virt-secret-init-encryption.service.in | 7 +++++++
> src/secret/virtsecretd.service.extra.in | 8 ++++++++
> 6 files changed, 37 insertions(+)
> create mode 100644 src/secret/virt-secret-init-encryption.service.in
[...]
> diff --git a/src/remote/libvirtd.service.in b/src/remote/libvirtd.service.in
> index b0a062e885..84447e0bcf 100644
> --- a/src/remote/libvirtd.service.in
> +++ b/src/remote/libvirtd.service.in
> @@ -29,6 +29,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
> ExecStart=@sbindir@/libvirtd $LIBVIRTD_ARGS
> ExecReload=/bin/kill -HUP $MAINPID
> KillMode=process
IIUC the libvird.service.in unit needs to depend the same way on
'virt-secret-init-encryption.service' as virtsecredtd.service does.
> diff --git a/src/secret/meson.build b/src/secret/meson.build
> index 3b859ea7b4..b0977eadc8 100644
> --- a/src/secret/meson.build
> +++ b/src/secret/meson.build
> @@ -31,6 +31,21 @@ if conf.has('WITH_SECRETS')
> 'name': 'virtsecretd',
> }
>
> + virt_secret_init_encryption_conf = configuration_data()
> +
> + virt_secret_init_encryption_conf.set('localstatedir', localstatedir)
---
> + virt_secret_init_encryption_conf.set('name', 'Libvirt Secret Encryption
> Init')
> + virt_secret_init_encryption_conf.set('service',
> 'virt-secret-init-encryption')
> + virt_secret_init_encryption_conf.set('SERVICE',
> 'virt-secret-init-encryption'.to_upper())
^^^
None of the above substitutions are actually used in
'virt-secret-init-encryption.service.in'.
> +
> + configure_file(
> + input: 'virt-secret-init-encryption.service.in',
> + output: '@[email protected]'.format('virt-secret-init-encryption'),
> + configuration: virt_secret_init_encryption_conf,
> + install: true,
> + install_dir: unitdir,
> + )
> +
> virt_daemon_units += {
> 'service': 'virtsecretd',
> 'name': 'secret',
> diff --git a/src/secret/virt-secret-init-encryption.service.in
> b/src/secret/virt-secret-init-encryption.service.in
> new file mode 100644
> index 0000000000..0a23d452e8
> --- /dev/null
> +++ b/src/secret/virt-secret-init-encryption.service.in
> @@ -0,0 +1,7 @@
> +[Unit]
> +Before=virtsecretd.service
libvirtd.service too
> +ConditionPathExists=!@localstatedir@/lib/libvirt/secrets/secrets-encryption-key
> +
> +[Service]
> +Type=oneshot
> +ExecStart=/usr/bin/sh -c 'umask 0066 && (dd if=/dev/urandom status=none
> bs=32 count=1 | systemd-creds encrypt --name=secrets-encryption-key -
> @localstatedir@/lib/libvirt/secrets/secrets-encryption-key)'
> diff --git a/src/secret/virtsecretd.service.extra.in
> b/src/secret/virtsecretd.service.extra.in
> index 1fc8c672f7..116458b22a 100644
> --- a/src/secret/virtsecretd.service.extra.in
> +++ b/src/secret/virtsecretd.service.extra.in
> @@ -1,2 +1,10 @@
> # The contents of this unit will be merged into a base template.
> # Additional units might be merged as well. See meson.build for details.
> +#
> +[Unit]
> +Requires=virt-secret-init-encryption.service
> +After=virt-secret-init-encryption.service
[1]