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>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
%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
%{_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
%attr(0755, root, root) %{_sbindir}/virtsecretd
%dir %attr(0700, root, root) %{_sysconfdir}/libvirt/secrets/
+%dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt/secrets/
%ghost %dir %attr(0700, root, root) %{_rundir}/libvirt/secrets/
%{_libdir}/libvirt/connection-driver/libvirt_driver_secret.so
%{_mandir}/man8/virtsecretd.8*
'sbindir': sbindir,
'sysconfdir': sysconfdir,
'initconfdir': initconfdir,
+ 'localstatedir': localstatedir,
'name': unit['name'],
'service': unit['service'],
'SERVICE': unit['service'].to_upper(),
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
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
'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',
virt_install_dirs += [
confdir / 'secrets',
runstatedir / 'libvirt' / 'secrets',
+ localstatedir / 'lib' / 'libvirt' / 'secrets',
]
endif
--- /dev/null
+[Unit]
+Before=virtsecretd.service
+Before=libvirtd.service
+ConditionPathExists=!@localstatedir@/lib/libvirt/secrets/secrets-encryption-key
+
+[Service]
+Type=oneshot
+ExecStart=/usr/bin/sh -c 'umask 0077 && (dd if=/dev/random status=none bs=32 count=1 | systemd-creds encrypt --name=secrets-encryption-key - @localstatedir@/lib/libvirt/secrets/secrets-encryption-key)'
# 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