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 <armenon@redhat.com> --- 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: '@0@.service'.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]