From fca0b18dcba99a7fbb8b430a55dc7bf60d5c1356 Mon Sep 17 00:00:00 2001 From: Aaron Lehmann Date: Thu, 21 Jul 2016 10:40:19 -0700 Subject: [PATCH] Require listen address and advertise address to be an IP address or an interface name Hostnames are not supported for now because libnetwork can't use them for overlay networking yet. Signed-off-by: Aaron Lehmann --- api/client/swarm/init.go | 4 +-- api/client/swarm/join.go | 4 +-- daemon/cluster/listen_addr.go | 26 ++++++++++++++++--- docs/reference/api/docker_remote_api_v1.24.md | 12 +++++++++ docs/reference/api/docker_remote_api_v1.25.md | 12 +++++++++ docs/reference/commandline/swarm_init.md | 8 +++--- docs/reference/commandline/swarm_join.md | 8 +++--- man/dockerd.8.md | 4 +-- 8 files changed, 60 insertions(+), 18 deletions(-) diff --git a/api/client/swarm/init.go b/api/client/swarm/init.go index d543610422..0555243f0d 100644 --- a/api/client/swarm/init.go +++ b/api/client/swarm/init.go @@ -44,8 +44,8 @@ func newInitCommand(dockerCli *client.DockerCli) *cobra.Command { } flags := cmd.Flags() - flags.Var(&opts.listenAddr, flagListenAddr, "Listen address (format: [:port])") - flags.StringVar(&opts.advertiseAddr, flagAdvertiseAddr, "", "Advertised address (format: [:port])") + flags.Var(&opts.listenAddr, flagListenAddr, "Listen address (format: [:port])") + flags.StringVar(&opts.advertiseAddr, flagAdvertiseAddr, "", "Advertised address (format: [:port])") flags.BoolVar(&opts.forceNewCluster, "force-new-cluster", false, "Force create a new cluster from current state.") addSwarmFlags(flags, &opts.swarmOptions) return cmd diff --git a/api/client/swarm/join.go b/api/client/swarm/join.go index 504cc790f8..de2e15ab23 100644 --- a/api/client/swarm/join.go +++ b/api/client/swarm/join.go @@ -35,8 +35,8 @@ func newJoinCommand(dockerCli *client.DockerCli) *cobra.Command { } flags := cmd.Flags() - flags.Var(&opts.listenAddr, flagListenAddr, "Listen address (format: [:port])") - flags.StringVar(&opts.advertiseAddr, flagAdvertiseAddr, "", "Advertised address (format: [:port])") + flags.Var(&opts.listenAddr, flagListenAddr, "Listen address (format: [:port])") + flags.StringVar(&opts.advertiseAddr, flagAdvertiseAddr, "", "Advertised address (format: [:port])") flags.StringVar(&opts.token, flagToken, "", "Token for entry into the swarm") return cmd } diff --git a/daemon/cluster/listen_addr.go b/daemon/cluster/listen_addr.go index b293a290b1..c3dbe083ea 100644 --- a/daemon/cluster/listen_addr.go +++ b/daemon/cluster/listen_addr.go @@ -7,10 +7,13 @@ import ( ) var ( - errNoSuchInterface = errors.New("no such interface") - errMultipleIPs = errors.New("could not choose an IP address to advertise since this system has multiple addresses") - errNoIP = errors.New("could not find the system's IP address") - errMustSpecifyListenAddr = errors.New("must specify a listening address because the address to advertise is not recognized as a system address") + errNoSuchInterface = errors.New("no such interface") + errMultipleIPs = errors.New("could not choose an IP address to advertise since this system has multiple addresses") + errNoIP = errors.New("could not find the system's IP address") + errMustSpecifyListenAddr = errors.New("must specify a listening address because the address to advertise is not recognized as a system address") + errBadListenAddr = errors.New("listen address must be an IP address or network interface (with optional port number)") + errBadAdvertiseAddr = errors.New("advertise address must be an IP address or network interface (with optional port number)") + errBadDefaultAdvertiseAddr = errors.New("default advertise address must be an IP address or network interface (without a port number)") ) func resolveListenAddr(specifiedAddr string) (string, string, error) { @@ -29,6 +32,11 @@ func resolveListenAddr(specifiedAddr string) (string, string, error) { return "", "", err } + // If it's not an interface, it must be an IP (for now) + if net.ParseIP(specifiedHost) == nil { + return "", "", errBadListenAddr + } + return specifiedHost, specifiedPort, nil } @@ -61,6 +69,11 @@ func (c *Cluster) resolveAdvertiseAddr(advertiseAddr, listenAddrPort string) (st return "", "", err } + // If it's not an interface, it must be an IP (for now) + if net.ParseIP(advertiseHost) == nil { + return "", "", errBadAdvertiseAddr + } + return advertiseHost, advertisePort, nil } @@ -76,6 +89,11 @@ func (c *Cluster) resolveAdvertiseAddr(advertiseAddr, listenAddrPort string) (st return "", "", err } + // If it's not an interface, it must be an IP (for now) + if net.ParseIP(c.config.DefaultAdvertiseAddr) == nil { + return "", "", errBadDefaultAdvertiseAddr + } + return c.config.DefaultAdvertiseAddr, listenAddrPort, nil } diff --git a/docs/reference/api/docker_remote_api_v1.24.md b/docs/reference/api/docker_remote_api_v1.24.md index e17263dbe5..7267f2da0d 100644 --- a/docs/reference/api/docker_remote_api_v1.24.md +++ b/docs/reference/api/docker_remote_api_v1.24.md @@ -3591,6 +3591,7 @@ Initialize a new Swarm { "ListenAddr": "0.0.0.0:4500", + "AdvertiseAddr": "192.168.1.1:4500", "ForceNewCluster": false, "Spec": { "Orchestration": {}, @@ -3619,6 +3620,11 @@ JSON Parameters: address/port combination in the form `192.168.1.1:4567`, or an interface followed by a port number, like `eth0:4567`. If the port number is omitted, the default swarm listening port is used. +- **AdvertiseAddr** – Externally reachable address advertised to other nodes. This can either be + an address/port combination in the form `192.168.1.1:4567`, or an interface followed by a port + number, like `eth0:4567`. If the port number is omitted, the port number from the listen + address is used. If `AdvertiseAddr` is not specified, it will be automatically detected when + possible. - **ForceNewCluster** – Force creating a new Swarm even if already part of one. - **Spec** – Configuration settings of the new Swarm. - **Orchestration** – Configuration settings for the orchestration aspects of the Swarm. @@ -3659,6 +3665,7 @@ Join an existing new Swarm { "ListenAddr": "0.0.0.0:4500", + "AdvertiseAddr: "192.168.1.1:4500", "RemoteAddrs": ["node1:4500"], "JoinToken": "SWMTKN-1-3pu6hszjas19xyp7ghgosyx9k8atbfcr8p2is99znpy26u2lkl-7p73s1dx5in4tatdymyhg9hu2" } @@ -3679,6 +3686,11 @@ JSON Parameters: - **ListenAddr** – Listen address used for inter-manager communication if the node gets promoted to manager, as well as determining the networking interface used for the VXLAN Tunnel Endpoint (VTEP). +- **AdvertiseAddr** – Externally reachable address advertised to other nodes. This can either be + an address/port combination in the form `192.168.1.1:4567`, or an interface followed by a port + number, like `eth0:4567`. If the port number is omitted, the port number from the listen + address is used. If `AdvertiseAddr` is not specified, it will be automatically detected when + possible. - **RemoteAddr** – Address of any manager node already participating in the Swarm to join. - **JoinToken** – Secret token for joining this Swarm. diff --git a/docs/reference/api/docker_remote_api_v1.25.md b/docs/reference/api/docker_remote_api_v1.25.md index 0d9c1d7e86..04a5d0c416 100644 --- a/docs/reference/api/docker_remote_api_v1.25.md +++ b/docs/reference/api/docker_remote_api_v1.25.md @@ -3592,6 +3592,7 @@ Initialize a new Swarm { "ListenAddr": "0.0.0.0:4500", + "AdvertiseAddr": "192.168.1.1:4500", "ForceNewCluster": false, "Spec": { "Orchestration": {}, @@ -3620,6 +3621,11 @@ JSON Parameters: address/port combination in the form `192.168.1.1:4567`, or an interface followed by a port number, like `eth0:4567`. If the port number is omitted, the default swarm listening port is used. +- **AdvertiseAddr** – Externally reachable address advertised to other nodes. This can either be + an address/port combination in the form `192.168.1.1:4567`, or an interface followed by a port + number, like `eth0:4567`. If the port number is omitted, the port number from the listen + address is used. If `AdvertiseAddr` is not specified, it will be automatically detected when + possible. - **ForceNewCluster** – Force creating a new Swarm even if already part of one. - **Spec** – Configuration settings of the new Swarm. - **Orchestration** – Configuration settings for the orchestration aspects of the Swarm. @@ -3660,6 +3666,7 @@ Join an existing new Swarm { "ListenAddr": "0.0.0.0:4500", + "AdvertiseAddr": "192.168.1.1:4500", "RemoteAddrs": ["node1:4500"], "JoinToken": "SWMTKN-1-3pu6hszjas19xyp7ghgosyx9k8atbfcr8p2is99znpy26u2lkl-7p73s1dx5in4tatdymyhg9hu2" } @@ -3680,6 +3687,11 @@ JSON Parameters: - **ListenAddr** – Listen address used for inter-manager communication if the node gets promoted to manager, as well as determining the networking interface used for the VXLAN Tunnel Endpoint (VTEP). +- **AdvertiseAddr** – Externally reachable address advertised to other nodes. This can either be + an address/port combination in the form `192.168.1.1:4567`, or an interface followed by a port + number, like `eth0:4567`. If the port number is omitted, the port number from the listen + address is used. If `AdvertiseAddr` is not specified, it will be automatically detected when + possible. - **RemoteAddr** – Address of any manager node already participating in the Swarm to join. - **JoinToken** – Secret token for joining this Swarm. diff --git a/docs/reference/commandline/swarm_init.md b/docs/reference/commandline/swarm_init.md index 8d9687abce..6534cba5de 100644 --- a/docs/reference/commandline/swarm_init.md +++ b/docs/reference/commandline/swarm_init.md @@ -17,13 +17,13 @@ Usage: docker swarm init [OPTIONS] Initialize a swarm Options: - --advertise-addr value Advertised address (format: [:port]) + --advertise-addr value Advertised address (format: [:port]) --cert-expiry duration Validity period for node certificates (default 2160h0m0s) --dispatcher-heartbeat duration Dispatcher heartbeat period (default 5s) --external-ca value Specifications of one or more certificate signing endpoints --force-new-cluster Force create a new cluster from current state. --help Print usage - --listen-addr value Listen address (format: [:port]) + --listen-addr value Listen address (format: [:port]) --task-history-limit int Task history retention limit (default 5) ``` @@ -79,7 +79,7 @@ The node listens for inbound Swarm manager traffic on this address. The default 0.0.0.0:2377. It is also possible to specify a network interface to listen on that interface's address; for example `--listen-addr eth0:2377`. -Specifying a port is optional. If the value is a bare IP address, hostname, or interface +Specifying a port is optional. If the value is a bare IP address or interface name, the default port 2377 will be used. ### `--advertise-addr value` @@ -94,7 +94,7 @@ inter-manager communication and overlay networking. It is also possible to specify a network interface to advertise that interface's address; for example `--advertise-addr eth0:2377`. -Specifying a port is optional. If the value is a bare IP address, hostname, or interface +Specifying a port is optional. If the value is a bare IP address or interface name, the default port 2377 will be used. ### `--task-history-limit` diff --git a/docs/reference/commandline/swarm_join.md b/docs/reference/commandline/swarm_join.md index 42638c09ae..9f5ff1dda8 100644 --- a/docs/reference/commandline/swarm_join.md +++ b/docs/reference/commandline/swarm_join.md @@ -17,9 +17,9 @@ Usage: docker swarm join [OPTIONS] HOST:PORT Join a swarm as a node and/or manager Options: - --advertise-addr value Advertised address (format: [:port]) + --advertise-addr value Advertised address (format: [:port]) --help Print usage - --listen-addr value Listen address + --listen-addr value Listen address (format: [:port) --token string Token for entry into the swarm ``` @@ -64,7 +64,7 @@ If the node is a manager, it will listen for inbound Swarm manager traffic on th address. The default is to listen on 0.0.0.0:2377. It is also possible to specify a network interface to listen on that interface's address; for example `--listen-addr eth0:2377`. -Specifying a port is optional. If the value is a bare IP address, hostname, or interface +Specifying a port is optional. If the value is a bare IP address, or interface name, the default port 2377 will be used. This flag is generally not necessary when joining an existing swarm. @@ -81,7 +81,7 @@ communication and overlay networking. It is also possible to specify a network interface to advertise that interface's address; for example `--advertise-addr eth0:2377`. -Specifying a port is optional. If the value is a bare IP address, hostname, or interface +Specifying a port is optional. If the value is a bare IP address, or interface name, the default port 2377 will be used. This flag is generally not necessary when joining an existing swarm. diff --git a/man/dockerd.8.md b/man/dockerd.8.md index 15e2d9635a..a098a708a3 100644 --- a/man/dockerd.8.md +++ b/man/dockerd.8.md @@ -55,7 +55,7 @@ dockerd - Enable daemon mode [**-s**|**--storage-driver**[=*STORAGE-DRIVER*]] [**--selinux-enabled**] [**--storage-opt**[=*[]*]] -[**--swarm-default-advertise-addr**[=*IP|HOSTNAME|INTERFACE*]] +[**--swarm-default-advertise-addr**[=*IP|INTERFACE*]] [**--tls**] [**--tlscacert**[=*~/.docker/ca.pem*]] [**--tlscert**[=*~/.docker/cert.pem*]] @@ -240,7 +240,7 @@ output otherwise. **--storage-opt**=[] Set storage driver options. See STORAGE DRIVER OPTIONS. -**--swarm-default-advertise-addr**=*IP|HOSTNAME|INTERFACE* +**--swarm-default-advertise-addr**=*IP|INTERFACE* Set default address or interface for swarm to advertise as its externally-reachable address to other cluster members. This can be a hostname, an IP address, or an interface such as `eth0`. A port cannot be specified with this option.