Replace external reachability with an owned canary
This commit is contained in:
parent
0f6825c3b9
commit
31e9ab0f2d
2 changed files with 1409 additions and 1972 deletions
|
|
@ -9,10 +9,7 @@ use lazaret_core::codec::{decode, encode};
|
|||
use lazaret_core::identity::{
|
||||
ConfigurationFingerprint, CoordinatorId, DomainId, GenerationId, NetworkSidecarId,
|
||||
};
|
||||
use lazaret_core::network::{
|
||||
DnsQueryExpectation, ReachabilityExpectation, ReadinessExpectation, accept_network_readiness,
|
||||
derive_policy, validate_network_attestation,
|
||||
};
|
||||
use lazaret_core::network::{ReadinessExpectation, derive_policy, validate_network_attestation};
|
||||
use lazaret_core::records::{
|
||||
AddressFamily, AddressFamilyDisposition, AddressFamilyDispositionValue, DefaultAction,
|
||||
DerivedNetworkPolicyFields, HostProcessOwnershipSlot, IpAddress, IpNetwork,
|
||||
|
|
@ -25,8 +22,7 @@ use lazaret_linux::process::{
|
|||
};
|
||||
use lazaret_linux::user_namespace::UserNamespaceMap;
|
||||
use lazaret_runtime_supervisor::network::{
|
||||
DnsProbeTarget, NetworkAttestationContext, NetworkProbeRequest, TcpProbeTarget,
|
||||
enter_generation_filesystem_namespaces, prepare_network, probe_current_network,
|
||||
NetworkAttestationContext, enter_generation_filesystem_namespaces, prepare_network,
|
||||
};
|
||||
use rustix::io::{FdFlags, fcntl_setfd};
|
||||
use rustix::process::Signal;
|
||||
|
|
@ -107,11 +103,6 @@ fn run_parent() -> std::io::Result<()> {
|
|||
{
|
||||
return cleanup_runtime(runtime, std::io::Error::other("attestation is incomplete"));
|
||||
}
|
||||
let probe_path = directory.path().join("probe.postcard");
|
||||
wait_for_path(&probe_path, &runtime)?;
|
||||
let probe: lazaret_core::records::NetworkReachabilityProbe =
|
||||
decode(&std::fs::read(&probe_path)?)
|
||||
.map_err(|error| std::io::Error::other(error.to_string()))?;
|
||||
let expectation = ReadinessExpectation {
|
||||
domain_id: attestation.domain_id,
|
||||
generation_id: attestation.generation_id,
|
||||
|
|
@ -121,14 +112,6 @@ fn run_parent() -> std::io::Result<()> {
|
|||
runtime_supervisor: &attestation.runtime_supervisor,
|
||||
connectivity_helper: &attestation.connectivity_helper,
|
||||
};
|
||||
accept_network_readiness(
|
||||
&policy,
|
||||
&expectation,
|
||||
attestation.clone(),
|
||||
probe,
|
||||
&reachability(),
|
||||
)
|
||||
.map_err(std::io::Error::other)?;
|
||||
let mut mutated = attestation.clone();
|
||||
mutated.derived_policy_digest = lazaret_core::identity::DerivedPolicyDigest::new([9; 32]);
|
||||
if validate_network_attestation(&policy, &expectation, &mutated).is_ok() {
|
||||
|
|
@ -184,11 +167,6 @@ fn run_child(arguments: &[OsString]) -> std::io::Result<()> {
|
|||
&directory.join("attestation.postcard"),
|
||||
&encode(&attestation).map_err(std::io::Error::other)?,
|
||||
)?;
|
||||
let probe = probe_current_network(&probe_request(attestation.enforcement_namespace))?;
|
||||
atomic_replace(
|
||||
&directory.join("probe.postcard"),
|
||||
&encode(&probe).map_err(std::io::Error::other)?,
|
||||
)?;
|
||||
loop {
|
||||
if prepared.helper_exited()? {
|
||||
prepared.reap_exited()?;
|
||||
|
|
@ -240,37 +218,6 @@ fn policy() -> std::io::Result<lazaret_core::network::CanonicalDerivedNetworkPol
|
|||
.map_err(std::io::Error::other)
|
||||
}
|
||||
|
||||
fn probe_request(namespace: lazaret_core::identity::NamespaceIdentity) -> NetworkProbeRequest {
|
||||
NetworkProbeRequest {
|
||||
domain_id: DomainId::new([1; 32]),
|
||||
generation_id: GenerationId::new(7),
|
||||
enforcement_namespace: namespace,
|
||||
denied: vec![TcpProbeTarget {
|
||||
address: IpAddress::V4([10, 1, 2, 3]),
|
||||
port: 443,
|
||||
}],
|
||||
permitted: vec![TcpProbeTarget {
|
||||
address: IpAddress::V4([1, 1, 1, 1]),
|
||||
port: 443,
|
||||
}],
|
||||
dns: vec![DnsProbeTarget {
|
||||
resolver: IpAddress::V4([10, 137, 54, 3]),
|
||||
query_name: "example.com".into(),
|
||||
}],
|
||||
}
|
||||
}
|
||||
|
||||
fn reachability() -> ReachabilityExpectation {
|
||||
ReachabilityExpectation {
|
||||
denied_destinations: vec![IpAddress::V4([10, 1, 2, 3])],
|
||||
permitted_destinations: vec![IpAddress::V4([1, 1, 1, 1])],
|
||||
dns_queries: vec![DnsQueryExpectation {
|
||||
resolver: IpAddress::V4([10, 137, 54, 3]),
|
||||
query_name: "example.com".into(),
|
||||
}],
|
||||
}
|
||||
}
|
||||
|
||||
fn wait_for_path(
|
||||
path: &Path,
|
||||
process: &lazaret_linux::process::RetainedProcess,
|
||||
|
|
|
|||
|
|
@ -57,11 +57,6 @@ volumes = [
|
|||
{{ host = "{{profile_dir}}/read-write", container = "/root/read-write", kind = "directory", access = "read-write", create = true }},
|
||||
]
|
||||
|
||||
[profiles.default.readiness]
|
||||
denied = [{{ address = "10.20.30.40", port = 443 }}]
|
||||
permitted = [{{ address = "192.0.2.10", port = 443 }}]
|
||||
dns = [{{ resolver = "198.51.100.53", query = "example.invalid" }}]
|
||||
|
||||
[profiles.unselected]
|
||||
image = "example.invalid/unselected:v1"
|
||||
env = {{ UNSELECTED_SECRET = "env:UNSELECTED_HOST_SECRET" }}
|
||||
|
|
@ -103,7 +98,7 @@ env = {{ UNSELECTED_SECRET = "env:UNSELECTED_HOST_SECRET" }}
|
|||
fn terminal(&self) -> lazaret_runtime_supervisor::sandbox::StagedHostTerminal {
|
||||
let terminal = HostTerminal::from_compiled_entry(
|
||||
"xterm-lazaret",
|
||||
Some("truecolor".to_owned()),
|
||||
Some("truecolor"),
|
||||
fs::read(&self.terminfo_source).unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
|
|
@ -174,6 +169,7 @@ env = {{ UNSELECTED_SECRET = "env:UNSELECTED_HOST_SECRET" }}
|
|||
format!("sandbox-control/{container}/mailbox/requests"),
|
||||
format!("sandbox-control/{container}/mailbox/results"),
|
||||
format!("sandbox-control/{container}/bin"),
|
||||
format!("sandbox-control/{container}/readiness"),
|
||||
] {
|
||||
fs::create_dir_all(runtime.join(directory)).unwrap();
|
||||
}
|
||||
|
|
@ -420,7 +416,7 @@ fn product_init_role_has_exact_terminal_neutral_rootless_bundle_shape() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn selected_environment_volume_modes_and_host_terminal_are_preserved() {
|
||||
fn trusted_init_environment_is_empty_and_volume_modes_are_preserved() {
|
||||
let fixture = Fixture::new();
|
||||
let bundle = build_sandbox_bundle(fixture.request(root_process([]))).unwrap();
|
||||
let specification = value(&bundle);
|
||||
|
|
@ -430,10 +426,7 @@ fn selected_environment_volume_modes_and_host_terminal_are_preserved() {
|
|||
.iter()
|
||||
.map(|entry| entry.as_str().unwrap())
|
||||
.collect::<BTreeSet<_>>();
|
||||
assert!(environment.contains("SELECTED_SECRET=selected-value"));
|
||||
assert!(environment.contains("TERM=xterm-lazaret"));
|
||||
assert!(environment.contains("COLORTERM=truecolor"));
|
||||
assert!(environment.contains("TERMINFO_DIRS=/run/lazaret/terminfo:"));
|
||||
assert!(environment.is_empty());
|
||||
|
||||
let mounts = mounts(&specification);
|
||||
assert!(options(mounts[WORKSPACE_DESTINATION]).contains("rw"));
|
||||
|
|
|
|||
Loading…
Reference in a new issue