Browse code

Default the tcp port to 2376 if tls is on, and 2375 if not

Refactor so that the Host flag validation doesn't destroy the user's input,
and then post process the flags when we know the TLS options

Signed-off-by: Sven Dowideit <SvenDowideit@home.org.au>

Sven Dowideit authored on 2015/08/21 22:28:49
Showing 8 changed files
... ...
@@ -106,13 +106,6 @@ func NewDockerCli(in io.ReadCloser, out, err io.Writer, clientFlags *cli.ClientF
106 106
 		switch len(hosts) {
107 107
 		case 0:
108 108
 			defaultHost := os.Getenv("DOCKER_HOST")
109
-			if defaultHost == "" {
110
-				defaultHost = opts.DefaultHost
111
-			}
112
-			defaultHost, err := opts.ValidateHost(defaultHost)
113
-			if err != nil {
114
-				return err
115
-			}
116 109
 			hosts = []string{defaultHost}
117 110
 		case 1:
118 111
 			// only accept one host to talk to
... ...
@@ -120,6 +113,15 @@ func NewDockerCli(in io.ReadCloser, out, err io.Writer, clientFlags *cli.ClientF
120 120
 			return errors.New("Please specify only one -H")
121 121
 		}
122 122
 
123
+		defaultHost := opts.DefaultTCPHost
124
+		if clientFlags.Common.TLSOptions != nil {
125
+			defaultHost = opts.DefaultTLSHost
126
+		}
127
+		var e error
128
+		if hosts[0], e = opts.ParseHost(defaultHost, hosts[0]); e != nil {
129
+			return e
130
+		}
131
+
123 132
 		protoAddrParts := strings.SplitN(hosts[0], "://", 2)
124 133
 		cli.proto, cli.addr = protoAddrParts[0], protoAddrParts[1]
125 134
 
... ...
@@ -169,9 +169,6 @@ func (cli *DaemonCli) CmdDaemon(args ...string) error {
169 169
 	daemonFlags.ParseFlags(args, true)
170 170
 	commonFlags.PostParse()
171 171
 
172
-	if len(commonFlags.Hosts) == 0 {
173
-		commonFlags.Hosts = []string{opts.DefaultHost}
174
-	}
175 172
 	if commonFlags.TrustKey == "" {
176 173
 		commonFlags.TrustKey = filepath.Join(getDaemonConfDir(), defaultTrustKeyFile)
177 174
 	}
... ...
@@ -212,6 +209,7 @@ func (cli *DaemonCli) CmdDaemon(args ...string) error {
212 212
 	}
213 213
 	serverConfig = setPlatformServerConfig(serverConfig, cli.Config)
214 214
 
215
+	defaultHost := opts.DefaultHost
215 216
 	if commonFlags.TLSOptions != nil {
216 217
 		if !commonFlags.TLSOptions.InsecureSkipVerify {
217 218
 			// server requires and verifies client's certificate
... ...
@@ -222,6 +220,14 @@ func (cli *DaemonCli) CmdDaemon(args ...string) error {
222 222
 			logrus.Fatal(err)
223 223
 		}
224 224
 		serverConfig.TLSConfig = tlsConfig
225
+		defaultHost = opts.DefaultTLSHost
226
+	}
227
+
228
+	for i := 0; i < len(commonFlags.Hosts); i++ {
229
+		var err error
230
+		if commonFlags.Hosts[i], err = opts.ParseHost(defaultHost, commonFlags.Hosts[i]); err != nil {
231
+			logrus.Fatalf("error parsing -H %s : %v", commonFlags.Hosts[i], err)
232
+		}
225 233
 	}
226 234
 	for _, protoAddr := range commonFlags.Hosts {
227 235
 		protoAddrParts := strings.SplitN(protoAddr, "://", 2)
... ...
@@ -82,13 +82,17 @@ then it is trivial for someone to gain root access to the host where the
82 82
 daemon is running.
83 83
 
84 84
 Similarly, the Docker client can use `-H` to connect to a custom port.
85
+The Docker client will default to connecting to `unix:///var/run/docker.sock`
86
+on Linux, and `tcp://127.0.0.1:2376` on Windows.
85 87
 
86 88
 `-H` accepts host and port assignment in the following format:
87 89
 
88
-    tcp://[host][:port][path] or unix://path
90
+    tcp://[host]:[port][path] or unix://path
89 91
 
90 92
 For example:
91 93
 
94
+-   `tcp://` -> TCP connection to `127.0.0.1` on either port `2376` when TLS encryption
95
+    is on, or port `2375` when communication is in plain text.
92 96
 -   `tcp://host:2375` -> TCP connection on
93 97
     host:2375
94 98
 -   `tcp://host:2375/path` -> TCP connection on
... ...
@@ -101,7 +105,7 @@ when no `-H` was passed in.
101 101
 
102 102
 `-H` also accepts short form for TCP bindings:
103 103
 
104
-    host[:port] or :port
104
+    `host:` or `host:port` or `:port`
105 105
 
106 106
 Run Docker in daemon mode:
107 107
 
... ...
@@ -265,9 +265,11 @@ Docker uses a bridge to manage container networking. By default, UFW drops all
265 265
 forwarding traffic. As a result, for Docker to run when UFW is
266 266
 enabled, you must set UFW's forwarding policy appropriately.
267 267
 
268
-Also, UFW's default set of rules denies all incoming traffic. If you want to be able
269
-to reach your containers from another host then you should also allow incoming
270
-connections on the Docker port (default `2375`).
268
+Also, UFW's default set of rules denies all incoming traffic. If you want to
269
+reach your containers from another host allow incoming connections on the Docker
270
+port. The Docker port defaults to `2376` if TLS is enabled or `2375` when it is
271
+not. If TLS is not enabled, communication is unencrypted. By default, Docker
272
+runs without TLS enabled.
271 273
 
272 274
 To configure UFW and allow incoming connections on the Docker port:
273 275
 
... ...
@@ -18,7 +18,7 @@ or execute `docker help`:
18 18
              docker daemon [ --help | ... ]
19 19
              docker [ --help | -v | --version ]
20 20
 
21
-        -H, --host=[]: The socket(s) to bind to in daemon mode, specified using one or more tcp://host:port, unix:///path/to/socket, fd://* or fd://socketfd.
21
+        -H, --host=[]: The socket(s) to talk to the Docker daemon in the format of tcp://host:port/path, unix:///path/to/socket, fd://* or fd://socketfd.
22 22
 
23 23
       A self-sufficient runtime for Linux containers.
24 24
 
... ...
@@ -36,10 +36,12 @@ To see the man page for a command run **man docker <command>**.
36 36
 **-D**, **--debug**=*true*|*false*
37 37
   Enable debug mode. Default is false.
38 38
 
39
-**-H**, **--host**=[unix:///var/run/docker.sock]: tcp://[host:port] to bind or
39
+**-H**, **--host**=[unix:///var/run/docker.sock]: tcp://[host]:[port][path] to bind or
40 40
 unix://[/path/to/socket] to use.
41 41
   The socket(s) to bind to in daemon mode specified using one or more
42
-  tcp://host:port, unix:///path/to/socket, fd://* or fd://socketfd.
42
+  tcp://host:port/path, unix:///path/to/socket, fd://* or fd://socketfd.
43
+  If the tcp port is not specified, then it will default to either `2375` when
44
+  `--tls` is off, or `2376` when `--tls` is on, or `--tlsverify` is specified.
43 45
 
44 46
 **-l**, **--log-level**="*debug*|*info*|*warn*|*error*|*fatal*""
45 47
   Set the logging level. Default is `info`.
... ...
@@ -17,16 +17,23 @@ var (
17 17
 	domainRegexp = regexp.MustCompile(`^(:?(:?[a-zA-Z0-9]|(:?[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9]))(:?\.(:?[a-zA-Z0-9]|(:?[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])))*)\.?\s*$`)
18 18
 	// DefaultHTTPHost Default HTTP Host used if only port is provided to -H flag e.g. docker daemon -H tcp://:8080
19 19
 	DefaultHTTPHost = "127.0.0.1"
20
+
20 21
 	// DefaultHTTPPort Default HTTP Port used if only the protocol is provided to -H flag e.g. docker daemon -H tcp://
21 22
 	// TODO Windows. DefaultHTTPPort is only used on Windows if a -H parameter
22 23
 	// is not supplied. A better longer term solution would be to use a named
23 24
 	// pipe as the default on the Windows daemon.
25
+	// These are the IANA registered port numbers for use with Docker
26
+	// see http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml?search=docker
24 27
 	DefaultHTTPPort = 2375 // Default HTTP Port
28
+	// DefaultTLSHTTPPort Default HTTP Port used when TLS enabled
29
+	DefaultTLSHTTPPort = 2376 // Default TLS encrypted HTTP Port
25 30
 	// DefaultUnixSocket Path for the unix socket.
26 31
 	// Docker daemon by default always listens on the default unix socket
27 32
 	DefaultUnixSocket = "/var/run/docker.sock"
28 33
 	// DefaultTCPHost constant defines the default host string used by docker on Windows
29 34
 	DefaultTCPHost = fmt.Sprintf("tcp://%s:%d", DefaultHTTPHost, DefaultHTTPPort)
35
+	// DefaultTLSHost constant defines the default host string used by docker for TLS sockets
36
+	DefaultTLSHost = fmt.Sprintf("tcp://%s:%d", DefaultHTTPHost, DefaultTLSHTTPPort)
30 37
 )
31 38
 
32 39
 // ListOpts holds a list of values and a validation function.
... ...
@@ -335,6 +342,17 @@ func ValidateLabel(val string) (string, error) {
335 335
 
336 336
 // ValidateHost validates that the specified string is a valid host and returns it.
337 337
 func ValidateHost(val string) (string, error) {
338
+	_, err := parsers.ParseDockerDaemonHost(DefaultTCPHost, DefaultUnixSocket, val)
339
+	if err != nil {
340
+		return val, err
341
+	}
342
+	// Note: unlike most flag validators, we don't return the mutated value here
343
+	//       we need to know what the user entered later (using ParseHost) to adjust for tls
344
+	return val, nil
345
+}
346
+
347
+// ParseHost and set defaults for a Daemon host string
348
+func ParseHost(defaultHTTPHost, val string) (string, error) {
338 349
 	host, err := parsers.ParseDockerDaemonHost(DefaultTCPHost, DefaultUnixSocket, val)
339 350
 	if err != nil {
340 351
 		return val, err
... ...
@@ -3,6 +3,7 @@ package opts
3 3
 import (
4 4
 	"fmt"
5 5
 	"os"
6
+	"runtime"
6 7
 	"strings"
7 8
 	"testing"
8 9
 )
... ...
@@ -423,7 +424,7 @@ func TestValidateLabel(t *testing.T) {
423 423
 	}
424 424
 }
425 425
 
426
-func TestValidateHost(t *testing.T) {
426
+func TestParseHost(t *testing.T) {
427 427
 	invalid := map[string]string{
428 428
 		"anything":              "Invalid bind address format: anything",
429 429
 		"something with spaces": "Invalid bind address format: something with spaces",
... ...
@@ -433,7 +434,14 @@ func TestValidateHost(t *testing.T) {
433 433
 		"tcp://invalid":      "Invalid bind address format: invalid",
434 434
 		"tcp://invalid:port": "Invalid bind address format: invalid:port",
435 435
 	}
436
+	const defaultHTTPHost = "tcp://127.0.0.1:2375"
437
+	var defaultHOST = "unix:///var/run/docker.sock"
438
+
439
+	if runtime.GOOS == "windows" {
440
+		defaultHOST = defaultHTTPHost
441
+	}
436 442
 	valid := map[string]string{
443
+		"":                         defaultHOST,
437 444
 		"fd://":                    "fd://",
438 445
 		"fd://something":           "fd://something",
439 446
 		"tcp://host:":              "tcp://host:2375",
... ...
@@ -450,12 +458,12 @@ func TestValidateHost(t *testing.T) {
450 450
 	}
451 451
 
452 452
 	for value, errorMessage := range invalid {
453
-		if _, err := ValidateHost(value); err == nil || err.Error() != errorMessage {
453
+		if _, err := ParseHost(defaultHTTPHost, value); err == nil || err.Error() != errorMessage {
454 454
 			t.Fatalf("Expected an error for %v with [%v], got [%v]", value, errorMessage, err)
455 455
 		}
456 456
 	}
457 457
 	for value, expected := range valid {
458
-		if actual, err := ValidateHost(value); err != nil || actual != expected {
458
+		if actual, err := ParseHost(defaultHTTPHost, value); err != nil || actual != expected {
459 459
 			t.Fatalf("Expected for %v [%v], got [%v, %v]", value, expected, actual, err)
460 460
 		}
461 461
 	}