From ff8a4ba0aa20dc3b382e2dcddcd89bb0bb168496 Mon Sep 17 00:00:00 2001 From: "Guillaume J. Charmes" Date: Tue, 5 Nov 2013 07:33:07 -0800 Subject: [PATCH 1/2] Check the output of iptables command. --- iptables/iptables.go | 43 +++++++++++++++++++++++++++++---------- iptables/iptables_test.go | 4 ++-- links.go | 8 ++++++-- network.go | 8 ++++++-- 4 files changed, 46 insertions(+), 17 deletions(-) diff --git a/iptables/iptables.go b/iptables/iptables.go index 463f443fda..8139b9881e 100644 --- a/iptables/iptables.go +++ b/iptables/iptables.go @@ -27,8 +27,10 @@ type Chain struct { } func NewChain(name, bridge string) (*Chain, error) { - if err := Raw("-t", "nat", "-N", name); err != nil { + if output, err := Raw("-t", "nat", "-N", name); err != nil { return nil, err + } else if len(output) != 0 { + return nil, fmt.Errorf("Error creating new iptables chain: %s", output) } chain := &Chain{ Name: name, @@ -52,13 +54,18 @@ func RemoveExistingChain(name string) error { } func (c *Chain) Forward(action Action, ip net.IP, port int, proto, dest_addr string, dest_port int) error { - return Raw("-t", "nat", fmt.Sprint(action), c.Name, + if output, err := Raw("-t", "nat", fmt.Sprint(action), c.Name, "-p", proto, "-d", ip.String(), "--dport", strconv.Itoa(port), "!", "-i", c.Bridge, "-j", "DNAT", - "--to-destination", net.JoinHostPort(dest_addr, strconv.Itoa(dest_port))) + "--to-destination", net.JoinHostPort(dest_addr, strconv.Itoa(dest_port))); err != nil { + return err + } else if len(output) != 0 { + return fmt.Errorf("Error iptables forward: %s", output) + } + return nil } func (c *Chain) Prerouting(action Action, args ...string) error { @@ -66,7 +73,12 @@ func (c *Chain) Prerouting(action Action, args ...string) error { if len(args) > 0 { a = append(a, args...) } - return Raw(append(a, "-j", c.Name)...) + if output, err := Raw(append(a, "-j", c.Name)...); err != nil { + return err + } else if len(output) != 0 { + return fmt.Errorf("Error iptables prerouting: %s", output) + } + return nil } func (c *Chain) Output(action Action, args ...string) error { @@ -74,7 +86,12 @@ func (c *Chain) Output(action Action, args ...string) error { if len(args) > 0 { a = append(a, args...) } - return Raw(append(a, "-j", c.Name)...) + if output, err := Raw(append(a, "-j", c.Name)...); err != nil { + return err + } else if len(output) != 0 { + return fmt.Errorf("Error iptables output: %s", output) + } + return nil } func (c *Chain) Remove() error { @@ -94,17 +111,21 @@ func (c *Chain) Remove() error { // Check if an existing rule exists func Exists(args ...string) bool { - return Raw(append([]string{"-C"}, args...)...) == nil + if _, err := Raw(append([]string{"-C"}, args...)...); err != nil { + return false + } + return true } -func Raw(args ...string) error { +func Raw(args ...string) ([]byte, error) { path, err := exec.LookPath("iptables") if err != nil { - return ErrIptablesNotFound + return nil, ErrIptablesNotFound } - if err := exec.Command(path, args...).Run(); err != nil { - return fmt.Errorf("iptables failed: iptables %v", strings.Join(args, " ")) + output, err := exec.Command(path, args...).CombinedOutput() + if err != nil { + return nil, fmt.Errorf("iptables failed: iptables %v: %s (%s)", strings.Join(args, " "), output, err) } - return nil + return output, err } diff --git a/iptables/iptables_test.go b/iptables/iptables_test.go index aad8acdb81..886a63c03f 100644 --- a/iptables/iptables_test.go +++ b/iptables/iptables_test.go @@ -6,13 +6,13 @@ import ( ) func TestIptables(t *testing.T) { - if err := Raw("-L"); err != nil { + if _, err := Raw("-L"); err != nil { t.Fatal(err) } path := os.Getenv("PATH") os.Setenv("PATH", "") defer os.Setenv("PATH", path) - if err := Raw("-L"); err == nil { + if _, err := Raw("-L"); err == nil { t.Fatal("Not finding iptables in the PATH should cause an error") } } diff --git a/links.go b/links.go index 60c738abb4..3c689d0bf3 100644 --- a/links.go +++ b/links.go @@ -120,7 +120,7 @@ func (l *Link) Disable() { func (l *Link) toggle(action string, ignoreErrors bool) error { for _, p := range l.Ports { - if err := iptables.Raw(action, "FORWARD", + if output, err := iptables.Raw(action, "FORWARD", "-i", l.BridgeInterface, "-o", l.BridgeInterface, "-p", p.Proto(), "-s", l.ParentIP, @@ -128,9 +128,11 @@ func (l *Link) toggle(action string, ignoreErrors bool) error { "-d", l.ChildIP, "-j", "ACCEPT"); !ignoreErrors && err != nil { return err + } else if len(output) != 0 { + return fmt.Errorf("Error toggle iptables forward: %s", output) } - if err := iptables.Raw(action, "FORWARD", + if output, err := iptables.Raw(action, "FORWARD", "-i", l.BridgeInterface, "-o", l.BridgeInterface, "-p", p.Proto(), "-s", l.ChildIP, @@ -138,6 +140,8 @@ func (l *Link) toggle(action string, ignoreErrors bool) error { "-d", l.ParentIP, "-j", "ACCEPT"); !ignoreErrors && err != nil { return err + } else if len(output) != 0 { + return fmt.Errorf("Error toggle iptables forward: %s", output) } } return nil diff --git a/network.go b/network.go index c237ccc86d..acb94ce1f5 100644 --- a/network.go +++ b/network.go @@ -141,9 +141,11 @@ func CreateBridgeIface(config *DaemonConfig) error { } if config.EnableIptables { - if err := iptables.Raw("-t", "nat", "-A", "POSTROUTING", "-s", ifaceAddr, + if output, err := iptables.Raw("-t", "nat", "-A", "POSTROUTING", "-s", ifaceAddr, "!", "-d", ifaceAddr, "-j", "MASQUERADE"); err != nil { return fmt.Errorf("Unable to enable network bridge NAT: %s", err) + } else if len(output) != 0 { + return fmt.Errorf("Error iptables postrouting: %s", output) } } return nil @@ -656,8 +658,10 @@ func newNetworkManager(config *DaemonConfig) (*NetworkManager, error) { if !config.InterContainerCommunication { if !iptables.Exists(args...) { utils.Debugf("Disable inter-container communication") - if err := iptables.Raw(append([]string{"-A"}, args...)...); err != nil { + if output, err := iptables.Raw(append([]string{"-A"}, args...)...); err != nil { return nil, fmt.Errorf("Unable to prevent intercontainer communication: %s", err) + } else if len(output) != 0 { + return nil, fmt.Errorf("Error enabling iptables: %s", output) } } } else { From 00f1398f7a8543e2448723635d93ea6ddf1eaadb Mon Sep 17 00:00:00 2001 From: "Guillaume J. Charmes" Date: Wed, 6 Nov 2013 07:37:43 -0800 Subject: [PATCH 2/2] Add debug to iptables --- iptables/iptables.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/iptables/iptables.go b/iptables/iptables.go index 8139b9881e..82ecf8bb5b 100644 --- a/iptables/iptables.go +++ b/iptables/iptables.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "net" + "os" "os/exec" "strconv" "strings" @@ -122,10 +123,12 @@ func Raw(args ...string) ([]byte, error) { if err != nil { return nil, ErrIptablesNotFound } + if os.Getenv("DEBUG") != "" { + fmt.Printf("[DEBUG] [iptables]: %s, %v\n", path, args) + } output, err := exec.Command(path, args...).CombinedOutput() if err != nil { return nil, fmt.Errorf("iptables failed: iptables %v: %s (%s)", strings.Join(args, " "), output, err) } return output, err - }