Use the migrate_tls_force configuration param to control whether
encrypted migration is mandatory. When enabled, libvirt unconditionally
attempts the TLS pre-shared key authentication mechanism during
migration and fails the migration if the peer does not agree to it.
When disabled, the TLS authentication mechanisms are used only when
the VIR_MIGRATE_TLS flag is set; otherwise unencrypted migration
remains permitted.

Signed-off-by: Abhisek Panda <[email protected]>
---
 src/qemu/qemu.conf.in     | 12 ++++++----
 src/qemu/qemu_migration.c | 48 +++++++++++++++++++--------------------
 2 files changed, 31 insertions(+), 29 deletions(-)

diff --git a/src/qemu/qemu.conf.in b/src/qemu/qemu.conf.in
index 4fdd655881..80ba46aca8 100644
--- a/src/qemu/qemu.conf.in
+++ b/src/qemu/qemu.conf.in
@@ -429,10 +429,14 @@
 #migrate_tls_priority = "@SYSTEM"
 
 
-# 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.
+# Enforce TLS encryption for all domain migrations using either X.509 
certificates
+# or pre-shared keys (PSK) authentication schemes. By default, Libvirt allows
+# unencrypted migrations to proceed whenever the VIR_MIGRATE_TLS flag is not
+# explicitly set in migration.
+#
+# Enabling this option strictly prohibits unencrypted migrations to proceed.
+# If the destination fails to negotiate TLS, migration fails immediately
+# rather than falling back to unencrypted migration.
 #
 #migrate_tls_force = 0
 
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index c958edef6a..7716419a40 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -2892,7 +2892,8 @@ qemuMigrationSrcBeginPhase(virQEMUDriver *driver,
                            unsigned int flags)
 {
     qemuDomainObjPrivate *priv = vm->privateData;
-    unsigned int cookieFlags = QEMU_MIGRATION_COOKIE_LOCKSTATE | 
QEMU_MIGRATION_COOKIE_TLS_PSK;
+    unsigned int cookieFlags = QEMU_MIGRATION_COOKIE_LOCKSTATE;
+    g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
 
     VIR_DEBUG("driver=%p, vm=%p, xmlin=%s, dname=%s,"
               " cookieout=%p, cookieoutlen=%p,"
@@ -2958,6 +2959,9 @@ qemuMigrationSrcBeginPhase(virQEMUDriver *driver,
         return NULL;
     }
 
+    if (cfg->migrateTLSForce || (flags & VIR_MIGRATE_TLS))
+        cookieFlags |= QEMU_MIGRATION_COOKIE_TLS_PSK;
+
     if (flags & (VIR_MIGRATE_NON_SHARED_DISK | VIR_MIGRATE_NON_SHARED_INC)) {
         if (flags & VIR_MIGRATE_TUNNELLED) {
             virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
@@ -3167,14 +3171,6 @@ qemuMigrationSrcBegin(virConnectPtr conn,
     g_autofree char *xml = NULL;
     char *ret = NULL;
 
-    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_POSTCOPY_RESUME) {
         ret = qemuMigrationSrcBeginResumePhase(conn, vm, xmlin,
                                                cookieout, cookieoutlen, flags);
@@ -3623,6 +3619,7 @@ qemuMigrationDstPrepareFresh(virQEMUDriver *driver,
     g_autofree char *xmlout = NULL;
     unsigned int cookieFlags = QEMU_MIGRATION_COOKIE_TLS_PSK;
     bool taint_hook = false;
+    g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
 
     VIR_DEBUG("name=%s, origname=%s, protocol=%s, port=%hu, "
               "listenAddress=%s, nbdPort=%d, nbdURI=%s, flags=0x%x",
@@ -3691,6 +3688,14 @@ qemuMigrationDstPrepareFresh(virQEMUDriver *driver,
                                          QEMU_MIGRATION_COOKIE_TLS_PSK)))
         goto cleanup;
 
+    if (!mig->tlsPSK &&
+        cfg->migrateTLSForce &&
+        !(flags & VIR_MIGRATE_TLS)) {
+        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+                       _("The destination host only supports encrypted 
migration"));
+        goto cleanup;
+    }
+
     if (!(vm = virDomainObjListAdd(driver->domains, def,
                                    driver->xmlopt,
                                    VIR_DOMAIN_OBJ_LIST_ADD_LIVE |
@@ -3924,14 +3929,6 @@ qemuMigrationDstPrepareAny(virQEMUDriver *driver,
         return -1;
     }
 
-    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_POSTCOPY_RESUME) {
         return qemuMigrationDstPrepareResume(driver, dconn, cookiein, 
cookieinlen,
                                              cookieout, cookieoutlen,
@@ -5085,6 +5082,7 @@ qemuMigrationSrcRun(virQEMUDriver *driver,
     int ret = -1;
     qemuDomainObjPrivate *priv = vm->privateData;
     g_autoptr(qemuMigrationCookie) mig = NULL;
+    g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
     g_autofree char *tlsAlias = NULL;
     qemuMigrationIOThread *iothread = NULL;
     VIR_AUTOCLOSE fd = -1;
@@ -5158,6 +5156,14 @@ qemuMigrationSrcRun(virQEMUDriver *driver,
     if (qemuMigrationSrcGraphicsRelocate(vm, mig, graphicsuri) < 0)
         VIR_WARN("unable to provide data for graphics client relocation");
 
+    if (cfg->migrateTLSForce &&
+        !(mig->flags & QEMU_MIGRATION_COOKIE_TLS_PSK) &&
+        !(flags & VIR_MIGRATE_TLS)) {
+        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+                       _("The source host only supports encrypted migration"));
+        goto error;
+    }
+
     if (mig->blockDirtyBitmaps &&
         qemuMigrationSrcRunPrepareBlockDirtyBitmaps(vm, mig, migParams, flags) 
< 0)
         goto error;
@@ -6681,14 +6687,6 @@ qemuMigrationSrcPerform(virQEMUDriver *driver,
               NULLSTR(cookiein), cookieinlen, cookieout, cookieoutlen,
               flags, NULLSTR(dname), bandwidth, 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,
-- 
2.43.7

Reply via email to