@@ -7,39 +7,34 @@ import (
7
7
"log/slog"
8
8
"os"
9
9
"os/exec"
10
- "syscall"
11
10
"time"
12
11
)
13
12
14
13
// Linux implements jail.Commander using Linux network namespaces
15
- type Linux struct {
16
- namespace string
17
- vethHost string // Host-side veth interface name for iptables rules
18
- logger * slog.Logger
19
- procAttr * syscall.SysProcAttr
20
- commandEnv []string
21
- httpProxyPort int
22
- httpsProxyPort int
23
- tlsConfigDir string
24
- caCertPath string
25
- userInfo UserInfo
14
+ type LinuxNetNamespace struct {
15
+ logger * slog.Logger
16
+ namespace string
17
+ vethHost string // Host-side veth interface name for iptables rules
18
+ commandEnv []string
19
+ httpProxyPort int
20
+ tlsConfigDir string
21
+ caCertPath string
22
+ userInfo UserInfo
26
23
}
27
24
28
- // NewLinux creates a new Linux network jail instance
29
- func NewLinux (config Config ) (* Linux , error ) {
30
- return & Linux {
31
- namespace : newNamespaceName (),
32
- logger : config .Logger ,
33
- httpProxyPort : config .HttpProxyPort ,
34
- httpsProxyPort : config .HttpsProxyPort ,
35
- tlsConfigDir : config .TlsConfigDir ,
36
- caCertPath : config .CACertPath ,
37
- userInfo : config .UserInfo ,
25
+ func NewLinux (config Config ) (* LinuxNetNamespace , error ) {
26
+ return & LinuxNetNamespace {
27
+ logger : config .Logger ,
28
+ namespace : newNamespaceName (),
29
+ httpProxyPort : config .HttpProxyPort ,
30
+ tlsConfigDir : config .TlsConfigDir ,
31
+ caCertPath : config .CACertPath ,
32
+ userInfo : config .UserInfo ,
38
33
}, nil
39
34
}
40
35
41
- // Setup creates network namespace and configures iptables rules
42
- func (l * Linux ) Start () error {
36
+ // Start creates network namespace and configures iptables rules
37
+ func (l * LinuxNetNamespace ) Start () error {
43
38
l .logger .Debug ("Setup called" )
44
39
45
40
// Setup DNS configuration BEFORE creating namespace
@@ -76,19 +71,12 @@ func (l *Linux) Start() error {
76
71
"LOGNAME" : l .userInfo .Username ,
77
72
})
78
73
79
- l .procAttr = & syscall.SysProcAttr {
80
- Credential : & syscall.Credential {
81
- Uid : uint32 (l .userInfo .Uid ),
82
- Gid : uint32 (l .userInfo .Gid ),
83
- },
84
- }
85
-
86
74
l .logger .Debug ("Setup completed successfully" )
87
75
return nil
88
76
}
89
77
90
78
// Command returns an exec.Cmd configured to run within the network namespace
91
- func (l * Linux ) Command (command []string ) * exec.Cmd {
79
+ func (l * LinuxNetNamespace ) Command (command []string ) * exec.Cmd {
92
80
l .logger .Debug ("Command called" , "command" , command )
93
81
94
82
// Create command with ip netns exec
@@ -104,14 +92,11 @@ func (l *Linux) Command(command []string) *exec.Cmd {
104
92
cmd .Stdout = os .Stdout
105
93
cmd .Stderr = os .Stderr
106
94
107
- // Use prepared process attributes from Open method
108
- cmd .SysProcAttr = l .procAttr
109
-
110
95
return cmd
111
96
}
112
97
113
- // Cleanup removes the network namespace and iptables rules
114
- func (l * Linux ) Close () error {
98
+ // Close removes the network namespace and iptables rules
99
+ func (l * LinuxNetNamespace ) Close () error {
115
100
// Remove iptables rules
116
101
err := l .removeIptables ()
117
102
if err != nil {
@@ -138,7 +123,7 @@ func (l *Linux) Close() error {
138
123
}
139
124
140
125
// createNamespace creates a new network namespace
141
- func (l * Linux ) createNamespace () error {
126
+ func (l * LinuxNetNamespace ) createNamespace () error {
142
127
cmd := exec .Command ("ip" , "netns" , "add" , l .namespace )
143
128
err := cmd .Run ()
144
129
if err != nil {
@@ -148,12 +133,12 @@ func (l *Linux) createNamespace() error {
148
133
}
149
134
150
135
// setupNetworking configures networking within the namespace
151
- func (l * Linux ) setupNetworking () error {
136
+ func (l * LinuxNetNamespace ) setupNetworking () error {
152
137
// Create veth pair with short names (Linux interface names limited to 15 chars)
153
138
// Generate unique ID to avoid conflicts
154
139
uniqueID := fmt .Sprintf ("%d" , time .Now ().UnixNano ()% 10000000 ) // 7 digits max
155
- vethHost := fmt .Sprintf ("veth_h_%s" , uniqueID ) // veth_h_1234567 = 14 chars
156
- vethNetJail := fmt .Sprintf ("veth_n_%s" , uniqueID ) // veth_n_1234567 = 14 chars
140
+ vethHost := fmt .Sprintf ("veth_h_%s" , uniqueID ) // veth_h_1234567 = 14 chars
141
+ vethNetJail := fmt .Sprintf ("veth_n_%s" , uniqueID ) // veth_n_1234567 = 14 chars
157
142
158
143
// Store veth interface name for iptables rules
159
144
l .vethHost = vethHost
@@ -184,7 +169,7 @@ func (l *Linux) setupNetworking() error {
184
169
// setupDNS configures DNS resolution for the namespace
185
170
// This ensures reliable DNS resolution by using public DNS servers
186
171
// instead of relying on the host's potentially complex DNS configuration
187
- func (l * Linux ) setupDNS () error {
172
+ func (l * LinuxNetNamespace ) setupDNS () error {
188
173
// Always create namespace-specific resolv.conf with reliable public DNS servers
189
174
// This avoids issues with systemd-resolved, Docker DNS, and other complex setups
190
175
netnsEtc := fmt .Sprintf ("/etc/netns/%s" , l .namespace )
@@ -212,7 +197,7 @@ options timeout:2 attempts:2
212
197
}
213
198
214
199
// setupIptables configures iptables rules for comprehensive TCP traffic interception
215
- func (l * Linux ) setupIptables () error {
200
+ func (l * LinuxNetNamespace ) setupIptables () error {
216
201
// Enable IP forwarding
217
202
cmd := exec .Command ("sysctl" , "-w" , "net.ipv4.ip_forward=1" )
218
203
cmd .Run () // Ignore error
@@ -237,7 +222,7 @@ func (l *Linux) setupIptables() error {
237
222
}
238
223
239
224
// removeIptables removes iptables rules
240
- func (l * Linux ) removeIptables () error {
225
+ func (l * LinuxNetNamespace ) removeIptables () error {
241
226
// Remove comprehensive TCP redirect rule
242
227
cmd := exec .Command ("iptables" , "-t" , "nat" , "-D" , "PREROUTING" , "-i" , l .vethHost , "-p" , "tcp" , "-j" , "REDIRECT" , "--to-ports" , fmt .Sprintf ("%d" , l .httpProxyPort ))
243
228
cmd .Run () // Ignore errors during cleanup
@@ -250,11 +235,11 @@ func (l *Linux) removeIptables() error {
250
235
}
251
236
252
237
// removeNamespace removes the network namespace
253
- func (l * Linux ) removeNamespace () error {
238
+ func (l * LinuxNetNamespace ) removeNamespace () error {
254
239
cmd := exec .Command ("ip" , "netns" , "del" , l .namespace )
255
240
err := cmd .Run ()
256
241
if err != nil {
257
242
return fmt .Errorf ("failed to remove namespace: %v" , err )
258
243
}
259
244
return nil
260
- }
245
+ }
0 commit comments