diff --git a/crates/openshell-sandbox/src/sandbox/linux/landlock.rs b/crates/openshell-sandbox/src/sandbox/linux/landlock.rs index e7f37ce4f..428675ebb 100644 --- a/crates/openshell-sandbox/src/sandbox/linux/landlock.rs +++ b/crates/openshell-sandbox/src/sandbox/linux/landlock.rs @@ -3,10 +3,10 @@ //! Landlock filesystem sandboxing. -use crate::policy::{LandlockCompatibility, SandboxPolicy}; +use crate::policy::{LandlockCompatibility, NetworkMode, SandboxPolicy}; use landlock::{ - ABI, Access, AccessFs, CompatLevel, Compatible, PathBeneath, PathFd, PathFdError, Ruleset, - RulesetAttr, RulesetCreatedAttr, + ABI, Access, AccessFs, AccessNet, CompatLevel, Compatible, NetPort, PathBeneath, PathFd, + PathFdError, Ruleset, RulesetAttr, RulesetCreatedAttr, }; use miette::{IntoDiagnostic, Result}; use std::path::{Path, PathBuf}; @@ -184,6 +184,26 @@ pub fn prepare(policy: &SandboxPolicy, workdir: Option<&str>) -> Result { + ruleset = r; + tcp_handled = true; + } + Err(e) => { + tracing::warn!( + error = %e, + "Landlock handle_access(ConnectTcp) failed (ABI v4 required). \ + TCP port restriction will not be applied." + ); + } + } + } + let mut ruleset = ruleset.create().into_diagnostic()?; let mut rules_applied: usize = 0; @@ -207,6 +227,34 @@ pub fn prepare(policy: &SandboxPolicy, workdir: Option<&str>) -> Result { + ruleset = r; + debug!( + port = proxy_port, + "Landlock allow TCP connect (proxy port only)" + ); + rules_applied += 1; + } + Err(e) => { + tracing::warn!( + error = %e, + "Landlock TCP port restriction unavailable. \ + Network enforcement degraded: agent can bypass proxy via direct \ + connect(). Upgrade to RHEL 9.6+ for kernel-enforced TCP port restriction." + ); + } + } + } + if rules_applied == 0 { return Err(miette::miette!( "Landlock ruleset has zero valid paths — all {} path(s) failed to open. \ @@ -215,7 +263,7 @@ pub fn prepare(policy: &SandboxPolicy, workdir: Option<&str>) -> Result