@@ -18,6 +18,7 @@ import (
1818type Linux struct {
1919config Config
2020namespace string
21+ vethHost string // Host-side veth interface name for iptables rules
2122logger * slog.Logger
2223preparedEnv map [string ]string
2324procAttr * syscall.SysProcAttr
@@ -26,9 +27,10 @@ type Linux struct {
2627// newLinux creates a new Linux network jail instance
2728func newLinux (config Config , logger * slog.Logger ) (* Linux , error ) {
2829return & Linux {
29- config : config ,
30- namespace : newNamespaceName (),
31- logger : logger ,
30+ config : config ,
31+ namespace : newNamespaceName (),
32+ logger : logger ,
33+ preparedEnv : make (map [string ]string ),
3234}, nil
3335}
3436
@@ -63,12 +65,14 @@ func (l *Linux) Open() error {
6365
6466// Prepare environment once during setup
6567l .logger .Debug ("Preparing environment" )
66- l .preparedEnv = make (map [string ]string )
6768
6869// Start with current environment
6970for _ , envVar := range os .Environ () {
7071if parts := strings .SplitN (envVar , "=" , 2 ); len (parts ) == 2 {
71- l .preparedEnv [parts [0 ]] = parts [1 ]
72+ // Only set if not already set by SetEnv
73+ if _ , exists := l .preparedEnv [parts [0 ]]; ! exists {
74+ l .preparedEnv [parts [0 ]] = parts [1 ]
75+ }
7276}
7377}
7478
@@ -193,6 +197,9 @@ func (l *Linux) setupNetworking() error {
193197vethHost := fmt .Sprintf ("veth_h_%s" , uniqueID ) // veth_h_1234567 = 14 chars
194198vethNetJail := fmt .Sprintf ("veth_n_%s" , uniqueID ) // veth_n_1234567 = 14 chars
195199
200+ // Store veth interface name for iptables rules
201+ l .vethHost = vethHost
202+
196203setupCmds := []struct {
197204description string
198205command * exec.Cmd
@@ -246,42 +253,40 @@ options timeout:2 attempts:2
246253return nil
247254}
248255
249- // setupIptables configures iptables rules for traffic redirection
256+ // setupIptables configures iptables rules for comprehensive TCP traffic interception
250257func (l * Linux ) setupIptables () error {
251258// Enable IP forwarding
252259cmd := exec .Command ("sysctl" , "-w" , "net.ipv4.ip_forward=1" )
253260cmd .Run () // Ignore error
254261
255- // NAT rules for outgoing traffic
262+ // NAT rules for outgoing traffic (MASQUERADE for return traffic)
256263cmd = exec .Command ("iptables" , "-t" , "nat" , "-A" , "POSTROUTING" , "-s" , "192.168.100.0/24" , "-j" , "MASQUERADE" )
257264err := cmd .Run ()
258265if err != nil {
259266return fmt .Errorf ("failed to add NAT rule: %v" , err )
260267}
261268
262- // Redirect HTTP traffic to proxy
263- cmd = exec .Command ("ip" , "netns" , "exec" , l .namespace , "iptables" , "-t" , "nat" , "-A" , "OUTPUT" ,
264- "-p" , "tcp" , "--dport" , "80" , "-j" , "DNAT" , "--to-destination" , fmt .Sprintf ("192.168.100.1:%d" , l .config .HTTPPort ))
265- err = cmd .Run ()
266- if err != nil {
267- return fmt .Errorf ("failed to add HTTP redirect rule: %v" , err )
268- }
269-
270- // Redirect HTTPS traffic to proxy
271- cmd = exec .Command ("ip" , "netns" , "exec" , l .namespace , "iptables" , "-t" , "nat" , "-A" , "OUTPUT" ,
272- "-p" , "tcp" , "--dport" , "443" , "-j" , "DNAT" , "--to-destination" , fmt .Sprintf ("192.168.100.1:%d" , l .config .HTTPSPort ))
269+ // COMPREHENSIVE APPROACH: Intercept ALL TCP traffic from namespace
270+ // Use PREROUTING on host to catch traffic after it exits namespace but before routing
271+ // This ensures NO TCP traffic can bypass the proxy
272+ cmd = exec .Command ("iptables" , "-t" , "nat" , "-A" , "PREROUTING" , "-i" , l .vethHost , "-p" , "tcp" , "-j" , "REDIRECT" , "--to-ports" , fmt .Sprintf ("%d" , l .config .HTTPSPort ))
273273err = cmd .Run ()
274274if err != nil {
275- return fmt .Errorf ("failed to add HTTPS redirect rule: %v" , err )
275+ return fmt .Errorf ("failed to add comprehensive TCP redirect rule: %v" , err )
276276}
277277
278+ l .logger .Debug ("Comprehensive TCP jailing enabled" , "interface" , l .vethHost , "proxy_port" , l .config .HTTPSPort )
278279return nil
279280}
280281
281282// removeIptables removes iptables rules
282283func (l * Linux ) removeIptables () error {
284+ // Remove comprehensive TCP redirect rule
285+ cmd := exec .Command ("iptables" , "-t" , "nat" , "-D" , "PREROUTING" , "-i" , l .vethHost , "-p" , "tcp" , "-j" , "REDIRECT" , "--to-ports" , fmt .Sprintf ("%d" , l .config .HTTPSPort ))
286+ cmd .Run () // Ignore errors during cleanup
287+
283288// Remove NAT rule
284- cmd : = exec .Command ("iptables" , "-t" , "nat" , "-D" , "POSTROUTING" , "-s" , "192.168.100.0/24" , "-j" , "MASQUERADE" )
289+ cmd = exec .Command ("iptables" , "-t" , "nat" , "-D" , "POSTROUTING" , "-s" , "192.168.100.0/24" , "-j" , "MASQUERADE" )
285290cmd .Run () // Ignore errors during cleanup
286291
287292return nil
@@ -295,4 +300,4 @@ func (l *Linux) removeNamespace() error {
295300return fmt .Errorf ("failed to remove namespace: %v" , err )
296301}
297302return nil
298- }
303+ }
0 commit comments