Skip to content

Commit 9e8af5b

Browse files
refactor
1 parent 61aab4f commit 9e8af5b

File tree

1 file changed

+88
-80
lines changed

1 file changed

+88
-80
lines changed

jail/linux.go

Lines changed: 88 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,90 @@ func (r *commandRunner) run() error {
4343
return nil
4444
}
4545

46+
func (l *LinuxJail) configureParentNetworkingStep1() error {
47+
// Create veth pair with short names (Linux interface names limited to 15 chars)
48+
// Generate unique ID to avoid conflicts
49+
uniqueID := fmt.Sprintf("%d", time.Now().UnixNano()%10000000) // 7 digits max
50+
vethHostName := fmt.Sprintf("veth_h_%s", uniqueID) // veth_h_1234567 = 14 chars
51+
vethJailName := fmt.Sprintf("veth_n_%s", uniqueID) // veth_n_1234567 = 14 chars
52+
53+
// Store veth interface name for iptables rules
54+
l.vethHostName = vethHostName
55+
l.vethJailName = vethJailName
56+
57+
runner := newCommandRunner([]*command{
58+
{
59+
"create veth pair",
60+
exec.Command("ip", "link", "add", vethHostName, "type", "veth", "peer", "name", vethJailName),
61+
[]uintptr{uintptr(unix.CAP_NET_ADMIN)},
62+
},
63+
{
64+
"configure host veth",
65+
exec.Command("ip", "addr", "add", "192.168.100.1/24", "dev", vethHostName),
66+
[]uintptr{uintptr(unix.CAP_NET_ADMIN)},
67+
},
68+
{
69+
"bring up host veth",
70+
exec.Command("ip", "link", "set", vethHostName, "up"),
71+
[]uintptr{uintptr(unix.CAP_NET_ADMIN)},
72+
},
73+
})
74+
if err := runner.run(); err != nil {
75+
return err
76+
}
77+
78+
return nil
79+
}
80+
81+
// setupNetworking configures networking within the namespace
82+
func (l *LinuxJail) configureParentNetworkingStep2(pidInt int) error {
83+
PID := fmt.Sprintf("%v", pidInt)
84+
85+
runner := newCommandRunner([]*command{
86+
{
87+
"move veth to namespace",
88+
exec.Command("ip", "link", "set", l.vethJailName, "netns", PID),
89+
[]uintptr{uintptr(unix.CAP_NET_ADMIN)},
90+
},
91+
})
92+
if err := runner.run(); err != nil {
93+
return err
94+
}
95+
96+
return nil
97+
}
98+
99+
// setupChildNetworking configures networking within the namespace
100+
func SetupChildNetworking(vethNetJail string) error {
101+
runner := newCommandRunner([]*command{
102+
{
103+
"configure namespace veth",
104+
exec.Command("ip", "addr", "add", "192.168.100.2/24", "dev", vethNetJail),
105+
[]uintptr{uintptr(unix.CAP_NET_ADMIN)},
106+
},
107+
{
108+
"bring up namespace veth",
109+
exec.Command("ip", "link", "set", vethNetJail, "up"),
110+
[]uintptr{uintptr(unix.CAP_NET_ADMIN)},
111+
},
112+
{
113+
"bring up loopback",
114+
exec.Command("ip", "link", "set", "lo", "up"),
115+
[]uintptr{uintptr(unix.CAP_NET_ADMIN)},
116+
},
117+
{
118+
"set default route in namespace",
119+
exec.Command("ip", "route", "add", "default", "via", "192.168.100.1"),
120+
[]uintptr{uintptr(unix.CAP_NET_ADMIN)},
121+
},
122+
})
123+
if err := runner.run(); err != nil {
124+
return err
125+
}
126+
127+
return nil
128+
}
129+
46130
// LinuxJail implements Jailer using Linux network namespaces
47131
type LinuxJail struct {
48132
logger *slog.Logger
@@ -80,34 +164,7 @@ func (l *LinuxJail) ConfigureBeforeCommandExecution() error {
80164
e := getEnvs(l.configDir, l.caCertPath)
81165
l.commandEnv = mergeEnvs(e, map[string]string{})
82166

83-
// Create veth pair with short names (Linux interface names limited to 15 chars)
84-
// Generate unique ID to avoid conflicts
85-
uniqueID := fmt.Sprintf("%d", time.Now().UnixNano()%10000000) // 7 digits max
86-
vethHostName := fmt.Sprintf("veth_h_%s", uniqueID) // veth_h_1234567 = 14 chars
87-
vethJailName := fmt.Sprintf("veth_n_%s", uniqueID) // veth_n_1234567 = 14 chars
88-
89-
// Store veth interface name for iptables rules
90-
l.vethHostName = vethHostName
91-
l.vethJailName = vethJailName
92-
93-
runner := newCommandRunner([]*command{
94-
{
95-
"create veth pair",
96-
exec.Command("ip", "link", "add", vethHostName, "type", "veth", "peer", "name", vethJailName),
97-
[]uintptr{uintptr(unix.CAP_NET_ADMIN)},
98-
},
99-
{
100-
"configure host veth",
101-
exec.Command("ip", "addr", "add", "192.168.100.1/24", "dev", vethHostName),
102-
[]uintptr{uintptr(unix.CAP_NET_ADMIN)},
103-
},
104-
{
105-
"bring up host veth",
106-
exec.Command("ip", "link", "set", vethHostName, "up"),
107-
[]uintptr{uintptr(unix.CAP_NET_ADMIN)},
108-
},
109-
})
110-
if err := runner.run(); err != nil {
167+
if err := l.configureParentNetworkingStep1(); err != nil {
111168
return err
112169
}
113170

@@ -136,13 +193,13 @@ func (l *LinuxJail) Command(command []string) *exec.Cmd {
136193
}
137194

138195
func (l *LinuxJail) ConfigureAfterCommandExecution(pidInt int) {
139-
err := l.setupParentNetworking(pidInt)
196+
err := l.configureParentNetworkingStep2(pidInt)
140197
if err != nil {
141198
fmt.Fprintf(os.Stderr, "failed setupParentNetworking: %v\n", err)
142199
os.Exit(1)
143200
}
144201

145-
err = l.setupIptables()
202+
err = l.configureIptables()
146203
if err != nil {
147204
fmt.Fprintf(os.Stderr, "can't setup iptables: %v\n", err)
148205
os.Exit(1)
@@ -200,55 +257,6 @@ func (l *LinuxJail) createNamespace() error {
200257
return nil
201258
}
202259

203-
// setupNetworking configures networking within the namespace
204-
func (l *LinuxJail) setupParentNetworking(pidInt int) error {
205-
PID := fmt.Sprintf("%v", pidInt)
206-
207-
runner := newCommandRunner([]*command{
208-
{
209-
"move veth to namespace",
210-
exec.Command("ip", "link", "set", l.vethJailName, "netns", PID),
211-
[]uintptr{uintptr(unix.CAP_NET_ADMIN)},
212-
},
213-
})
214-
if err := runner.run(); err != nil {
215-
return err
216-
}
217-
218-
return nil
219-
}
220-
221-
// setupChildNetworking configures networking within the namespace
222-
func SetupChildNetworking(vethNetJail string) error {
223-
runner := newCommandRunner([]*command{
224-
{
225-
"configure namespace veth",
226-
exec.Command("ip", "addr", "add", "192.168.100.2/24", "dev", vethNetJail),
227-
[]uintptr{uintptr(unix.CAP_NET_ADMIN)},
228-
},
229-
{
230-
"bring up namespace veth",
231-
exec.Command("ip", "link", "set", vethNetJail, "up"),
232-
[]uintptr{uintptr(unix.CAP_NET_ADMIN)},
233-
},
234-
{
235-
"bring up loopback",
236-
exec.Command("ip", "link", "set", "lo", "up"),
237-
[]uintptr{uintptr(unix.CAP_NET_ADMIN)},
238-
},
239-
{
240-
"set default route in namespace",
241-
exec.Command("ip", "route", "add", "default", "via", "192.168.100.1"),
242-
[]uintptr{uintptr(unix.CAP_NET_ADMIN)},
243-
},
244-
})
245-
if err := runner.run(); err != nil {
246-
return err
247-
}
248-
249-
return nil
250-
}
251-
252260
// setupDNS configures DNS resolution for the namespace
253261
// This ensures reliable DNS resolution by using public DNS servers
254262
// instead of relying on the host's potentially complex DNS configuration
@@ -280,7 +288,7 @@ options timeout:2 attempts:2
280288
}
281289

282290
// setupIptables configures iptables rules for comprehensive TCP traffic interception
283-
func (l *LinuxJail) setupIptables() error {
291+
func (l *LinuxJail) configureIptables() error {
284292
// Enable IP forwarding
285293
cmd := exec.Command("sysctl", "-w", "net.ipv4.ip_forward=1")
286294
_ = cmd.Run() // Ignore error

0 commit comments

Comments
 (0)