1
0
mirror of https://github.com/kata-containers/kata-containers.git synced 2025-05-06 15:37:33 +00:00

agent: Launch the confidential data hub

Let's introduce a new method to start the confidential data hub and the
attestation agent.  The former depends on the later, and it needs to be
started before the RPC server.

Starting the attestation components is based on whether the confidential
containers guest components binaries are found in the rootfs.

Fixes: 

Signed-off-by: Biao Lu <biao.lu@intel.com>
Signed-off-by: Fabiano Fidêncio <fabiano.fidencio@intel.com>
Signed-off-by: Linda Yu <linda.yu@intel.com>
Co-authored-by: stevenhorsman <steven@uk.ibm.com>
Co-authored-by: Jakob Naucke <jakob.naucke@ibm.com>
Co-authored-by: Wang, Arron <arron.wang@intel.com>
Co-authored-by: zhouliang121 <liang.a.zhou@linux.alibaba.com>
Co-authored-by: Alex Carter <alex.carter@ibm.com>
Co-authored-by: Suraj Deshmukh <suraj.deshmukh@microsoft.com>
Co-authored-by: Xynnn007 <xynnn@linux.alibaba.com>
This commit is contained in:
Biao Lu 2023-08-23 14:26:48 +08:00 committed by stevenhorsman
parent be8f0cb520
commit f476d671ed
3 changed files with 119 additions and 6 deletions

27
src/agent/Cargo.lock generated
View File

@ -817,6 +817,26 @@ version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
[[package]]
name = "const_format"
version = "0.2.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3a214c7af3d04997541b18d432afaff4c455e79e2029079647e72fc2bd27673"
dependencies = [
"const_format_proc_macros",
]
[[package]]
name = "const_format_proc_macros"
version = "0.2.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7f6ff08fd20f4f299298a28e2dfa8a8ba1036e6cd2460ac1de7b425d76f2500"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "core-foundation"
version = "0.9.3"
@ -2081,6 +2101,7 @@ dependencies = [
"cfg-if 1.0.0",
"cgroups-rs",
"clap",
"const_format",
"futures",
"http",
"image-rs",
@ -5210,6 +5231,12 @@ version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99"
[[package]]
name = "unicode-xid"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
[[package]]
name = "universal-hash"
version = "0.5.1"

View File

@ -26,6 +26,7 @@ url = "2.5.0"
kata-sys-util = { path = "../libs/kata-sys-util" }
kata-types = { path = "../libs/kata-types" }
safe-path = { path = "../libs/safe-path" }
const_format = "0.2.30"
# Async helpers
async-trait = "0.1.42"
@ -36,7 +37,7 @@ futures = "0.3.30"
tokio = { version = "1.28.1", features = ["full"] }
tokio-vsock = "0.3.1"
netlink-sys = { version = "0.7.0", features = ["tokio_socket",]}
netlink-sys = { version = "0.7.0", features = ["tokio_socket"] }
rtnetlink = "0.8.0"
netlink-packet-utils = "0.4.1"
ipnetwork = "0.17.0"
@ -62,7 +63,7 @@ cgroups = { package = "cgroups-rs", version = "0.3.3" }
tracing = "0.1.26"
tracing-subscriber = "0.2.18"
tracing-opentelemetry = "0.13.0"
opentelemetry = { version = "0.14.0", features = ["rt-tokio-current-thread"]}
opentelemetry = { version = "0.14.0", features = ["rt-tokio-current-thread"] }
vsock-exporter = { path = "vsock-exporter" }
# Configuration
@ -87,16 +88,14 @@ rstest = "0.18.0"
async-std = { version = "1.12.0", features = ["attributes"] }
[workspace]
members = [
"rustjail",
]
members = ["rustjail"]
[profile.release]
lto = true
[features]
# The default-pull feature would support all pull types, including sharing images by virtio-fs and pulling images in the guest
default-pull = [ "guest-pull" ]
default-pull = ["guest-pull"]
seccomp = ["rustjail/seccomp"]
standard-oci-runtime = ["rustjail/standard-oci-runtime"]
agent-policy = ["http", "openssl", "reqwest"]

View File

@ -22,6 +22,7 @@ extern crate slog;
use anyhow::{anyhow, Context, Result};
use cfg_if::cfg_if;
use clap::{AppSettings, Parser};
use const_format::concatcp;
use nix::fcntl::OFlag;
use nix::sys::socket::{self, AddressFamily, SockFlag, SockType, VsockAddr};
use nix::unistd::{self, dup, Pid};
@ -32,6 +33,7 @@ use std::os::unix::fs as unixfs;
use std::os::unix::io::AsRawFd;
use std::path::Path;
use std::process::exit;
use std::process::Command;
use std::sync::Arc;
use tracing::{instrument, span};
@ -91,6 +93,20 @@ cfg_if! {
const NAME: &str = "kata-agent";
const UNIX_SOCKET_PREFIX: &str = "unix://";
const AA_PATH: &str = "/usr/local/bin/attestation-agent";
const AA_ATTESTATION_SOCKET: &str =
"/run/confidential-containers/attestation-agent/attestation-agent.sock";
const AA_ATTESTATION_URI: &str = concatcp!(UNIX_SOCKET_PREFIX, AA_ATTESTATION_SOCKET);
const CDH_PATH: &str = "/usr/local/bin/confidential-data-hub";
const CDH_SOCKET: &str = "/run/confidential-containers/cdh.sock";
const API_SERVER_PATH: &str = "/usr/local/bin/api-server-rest";
const DEFAULT_LAUNCH_PROCESS_TIMEOUT: i32 = 6;
lazy_static! {
static ref AGENT_CONFIG: AgentConfig =
// Note: We can't do AgentOpts.parse() here to send through the processed arguments to AgentConfig
@ -384,6 +400,10 @@ async fn start_sandbox(
let (tx, rx) = tokio::sync::oneshot::channel();
sandbox.lock().await.sender = Some(tx);
if Path::new(CDH_PATH).exists() && Path::new(AA_PATH).exists() {
init_attestation_components(logger)?;
}
// vsock:///dev/vsock, port
let mut server = rpc::start(sandbox.clone(), config.server_addr.as_str(), init_mode).await?;
server.start().await?;
@ -394,6 +414,73 @@ async fn start_sandbox(
Ok(())
}
// Start-up attestation-agent, CDH and api-server-rest if they are packaged in the rootfs
fn init_attestation_components(logger: &Logger) -> Result<()> {
// The Attestation Agent will run for the duration of the guest.
launch_process(
logger,
AA_PATH,
&vec!["--attestation_sock", AA_ATTESTATION_URI],
AA_ATTESTATION_SOCKET,
DEFAULT_LAUNCH_PROCESS_TIMEOUT,
)
.map_err(|e| anyhow!("launch_process {} failed: {:?}", AA_PATH, e))?;
if let Err(e) = launch_process(
logger,
CDH_PATH,
&vec![],
CDH_SOCKET,
DEFAULT_LAUNCH_PROCESS_TIMEOUT,
) {
error!(logger, "launch_process {} failed: {:?}", CDH_PATH, e);
}
Ok(())
}
fn wait_for_path_to_exist(logger: &Logger, path: &str, timeout_secs: i32) -> Result<()> {
let p = Path::new(path);
let mut attempts = 0;
loop {
std::thread::sleep(std::time::Duration::from_secs(1));
if p.exists() {
return Ok(());
}
if attempts >= timeout_secs {
break;
}
attempts += 1;
info!(
logger,
"waiting for {} to exist (attempts={})", path, attempts
);
}
Err(anyhow!("wait for {} to exist timeout.", path))
}
fn launch_process(
logger: &Logger,
path: &str,
args: &Vec<&str>,
unix_socket_path: &str,
timeout_secs: i32,
) -> Result<()> {
if !Path::new(path).exists() {
return Err(anyhow!("path {} does not exist.", path));
}
if !unix_socket_path.is_empty() && Path::new(unix_socket_path).exists() {
fs::remove_file(unix_socket_path)?;
}
Command::new(path).args(args).spawn()?;
if !unix_socket_path.is_empty() && timeout_secs > 0 {
wait_for_path_to_exist(logger, unix_socket_path, timeout_secs)?;
}
Ok(())
}
// init_agent_as_init will do the initializations such as setting up the rootfs
// when this agent has been run as the init process.
fn init_agent_as_init(logger: &Logger, unified_cgroup_hierarchy: bool) -> Result<()> {