Browse code

network: add iptables rules to explicitly allow forwarding

Explicitly enable container networking for Fedora and other distros that
have a REJECT all rule at the end of their FORWARD table.

Josh Poimboeuf authored on 2013/11/02 08:29:25
Showing 2 changed files
... ...
@@ -94,6 +94,7 @@ Jonathan Rudenberg <jonathan@titanous.com>
94 94
 Joost Cassee <joost@cassee.net>
95 95
 Jordan Arentsen <blissdev@gmail.com>
96 96
 Joseph Anthony Pasquale Holsten <joseph@josephholsten.com>
97
+Josh Poimboeuf <jpoimboe@redhat.com>
97 98
 Julien Barbier <write0@gmail.com>
98 99
 Jérôme Petazzoni <jerome.petazzoni@dotcloud.com>
99 100
 Karan Lyons <karan@karanlyons.com>
... ...
@@ -168,12 +168,28 @@ func CreateBridgeIface(config *DaemonConfig) error {
168 168
 	}
169 169
 
170 170
 	if config.EnableIptables {
171
+		// Enable NAT
171 172
 		if output, err := iptables.Raw("-t", "nat", "-A", "POSTROUTING", "-s", ifaceAddr,
172 173
 			"!", "-d", ifaceAddr, "-j", "MASQUERADE"); err != nil {
173 174
 			return fmt.Errorf("Unable to enable network bridge NAT: %s", err)
174 175
 		} else if len(output) != 0 {
175 176
 			return fmt.Errorf("Error iptables postrouting: %s", output)
176 177
 		}
178
+
179
+		// Accept incoming packets for existing connections
180
+		if output, err := iptables.Raw("-I", "FORWARD", "-o", config.BridgeIface, "-m", "conntrack", "--ctstate", "RELATED,ESTABLISHED", "-j", "ACCEPT"); err != nil {
181
+			return fmt.Errorf("Unable to allow incoming packets: %s", err)
182
+		} else if len(output) != 0 {
183
+			return fmt.Errorf("Error iptables allow incoming: %s", output)
184
+		}
185
+
186
+		// Accept all non-intercontainer outgoing packets
187
+		if output, err := iptables.Raw("-I", "FORWARD", "-i", config.BridgeIface, "!", "-o", config.BridgeIface, "-j", "ACCEPT"); err != nil {
188
+			return fmt.Errorf("Unable to allow outgoing packets: %s", err)
189
+		} else if len(output) != 0 {
190
+			return fmt.Errorf("Error iptables allow outgoing: %s", output)
191
+		}
192
+
177 193
 	}
178 194
 	return nil
179 195
 }
... ...
@@ -680,20 +696,30 @@ func newNetworkManager(config *DaemonConfig) (*NetworkManager, error) {
680 680
 
681 681
 	// Configure iptables for link support
682 682
 	if config.EnableIptables {
683
-		args := []string{"FORWARD", "-i", config.BridgeIface, "-o", config.BridgeIface, "-j", "DROP"}
683
+		args := []string{"FORWARD", "-i", config.BridgeIface, "-o", config.BridgeIface, "-j"}
684
+		acceptArgs := append(args, "ACCEPT")
685
+		dropArgs := append(args, "DROP")
684 686
 
685 687
 		if !config.InterContainerCommunication {
686
-			if !iptables.Exists(args...) {
688
+			iptables.Raw(append([]string{"-D"}, acceptArgs...)...)
689
+			if !iptables.Exists(dropArgs...) {
687 690
 				utils.Debugf("Disable inter-container communication")
688
-				if output, err := iptables.Raw(append([]string{"-A"}, args...)...); err != nil {
691
+				if output, err := iptables.Raw(append([]string{"-I"}, dropArgs...)...); err != nil {
689 692
 					return nil, fmt.Errorf("Unable to prevent intercontainer communication: %s", err)
690 693
 				} else if len(output) != 0 {
691
-					return nil, fmt.Errorf("Error enabling iptables: %s", output)
694
+					return nil, fmt.Errorf("Error disabling intercontainer communication: %s", output)
692 695
 				}
693 696
 			}
694 697
 		} else {
695
-			utils.Debugf("Enable inter-container communication")
696
-			iptables.Raw(append([]string{"-D"}, args...)...)
698
+			iptables.Raw(append([]string{"-D"}, dropArgs...)...)
699
+			if !iptables.Exists(acceptArgs...) {
700
+				utils.Debugf("Enable inter-container communication")
701
+				if output, err := iptables.Raw(append([]string{"-I"}, acceptArgs...)...); err != nil {
702
+					return nil, fmt.Errorf("Unable to allow intercontainer communication: %s", err)
703
+				} else if len(output) != 0 {
704
+					return nil, fmt.Errorf("Error enabling intercontainer communication: %s", output)
705
+				}
706
+			}
697 707
 		}
698 708
 	}
699 709