diff --git a/firewall/firewall_linux.go b/firewall/firewall_linux.go index 39508e4d..28689020 100644 --- a/firewall/firewall_linux.go +++ b/firewall/firewall_linux.go @@ -8,7 +8,6 @@ import ( "github.com/bettercap/bettercap/v2/core" "github.com/bettercap/bettercap/v2/network" - "github.com/evilsocket/islazy/fs" "github.com/evilsocket/islazy/str" ) @@ -32,143 +31,46 @@ func Make(iface *network.Endpoint) FirewallManager { restore: false, redirections: make(map[string]*Redirection), } - firewall.forwarding = firewall.IsForwardingEnabled() - return firewall } -func (f LinuxFirewall) enableFeature(filename string, enable bool) error { - var value string +func (f *LinuxFirewall) enableFeature(filename string, enable bool) error { + value := "0" if enable { value = "1" - } else { - value = "0" } - fd, err := os.OpenFile(filename, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0600) + fd, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY, 0600) if err != nil { - return err + return fmt.Errorf("failed to open file %s: %w", filename, err) } defer fd.Close() - _, err = fd.WriteString(value) - return err -} - -func (f LinuxFirewall) IsForwardingEnabled() bool { - - if out, err := ioutil.ReadFile(IPV4ForwardingFile); err != nil { - return false - } else { - return str.Trim(string(out)) == "1" + if _, err := fd.WriteString(value); err != nil { + return fmt.Errorf("failed to write to file %s: %w", filename, err) } + return nil } -func (f LinuxFirewall) EnableForwarding(enabled bool) error { +func (f *LinuxFirewall) IsForwardingEnabled() bool { + content, err := ioutil.ReadFile(IPV4ForwardingFile) + if err != nil { + return false + } + return str.Trim(string(content)) == "1" +} + +func (f *LinuxFirewall) EnableForwarding(enabled bool) error { if err := f.enableFeature(IPV4ForwardingFile, enabled); err != nil { return err } if fs.Exists(IPV6ForwardingFile) { - return f.enableFeature(IPV6ForwardingFile, enabled) + if err := f.enableFeature(IPV6ForwardingFile, enabled); err != nil { + return err + } } f.restore = true return nil -} - -func (f *LinuxFirewall) getCommandLine(r *Redirection, enabled bool) (cmdLine []string) { - action := "-A" - destination := "" - - if !enabled { - action = "-D" - } - - if strings.Count(r.DstAddress, ":") < 2 { - destination = r.DstAddress - } else { - destination = fmt.Sprintf("[%s]", r.DstAddress) - } - - if r.SrcAddress == "" { - cmdLine = []string{ - "-t", "nat", - action, "PREROUTING", - "-i", r.Interface, - "-p", r.Protocol, - "--dport", fmt.Sprintf("%d", r.SrcPort), - "-j", "DNAT", - "--to", fmt.Sprintf("%s:%d", destination, r.DstPort), - } - } else { - cmdLine = []string{ - "-t", "nat", - action, "PREROUTING", - "-i", r.Interface, - "-p", r.Protocol, - "-d", r.SrcAddress, - "--dport", fmt.Sprintf("%d", r.SrcPort), - "-j", "DNAT", - "--to", fmt.Sprintf("%s:%d", destination, r.DstPort), - } - } - - return -} - -func (f *LinuxFirewall) EnableRedirection(r *Redirection, enabled bool) error { - cmdLine := f.getCommandLine(r, enabled) - rkey := r.String() - _, found := f.redirections[rkey] - cmd := "" - - if strings.Count(r.DstAddress, ":") < 2 { - cmd = "iptables" - } else { - cmd = "ip6tables" - } - - if enabled { - if found { - return fmt.Errorf("Redirection '%s' already enabled.", rkey) - } - - f.redirections[rkey] = r - - // accept all - if _, err := core.Exec(cmd, []string{"-P", "FORWARD", "ACCEPT"}); err != nil { - return err - } else if _, err := core.Exec(cmd, cmdLine); err != nil { - return err - } - } else { - if !found { - return nil - } - - delete(f.redirections, r.String()) - - if _, err := core.Exec(cmd, cmdLine); err != nil { - return err - } - } - - return nil -} - -func (f LinuxFirewall) Restore() { - if f.restore == false { - return - } - for _, r := range f.redirections { - if err := f.EnableRedirection(r, false); err != nil { - fmt.Printf("%s", err) - } - } - - if err := f.EnableForwarding(f.forwarding); err != nil { - fmt.Printf("%s", err) - } -}