Skip to content

Commit 61aab4f

Browse files
add commandRunner to avoid copy-pasting
1 parent 384e0da commit 61aab4f

File tree

6 files changed

+68
-75
lines changed

6 files changed

+68
-75
lines changed

boundary.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ func New(ctx context.Context, config Config) (*Boundary, error) {
5656

5757
func (b *Boundary) Start() error {
5858
// Start the jailer (network isolation)
59-
err := b.jailer.Start()
59+
err := b.jailer.ConfigureBeforeCommandExecution()
6060
if err != nil {
6161
return fmt.Errorf("failed to start jailer: %v", err)
6262
}
@@ -78,8 +78,8 @@ func (b *Boundary) Command(command []string) *exec.Cmd {
7878
return b.jailer.Command(command)
7979
}
8080

81-
func (b *Boundary) ConfigureAfterRun(processPID int) {
82-
b.jailer.ConfigureAfterRun(processPID)
81+
func (b *Boundary) ConfigureAfterCommandExecution(processPID int) {
82+
b.jailer.ConfigureAfterCommandExecution(processPID)
8383
}
8484

8585
func (b *Boundary) GetNetworkConfiguration() jail.NetworkConfiguration {

cli/cli.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ func Run(ctx context.Context, config Config, args []string) error {
235235
logger.Error("Command execution failed", "error", err)
236236
}
237237

238-
boundaryInstance.ConfigureAfterRun(cmd.Process.Pid)
238+
boundaryInstance.ConfigureAfterCommandExecution(cmd.Process.Pid)
239239

240240
err = cmd.Wait()
241241
if err != nil {

jail/jail.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ import (
88
)
99

1010
type Jailer interface {
11-
Start() error
11+
ConfigureBeforeCommandExecution() error
1212
Command(command []string) *exec.Cmd
13-
ConfigureAfterRun(processPID int)
13+
ConfigureAfterCommandExecution(processPID int)
1414
Close() error
1515
GetNetworkConfiguration() NetworkConfiguration
1616
}

jail/linux.go

Lines changed: 58 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,42 @@ import (
1313
"golang.org/x/sys/unix"
1414
)
1515

16+
type command struct {
17+
description string
18+
cmd *exec.Cmd
19+
ambientCaps []uintptr
20+
}
21+
22+
type commandRunner struct {
23+
commands []*command
24+
}
25+
26+
func newCommandRunner(commands []*command) *commandRunner {
27+
return &commandRunner{
28+
commands: commands,
29+
}
30+
}
31+
32+
func (r *commandRunner) run() error {
33+
for _, command := range r.commands {
34+
command.cmd.SysProcAttr = &syscall.SysProcAttr{
35+
AmbientCaps: command.ambientCaps,
36+
}
37+
38+
if err := command.cmd.Run(); err != nil {
39+
return fmt.Errorf("failed to %s: %v", command.description, err)
40+
}
41+
}
42+
43+
return nil
44+
}
45+
1646
// LinuxJail implements Jailer using Linux network namespaces
1747
type LinuxJail struct {
1848
logger *slog.Logger
1949
namespace string
20-
vethHost string // Host-side veth interface name for iptables rules
21-
vethNetJail string // Host-side veth interface name for iptables rules
50+
vethHostName string // Host-side veth interface name for iptables rules
51+
vethJailName string // Jail-side veth interface name for iptables rules
2252
commandEnv []string
2353
httpProxyPort int
2454
configDir string
@@ -44,7 +74,7 @@ func NewLinuxJail(config Config) (*LinuxJail, error) {
4474
}
4575

4676
// Start creates network namespace and configures iptables rules
47-
func (l *LinuxJail) Start() error {
77+
func (l *LinuxJail) ConfigureBeforeCommandExecution() error {
4878
l.logger.Debug("Setup called")
4979

5080
e := getEnvs(l.configDir, l.caCertPath)
@@ -53,43 +83,32 @@ func (l *LinuxJail) Start() error {
5383
// Create veth pair with short names (Linux interface names limited to 15 chars)
5484
// Generate unique ID to avoid conflicts
5585
uniqueID := fmt.Sprintf("%d", time.Now().UnixNano()%10000000) // 7 digits max
56-
vethHost := fmt.Sprintf("veth_h_%s", uniqueID) // veth_h_1234567 = 14 chars
57-
vethNetJail := fmt.Sprintf("veth_n_%s", uniqueID) // veth_n_1234567 = 14 chars
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
5888

5989
// Store veth interface name for iptables rules
60-
l.vethHost = vethHost
61-
l.vethNetJail = vethNetJail
90+
l.vethHostName = vethHostName
91+
l.vethJailName = vethJailName
6292

63-
setupCmds := []struct {
64-
description string
65-
command *exec.Cmd
66-
ambientCaps []uintptr
67-
}{
93+
runner := newCommandRunner([]*command{
6894
{
6995
"create veth pair",
70-
exec.Command("ip", "link", "add", vethHost, "type", "veth", "peer", "name", vethNetJail),
96+
exec.Command("ip", "link", "add", vethHostName, "type", "veth", "peer", "name", vethJailName),
7197
[]uintptr{uintptr(unix.CAP_NET_ADMIN)},
7298
},
7399
{
74100
"configure host veth",
75-
exec.Command("ip", "addr", "add", "192.168.100.1/24", "dev", vethHost),
101+
exec.Command("ip", "addr", "add", "192.168.100.1/24", "dev", vethHostName),
76102
[]uintptr{uintptr(unix.CAP_NET_ADMIN)},
77103
},
78104
{
79105
"bring up host veth",
80-
exec.Command("ip", "link", "set", vethHost, "up"),
106+
exec.Command("ip", "link", "set", vethHostName, "up"),
81107
[]uintptr{uintptr(unix.CAP_NET_ADMIN)},
82108
},
83-
}
84-
85-
for _, command := range setupCmds {
86-
command.command.SysProcAttr = &syscall.SysProcAttr{
87-
AmbientCaps: command.ambientCaps,
88-
}
89-
90-
if err := command.command.Run(); err != nil {
91-
return fmt.Errorf("failed to %s: %v", command.description, err)
92-
}
109+
})
110+
if err := runner.run(); err != nil {
111+
return err
93112
}
94113

95114
return nil
@@ -99,10 +118,6 @@ func (l *LinuxJail) Start() error {
99118
func (l *LinuxJail) Command(command []string) *exec.Cmd {
100119
l.logger.Debug("Creating command with namespace", "namespace", l.namespace)
101120

102-
//cmdArgs := []string{"netns", "exec", l.namespace}
103-
//cmdArgs = append(cmdArgs, command...)
104-
//
105-
//cmd := exec.Command("ip", cmdArgs...)
106121
cmd := exec.Command(command[0], command[1:]...)
107122
cmd.Env = l.commandEnv
108123
cmd.Env = append(cmd.Env, "CHILD=true")
@@ -120,7 +135,7 @@ func (l *LinuxJail) Command(command []string) *exec.Cmd {
120135
return cmd
121136
}
122137

123-
func (l *LinuxJail) ConfigureAfterRun(pidInt int) {
138+
func (l *LinuxJail) ConfigureAfterCommandExecution(pidInt int) {
124139
err := l.setupParentNetworking(pidInt)
125140
if err != nil {
126141
fmt.Fprintf(os.Stderr, "failed setupParentNetworking: %v\n", err)
@@ -136,7 +151,7 @@ func (l *LinuxJail) ConfigureAfterRun(pidInt int) {
136151

137152
func (l *LinuxJail) GetNetworkConfiguration() NetworkConfiguration {
138153
return NetworkConfiguration{
139-
VethNetJail: l.vethNetJail,
154+
VethNetJail: l.vethJailName,
140155
}
141156
}
142157

@@ -189,38 +204,23 @@ func (l *LinuxJail) createNamespace() error {
189204
func (l *LinuxJail) setupParentNetworking(pidInt int) error {
190205
PID := fmt.Sprintf("%v", pidInt)
191206

192-
setupCmds := []struct {
193-
description string
194-
command *exec.Cmd
195-
ambientCaps []uintptr
196-
}{
207+
runner := newCommandRunner([]*command{
197208
{
198209
"move veth to namespace",
199-
exec.Command("ip", "link", "set", l.vethNetJail, "netns", PID),
210+
exec.Command("ip", "link", "set", l.vethJailName, "netns", PID),
200211
[]uintptr{uintptr(unix.CAP_NET_ADMIN)},
201212
},
202-
}
203-
204-
for _, command := range setupCmds {
205-
command.command.SysProcAttr = &syscall.SysProcAttr{
206-
AmbientCaps: command.ambientCaps,
207-
}
208-
209-
if err := command.command.Run(); err != nil {
210-
return fmt.Errorf("failed to %s: %v", command.description, err)
211-
}
213+
})
214+
if err := runner.run(); err != nil {
215+
return err
212216
}
213217

214218
return nil
215219
}
216220

217221
// setupChildNetworking configures networking within the namespace
218222
func SetupChildNetworking(vethNetJail string) error {
219-
setupCmds := []struct {
220-
description string
221-
command *exec.Cmd
222-
ambientCaps []uintptr
223-
}{
223+
runner := newCommandRunner([]*command{
224224
{
225225
"configure namespace veth",
226226
exec.Command("ip", "addr", "add", "192.168.100.2/24", "dev", vethNetJail),
@@ -241,16 +241,9 @@ func SetupChildNetworking(vethNetJail string) error {
241241
exec.Command("ip", "route", "add", "default", "via", "192.168.100.1"),
242242
[]uintptr{uintptr(unix.CAP_NET_ADMIN)},
243243
},
244-
}
245-
246-
for _, command := range setupCmds {
247-
command.command.SysProcAttr = &syscall.SysProcAttr{
248-
AmbientCaps: command.ambientCaps,
249-
}
250-
251-
if output, err := command.command.CombinedOutput(); err != nil {
252-
return fmt.Errorf("failed to %s: %v, output: %s, args: %v", command.description, err, output, command.command.Args)
253-
}
244+
})
245+
if err := runner.run(); err != nil {
246+
return err
254247
}
255248

256249
return nil
@@ -304,7 +297,7 @@ func (l *LinuxJail) setupIptables() error {
304297

305298
// COMPREHENSIVE APPROACH: Route ALL TCP traffic to HTTP proxy
306299
// The HTTP proxy will intelligently handle both HTTP and TLS traffic
307-
cmd = exec.Command("iptables", "-t", "nat", "-A", "PREROUTING", "-i", l.vethHost, "-p", "tcp", "-j", "REDIRECT", "--to-ports", fmt.Sprintf("%d", l.httpProxyPort))
300+
cmd = exec.Command("iptables", "-t", "nat", "-A", "PREROUTING", "-i", l.vethHostName, "-p", "tcp", "-j", "REDIRECT", "--to-ports", fmt.Sprintf("%d", l.httpProxyPort))
308301
cmd.SysProcAttr = &syscall.SysProcAttr{
309302
AmbientCaps: []uintptr{uintptr(unix.CAP_NET_ADMIN)},
310303
}
@@ -332,14 +325,14 @@ func (l *LinuxJail) setupIptables() error {
332325
return fmt.Errorf("forward -r error: %v", err)
333326
}
334327

335-
l.logger.Debug("Comprehensive TCP boundarying enabled", "interface", l.vethHost, "proxy_port", l.httpProxyPort)
328+
l.logger.Debug("Comprehensive TCP boundarying enabled", "interface", l.vethHostName, "proxy_port", l.httpProxyPort)
336329
return nil
337330
}
338331

339332
// cleanupIptables removes iptables rules
340333
func (l *LinuxJail) cleanupIptables() error {
341334
// Remove comprehensive TCP redirect rule
342-
cmd := exec.Command("iptables", "-t", "nat", "-D", "PREROUTING", "-i", l.vethHost, "-p", "tcp", "-j", "REDIRECT", "--to-ports", fmt.Sprintf("%d", l.httpProxyPort))
335+
cmd := exec.Command("iptables", "-t", "nat", "-D", "PREROUTING", "-i", l.vethHostName, "-p", "tcp", "-j", "REDIRECT", "--to-ports", fmt.Sprintf("%d", l.httpProxyPort))
343336
err := cmd.Run()
344337
if err != nil {
345338
l.logger.Error("Failed to remove TCP redirect rule", "error", err)

jail/macos.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ func NewMacOSJail(config Config) (*MacOSJail, error) {
5555
}
5656

5757
// Setup creates the network boundary group and configures PF rules
58-
func (n *MacOSJail) Start() error {
58+
func (n *MacOSJail) ConfigureBeforeCommandExecution() error {
5959
n.logger.Debug("Setup called")
6060

6161
// Create or get network boundary group
@@ -341,7 +341,7 @@ func (n *MacOSJail) cleanupTempFiles() {
341341
}
342342
}
343343

344-
func (u *MacOSJail) ConfigureAfterRun(processPID int) {}
344+
func (u *MacOSJail) ConfigureAfterCommandExecution(processPID int) {}
345345

346346
func (l *MacOSJail) GetNetworkConfiguration() NetworkConfiguration {
347347
return NetworkConfiguration{}

jail/unprivileged.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ func NewUnprivileged(config Config) (*Unprivileged, error) {
3131
}, nil
3232
}
3333

34-
func (u *Unprivileged) Start() error {
34+
func (u *Unprivileged) ConfigureBeforeCommandExecution() error {
3535
u.logger.Debug("Starting in unprivileged mode")
3636
e := getEnvs(u.configDir, u.caCertPath)
3737
p := fmt.Sprintf("http://localhost:%d", u.httpProxyPort)
@@ -61,7 +61,7 @@ func (u *Unprivileged) Close() error {
6161
return nil
6262
}
6363

64-
func (u *Unprivileged) ConfigureAfterRun(processPID int) {}
64+
func (u *Unprivileged) ConfigureAfterCommandExecution(processPID int) {}
6565

6666
func (l *Unprivileged) GetNetworkConfiguration() NetworkConfiguration {
6767
return NetworkConfiguration{}

0 commit comments

Comments
 (0)