Enable TLS-PSK based secure migration, if and only if both source and destination supports the tls-creds-psk object. Suggested-by: Tejus GK <tejus.gk@nutanix.com> Signed-off-by: Abhisek Panda <abhisek.panda1@nutanix.com> --- include/libvirt/libvirt-domain.h | 10 ++++-- src/qemu/qemu_migration.c | 56 ++++++++++++++++++++++++-------- 2 files changed, 49 insertions(+), 17 deletions(-) diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h index 99208137c3..2ec3956f8b 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -1089,9 +1089,13 @@ typedef enum { VIR_MIGRATE_POSTCOPY = (1 << 15), /* Setting the VIR_MIGRATE_TLS flag will cause the migration to attempt - * to use the TLS environment configured by the hypervisor in order to - * perform the migration. If incorrectly configured on either source or - * destination, the migration will fail. + * to use the TLS X.509 authentication mechanisms only if the TLS pre-shared + * key (PSK) authentication mechanism is not supported by either source + * or destination. If the certificate or the key files are incorrectly configured + * on either source or destination, then the migration will fail. + * + * Note: Since 12.7.0, Libvirt supports the TLS pre-shared key (PSK) authentication + * mechanism along with the TLS X.509 authentication scheme. * * Since: 3.2.0 */ diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 2fc8af9c15..e9c8ddc343 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -3499,9 +3499,19 @@ qemuMigrationDstPrepareActive(virQEMUDriver *driver, /* Save original migration parameters */ qemuDomainSaveStatus(vm); - /* Migrations using TLS need to add the "tls-creds-x509" object and - * set the migration TLS parameters */ - if (flags & VIR_MIGRATE_TLS) { + /* Migrations need to add the "tls-creds-psk" object whenever both + * sides support TLS-PSK authentication regardless of the + * VIR_MIGRATE_TLS flag. Otherwise, fall back to "tls-creds-x509" if + * VIR_MIGRATE_TLS is enabled. Finally, set the appropriate migration + * TLS parameters. */ + if ((mig->flags & QEMU_MIGRATION_COOKIE_TLS_PSK) && mig->tlsPSK) { + if (qemuMigrationPersistPSK(driver, vm, mig->tlsPSK) < 0) + goto error; + if (qemuMigrationParamsEnableTLSPSK(driver, vm, true, + VIR_ASYNC_JOB_MIGRATION_IN, + &tlsAlias, migParams) < 0) + goto error; + } else if (flags & VIR_MIGRATE_TLS) { if (qemuMigrationParamsEnableTLSx509(driver, vm, true, VIR_ASYNC_JOB_MIGRATION_IN, &tlsAlias, NULL, @@ -3516,14 +3526,13 @@ qemuMigrationDstPrepareActive(virQEMUDriver *driver, flags & (VIR_MIGRATE_NON_SHARED_DISK | VIR_MIGRATE_NON_SHARED_INC)) { const char *nbdTLSAlias = NULL; - if (flags & VIR_MIGRATE_TLS) { - if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NBD_TLS)) { - virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", - _("QEMU NBD server does not support TLS transport")); - goto error; - } - + if (tlsAlias && virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NBD_TLS)) { nbdTLSAlias = tlsAlias; + } else if ((flags & VIR_MIGRATE_TLS) && + !virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NBD_TLS)) { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", + _("QEMU NBD server does not support TLS transport")); + goto error; } if (qemuMigrationDstStartNBDServer(driver, vm, incoming->address, @@ -3611,7 +3620,7 @@ qemuMigrationDstPrepareFresh(virQEMUDriver *driver, qemuDomainObjPrivate *priv = NULL; g_autoptr(qemuMigrationCookie) mig = NULL; g_autofree char *xmlout = NULL; - unsigned int cookieFlags = 0; + unsigned int cookieFlags = QEMU_MIGRATION_COOKIE_TLS_PSK; bool taint_hook = false; VIR_DEBUG("name=%s, origname=%s, protocol=%s, port=%hu, " @@ -3677,7 +3686,8 @@ qemuMigrationDstPrepareFresh(virQEMUDriver *driver, QEMU_MIGRATION_COOKIE_CPU_HOTPLUG | QEMU_MIGRATION_COOKIE_CPU | QEMU_MIGRATION_COOKIE_CAPS | - QEMU_MIGRATION_COOKIE_BLOCK_DIRTY_BITMAPS))) + QEMU_MIGRATION_COOKIE_BLOCK_DIRTY_BITMAPS | + QEMU_MIGRATION_COOKIE_TLS_PSK))) goto cleanup; if (!(vm = virDomainObjListAdd(driver->domains, def, @@ -5102,6 +5112,9 @@ qemuMigrationSrcRun(virQEMUDriver *driver, if (storageMigration) cookieFlags |= QEMU_MIGRATION_COOKIE_NBD; + if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_OBJECT_TLS_CREDS_PSK)) + cookieFlags |= QEMU_MIGRATION_COOKIE_TLS_PSK; + if (virLockManagerPluginUsesState(driver->lockManager) && !cookieout) { virReportError(VIR_ERR_INTERNAL_ERROR, @@ -5152,7 +5165,12 @@ qemuMigrationSrcRun(virQEMUDriver *driver, /* Save original migration parameters */ qemuDomainSaveStatus(vm); - if (flags & VIR_MIGRATE_TLS) { + if (mig->flags & QEMU_MIGRATION_COOKIE_TLS_PSK) { + if (qemuMigrationParamsEnableTLSPSK(driver, vm, false, + VIR_ASYNC_JOB_MIGRATION_OUT, + &tlsAlias, migParams) < 0) + goto error; + } else if (flags & VIR_MIGRATE_TLS) { const char *hostname = NULL; /* We need to add tls-hostname whenever QEMU itself does not @@ -5201,6 +5219,7 @@ qemuMigrationSrcRun(virQEMUDriver *driver, if (storageMigration) { const char *host = ""; const char *tlsHostname = qemuMigrationParamsGetTLSHostname(migParams); + const char *nbdTLSAlias = NULL; if (!mig->nbd) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", @@ -5213,13 +5232,22 @@ qemuMigrationSrcRun(virQEMUDriver *driver, host = spec->dest.host.name; } + if (tlsAlias && virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NBD_TLS)) { + nbdTLSAlias = tlsAlias; + } else if ((flags & VIR_MIGRATE_TLS) && + !virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NBD_TLS)) { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", + _("QEMU NBD client does not support TLS transport")); + goto error; + } + if (qemuMigrationSrcNBDStorageCopy(driver, vm, mig, host, priv->migMaxBandwidth, migrate_disks, migrate_disks_detect_zeroes, migrate_disks_target_zero, - dconn, tlsAlias, tlsHostname, + dconn, nbdTLSAlias, tlsHostname, nbdURI, flags) < 0) { goto error; } -- 2.43.7