Route Windows sandbox proxy traffic by restricting SID (#34613)

## Why

Elevated Windows sandboxes need stable managed-proxy ports while preserving the network policy and environment attribution of each sandboxed process.

## What changed

- Keep shared HTTP and SOCKS5 loopback ingress listeners alive across managed-proxy instances.
- Add a per-route restricting SID to elevated sandbox tokens and dispatch incoming connections to the matching proxy policy after attributing the client process.
- Reject connections without exactly one registered route, remove routes when their proxy handle is dropped, and keep unsandboxed Windows launches off the managed ingress.
- Provision the elevated sandbox with the configured proxy ports and local-binding setting, honoring the selected profile and CLI overrides.

## Testing

- Add Windows unit tests for TCP ownership attribution, route selection, restricting-token propagation, and setup settings.
- Add an end-to-end Windows test covering stable ports, isolated environment policies, HTTP and SOCKS5 routing, and route teardown.

GitOrigin-RevId: 783fac6e0f904dc9bb1955b75d4a5895e8bb9690
This commit is contained in:
iceweasel-oai
2026-07-21 21:06:04 +00:00
committed by copyberry
parent dfd2d8133c
commit 999a715089
40 changed files with 2792 additions and 191 deletions
+18 -12
View File
@@ -40,6 +40,7 @@ use rama_core::error::ErrorExt as _;
use rama_core::error::OpaqueError;
use rama_core::extensions::ExtensionsMut;
use rama_core::extensions::ExtensionsRef;
use rama_core::service::BoxService;
use rama_core::service::service_fn;
use rama_core::stream::Stream;
use rama_http::Body;
@@ -66,6 +67,7 @@ use rama_net::proxy::ProxyRequest;
use rama_net::proxy::ProxyTarget;
use rama_net::proxy::StreamForwardService;
use rama_net::stream::SocketInfo;
use rama_tcp::TcpStream;
use rama_tcp::client::Request as TcpRequest;
use rama_tcp::server::TcpListener;
use rama_tls_rustls::client::TlsConnectorDataBuilder;
@@ -124,12 +126,25 @@ async fn run_http_proxy_with_listener(
policy_decider: Option<Arc<dyn NetworkPolicyDecider>>,
environment_id: Option<String>,
) -> Result<()> {
ensure_rustls_crypto_provider();
let addr = listener
.local_addr()
.context("read HTTP proxy listener local addr")?;
info!("HTTP proxy listening on {addr}");
listener
.serve(http_proxy_service(state, policy_decider, environment_id))
.await;
Ok(())
}
pub(crate) fn http_proxy_service(
state: Arc<NetworkProxyState>,
policy_decider: Option<Arc<dyn NetworkPolicyDecider>>,
environment_id: Option<String>,
) -> BoxService<TcpStream, (), rama_core::error::BoxError> {
ensure_rustls_crypto_provider();
// This proxy listener only needs HTTP/1 proxy semantics. Using Rama's auto builder
// forces every accepted socket through the HTTP version sniffing pre-read path before proxy
// request parsing, which can stall some local clients on macOS before CONNECT/absolute-form
@@ -156,16 +171,7 @@ async fn run_http_proxy_with_listener(
})),
);
info!("HTTP proxy listening on {addr}");
listener
.serve(BindConnectionAttribution::new(
http_service,
state,
environment_id,
))
.await;
Ok(())
BindConnectionAttribution::new(http_service, state, environment_id).boxed()
}
async fn http_connect_accept(