@@ -23,18 +23,27 @@ func (l *LinuxJail) configureHostNetworkBeforeCmdExec() error {
2323 l .vethJailName = vethJailName
2424
2525 runner := newCommandRunner ([]* command {
26+ // Create a virtual Ethernet (veth) pair that forms a point-to-point link
27+ // between the host and the jail namespace. One end stays on the host,
28+ // the other will be moved into the jail. This provides a dedicated,
29+ // isolated L2 network for the jail.
2630 {
27- "create veth pair" ,
31+ "Create host–jail veth interface pair" ,
2832 exec .Command ("ip" , "link" , "add" , vethHostName , "type" , "veth" , "peer" , "name" , vethJailName ),
2933 []uintptr {uintptr (unix .CAP_NET_ADMIN )},
3034 },
35+ // Assign an IP address to the host side of the veth pair. The /24 mask
36+ // implicitly defines the jail's entire subnet as 192.168.100.0/24.
37+ // The host address (192.168.100.1) becomes the default gateway for
38+ // processes inside the jail and is used by NAT and interception rules
39+ // to route traffic out of the namespace.
3140 {
32- "configure host veth" ,
41+ "Assign IP to host-side veth" ,
3342 exec .Command ("ip" , "addr" , "add" , "192.168.100.1/24" , "dev" , vethHostName ),
3443 []uintptr {uintptr (unix .CAP_NET_ADMIN )},
3544 },
3645 {
37- "bring up host veth" ,
46+ "Activate host-side veth interface " ,
3847 exec .Command ("ip" , "link" , "set" , vethHostName , "up" ),
3948 []uintptr {uintptr (unix .CAP_NET_ADMIN )},
4049 },
@@ -54,8 +63,12 @@ func (l *LinuxJail) configureHostNetworkAfterCmdExec(pidInt int) error {
5463 PID := fmt .Sprintf ("%v" , pidInt )
5564
5665 runner := newCommandRunner ([]* command {
66+ // Move the jail-side veth interface into the target network namespace.
67+ // This isolates the interface so that it becomes visible only inside the
68+ // jail's netns. From this point on, the jail will configure its end of
69+ // the veth pair (IP address, routes, etc.) independently of the host.
5770 {
58- "move veth to namespace" ,
71+ "Move jail-side veth into network namespace" ,
5972 exec .Command ("ip" , "link" , "set" , l .vethJailName , "netns" , PID ),
6073 []uintptr {uintptr (unix .CAP_NET_ADMIN )},
6174 },
@@ -70,30 +83,70 @@ func (l *LinuxJail) configureHostNetworkAfterCmdExec(pidInt int) error {
7083// setupIptables configures iptables rules for comprehensive TCP traffic interception
7184func (l * LinuxJail ) configureIptables () error {
7285 runner := newCommandRunner ([]* command {
86+ // Enable IPv4 packet forwarding so the host can route packets between
87+ // the jail's veth interface and the outside network. Without this,
88+ // NAT and forwarding rules would have no effect because the kernel
89+ // would drop transit packets.
7390 {
7491 "enable IP forwarding" ,
7592 exec .Command ("sysctl" , "-w" , "net.ipv4.ip_forward=1" ),
7693 []uintptr {},
7794 },
95+ // Apply source NAT (MASQUERADE) for all traffic leaving the jail’s
96+ // private subnet. This rewrites the source IP of packets originating
97+ // from 192.168.100.0/24 to the host’s external interface IP. It enables:
98+ //
99+ // - outbound connectivity for jailed processes,
100+ // - correct return routing from external endpoints,
101+ // - avoidance of static IP assignment for the host interface.
102+ //
103+ // MASQUERADE is used instead of SNAT so it works even when the host IP
104+ // changes dynamically.
78105 {
79106 "NAT rules for outgoing traffic (MASQUERADE for return traffic)" ,
80107 exec .Command ("iptables" , "-t" , "nat" , "-A" , "POSTROUTING" , "-s" , "192.168.100.0/24" , "-j" , "MASQUERADE" ),
81108 []uintptr {uintptr (unix .CAP_NET_ADMIN )},
82109 },
110+ // Redirect *ALL TCP traffic* coming from the jail’s veth interface
111+ // to the local HTTP/TLS-intercepting proxy. This causes *every* TCP
112+ // connection (HTTP, HTTPS, plain TCP protocols) initiated by jailed
113+ // processes to be transparently intercepted.
114+ //
115+ // The HTTP proxy will intelligently handle both HTTP and TLS traffic.
116+ //
117+ // PREROUTING is used so redirection happens before routing decisions.
118+ // REDIRECT rewrites the destination IP to 127.0.0.1 and the destination
119+ // port to the HTTP proxy's port, forcing traffic through the proxy without
120+ // requiring any configuration inside the jail.
83121 {
84- // COMPREHENSIVE APPROACH: Route ALL TCP traffic to HTTP proxy
85- // The HTTP proxy will intelligently handle both HTTP and TLS traffic
86122 "Route ALL TCP traffic to HTTP proxy" ,
87123 exec .Command ("iptables" , "-t" , "nat" , "-A" , "PREROUTING" , "-i" , l .vethHostName , "-p" , "tcp" , "-j" , "REDIRECT" , "--to-ports" , fmt .Sprintf ("%d" , l .httpProxyPort )),
88124 []uintptr {uintptr (unix .CAP_NET_ADMIN )},
89125 },
126+ // Allow forwarding of non-TCP packets originating from the jail’s subnet.
127+ // This rule is primarily needed for traffic that is *not* intercepted by
128+ // the TCP REDIRECT rule — for example:
129+ //
130+ // - DNS queries (UDP/53)
131+ // - ICMP (ping, errors)
132+ // - Any other UDP or non-TCP protocols
133+ //
134+ // Redirected TCP flows never reach the FORWARD chain (they are locally
135+ // redirected in PREROUTING), so this rule does not apply to TCP traffic.
90136 {
91- "iptables FORWARD -s " ,
137+ "Allow outbound non-TCP traffic from jail subnet " ,
92138 exec .Command ("iptables" , "-A" , "FORWARD" , "-s" , "192.168.100.0/24" , "-j" , "ACCEPT" ),
93139 []uintptr {uintptr (unix .CAP_NET_ADMIN )},
94140 },
141+ // Allow forwarding of return traffic destined for the jail’s subnet for
142+ // non-TCP flows. This complements the previous FORWARD rule and ensures
143+ // that responses to DNS (UDP) or ICMP packets can reach the jail.
144+ //
145+ // As with the previous rule, this has no effect on TCP traffic because
146+ // all TCP connections from the jail are intercepted and redirected to
147+ // the local proxy before reaching the forwarding path.
95148 {
96- "iptables FORWARD -d " ,
149+ "Allow inbound return traffic to jail subnet (non-TCP) " ,
97150 exec .Command ("iptables" , "-A" , "FORWARD" , "-d" , "192.168.100.0/24" , "-j" , "ACCEPT" ),
98151 []uintptr {uintptr (unix .CAP_NET_ADMIN )},
99152 },
@@ -127,22 +180,22 @@ func (l *LinuxJail) cleanupNetworking() error {
127180func (l * LinuxJail ) cleanupIptables () error {
128181 runner := newCommandRunner ([]* command {
129182 {
130- "Remove comprehensive TCP redirect rule " ,
131- exec .Command ("iptables" , "-t" , "nat" , "-D" , "PREROUTING " , "-i " , l . vethHostName , "-p" , "tcp" , " -j" , "REDIRECT" , "--to-ports" , fmt . Sprintf ( "%d" , l . httpProxyPort ) ),
183+ "Remove: NAT rules for outgoing traffic (MASQUERADE for return traffic) " ,
184+ exec .Command ("iptables" , "-t" , "nat" , "-D" , "POSTROUTING " , "-s " , "192.168.100.0/24" , "-j" , "MASQUERADE" ),
132185 []uintptr {uintptr (unix .CAP_NET_ADMIN )},
133186 },
134187 {
135- "Remove NAT rule " ,
136- exec .Command ("iptables" , "-t" , "nat" , "-D" , "POSTROUTING " , "-s " , "192.168.100.0/24" , "-j" , "MASQUERADE" ),
188+ "Remove: Route ALL TCP traffic to HTTP proxy " ,
189+ exec .Command ("iptables" , "-t" , "nat" , "-D" , "PREROUTING " , "-i " , l . vethHostName , "-p" , "tcp" , " -j" , "REDIRECT" , "--to-ports" , fmt . Sprintf ( "%d" , l . httpProxyPort ) ),
137190 []uintptr {uintptr (unix .CAP_NET_ADMIN )},
138191 },
139192 {
140- "Remove iptables FORWARD -s " ,
193+ "Remove: Allow outbound non-TCP traffic from jail subnet " ,
141194 exec .Command ("iptables" , "-D" , "FORWARD" , "-s" , "192.168.100.0/24" , "-j" , "ACCEPT" ),
142195 []uintptr {uintptr (unix .CAP_NET_ADMIN )},
143196 },
144197 {
145- "Remove iptables FORWARD -d " ,
198+ "Remove: Allow inbound return traffic to jail subnet (non-TCP) " ,
146199 exec .Command ("iptables" , "-D" , "FORWARD" , "-d" , "192.168.100.0/24" , "-j" , "ACCEPT" ),
147200 []uintptr {uintptr (unix .CAP_NET_ADMIN )},
148201 },
0 commit comments