diff --git a/cli/cli.go b/cli/cli.go index f495da2..4975bfa 100644 --- a/cli/cli.go +++ b/cli/cli.go @@ -166,7 +166,8 @@ func Run(config Config, args []string) error { // Write CA certificate to a temporary file for tools that need a file path caCertPath := filepath.Join(configDir, "ca-cert.pem") - if err := os.WriteFile(caCertPath, caCertPEM, 0644); err != nil { + err = os.WriteFile(caCertPath, caCertPEM, 0644) + if err != nil { logger.Error("Failed to write CA certificate file", "error", err) return fmt.Errorf("failed to write CA certificate file: %v", err) } @@ -205,7 +206,8 @@ func Run(config Config, args []string) error { go func() { sig := <-sigChan logger.Info("Received signal during setup, cleaning up...", "signal", sig) - if err := networkInstance.Cleanup(); err != nil { + err := networkInstance.Cleanup() + if err != nil { logger.Error("Emergency cleanup failed", "error", err) } os.Exit(1) @@ -214,7 +216,8 @@ func Run(config Config, args []string) error { // Ensure cleanup happens no matter what defer func() { logger.Debug("Starting cleanup process") - if err := networkInstance.Cleanup(); err != nil { + err := networkInstance.Cleanup() + if err != nil { logger.Error("Failed to cleanup network jail", "error", err) } else { logger.Debug("Cleanup completed successfully") @@ -222,7 +225,8 @@ func Run(config Config, args []string) error { }() // Setup network jail - if err := networkInstance.Setup(networkConfig.HTTPPort, networkConfig.HTTPSPort); err != nil { + err = networkInstance.Setup(networkConfig.HTTPPort, networkConfig.HTTPSPort) + if err != nil { logger.Error("Failed to setup network jail", "error", err) return fmt.Errorf("failed to setup network jail: %v", err) } @@ -248,7 +252,8 @@ func Run(config Config, args []string) error { // Start proxy server in background go func() { - if err := proxyServer.Start(ctx); err != nil { + err := proxyServer.Start(ctx) + if err != nil { logger.Error("Proxy server error", "error", err) } }() @@ -259,7 +264,8 @@ func Run(config Config, args []string) error { // Execute command in network jail go func() { defer cancel() - if err := networkInstance.Execute(args, extraEnv); err != nil { + err := networkInstance.Execute(args, extraEnv) + if err != nil { logger.Error("Command execution failed", "error", err) } }() @@ -274,7 +280,8 @@ func Run(config Config, args []string) error { } // Stop proxy server - if err := proxyServer.Stop(); err != nil { + err = proxyServer.Stop() + if err != nil { logger.Error("Failed to stop proxy server", "error", err) } diff --git a/network/linux.go b/network/linux.go index e05e04d..f245014 100644 --- a/network/linux.go +++ b/network/linux.go @@ -45,28 +45,32 @@ func (l *LinuxJail) Setup(httpPort, httpsPort int) error { // Setup DNS configuration BEFORE creating namespace // This ensures the namespace-specific resolv.conf is available when namespace is created l.logger.Debug("Setting up DNS configuration") - if err := l.setupDNS(); err != nil { + err := l.setupDNS() + if err != nil { return fmt.Errorf("failed to setup DNS: %v", err) } l.logger.Debug("DNS setup completed") // Create network namespace l.logger.Debug("Creating network namespace", "namespace", l.namespace) - if err := l.createNamespace(); err != nil { + err = l.createNamespace() + if err != nil { return fmt.Errorf("failed to create namespace: %v", err) } l.logger.Debug("Network namespace created") // Setup network interface in namespace l.logger.Debug("Setting up networking") - if err := l.setupNetworking(); err != nil { + err = l.setupNetworking() + if err != nil { return fmt.Errorf("failed to setup networking: %v", err) } l.logger.Debug("Networking setup completed") // Setup iptables rules l.logger.Debug("Setting up iptables rules") - if err := l.setupIptables(); err != nil { + err = l.setupIptables() + if err != nil { return fmt.Errorf("failed to setup iptables: %v", err) } l.logger.Debug("Iptables setup completed") @@ -175,21 +179,24 @@ func (l *LinuxJail) Cleanup() error { } // Remove iptables rules - if err := l.removeIptables(); err != nil { + err := l.removeIptables() + if err != nil { return fmt.Errorf("failed to remove iptables rules: %v", err) } // Clean up namespace-specific DNS config directory netnsEtc := fmt.Sprintf("/etc/netns/%s", l.namespace) if _, err := os.Stat(netnsEtc); err == nil { - if err := os.RemoveAll(netnsEtc); err != nil { + err := os.RemoveAll(netnsEtc) + if err != nil { // Don't fail cleanup for this, just log fmt.Printf("Warning: failed to remove DNS config directory %s: %v\n", netnsEtc, err) } } // Remove network namespace - if err := l.removeNamespace(); err != nil { + err = l.removeNamespace() + if err != nil { return fmt.Errorf("failed to remove namespace: %v", err) } @@ -199,7 +206,8 @@ func (l *LinuxJail) Cleanup() error { // createNamespace creates a new network namespace func (l *LinuxJail) createNamespace() error { cmd := exec.Command("ip", "netns", "add", l.namespace) - if err := cmd.Run(); err != nil { + err := cmd.Run() + if err != nil { return fmt.Errorf("failed to create namespace: %v", err) } return nil @@ -214,46 +222,54 @@ func (l *LinuxJail) setupNetworking() error { vethNetJail := fmt.Sprintf("veth_n_%s", uniqueID) // veth_n_1234567 = 14 chars cmd := exec.Command("ip", "link", "add", vethHost, "type", "veth", "peer", "name", vethNetJail) - if err := cmd.Run(); err != nil { + err := cmd.Run() + if err != nil { return fmt.Errorf("failed to create veth pair: %v", err) } // Move netjail end to namespace cmd = exec.Command("ip", "link", "set", vethNetJail, "netns", l.namespace) - if err := cmd.Run(); err != nil { + err = cmd.Run() + if err != nil { return fmt.Errorf("failed to move veth to namespace: %v", err) } // Configure host side of veth pair cmd = exec.Command("ip", "addr", "add", "192.168.100.1/24", "dev", vethHost) - if err := cmd.Run(); err != nil { + err = cmd.Run() + if err != nil { return fmt.Errorf("failed to configure host veth: %v", err) } cmd = exec.Command("ip", "link", "set", vethHost, "up") - if err := cmd.Run(); err != nil { + err = cmd.Run() + if err != nil { return fmt.Errorf("failed to bring up host veth: %v", err) } // Configure namespace side of veth pair cmd = exec.Command("ip", "netns", "exec", l.namespace, "ip", "addr", "add", "192.168.100.2/24", "dev", vethNetJail) - if err := cmd.Run(); err != nil { + err = cmd.Run() + if err != nil { return fmt.Errorf("failed to configure namespace veth: %v", err) } cmd = exec.Command("ip", "netns", "exec", l.namespace, "ip", "link", "set", vethNetJail, "up") - if err := cmd.Run(); err != nil { + err = cmd.Run() + if err != nil { return fmt.Errorf("failed to bring up namespace veth: %v", err) } cmd = exec.Command("ip", "netns", "exec", l.namespace, "ip", "link", "set", "lo", "up") - if err := cmd.Run(); err != nil { + err = cmd.Run() + if err != nil { return fmt.Errorf("failed to bring up loopback: %v", err) } // Set default route in namespace cmd = exec.Command("ip", "netns", "exec", l.namespace, "ip", "route", "add", "default", "via", "192.168.100.1") - if err := cmd.Run(); err != nil { + err = cmd.Run() + if err != nil { return fmt.Errorf("failed to set default route: %v", err) } @@ -267,7 +283,8 @@ func (l *LinuxJail) setupDNS() error { // Always create namespace-specific resolv.conf with reliable public DNS servers // This avoids issues with systemd-resolved, Docker DNS, and other complex setups netnsEtc := fmt.Sprintf("/etc/netns/%s", l.namespace) - if err := os.MkdirAll(netnsEtc, 0755); err != nil { + err := os.MkdirAll(netnsEtc, 0755) + if err != nil { return fmt.Errorf("failed to create /etc/netns directory: %v", err) } @@ -280,7 +297,8 @@ nameserver 1.1.1.1 nameserver 9.9.9.9 options timeout:2 attempts:2 ` - if err := os.WriteFile(resolvConfPath, []byte(dnsConfig), 0644); err != nil { + err = os.WriteFile(resolvConfPath, []byte(dnsConfig), 0644) + if err != nil { return fmt.Errorf("failed to write namespace-specific resolv.conf: %v", err) } @@ -296,21 +314,24 @@ func (l *LinuxJail) setupIptables() error { // NAT rules for outgoing traffic cmd = exec.Command("iptables", "-t", "nat", "-A", "POSTROUTING", "-s", "192.168.100.0/24", "-j", "MASQUERADE") - if err := cmd.Run(); err != nil { + err := cmd.Run() + if err != nil { return fmt.Errorf("failed to add NAT rule: %v", err) } // Redirect HTTP traffic to proxy cmd = exec.Command("ip", "netns", "exec", l.namespace, "iptables", "-t", "nat", "-A", "OUTPUT", "-p", "tcp", "--dport", "80", "-j", "DNAT", "--to-destination", fmt.Sprintf("192.168.100.1:%d", l.config.HTTPPort)) - if err := cmd.Run(); err != nil { + err = cmd.Run() + if err != nil { return fmt.Errorf("failed to add HTTP redirect rule: %v", err) } // Redirect HTTPS traffic to proxy cmd = exec.Command("ip", "netns", "exec", l.namespace, "iptables", "-t", "nat", "-A", "OUTPUT", "-p", "tcp", "--dport", "443", "-j", "DNAT", "--to-destination", fmt.Sprintf("192.168.100.1:%d", l.config.HTTPSPort)) - if err := cmd.Run(); err != nil { + err = cmd.Run() + if err != nil { return fmt.Errorf("failed to add HTTPS redirect rule: %v", err) } @@ -329,8 +350,9 @@ func (l *LinuxJail) removeIptables() error { // removeNamespace removes the network namespace func (l *LinuxJail) removeNamespace() error { cmd := exec.Command("ip", "netns", "del", l.namespace) - if err := cmd.Run(); err != nil { + err := cmd.Run() + if err != nil { return fmt.Errorf("failed to remove namespace: %v", err) } return nil -} +} \ No newline at end of file diff --git a/network/macos.go b/network/macos.go index e3b9809..8823587 100644 --- a/network/macos.go +++ b/network/macos.go @@ -40,7 +40,7 @@ func newMacOSJail(config JailConfig, logger *slog.Logger) (*MacOSNetJail, error) }, nil } -// Setup configures PF rules and creates the network jail group +// Setup creates the network jail group and configures PF rules func (m *MacOSNetJail) Setup(httpPort, httpsPort int) error { m.logger.Debug("Setup called", "httpPort", httpPort, "httpsPort", httpsPort) m.config.HTTPPort = httpPort @@ -48,14 +48,16 @@ func (m *MacOSNetJail) Setup(httpPort, httpsPort int) error { // Create or get network jail group m.logger.Debug("Creating or ensuring network jail group") - if err := m.ensureGroup(); err != nil { + err := m.ensureGroup() + if err != nil { return fmt.Errorf("failed to ensure group: %v", err) } m.logger.Debug("Network jail group ready", "groupID", m.groupID) // Setup PF rules m.logger.Debug("Setting up PF rules") - if err := m.setupPFRules(); err != nil { + err = m.setupPFRules() + if err != nil { return fmt.Errorf("failed to setup PF rules: %v", err) } m.logger.Debug("PF rules setup completed") @@ -165,7 +167,8 @@ func (m *MacOSNetJail) Cleanup() error { // Remove PF rules m.logger.Debug("Removing PF rules") - if err := m.removePFRules(); err != nil { + err := m.removePFRules() + if err != nil { return fmt.Errorf("failed to remove PF rules: %v", err) } @@ -201,7 +204,8 @@ func (m *MacOSNetJail) ensureGroup() error { // Group doesn't exist, create it cmd := exec.Command("dseditgroup", "-o", "create", GROUP_NAME) - if err := cmd.Run(); err != nil { + err = cmd.Run() + if err != nil { return fmt.Errorf("failed to create group: %v", err) } @@ -299,13 +303,15 @@ func (m *MacOSNetJail) setupPFRules() error { } // Write rules to temp file - if err := os.WriteFile(m.pfRulesPath, []byte(rules), 0644); err != nil { + err = os.WriteFile(m.pfRulesPath, []byte(rules), 0644) + if err != nil { return fmt.Errorf("failed to write PF rules file: %v", err) } // Load rules into anchor cmd := exec.Command("pfctl", "-a", PF_ANCHOR_NAME, "-f", m.pfRulesPath) - if err := cmd.Run(); err != nil { + err = cmd.Run() + if err != nil { return fmt.Errorf("failed to load PF rules: %v", err) } @@ -330,12 +336,14 @@ anchor "%s" `, PF_ANCHOR_NAME, PF_ANCHOR_NAME) // Write and load the main ruleset - if err := os.WriteFile(m.mainRulesPath, []byte(mainRules), 0644); err != nil { + err = os.WriteFile(m.mainRulesPath, []byte(mainRules), 0644) + if err != nil { return fmt.Errorf("failed to write main PF rules: %v", err) } cmd = exec.Command("pfctl", "-f", m.mainRulesPath) - if err := cmd.Run(); err != nil { + err = cmd.Run() + if err != nil { // Don't fail if main rules can't be loaded, but warn fmt.Fprintf(os.Stderr, "Warning: failed to load main PF rules: %v\n", err) } @@ -368,4 +376,4 @@ func (m *MacOSNetJail) cleanupTempFiles() { if m.mainRulesPath != "" { os.Remove(m.mainRulesPath) } -} +} \ No newline at end of file diff --git a/proxy/proxy.go b/proxy/proxy.go index 1fab9cc..cedc223 100644 --- a/proxy/proxy.go +++ b/proxy/proxy.go @@ -66,7 +66,8 @@ func (p *ProxyServer) Start(ctx context.Context) error { // Start HTTP server go func() { p.logger.Info("Starting HTTP proxy", "port", p.httpPort) - if err := p.httpServer.ListenAndServe(); err != nil && err != http.ErrServerClosed { + err := p.httpServer.ListenAndServe() + if err != nil && err != http.ErrServerClosed { p.logger.Error("HTTP proxy server error", "error", err) } }() @@ -74,7 +75,8 @@ func (p *ProxyServer) Start(ctx context.Context) error { // Start HTTPS server go func() { p.logger.Info("Starting HTTPS proxy", "port", p.httpsPort) - if err := p.httpsServer.ListenAndServeTLS("", ""); err != nil && err != http.ErrServerClosed { + err := p.httpsServer.ListenAndServeTLS("", "") + if err != nil && err != http.ErrServerClosed { p.logger.Error("HTTPS proxy server error", "error", err) } }() diff --git a/tls/tls.go b/tls/tls.go index 07ef6ad..3dd54e7 100644 --- a/tls/tls.go +++ b/tls/tls.go @@ -38,7 +38,8 @@ func NewCertificateManager(configDir string, logger *slog.Logger) (*CertificateM } // Load or generate CA certificate - if err := cm.loadOrGenerateCA(); err != nil { + err := cm.loadOrGenerateCA() + if err != nil { return nil, fmt.Errorf("failed to load or generate CA: %v", err) } @@ -139,7 +140,8 @@ func (cm *CertificateManager) loadExistingCA(keyPath, certPath string) bool { // generateCA generates a new CA certificate and key func (cm *CertificateManager) generateCA(keyPath, certPath string) error { // Create config directory if it doesn't exist - if err := os.MkdirAll(cm.configDir, 0700); err != nil { + err := os.MkdirAll(cm.configDir, 0700) + if err != nil { return fmt.Errorf("failed to create config directory: %v", err) } @@ -151,7 +153,8 @@ func (cm *CertificateManager) generateCA(keyPath, certPath string) error { gid, err2 := strconv.Atoi(sudoGID) if err1 == nil && err2 == nil { // Change ownership of the config directory to the original user - if err := os.Chown(cm.configDir, uid, gid); err != nil { + err := os.Chown(cm.configDir, uid, gid) + if err != nil { cm.logger.Warn("Failed to change config directory ownership", "error", err) } }