From 3a01ad081a036a43900488368823e36a3e1b2e4d Mon Sep 17 00:00:00 2001 From: Sebastian Eydam Date: Fri, 24 Apr 2026 09:15:01 +0200 Subject: [PATCH] docs: document live migration TLS encryption On-behalf-of: SAP sebastian.eydam@sap.com Signed-off-by: Sebastian Eydam --- docs/live_migration.md | 153 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) diff --git a/docs/live_migration.md b/docs/live_migration.md index bf94d5ffe..daa15f43b 100644 --- a/docs/live_migration.md +++ b/docs/live_migration.md @@ -191,6 +191,159 @@ the destination host and continue running there. The source VM instance will terminate normally. All ongoing processes and connections within the VM should remain intact after the migration. +#### Encryption + +TCP migration can be protected with TLS by passing `tls_dir=` to +both `receive-migration` and `send-migration`. + +The destination host needs a directory containing: + +- `ca-cert.pem`: the CA certificate used to verify source certificates +- `server-cert.pem`: the certificate presented by the destination +- `server-key.pem`: the private key for `server-cert.pem` + +The source host needs a directory containing: + +- `ca-cert.pem`: the CA certificate used to verify the destination + certificate +- `client-cert.pem`: the certificate presented by the source +- `client-key.pem`: the private key for `client-cert.pem` + +Protect the private key files with file mode `0600` to reduce the risk +of accidental disclosure: + +```console +$ chmod 600 server-key.pem client-key.pem +``` + +Current TCP migration uses mutual TLS (mTLS) authentication. The source +verifies the destination certificate against `ca-cert.pem` and presents +`client-cert.pem` and `client-key.pem`. The destination presents +`server-cert.pem` and `server-key.pem`, and only accepts client +certificates that chain to `ca-cert.pem`. + +Example receiver command: + +```console +dst $ ch-remote --api-socket=/tmp/api receive-migration receiver_url=tcp:0.0.0.0:{port},tls_dir=/path/to/dst-tls +``` + +Example sender command: + +```console +src $ ch-remote --api-socket=/tmp/api send-migration destination_url=tcp:{dst}:{port},tls_dir=/path/to/src-tls +``` + +TLS encryption is only supported with `tcp::` migration +URLs, not with local UNIX-socket migration. + +The commands below describe how to create the encryption material necessary +to perform a same-host TCP migration with TLS. + +##### Setup the Certificate Authority + +First, set up the CA with a private key and a self-signed certificate. + +```console +$ certtool --generate-privkey \ + --outfile ca-key.pem +``` + +To generate the certificate, provide at least your organization name in a template file, for example `ca.info`: + +```text +cn = Name of your organization +ca +cert_signing_key +``` + +Then you can create the certificate: + +```console +$ certtool --generate-self-signed \ + --load-privkey ca-key.pem \ + --template ca.info \ + --outfile ca-cert.pem +``` + +##### Issuing host certificates + +Generate a private key and a certificate for each side. Cloud Hypervisor enforces mTLS, thus you also need a key for the migration sender. + +The certificates also require template data. You can use separate templates for sender and receiver, but this example uses a single template, `hosts.info`: + +```text +organization = Name of your organization +cn = localhost +tls_www_server +tls_www_client +signing_key +dns_name = localhost +ip_address = 127.0.0.1 +``` + +Then you can create the necessary files for the client (migration sender): + +```console +$ certtool --generate-privkey \ + --outfile client-key.pem + +$ certtool --generate-certificate \ + --load-ca-certificate ca-cert.pem \ + --load-ca-privkey ca-key.pem \ + --load-privkey client-key.pem \ + --template hosts.info \ + --outfile client-cert.pem +``` + +And the necessary files for the server (migration receiver): + +```console +$ certtool --generate-privkey \ + --outfile server-key.pem + +$ certtool --generate-certificate \ + --load-ca-certificate ca-cert.pem \ + --load-ca-privkey ca-key.pem \ + --load-privkey server-key.pem \ + --template hosts.info \ + --outfile server-cert.pem +``` + +For a same-host test, place these files in a single directory and use that directory as `tls_dir` for both commands. + +##### Performing the Migration + +On the receiver side, we prepare an empty VM: + +```console +dst $ cloud-hypervisor --api-socket /tmp/api-rcv +``` + +In a different terminal, prepare to receive the migration: + +```console +dst $ ch-remote --api-socket=/tmp/api-rcv receive-migration receiver_url=tcp:0.0.0.0:9000,tls_dir=/path/to/certificates +``` + +On the sender side, we start a VM: + +```console +src $ cloud-hypervisor \ + --serial tty --console off \ + --cpus boot=2 --memory size=4G \ + --kernel /var/images/linux \ + --initramfs /var/images/initrd \ + --cmdline "console=ttyS0" \ + --api-socket /tmp/api-src +``` + +After a few seconds the VM should be up and you can interact with it. Then trigger the migration: + +```console +src $ ch-remote --api-socket=/tmp/api-src send-migration destination_url=tcp:localhost:9000,tls_dir=/path/to/certificates +``` + #### Migration Parameters Cloud Hypervisor supports additional parameters to control the