From a21d577b8b943133a43b5b829e91fc04342097ff Mon Sep 17 00:00:00 2001 From: Alessandro Boch Date: Wed, 5 Oct 2016 00:04:05 -0700 Subject: [PATCH] Block non exposed port traffic on ingress nw interfaces Signed-off-by: Alessandro Boch --- libnetwork/iptables/iptables.go | 17 ++++++++++++++++- libnetwork/service_linux.go | 34 ++++++++++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/libnetwork/iptables/iptables.go b/libnetwork/iptables/iptables.go index 340bba6b0b..b7fe816261 100644 --- a/libnetwork/iptables/iptables.go +++ b/libnetwork/iptables/iptables.go @@ -326,6 +326,21 @@ func (c *ChainInfo) Remove() error { // Exists checks if a rule exists func Exists(table Table, chain string, rule ...string) bool { + return exists(false, table, chain, rule...) +} + +// ExistsNative behaves as Exists with the difference it +// will always invoke `iptables` binary. +func ExistsNative(table Table, chain string, rule ...string) bool { + return exists(true, table, chain, rule...) +} + +func exists(native bool, table Table, chain string, rule ...string) bool { + f := Raw + if native { + f = raw + } + if string(table) == "" { table = Filter } @@ -334,7 +349,7 @@ func Exists(table Table, chain string, rule ...string) bool { if supportsCOpt { // if exit status is 0 then return true, the rule exists - _, err := Raw(append([]string{"-t", string(table), "-C", chain}, rule...)...) + _, err := f(append([]string{"-t", string(table), "-C", chain}, rule...)...) return err == nil } diff --git a/libnetwork/service_linux.go b/libnetwork/service_linux.go index 158411d140..a3f49c28f8 100644 --- a/libnetwork/service_linux.go +++ b/libnetwork/service_linux.go @@ -935,6 +935,14 @@ func redirecter() { rule := strings.Fields(fmt.Sprintf("-t nat -A PREROUTING -d %s -p %s --dport %d -j REDIRECT --to-port %d", eIP.String(), strings.ToLower(PortConfig_Protocol_name[int32(iPort.Protocol)]), iPort.PublishedPort, iPort.TargetPort)) rules = append(rules, rule) + // Allow only incoming connections to exposed ports + iRule := strings.Fields(fmt.Sprintf("-I INPUT -d %s -p %s --dport %d -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT", + eIP.String(), strings.ToLower(PortConfig_Protocol_name[int32(iPort.Protocol)]), iPort.TargetPort)) + rules = append(rules, iRule) + // Allow only outgoing connections from exposed ports + oRule := strings.Fields(fmt.Sprintf("-I OUTPUT -s %s -p %s --sport %d -m conntrack --ctstate ESTABLISHED -j ACCEPT", + eIP.String(), strings.ToLower(PortConfig_Protocol_name[int32(iPort.Protocol)]), iPort.TargetPort)) + rules = append(rules, oRule) } ns, err := netns.GetFromPath(os.Args[1]) @@ -952,7 +960,31 @@ func redirecter() { for _, rule := range rules { if err := iptables.RawCombinedOutputNative(rule...); err != nil { logrus.Errorf("setting up rule failed, %v: %v", rule, err) - os.Exit(5) + os.Exit(6) + } + } + + if len(ingressPorts) == 0 { + return + } + + // Ensure blocking rules for anything else in/to ingress network + for _, rule := range [][]string{ + {"-d", eIP.String(), "-p", "udp", "-j", "DROP"}, + {"-d", eIP.String(), "-p", "tcp", "-j", "DROP"}, + } { + if !iptables.ExistsNative(iptables.Filter, "INPUT", rule...) { + if err := iptables.RawCombinedOutputNative(append([]string{"-A", "INPUT"}, rule...)...); err != nil { + logrus.Errorf("setting up rule failed, %v: %v", rule, err) + os.Exit(7) + } + } + rule[0] = "-s" + if !iptables.ExistsNative(iptables.Filter, "OUTPUT", rule...) { + if err := iptables.RawCombinedOutputNative(append([]string{"-A", "OUTPUT"}, rule...)...); err != nil { + logrus.Errorf("setting up rule failed, %v: %v", rule, err) + os.Exit(8) + } } } }