Forgetting to use the VIR_MIGRATE_TLS flag with migration can lead to
leak of sensitive information. Add an administrative knob to force use
of the flag.
Note that without VIR_MIGRATE_PEER2PEER, the migration is driven by an
instance of the client library which doesn't necessarily run on either
of the hosts so the flag can't be used to assume VIR_MIGRATE_TLS even
if it wasn't provided by the user instead of rejecting if it's not.
Resolves:
https://gitlab.com/libvirt/libvirt/-/issues/67
Signed-off-by: Peter Krempa <pkrempa(a)redhat.com>
---
src/qemu/libvirtd_qemu.aug | 1 +
src/qemu/qemu.conf | 8 ++++++++
src/qemu/qemu_conf.c | 2 ++
src/qemu/qemu_conf.h | 1 +
src/qemu/qemu_migration.c | 28 ++++++++++++++++++++++++++++
src/qemu/test_libvirtd_qemu.aug.in | 1 +
6 files changed, 41 insertions(+)
diff --git a/src/qemu/libvirtd_qemu.aug b/src/qemu/libvirtd_qemu.aug
index abbac549f2..3c1045858b 100644
--- a/src/qemu/libvirtd_qemu.aug
+++ b/src/qemu/libvirtd_qemu.aug
@@ -58,6 +58,7 @@ module Libvirtd_qemu =
let migrate_entry = str_entry "migrate_tls_x509_cert_dir"
| bool_entry "migrate_tls_x509_verify"
| str_entry "migrate_tls_x509_secret_uuid"
+ | bool_entry "migrate_tls_force"
let backup_entry = str_entry "backup_tls_x509_cert_dir"
| bool_entry "backup_tls_x509_verify"
diff --git a/src/qemu/qemu.conf b/src/qemu/qemu.conf
index a7b864f594..0c1054f198 100644
--- a/src/qemu/qemu.conf
+++ b/src/qemu/qemu.conf
@@ -401,6 +401,14 @@
#migrate_tls_x509_secret_uuid = "00000000-0000-0000-0000-000000000000"
+# By default TLS is requested using the VIR_MIGRATE_TLS flag, thus not requested
+# automatically. Setting 'migate_tls_force' to "1" will prevent any
migration
+# which is not using VIR_MIGRATE_TLS to ensure higher level of security in
+# deployments with TLS.
+#
+#migrate_tls_force = 0
+
+
# In order to override the default TLS certificate location for backup NBD
# server certificates, supply a valid path to the certificate directory. If the
# provided path does not exist, libvirtd will fail to start. If the path is
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index 83de26ab56..d6615ca0dd 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -494,6 +494,8 @@ virQEMUDriverConfigLoadSpecificTLSEntry(virQEMUDriverConfigPtr cfg,
return -1;
if (virConfGetValueBool(conf, "chardev_tls", &cfg->chardevTLS) <
0)
return -1;
+ if (virConfGetValueBool(conf, "migrate_tls_force",
&cfg->migrateTLSForce) < 0)
+ return -1;
#define GET_CONFIG_TLS_CERTINFO_COMMON(val) \
do { \
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index 8748212a82..411d08db36 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -140,6 +140,7 @@ struct _virQEMUDriverConfig {
bool migrateTLSx509verify;
bool migrateTLSx509verifyPresent;
char *migrateTLSx509secretUUID;
+ bool migrateTLSForce;
char *backupTLSx509certdir;
bool backupTLSx509verify;
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 2be0fc29ae..122481dea1 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -2332,9 +2332,18 @@ qemuMigrationSrcBegin(virConnectPtr conn,
unsigned long flags)
{
virQEMUDriverPtr driver = conn->privateData;
+ g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
char *xml = NULL;
qemuDomainAsyncJob asyncJob;
+ if (cfg->migrateTLSForce &&
+ !(flags & VIR_MIGRATE_TUNNELLED) &&
+ !(flags & VIR_MIGRATE_TLS)) {
+ virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("this libvirtd instance allows migration only with
VIR_MIGRATE_TLS flag"));
+ goto cleanup;
+ }
+
if ((flags & VIR_MIGRATE_CHANGE_PROTECTION)) {
if (qemuMigrationJobStart(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT,
flags) < 0)
@@ -2501,6 +2510,7 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver,
qemuMigrationParamsPtr migParams,
unsigned long flags)
{
+ g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
virDomainObjPtr vm = NULL;
virObjectEventPtr event = NULL;
virErrorPtr origErr;
@@ -2563,6 +2573,14 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver,
goto cleanup;
}
+ if (cfg->migrateTLSForce &&
+ !(flags & VIR_MIGRATE_TUNNELLED) &&
+ !(flags & VIR_MIGRATE_TLS)) {
+ virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("this libvirtd instance allows migration only with
VIR_MIGRATE_TLS flag"));
+ goto cleanup;
+ }
+
if (!qemuMigrationSrcIsAllowedHostdev(*def))
goto cleanup;
@@ -5013,6 +5031,8 @@ qemuMigrationSrcPerform(virQEMUDriverPtr driver,
unsigned long resource,
bool v3proto)
{
+ g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
+
VIR_DEBUG("driver=%p, conn=%p, vm=%p, xmlin=%s, dconnuri=%s, "
"uri=%s, graphicsuri=%s, listenAddress=%s, "
"nmigrate_disks=%zu, migrate_disks=%p, nbdPort=%d, "
@@ -5025,6 +5045,14 @@ qemuMigrationSrcPerform(virQEMUDriverPtr driver,
NULLSTR(cookiein), cookieinlen, cookieout, cookieoutlen,
flags, NULLSTR(dname), resource, v3proto);
+ if (cfg->migrateTLSForce &&
+ !(flags & VIR_MIGRATE_TUNNELLED) &&
+ !(flags & VIR_MIGRATE_TLS)) {
+ virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("this libvirtd instance allows migration only with
VIR_MIGRATE_TLS flag"));
+ return -1;
+ }
+
if ((flags & (VIR_MIGRATE_TUNNELLED | VIR_MIGRATE_PEER2PEER))) {
if (cookieinlen) {
virReportError(VIR_ERR_OPERATION_INVALID,
diff --git a/src/qemu/test_libvirtd_qemu.aug.in b/src/qemu/test_libvirtd_qemu.aug.in
index 6a54e2322a..9310dcec1c 100644
--- a/src/qemu/test_libvirtd_qemu.aug.in
+++ b/src/qemu/test_libvirtd_qemu.aug.in
@@ -35,6 +35,7 @@ module Test_libvirtd_qemu =
{ "migrate_tls_x509_cert_dir" = "/etc/pki/libvirt-migrate" }
{ "migrate_tls_x509_verify" = "1" }
{ "migrate_tls_x509_secret_uuid" =
"00000000-0000-0000-0000-000000000000" }
+{ "migrate_tls_force" = "0" }
{ "backup_tls_x509_cert_dir" = "/etc/pki/libvirt-backup" }
{ "backup_tls_x509_verify" = "1" }
{ "backup_tls_x509_secret_uuid" =
"00000000-0000-0000-0000-000000000000" }
--
2.28.0