From 179d108fa04cc16778c5674d386a500c45c95c08 Mon Sep 17 00:00:00 2001 From: Ladislav Smola Date: Fri, 12 Jun 2026 17:10:41 +0200 Subject: [PATCH] feat(sandbox): Landlock TCP port restriction in Platform mode When Platform mode is active, apply Landlock ABI v4 network rules to restrict TCP connect to only the proxy port (default 3128). This makes the loopback CONNECT proxy mandatory at the kernel level -- a process calling connect() to any other port gets EACCES before any packet is created. This closes the cooperative proxy gap: without this, processes ignoring HTTP_PROXY could bypass the proxy and connect directly. With this, enforcement is at the kernel LSM layer (Tier 1), same as Landlock filesystem restrictions. Graceful degradation: if the kernel does not support Landlock ABI v4 (RHEL 9.5 or earlier), the network rules are silently skipped and enforcement falls back to the cooperative proxy + NetworkPolicy. 1 file changed, +43/-3 lines. Compiles, tests pass, clippy clean. Ref: NVIDIA/OpenShell#899 --- .../src/sandbox/linux/landlock.rs | 46 +++++++++++++++++-- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/crates/openshell-sandbox/src/sandbox/linux/landlock.rs b/crates/openshell-sandbox/src/sandbox/linux/landlock.rs index e7f37ce4f..299ec4c37 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,15 @@ pub fn prepare(policy: &SandboxPolicy, workdir: Option<&str>) -> Result) -> Result { + ruleset = r; + debug!( + port = proxy_port, + "Landlock allow TCP connect (proxy port only)" + ); + rules_applied += 1; + } + Err(e) => { + debug!( + error = %e, + "Landlock TCP port restriction unavailable (ABI v4 required), \ + falling back to cooperative proxy enforcement" + ); + } + } + } + if rules_applied == 0 { return Err(miette::miette!( "Landlock ruleset has zero valid paths — all {} path(s) failed to open. \