浏览代码

Merge pull request #1496 from aboch/st

Block non exposed port traffic on ingress nw interfaces
Santhosh Manohar 8 年之前
父节点
当前提交
b249e8afe0
共有 2 个文件被更改,包括 49 次插入2 次删除
  1. 16 1
      libnetwork/iptables/iptables.go
  2. 33 1
      libnetwork/service_linux.go

+ 16 - 1
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
 	}
 

+ 33 - 1
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)
+			}
 		}
 	}
 }