[PATCH v2 2/5] secret: Set up default encryption secret key for the virtsecretd service

Arun Menon via Devel posted 5 patches 20 hours ago
There is a newer version of this series
[PATCH v2 2/5] secret: Set up default encryption secret key for the virtsecretd service
Posted by Arun Menon via Devel 20 hours ago
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                    |  4 ++++
 src/secret/meson.build                            | 12 ++++++++++++
 src/secret/virt-secret-init-encryption.service.in |  8 ++++++++
 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/libvirt.spec.in b/libvirt.spec.in
index ccfe75135b..8505a220c7 100644
--- a/libvirt.spec.in
+++ b/libvirt.spec.in
@@ -1890,13 +1890,16 @@ exit 0
 %pre daemon-driver-secret
 %libvirt_sysconfig_pre virtsecretd
 %libvirt_systemd_unix_pre virtsecretd
+%libvirt_systemd_oneshot_pre virt-secret-init-encryption
 
 %posttrans daemon-driver-secret
 %libvirt_sysconfig_posttrans virtsecretd
 %libvirt_systemd_unix_posttrans virtsecretd
+%libvirt_systemd_unix_posttrans virt-secret-init-encryption
 
 %preun daemon-driver-secret
 %libvirt_systemd_unix_preun virtsecretd
+%libvirt_systemd_unix_preun virt-secret-init-encryption
 
 %pre daemon-driver-storage-core
 %libvirt_sysconfig_pre virtstoraged
@@ -2248,6 +2251,7 @@ exit 0
 %{_datadir}/augeas/lenses/virtsecretd.aug
 %{_datadir}/augeas/lenses/tests/test_virtsecretd.aug
 %{_unitdir}/virtsecretd.service
+%{_unitdir}/virt-secret-init-encryption.service
 %{_unitdir}/virtsecretd.socket
 %{_unitdir}/virtsecretd-ro.socket
 %{_unitdir}/virtsecretd-admin.socket
diff --git a/src/meson.build b/src/meson.build
index 47c978cc1f..f18f562fd9 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -837,6 +837,7 @@ if conf.has('WITH_LIBVIRTD')
         'sbindir': sbindir,
         'sysconfdir': sysconfdir,
         'initconfdir': initconfdir,
+        'localstatedir': localstatedir,
         'name': unit['name'],
         'service': unit['service'],
         'SERVICE': unit['service'].to_upper(),
diff --git a/src/remote/libvirtd.service.in b/src/remote/libvirtd.service.in
index b0a062e885..7965010a0a 100644
--- a/src/remote/libvirtd.service.in
+++ 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
 ExecStart=@sbindir@/libvirtd $LIBVIRTD_ARGS
 ExecReload=/bin/kill -HUP $MAINPID
 KillMode=process
diff --git a/src/secret/meson.build b/src/secret/meson.build
index 3b859ea7b4..6d47569a4a 100644
--- a/src/secret/meson.build
+++ b/src/secret/meson.build
@@ -31,6 +31,18 @@ if conf.has('WITH_SECRETS')
     'name': 'virtsecretd',
   }
 
+  virt_secret_init_encryption_conf = configuration_data()
+
+  virt_secret_init_encryption_conf.set('localstatedir', localstatedir)
+
+  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..44940bd72b
--- /dev/null
+++ b/src/secret/virt-secret-init-encryption.service.in
@@ -0,0 +1,8 @@
+[Unit]
+Before=virtsecretd.service
+Before=libvirtd.service
+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
+
+[Service]
+LoadCredentialEncrypted=secrets-encryption-key:@localstatedir@/lib/libvirt/secrets/secrets-encryption-key
+Environment=SECRETS_ENCRYPTION_KEY=%d/secrets-encryption-key
-- 
2.51.1