Skip to main content

starpod_proxy/
tier.rs

1//! Isolation tier detection.
2//!
3//! Automatically selects the strongest network isolation available:
4//! - **Tier 1 (NetNamespace)**: Linux + CAP_NET_ADMIN → kernel-enforced isolation
5//! - **Tier 0 (EnvProxy)**: All platforms → env var proxy injection
6
7use tracing::info;
8
9/// Network isolation tier.
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub enum IsolationTier {
12    /// Tier 0: HTTP_PROXY env vars. Tools _can_ ignore them.
13    EnvProxy,
14    /// Tier 1: Network namespace. All traffic forced through proxy at kernel level.
15    #[cfg(all(target_os = "linux", feature = "netns"))]
16    NetNamespace,
17}
18
19/// Check if the current process has CAP_NET_ADMIN.
20///
21/// Reads `/proc/self/status` and checks the effective capabilities bitmask.
22/// CAP_NET_ADMIN is bit 12 (value 0x1000).
23#[cfg(all(target_os = "linux", feature = "netns"))]
24fn has_cap_net_admin() -> bool {
25    let Ok(status) = std::fs::read_to_string("/proc/self/status") else {
26        return false;
27    };
28    for line in status.lines() {
29        if let Some(hex) = line.strip_prefix("CapEff:\t") {
30            let Ok(caps) = u64::from_str_radix(hex.trim(), 16) else {
31                return false;
32            };
33            // CAP_NET_ADMIN = bit 12
34            return caps & (1 << 12) != 0;
35        }
36    }
37    false
38}
39
40/// Detect and log the best available isolation tier.
41pub fn detect_and_log() -> IsolationTier {
42    #[cfg(all(target_os = "linux", feature = "netns"))]
43    {
44        if has_cap_net_admin() {
45            info!("proxy: network namespace isolation (linux/netns)");
46            return IsolationTier::NetNamespace;
47        }
48        info!("proxy: env var mode (netns unavailable: missing CAP_NET_ADMIN)");
49        return IsolationTier::EnvProxy;
50    }
51
52    #[cfg(not(all(target_os = "linux", feature = "netns")))]
53    {
54        #[cfg(target_os = "linux")]
55        info!("proxy: env var mode (netns feature not compiled)");
56        #[cfg(not(target_os = "linux"))]
57        info!("proxy: env var mode (not linux)");
58        IsolationTier::EnvProxy
59    }
60}
61
62#[cfg(test)]
63mod tests {
64    use super::*;
65
66    #[test]
67    fn detect_returns_valid_tier() {
68        let tier = detect_and_log();
69        #[cfg(not(all(target_os = "linux", feature = "netns")))]
70        assert_eq!(tier, IsolationTier::EnvProxy);
71        let _ = tier; // suppress unused on netns-enabled Linux
72    }
73}