From 4dc4d56db9797159e2e329845e0b94e3e0f780a0 Mon Sep 17 00:00:00 2001 From: Eugene Yakubovich Date: Tue, 16 Sep 2014 20:00:15 -0700 Subject: [PATCH] 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 --- daemon/config.go | 2 ++ daemon/daemon.go | 4 ++++ daemon/networkdriver/bridge/driver.go | 20 ++++++++++++-------- docs/man/docker.1.md | 3 +++ docs/sources/reference/commandline/cli.md | 5 +++++ 5 files changed, 26 insertions(+), 8 deletions(-) diff --git a/daemon/config.go b/daemon/config.go index 00ebc7a74d..c7c4d90150 100644 --- a/daemon/config.go +++ b/daemon/config.go @@ -26,6 +26,7 @@ type Config struct { Mirrors []string EnableIptables bool EnableIpForward bool + EnableIpMasq bool DefaultIp net.IP BridgeIface 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.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.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.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") diff --git a/daemon/daemon.go b/daemon/daemon.go index aef5a1a07d..5529f4b195 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -695,6 +695,9 @@ func NewDaemonFromDirectory(config *Config, eng *engine.Engine) (*Daemon, error) 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.") } + 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 // 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("InterContainerCommunication", config.InterContainerCommunication) job.SetenvBool("EnableIpForward", config.EnableIpForward) + job.SetenvBool("EnableIpMasq", config.EnableIpMasq) job.Setenv("BridgeIface", config.BridgeIface) job.Setenv("BridgeIP", config.BridgeIP) job.Setenv("DefaultBindingIP", config.DefaultIp.String()) diff --git a/daemon/networkdriver/bridge/driver.go b/daemon/networkdriver/bridge/driver.go index 06cf37e79f..f44e81ad62 100644 --- a/daemon/networkdriver/bridge/driver.go +++ b/daemon/networkdriver/bridge/driver.go @@ -81,6 +81,7 @@ func InitDriver(job *engine.Job) engine.Status { network *net.IPNet enableIPTables = job.GetenvBool("EnableIptables") icc = job.GetenvBool("InterContainerCommunication") + ipMasq = job.GetenvBool("EnableIpMasq") ipForward = job.GetenvBool("EnableIpForward") bridgeIP = job.Getenv("BridgeIP") ) @@ -131,7 +132,7 @@ func InitDriver(job *engine.Job) engine.Status { // Configure iptables for link support if enableIPTables { - if err := setupIPTables(addr, icc); err != nil { + if err := setupIPTables(addr, icc, ipMasq); err != nil { return job.Error(err) } } @@ -174,15 +175,18 @@ func InitDriver(job *engine.Job) engine.Status { return engine.StatusOK } -func setupIPTables(addr net.Addr, icc bool) error { +func setupIPTables(addr net.Addr, icc, ipmasq bool) error { // 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) + } } } diff --git a/docs/man/docker.1.md b/docs/man/docker.1.md index 9a4682d010..54ce050470 100644 --- a/docs/man/docker.1.md +++ b/docs/man/docker.1.md @@ -55,6 +55,9 @@ unix://[/path/to/socket] to use. **--ip**="" 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* Disable Docker's addition of iptables rules. Default is true. diff --git a/docs/sources/reference/commandline/cli.md b/docs/sources/reference/commandline/cli.md index a566bf6820..3f9923e5bd 100644 --- a/docs/sources/reference/commandline/cli.md +++ b/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 --ip=0.0.0.0 Default IP address to use when binding container ports --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 --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 @@ -110,6 +111,10 @@ the `-H` flag for the client. $ sudo docker ps # 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]( http://0pointer.de/blog/projects/socket-activation.html), use `docker -d -H fd://`. Using `fd://` will work perfectly for most setups but