diff --git a/extensions/simplebridge/driver.go b/extensions/simplebridge/driver.go index b5d158d613d7e..f77efa7bc67af 100644 --- a/extensions/simplebridge/driver.go +++ b/extensions/simplebridge/driver.go @@ -8,8 +8,8 @@ import ( "sync" log "github.com/Sirupsen/logrus" - "github.com/docker/docker/network" + "github.com/docker/docker/pkg/iptables" "github.com/docker/docker/sandbox" "github.com/docker/docker/state" @@ -249,6 +249,10 @@ func (d *BridgeDriver) createBridge(id string, vlanid uint, port uint, peer stri return nil, err } + if err := setupIPTables(id, addr, true, true); err != nil { + return nil, err + } + var vxlan *netlink.Vxlan if peer != "" { @@ -299,3 +303,72 @@ func (d *BridgeDriver) destroyBridge(b *netlink.Bridge, v *netlink.Vxlan) error return netlink.LinkDel(b) } + +// FIXME remove last two parameters +func setupIPTables(bridgeIface string, addr net.Addr, icc, ipmasq bool) error { + // Enable NAT + + if ipmasq { + natArgs := []string{"POSTROUTING", "-t", "nat", "-s", addr.String(), "!", "-o", bridgeIface, "-j", "MASQUERADE"} + + if !iptables.Exists(natArgs...) { + if output, err := iptables.Raw(append([]string{"-I"}, natArgs...)...); err != nil { + return fmt.Errorf("Unable to enable network bridge NAT: %s", err) + } else if len(output) != 0 { + return &iptables.ChainError{Chain: "POSTROUTING", Output: output} + } + } + } + + var ( + args = []string{"FORWARD", "-i", bridgeIface, "-o", bridgeIface, "-j"} + acceptArgs = append(args, "ACCEPT") + dropArgs = append(args, "DROP") + ) + + if !icc { + iptables.Raw(append([]string{"-D"}, acceptArgs...)...) + + if !iptables.Exists(dropArgs...) { + log.Debugf("Disable inter-container communication") + if output, err := iptables.Raw(append([]string{"-I"}, dropArgs...)...); err != nil { + return fmt.Errorf("Unable to prevent intercontainer communication: %s", err) + } else if len(output) != 0 { + return fmt.Errorf("Error disabling intercontainer communication: %s", output) + } + } + } else { + iptables.Raw(append([]string{"-D"}, dropArgs...)...) + + if !iptables.Exists(acceptArgs...) { + log.Debugf("Enable inter-container communication") + if output, err := iptables.Raw(append([]string{"-I"}, acceptArgs...)...); err != nil { + return fmt.Errorf("Unable to allow intercontainer communication: %s", err) + } else if len(output) != 0 { + return fmt.Errorf("Error enabling intercontainer communication: %s", output) + } + } + } + + // Accept all non-intercontainer outgoing packets + outgoingArgs := []string{"FORWARD", "-i", bridgeIface, "!", "-o", bridgeIface, "-j", "ACCEPT"} + if !iptables.Exists(outgoingArgs...) { + if output, err := iptables.Raw(append([]string{"-I"}, outgoingArgs...)...); err != nil { + return fmt.Errorf("Unable to allow outgoing packets: %s", err) + } else if len(output) != 0 { + return &iptables.ChainError{Chain: "FORWARD outgoing", Output: output} + } + } + + // Accept incoming packets for existing connections + existingArgs := []string{"FORWARD", "-o", bridgeIface, "-m", "conntrack", "--ctstate", "RELATED,ESTABLISHED", "-j", "ACCEPT"} + + if !iptables.Exists(existingArgs...) { + if output, err := iptables.Raw(append([]string{"-I"}, existingArgs...)...); err != nil { + return fmt.Errorf("Unable to allow incoming packets: %s", err) + } else if len(output) != 0 { + return &iptables.ChainError{Chain: "FORWARD incoming", Output: output} + } + } + return nil +}