Преглед изворни кода

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 пре 10 година
родитељ
комит
4dc4d56db9

+ 2 - 0
daemon/config.go

@@ -26,6 +26,7 @@ type Config struct {
 	Mirrors                     []string
 	Mirrors                     []string
 	EnableIptables              bool
 	EnableIptables              bool
 	EnableIpForward             bool
 	EnableIpForward             bool
+	EnableIpMasq                bool
 	DefaultIp                   net.IP
 	DefaultIp                   net.IP
 	BridgeIface                 string
 	BridgeIface                 string
 	BridgeIP                    string
 	BridgeIP                    string
@@ -49,6 +50,7 @@ func (config *Config) InstallFlags() {
 	flag.BoolVar(&config.AutoRestart, []string{"#r", "#-restart"}, true, "--restart on the daemon has been deprecated in favor of --restart policies on docker run")
 	flag.BoolVar(&config.AutoRestart, []string{"#r", "#-restart"}, true, "--restart on the daemon has been deprecated in favor of --restart policies on docker run")
 	flag.BoolVar(&config.EnableIptables, []string{"#iptables", "-iptables"}, true, "Enable Docker's addition of iptables rules")
 	flag.BoolVar(&config.EnableIptables, []string{"#iptables", "-iptables"}, true, "Enable Docker's addition of iptables rules")
 	flag.BoolVar(&config.EnableIpForward, []string{"#ip-forward", "-ip-forward"}, true, "Enable net.ipv4.ip_forward")
 	flag.BoolVar(&config.EnableIpForward, []string{"#ip-forward", "-ip-forward"}, true, "Enable net.ipv4.ip_forward")
+	flag.BoolVar(&config.EnableIpMasq, []string{"-ip-masq"}, true, "Enable IP masquerading for bridge's IP range")
 	flag.StringVar(&config.BridgeIP, []string{"#bip", "-bip"}, "", "Use this CIDR notation address for the network bridge's IP, not compatible with -b")
 	flag.StringVar(&config.BridgeIP, []string{"#bip", "-bip"}, "", "Use this CIDR notation address for the network bridge's IP, not compatible with -b")
 	flag.StringVar(&config.BridgeIface, []string{"b", "-bridge"}, "", "Attach containers to a pre-existing network bridge\nuse 'none' to disable container networking")
 	flag.StringVar(&config.BridgeIface, []string{"b", "-bridge"}, "", "Attach containers to a pre-existing network bridge\nuse 'none' to disable container networking")
 	flag.BoolVar(&config.InterContainerCommunication, []string{"#icc", "-icc"}, true, "Enable inter-container communication")
 	flag.BoolVar(&config.InterContainerCommunication, []string{"#icc", "-icc"}, true, "Enable inter-container communication")

+ 4 - 0
daemon/daemon.go

@@ -695,6 +695,9 @@ func NewDaemonFromDirectory(config *Config, eng *engine.Engine) (*Daemon, error)
 	if !config.EnableIptables && !config.InterContainerCommunication {
 	if !config.EnableIptables && !config.InterContainerCommunication {
 		return nil, fmt.Errorf("You specified --iptables=false with --icc=false. ICC uses iptables to function. Please set --icc or --iptables to true.")
 		return nil, fmt.Errorf("You specified --iptables=false with --icc=false. ICC uses iptables to function. Please set --icc or --iptables to true.")
 	}
 	}
+	if !config.EnableIptables && config.EnableIpMasq {
+		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.")
+	}
 	config.DisableNetwork = config.BridgeIface == disableNetworkBridge
 	config.DisableNetwork = config.BridgeIface == disableNetworkBridge
 
 
 	// Claim the pidfile first, to avoid any and all unexpected race conditions.
 	// 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)
 		job.SetenvBool("EnableIptables", config.EnableIptables)
 		job.SetenvBool("EnableIptables", config.EnableIptables)
 		job.SetenvBool("InterContainerCommunication", config.InterContainerCommunication)
 		job.SetenvBool("InterContainerCommunication", config.InterContainerCommunication)
 		job.SetenvBool("EnableIpForward", config.EnableIpForward)
 		job.SetenvBool("EnableIpForward", config.EnableIpForward)
+		job.SetenvBool("EnableIpMasq", config.EnableIpMasq)
 		job.Setenv("BridgeIface", config.BridgeIface)
 		job.Setenv("BridgeIface", config.BridgeIface)
 		job.Setenv("BridgeIP", config.BridgeIP)
 		job.Setenv("BridgeIP", config.BridgeIP)
 		job.Setenv("DefaultBindingIP", config.DefaultIp.String())
 		job.Setenv("DefaultBindingIP", config.DefaultIp.String())

+ 12 - 8
daemon/networkdriver/bridge/driver.go

@@ -81,6 +81,7 @@ func InitDriver(job *engine.Job) engine.Status {
 		network        *net.IPNet
 		network        *net.IPNet
 		enableIPTables = job.GetenvBool("EnableIptables")
 		enableIPTables = job.GetenvBool("EnableIptables")
 		icc            = job.GetenvBool("InterContainerCommunication")
 		icc            = job.GetenvBool("InterContainerCommunication")
+		ipMasq         = job.GetenvBool("EnableIpMasq")
 		ipForward      = job.GetenvBool("EnableIpForward")
 		ipForward      = job.GetenvBool("EnableIpForward")
 		bridgeIP       = job.Getenv("BridgeIP")
 		bridgeIP       = job.Getenv("BridgeIP")
 	)
 	)
@@ -131,7 +132,7 @@ func InitDriver(job *engine.Job) engine.Status {
 
 
 	// Configure iptables for link support
 	// Configure iptables for link support
 	if enableIPTables {
 	if enableIPTables {
-		if err := setupIPTables(addr, icc); err != nil {
+		if err := setupIPTables(addr, icc, ipMasq); err != nil {
 			return job.Error(err)
 			return job.Error(err)
 		}
 		}
 	}
 	}
@@ -174,15 +175,18 @@ func InitDriver(job *engine.Job) engine.Status {
 	return engine.StatusOK
 	return engine.StatusOK
 }
 }
 
 
-func setupIPTables(addr net.Addr, icc bool) error {
+func setupIPTables(addr net.Addr, icc, ipmasq bool) error {
 	// Enable NAT
 	// Enable NAT
-	natArgs := []string{"POSTROUTING", "-t", "nat", "-s", addr.String(), "!", "-o", bridgeIface, "-j", "MASQUERADE"}
 
 
-	if !iptables.Exists(natArgs...) {
-		if output, err := iptables.Raw(append([]string{"-I"}, natArgs...)...); err != nil {
-			return fmt.Errorf("Unable to enable network bridge NAT: %s", err)
-		} else if len(output) != 0 {
-			return fmt.Errorf("Error iptables postrouting: %s", output)
+	if ipmasq {
+		natArgs := []string{"POSTROUTING", "-t", "nat", "-s", addr.String(), "!", "-o", bridgeIface, "-j", "MASQUERADE"}
+
+		if !iptables.Exists(natArgs...) {
+			if output, err := iptables.Raw(append([]string{"-I"}, natArgs...)...); err != nil {
+				return fmt.Errorf("Unable to enable network bridge NAT: %s", err)
+			} else if len(output) != 0 {
+				return fmt.Errorf("Error iptables postrouting: %s", output)
+			}
 		}
 		}
 	}
 	}
 
 

+ 3 - 0
docs/man/docker.1.md

@@ -55,6 +55,9 @@ unix://[/path/to/socket] to use.
 **--ip**=""
 **--ip**=""
   Default IP address to use when binding container ports. Default is `0.0.0.0`.
   Default IP address to use when binding container ports. Default is `0.0.0.0`.
 
 
+**--ip-masq**=*true*|*false*
+  Enable IP masquerading for bridge's IP range. Default is true.
+
 **--iptables**=*true*|*false*
 **--iptables**=*true*|*false*
   Disable Docker's addition of iptables rules. Default is true.
   Disable Docker's addition of iptables rules. Default is true.
 
 

+ 5 - 0
docs/sources/reference/commandline/cli.md

@@ -67,6 +67,7 @@ expect an integer, and they can only be specified once.
       --icc=true                                 Enable inter-container communication
       --icc=true                                 Enable inter-container communication
       --ip=0.0.0.0                               Default IP address to use when binding container ports
       --ip=0.0.0.0                               Default IP address to use when binding container ports
       --ip-forward=true                          Enable net.ipv4.ip_forward
       --ip-forward=true                          Enable net.ipv4.ip_forward
+      --ip-masq=true                             Enable IP masquerading for bridge's IP range.
       --iptables=true                            Enable Docker's addition of iptables rules
       --iptables=true                            Enable Docker's addition of iptables rules
       --mtu=0                                    Set the containers network MTU
       --mtu=0                                    Set the containers network MTU
                                                    if no value is provided: default to the default route MTU or 1500 if no default route is available
                                                    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.
     $ sudo docker ps
     $ sudo docker ps
     # both are equal
     # both are equal
 
 
+IP masquerading uses address translation to allow containers without a public IP to talk
+to other machines on the Internet. This may interfere with some network topologies and
+can be disabled with --ip-masq=false.
+
 To run the daemon with [systemd socket activation](
 To run the daemon with [systemd socket activation](
 http://0pointer.de/blog/projects/socket-activation.html), use
 http://0pointer.de/blog/projects/socket-activation.html), use
 `docker -d -H fd://`. Using `fd://` will work perfectly for most setups but
 `docker -d -H fd://`. Using `fd://` will work perfectly for most setups but