From 81e8dc62beb8d3715b7a26aa892736fd9e3fe769 Mon Sep 17 00:00:00 2001 From: matt Date: Mon, 12 Jun 2017 10:35:30 -0700 Subject: [PATCH] Add iptables rule to prevent masquerade on some external traffic This fixes a bug that was preventing OnlyLocal annotation in Kubernetes from working correctly. Prevents masquerade on external traffic to containers/pods in the subnet. Fixes #734 --- main.go | 6 +++--- network/ipmasq.go | 14 +++++++++----- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/main.go b/main.go index 3369e54d5a..be3cbde61c 100644 --- a/main.go +++ b/main.go @@ -23,9 +23,9 @@ import ( "os" "os/signal" "path/filepath" + "strconv" "strings" "syscall" - "strconv" "github.com/coreos/pkg/flagutil" log "github.com/golang/glog" @@ -187,14 +187,14 @@ func main() { // Set up ipMasq if needed if opts.ipMasq { - err = network.SetupIPMasq(config.Network) + err = network.SetupIPMasq(config.Network, bn.Lease()) if err != nil { // Continue, even though it failed. log.Errorf("Failed to set up IP Masquerade: %v", err) } defer func() { - if err := network.TeardownIPMasq(config.Network); err != nil { + if err := network.TeardownIPMasq(config.Network, bn.Lease()); err != nil { log.Errorf("Failed to tear down IP Masquerade: %v", err) } }() diff --git a/network/ipmasq.go b/network/ipmasq.go index 1825d63dc7..2136bbe0ce 100644 --- a/network/ipmasq.go +++ b/network/ipmasq.go @@ -22,28 +22,32 @@ import ( log "github.com/golang/glog" "github.com/coreos/flannel/pkg/ip" + "github.com/coreos/flannel/subnet" ) -func rules(ipn ip.IP4Net) [][]string { +func rules(ipn ip.IP4Net, lease *subnet.Lease) [][]string { n := ipn.String() + sn := lease.Subnet.String() return [][]string{ // This rule makes sure we don't NAT traffic within overlay network (e.g. coming out of docker0) {"-s", n, "-d", n, "-j", "RETURN"}, // NAT if it's not multicast traffic {"-s", n, "!", "-d", "224.0.0.0/4", "-j", "MASQUERADE"}, + // Prevent performing Masquerade on external traffic which arrives from a Node that owns the container/pod IP address + {"!", "-s", n, "-d", sn, "-j", "RETURN"}, // Masquerade anything headed towards flannel from the host {"!", "-s", n, "-d", n, "-j", "MASQUERADE"}, } } -func SetupIPMasq(ipn ip.IP4Net) error { +func SetupIPMasq(ipn ip.IP4Net, lease *subnet.Lease) error { ipt, err := iptables.New() if err != nil { return fmt.Errorf("failed to set up IP Masquerade. iptables was not found") } - for _, rule := range rules(ipn) { + for _, rule := range rules(ipn, lease) { log.Info("Adding iptables rule: ", strings.Join(rule, " ")) err = ipt.AppendUnique("nat", "POSTROUTING", rule...) if err != nil { @@ -54,13 +58,13 @@ func SetupIPMasq(ipn ip.IP4Net) error { return nil } -func TeardownIPMasq(ipn ip.IP4Net) error { +func TeardownIPMasq(ipn ip.IP4Net, lease *subnet.Lease) error { ipt, err := iptables.New() if err != nil { return fmt.Errorf("failed to teardown IP Masquerade. iptables was not found") } - for _, rule := range rules(ipn) { + for _, rule := range rules(ipn, lease) { log.Info("Deleting iptables rule: ", strings.Join(rule, " ")) err = ipt.Delete("nat", "POSTROUTING", rule...) if err != nil {