Browse code

Add an option to disable IP masquerading

For the cases where --bip option is used it is sometimes best to disable
IP masquerading as the provided bridge IP range may be routable.

Signed-off-by: Eugene Yakubovich <eugene.yakubovich@coreos.com>

Eugene Yakubovich authored on 2014/09/17 12:00:15
Showing 5 changed files
... ...
@@ -26,6 +26,7 @@ type Config struct {
26 26
 	Mirrors                     []string
27 27
 	EnableIptables              bool
28 28
 	EnableIpForward             bool
29
+	EnableIpMasq                bool
29 30
 	DefaultIp                   net.IP
30 31
 	BridgeIface                 string
31 32
 	BridgeIP                    string
... ...
@@ -49,6 +50,7 @@ func (config *Config) InstallFlags() {
49 49
 	flag.BoolVar(&config.AutoRestart, []string{"#r", "#-restart"}, true, "--restart on the daemon has been deprecated in favor of --restart policies on docker run")
50 50
 	flag.BoolVar(&config.EnableIptables, []string{"#iptables", "-iptables"}, true, "Enable Docker's addition of iptables rules")
51 51
 	flag.BoolVar(&config.EnableIpForward, []string{"#ip-forward", "-ip-forward"}, true, "Enable net.ipv4.ip_forward")
52
+	flag.BoolVar(&config.EnableIpMasq, []string{"-ip-masq"}, true, "Enable IP masquerading for bridge's IP range")
52 53
 	flag.StringVar(&config.BridgeIP, []string{"#bip", "-bip"}, "", "Use this CIDR notation address for the network bridge's IP, not compatible with -b")
53 54
 	flag.StringVar(&config.BridgeIface, []string{"b", "-bridge"}, "", "Attach containers to a pre-existing network bridge\nuse 'none' to disable container networking")
54 55
 	flag.BoolVar(&config.InterContainerCommunication, []string{"#icc", "-icc"}, true, "Enable inter-container communication")
... ...
@@ -695,6 +695,9 @@ func NewDaemonFromDirectory(config *Config, eng *engine.Engine) (*Daemon, error)
695 695
 	if !config.EnableIptables && !config.InterContainerCommunication {
696 696
 		return nil, fmt.Errorf("You specified --iptables=false with --icc=false. ICC uses iptables to function. Please set --icc or --iptables to true.")
697 697
 	}
698
+	if !config.EnableIptables && config.EnableIpMasq {
699
+		return nil, fmt.Errorf("You specified --iptables=false with --ipmasq=true. IP masquerading uses iptables to function. Please set --ipmasq to false or --iptables to true.")
700
+	}
698 701
 	config.DisableNetwork = config.BridgeIface == disableNetworkBridge
699 702
 
700 703
 	// Claim the pidfile first, to avoid any and all unexpected race conditions.
... ...
@@ -805,6 +808,7 @@ func NewDaemonFromDirectory(config *Config, eng *engine.Engine) (*Daemon, error)
805 805
 		job.SetenvBool("EnableIptables", config.EnableIptables)
806 806
 		job.SetenvBool("InterContainerCommunication", config.InterContainerCommunication)
807 807
 		job.SetenvBool("EnableIpForward", config.EnableIpForward)
808
+		job.SetenvBool("EnableIpMasq", config.EnableIpMasq)
808 809
 		job.Setenv("BridgeIface", config.BridgeIface)
809 810
 		job.Setenv("BridgeIP", config.BridgeIP)
810 811
 		job.Setenv("DefaultBindingIP", config.DefaultIp.String())
... ...
@@ -81,6 +81,7 @@ func InitDriver(job *engine.Job) engine.Status {
81 81
 		network        *net.IPNet
82 82
 		enableIPTables = job.GetenvBool("EnableIptables")
83 83
 		icc            = job.GetenvBool("InterContainerCommunication")
84
+		ipMasq         = job.GetenvBool("EnableIpMasq")
84 85
 		ipForward      = job.GetenvBool("EnableIpForward")
85 86
 		bridgeIP       = job.Getenv("BridgeIP")
86 87
 	)
... ...
@@ -131,7 +132,7 @@ func InitDriver(job *engine.Job) engine.Status {
131 131
 
132 132
 	// Configure iptables for link support
133 133
 	if enableIPTables {
134
-		if err := setupIPTables(addr, icc); err != nil {
134
+		if err := setupIPTables(addr, icc, ipMasq); err != nil {
135 135
 			return job.Error(err)
136 136
 		}
137 137
 	}
... ...
@@ -174,15 +175,18 @@ func InitDriver(job *engine.Job) engine.Status {
174 174
 	return engine.StatusOK
175 175
 }
176 176
 
177
-func setupIPTables(addr net.Addr, icc bool) error {
177
+func setupIPTables(addr net.Addr, icc, ipmasq bool) error {
178 178
 	// Enable NAT
179
-	natArgs := []string{"POSTROUTING", "-t", "nat", "-s", addr.String(), "!", "-o", bridgeIface, "-j", "MASQUERADE"}
180 179
 
181
-	if !iptables.Exists(natArgs...) {
182
-		if output, err := iptables.Raw(append([]string{"-I"}, natArgs...)...); err != nil {
183
-			return fmt.Errorf("Unable to enable network bridge NAT: %s", err)
184
-		} else if len(output) != 0 {
185
-			return fmt.Errorf("Error iptables postrouting: %s", output)
180
+	if ipmasq {
181
+		natArgs := []string{"POSTROUTING", "-t", "nat", "-s", addr.String(), "!", "-o", bridgeIface, "-j", "MASQUERADE"}
182
+
183
+		if !iptables.Exists(natArgs...) {
184
+			if output, err := iptables.Raw(append([]string{"-I"}, natArgs...)...); err != nil {
185
+				return fmt.Errorf("Unable to enable network bridge NAT: %s", err)
186
+			} else if len(output) != 0 {
187
+				return fmt.Errorf("Error iptables postrouting: %s", output)
188
+			}
186 189
 		}
187 190
 	}
188 191
 
... ...
@@ -55,6 +55,9 @@ unix://[/path/to/socket] to use.
55 55
 **--ip**=""
56 56
   Default IP address to use when binding container ports. Default is `0.0.0.0`.
57 57
 
58
+**--ip-masq**=*true*|*false*
59
+  Enable IP masquerading for bridge's IP range. Default is true.
60
+
58 61
 **--iptables**=*true*|*false*
59 62
   Disable Docker's addition of iptables rules. Default is true.
60 63
 
... ...
@@ -67,6 +67,7 @@ expect an integer, and they can only be specified once.
67 67
       --icc=true                                 Enable inter-container communication
68 68
       --ip=0.0.0.0                               Default IP address to use when binding container ports
69 69
       --ip-forward=true                          Enable net.ipv4.ip_forward
70
+      --ip-masq=true                             Enable IP masquerading for bridge's IP range.
70 71
       --iptables=true                            Enable Docker's addition of iptables rules
71 72
       --mtu=0                                    Set the containers network MTU
72 73
                                                    if no value is provided: default to the default route MTU or 1500 if no default route is available
... ...
@@ -110,6 +111,10 @@ the `-H` flag for the client.
110 110
     $ sudo docker ps
111 111
     # both are equal
112 112
 
113
+IP masquerading uses address translation to allow containers without a public IP to talk
114
+to other machines on the Internet. This may interfere with some network topologies and
115
+can be disabled with --ip-masq=false.
116
+
113 117
 To run the daemon with [systemd socket activation](
114 118
 http://0pointer.de/blog/projects/socket-activation.html), use
115 119
 `docker -d -H fd://`. Using `fd://` will work perfectly for most setups but