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@xxxxxxxxxx> --- 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