@@ -18,6 +18,7 @@ import (
18
18
type Linux struct {
19
19
config Config
20
20
namespace string
21
+ vethHost string // Host-side veth interface name for iptables rules
21
22
logger * slog.Logger
22
23
preparedEnv map [string ]string
23
24
procAttr * syscall.SysProcAttr
@@ -193,6 +194,9 @@ func (l *Linux) setupNetworking() error {
193
194
vethHost := fmt .Sprintf ("veth_h_%s" , uniqueID ) // veth_h_1234567 = 14 chars
194
195
vethNetJail := fmt .Sprintf ("veth_n_%s" , uniqueID ) // veth_n_1234567 = 14 chars
195
196
197
+ // Store veth interface name for iptables rules
198
+ l .vethHost = vethHost
199
+
196
200
setupCmds := []struct {
197
201
description string
198
202
command * exec.Cmd
@@ -246,42 +250,40 @@ options timeout:2 attempts:2
246
250
return nil
247
251
}
248
252
249
- // setupIptables configures iptables rules for traffic redirection
253
+ // setupIptables configures iptables rules for comprehensive TCP traffic interception
250
254
func (l * Linux ) setupIptables () error {
251
255
// Enable IP forwarding
252
256
cmd := exec .Command ("sysctl" , "-w" , "net.ipv4.ip_forward=1" )
253
257
cmd .Run () // Ignore error
254
258
255
- // NAT rules for outgoing traffic
259
+ // NAT rules for outgoing traffic (MASQUERADE for return traffic)
256
260
cmd = exec .Command ("iptables" , "-t" , "nat" , "-A" , "POSTROUTING" , "-s" , "192.168.100.0/24" , "-j" , "MASQUERADE" )
257
261
err := cmd .Run ()
258
262
if err != nil {
259
263
return fmt .Errorf ("failed to add NAT rule: %v" , err )
260
264
}
261
265
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 ))
266
+ // COMPREHENSIVE APPROACH: Intercept ALL TCP traffic from namespace
267
+ // Use PREROUTING on host to catch traffic after it exits namespace but before routing
268
+ // This ensures NO TCP traffic can bypass the proxy
269
+ cmd = exec .Command ("iptables" , "-t" , "nat" , "-A" , "PREROUTING" , "-i" , l .vethHost , "-p" , "tcp" , "-j" , "REDIRECT" , "--to-ports" , fmt .Sprintf ("%d" , l .config .HTTPSPort ))
273
270
err = cmd .Run ()
274
271
if err != nil {
275
- return fmt .Errorf ("failed to add HTTPS redirect rule: %v" , err )
272
+ return fmt .Errorf ("failed to add comprehensive TCP redirect rule: %v" , err )
276
273
}
277
274
275
+ l .logger .Debug ("Comprehensive TCP jailing enabled" , "interface" , l .vethHost , "proxy_port" , l .config .HTTPSPort )
278
276
return nil
279
277
}
280
278
281
279
// removeIptables removes iptables rules
282
280
func (l * Linux ) removeIptables () error {
281
+ // Remove comprehensive TCP redirect rule
282
+ cmd := exec .Command ("iptables" , "-t" , "nat" , "-D" , "PREROUTING" , "-i" , l .vethHost , "-p" , "tcp" , "-j" , "REDIRECT" , "--to-ports" , fmt .Sprintf ("%d" , l .config .HTTPSPort ))
283
+ cmd .Run () // Ignore errors during cleanup
284
+
283
285
// Remove NAT rule
284
- cmd : = exec .Command ("iptables" , "-t" , "nat" , "-D" , "POSTROUTING" , "-s" , "192.168.100.0/24" , "-j" , "MASQUERADE" )
286
+ cmd = exec .Command ("iptables" , "-t" , "nat" , "-D" , "POSTROUTING" , "-s" , "192.168.100.0/24" , "-j" , "MASQUERADE" )
285
287
cmd .Run () // Ignore errors during cleanup
286
288
287
289
return nil
@@ -295,4 +297,4 @@ func (l *Linux) removeNamespace() error {
295
297
return fmt .Errorf ("failed to remove namespace: %v" , err )
296
298
}
297
299
return nil
298
- }
300
+ }
0 commit comments