mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
vmm: encrypt migration data with TLS if configured
Wire in the code paths that activate the TLS encrypting if the necessary API arguments are provided. On-behalf-of: SAP sebastian.eydam@sap.com Signed-off-by: Sebastian Eydam <sebastian.eydam@cyberus-technology.de>
This commit is contained in:
committed by
Rob Bradford
parent
320403a11e
commit
cf28552085
@@ -1414,8 +1414,10 @@ impl Vmm {
|
||||
let mut ctx = OngoingMigrationContext::new();
|
||||
|
||||
// Set up the socket connection
|
||||
let mut socket =
|
||||
migration_transport::send_migration_socket(&send_data_migration.destination_url)?;
|
||||
let mut socket = migration_transport::send_migration_socket(
|
||||
&send_data_migration.destination_url,
|
||||
send_data_migration.tls_dir.as_deref(),
|
||||
)?;
|
||||
|
||||
// Start the migration
|
||||
migration_transport::send_request_expect_ok(
|
||||
@@ -1505,6 +1507,7 @@ impl Vmm {
|
||||
let mut mem_send = migration_transport::SendAdditionalConnections::new(
|
||||
&send_data_migration.destination_url,
|
||||
send_data_migration.connections,
|
||||
send_data_migration.tls_dir.as_deref(),
|
||||
&vm.guest_memory(),
|
||||
)?;
|
||||
|
||||
@@ -2549,13 +2552,21 @@ impl RequestHandler for Vmm {
|
||||
&mut self,
|
||||
receive_data_migration: VmReceiveMigrationData,
|
||||
) -> result::Result<(), MigratableError> {
|
||||
receive_data_migration
|
||||
.validate()
|
||||
.context("Invalid receive migration configuration")
|
||||
.map_err(MigratableError::MigrateReceive)?;
|
||||
|
||||
info!(
|
||||
"Receiving migration: receiver_url = {}",
|
||||
receive_data_migration.receiver_url
|
||||
"Receiving migration: receiver_url={},tls={}",
|
||||
receive_data_migration.receiver_url,
|
||||
receive_data_migration.tls_dir.is_some()
|
||||
);
|
||||
|
||||
let mut listener =
|
||||
migration_transport::receive_migration_listener(&receive_data_migration.receiver_url)?;
|
||||
let mut listener = migration_transport::receive_migration_listener(
|
||||
&receive_data_migration.receiver_url,
|
||||
receive_data_migration.tls_dir.as_deref(),
|
||||
)?;
|
||||
|
||||
event!("vm", "migration-receive-ready");
|
||||
|
||||
@@ -2614,9 +2625,10 @@ impl RequestHandler for Vmm {
|
||||
.map_err(MigratableError::MigrateSend)?;
|
||||
|
||||
info!(
|
||||
"Sending migration: destination_url={},local={},downtime={}ms,timeout={}s,timeout_strategy={:?}",
|
||||
"Sending migration: destination_url={},local={},tls={},downtime={}ms,timeout={}s,timeout_strategy={:?}",
|
||||
send_data_migration.destination_url,
|
||||
send_data_migration.local,
|
||||
send_data_migration.tls_dir.is_some(),
|
||||
send_data_migration.downtime().as_millis(),
|
||||
send_data_migration.timeout().as_secs(),
|
||||
send_data_migration.timeout_strategy
|
||||
|
||||
@@ -9,7 +9,7 @@ use std::num::{NonZeroU32, ParseIntError};
|
||||
use std::os::fd::{AsFd, BorrowedFd};
|
||||
use std::os::unix::io::AsRawFd;
|
||||
use std::os::unix::net::{UnixListener, UnixStream};
|
||||
use std::path::PathBuf;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::result::Result;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::mpsc::{Receiver, Sender, SyncSender, TrySendError, channel, sync_channel};
|
||||
@@ -511,6 +511,7 @@ impl SendAdditionalConnections {
|
||||
pub(crate) fn new(
|
||||
destination: &str,
|
||||
connections: NonZeroU32,
|
||||
tls_dir: Option<&Path>,
|
||||
guest_memory: &GuestMemoryAtomic<GuestMemoryMmap>,
|
||||
) -> Result<Self, MigratableError> {
|
||||
let mut threads = Vec::new();
|
||||
@@ -537,7 +538,7 @@ impl SendAdditionalConnections {
|
||||
// the memory chunks to the workers, but does not send memory anymore. Thus in
|
||||
// this case we create one additional thread for each connection.
|
||||
for n in 0..configured_connections {
|
||||
let mut socket = send_migration_socket(destination)?;
|
||||
let mut socket = send_migration_socket(destination, tls_dir)?;
|
||||
let guest_memory = guest_memory.clone();
|
||||
let message_rx = message_rx.clone();
|
||||
let worker_error = worker_error.clone();
|
||||
@@ -852,6 +853,7 @@ pub fn tcp_address_to_server_name(address: &str) -> Result<&str, TcpAddressParse
|
||||
/// Connect to a migration endpoint and return the established stream.
|
||||
pub(crate) fn send_migration_socket(
|
||||
destination_url: &str,
|
||||
tls_dir: Option<&Path>,
|
||||
) -> Result<SocketStream, MigratableError> {
|
||||
if let Some(address) = destination_url.strip_prefix("tcp:") {
|
||||
info!("Connecting to TCP socket at {address}");
|
||||
@@ -860,7 +862,19 @@ pub(crate) fn send_migration_socket(
|
||||
MigratableError::MigrateSend(anyhow!("Error connecting to TCP socket: {e}"))
|
||||
})?;
|
||||
|
||||
Ok(SocketStream::Tcp(socket))
|
||||
if let Some(tls_dir) = tls_dir {
|
||||
// The address should have been validated by the API using this exact function.
|
||||
// Any error here has to be treated as a programming error.
|
||||
let server_name = tcp_address_to_server_name(address)
|
||||
.expect("TCP address should have been validated by the API");
|
||||
TlsStream::new_client(socket, tls_dir, server_name)
|
||||
.map(Box::new)
|
||||
.map(SocketStream::Tls)
|
||||
.context("Error creating TLS migration stream")
|
||||
.map_err(MigratableError::MigrateSend)
|
||||
} else {
|
||||
Ok(SocketStream::Tcp(socket))
|
||||
}
|
||||
} else {
|
||||
let path = socket_url_to_path(destination_url).map_err(MigratableError::MigrateSend)?;
|
||||
info!("Connecting to UNIX socket at {path:?}");
|
||||
@@ -876,12 +890,21 @@ pub(crate) fn send_migration_socket(
|
||||
/// Bind a migration listener for the receiver side.
|
||||
pub(crate) fn receive_migration_listener(
|
||||
receiver_url: &str,
|
||||
tls_dir: Option<&Path>,
|
||||
) -> Result<ReceiveListener, MigratableError> {
|
||||
if let Some(address) = receiver_url.strip_prefix("tcp:") {
|
||||
TcpListener::bind(address)
|
||||
.map(ReceiveListener::Tcp)
|
||||
let listener = TcpListener::bind(address)
|
||||
.context("Error binding to TCP socket")
|
||||
.map_err(MigratableError::MigrateReceive)
|
||||
.map_err(MigratableError::MigrateReceive)?;
|
||||
|
||||
if let Some(tls_dir) = tls_dir {
|
||||
let config = TlsServerConfig::new(tls_dir)
|
||||
.context("Error creating TLS server config")
|
||||
.map_err(MigratableError::MigrateReceive)?;
|
||||
Ok(ReceiveListener::Tls(listener, config))
|
||||
} else {
|
||||
Ok(ReceiveListener::Tcp(listener))
|
||||
}
|
||||
} else {
|
||||
let path = socket_url_to_path(receiver_url).map_err(MigratableError::MigrateReceive)?;
|
||||
UnixListener::bind(&path)
|
||||
|
||||
Reference in New Issue
Block a user