diff --git a/api/client/cli.go b/api/client/cli.go index d11abbb46d..4c9ae1402e 100644 --- a/api/client/cli.go +++ b/api/client/cli.go @@ -106,13 +106,6 @@ func NewDockerCli(in io.ReadCloser, out, err io.Writer, clientFlags *cli.ClientF switch len(hosts) { case 0: defaultHost := os.Getenv("DOCKER_HOST") - if defaultHost == "" { - defaultHost = opts.DefaultHost - } - defaultHost, err := opts.ValidateHost(defaultHost) - if err != nil { - return err - } hosts = []string{defaultHost} case 1: // only accept one host to talk to @@ -120,6 +113,15 @@ func NewDockerCli(in io.ReadCloser, out, err io.Writer, clientFlags *cli.ClientF return errors.New("Please specify only one -H") } + defaultHost := opts.DefaultTCPHost + if clientFlags.Common.TLSOptions != nil { + defaultHost = opts.DefaultTLSHost + } + var e error + if hosts[0], e = opts.ParseHost(defaultHost, hosts[0]); e != nil { + return e + } + protoAddrParts := strings.SplitN(hosts[0], "://", 2) cli.proto, cli.addr = protoAddrParts[0], protoAddrParts[1] diff --git a/docker/daemon.go b/docker/daemon.go index 6a48a90e88..a0cc336d24 100644 --- a/docker/daemon.go +++ b/docker/daemon.go @@ -169,9 +169,6 @@ func (cli *DaemonCli) CmdDaemon(args ...string) error { daemonFlags.ParseFlags(args, true) commonFlags.PostParse() - if len(commonFlags.Hosts) == 0 { - commonFlags.Hosts = []string{opts.DefaultHost} - } if commonFlags.TrustKey == "" { commonFlags.TrustKey = filepath.Join(getDaemonConfDir(), defaultTrustKeyFile) } @@ -212,6 +209,7 @@ func (cli *DaemonCli) CmdDaemon(args ...string) error { } serverConfig = setPlatformServerConfig(serverConfig, cli.Config) + defaultHost := opts.DefaultHost if commonFlags.TLSOptions != nil { if !commonFlags.TLSOptions.InsecureSkipVerify { // server requires and verifies client's certificate @@ -222,6 +220,14 @@ func (cli *DaemonCli) CmdDaemon(args ...string) error { logrus.Fatal(err) } serverConfig.TLSConfig = tlsConfig + defaultHost = opts.DefaultTLSHost + } + + for i := 0; i < len(commonFlags.Hosts); i++ { + var err error + if commonFlags.Hosts[i], err = opts.ParseHost(defaultHost, commonFlags.Hosts[i]); err != nil { + logrus.Fatalf("error parsing -H %s : %v", commonFlags.Hosts[i], err) + } } for _, protoAddr := range commonFlags.Hosts { protoAddrParts := strings.SplitN(protoAddr, "://", 2) diff --git a/docs/articles/basics.md b/docs/articles/basics.md index 92f791cc36..900d111646 100644 --- a/docs/articles/basics.md +++ b/docs/articles/basics.md @@ -82,13 +82,17 @@ then it is trivial for someone to gain root access to the host where the daemon is running. Similarly, the Docker client can use `-H` to connect to a custom port. +The Docker client will default to connecting to `unix:///var/run/docker.sock` +on Linux, and `tcp://127.0.0.1:2376` on Windows. `-H` accepts host and port assignment in the following format: - tcp://[host][:port][path] or unix://path + tcp://[host]:[port][path] or unix://path For example: +- `tcp://` -> TCP connection to `127.0.0.1` on either port `2376` when TLS encryption + is on, or port `2375` when communication is in plain text. - `tcp://host:2375` -> TCP connection on host:2375 - `tcp://host:2375/path` -> TCP connection on @@ -101,7 +105,7 @@ when no `-H` was passed in. `-H` also accepts short form for TCP bindings: - host[:port] or :port + `host:` or `host:port` or `:port` Run Docker in daemon mode: diff --git a/docs/installation/ubuntulinux.md b/docs/installation/ubuntulinux.md index b8aad8eeb4..2a515aca43 100644 --- a/docs/installation/ubuntulinux.md +++ b/docs/installation/ubuntulinux.md @@ -265,9 +265,11 @@ Docker uses a bridge to manage container networking. By default, UFW drops all forwarding traffic. As a result, for Docker to run when UFW is enabled, you must set UFW's forwarding policy appropriately. -Also, UFW's default set of rules denies all incoming traffic. If you want to be able -to reach your containers from another host then you should also allow incoming -connections on the Docker port (default `2375`). +Also, UFW's default set of rules denies all incoming traffic. If you want to +reach your containers from another host allow incoming connections on the Docker +port. The Docker port defaults to `2376` if TLS is enabled or `2375` when it is +not. If TLS is not enabled, communication is unencrypted. By default, Docker +runs without TLS enabled. To configure UFW and allow incoming connections on the Docker port: diff --git a/docs/reference/commandline/cli.md b/docs/reference/commandline/cli.md index a07fc8b333..ee6c9a16a1 100644 --- a/docs/reference/commandline/cli.md +++ b/docs/reference/commandline/cli.md @@ -18,7 +18,7 @@ or execute `docker help`: docker daemon [ --help | ... ] docker [ --help | -v | --version ] - -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. + -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. A self-sufficient runtime for Linux containers. diff --git a/man/docker.1.md b/man/docker.1.md index 41329deb3b..18df3b5cf2 100644 --- a/man/docker.1.md +++ b/man/docker.1.md @@ -36,10 +36,12 @@ To see the man page for a command run **man docker **. **-D**, **--debug**=*true*|*false* Enable debug mode. Default is false. -**-H**, **--host**=[unix:///var/run/docker.sock]: tcp://[host:port] to bind or +**-H**, **--host**=[unix:///var/run/docker.sock]: tcp://[host]:[port][path] to bind or unix://[/path/to/socket] to use. 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. + tcp://host:port/path, unix:///path/to/socket, fd://* or fd://socketfd. + If the tcp port is not specified, then it will default to either `2375` when + `--tls` is off, or `2376` when `--tls` is on, or `--tlsverify` is specified. **-l**, **--log-level**="*debug*|*info*|*warn*|*error*|*fatal*"" Set the logging level. Default is `info`. diff --git a/opts/opts.go b/opts/opts.go index 6b44e8d801..48b9d842aa 100644 --- a/opts/opts.go +++ b/opts/opts.go @@ -17,16 +17,23 @@ var ( 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*$`) // DefaultHTTPHost Default HTTP Host used if only port is provided to -H flag e.g. docker daemon -H tcp://:8080 DefaultHTTPHost = "127.0.0.1" + // DefaultHTTPPort Default HTTP Port used if only the protocol is provided to -H flag e.g. docker daemon -H tcp:// // TODO Windows. DefaultHTTPPort is only used on Windows if a -H parameter // is not supplied. A better longer term solution would be to use a named // pipe as the default on the Windows daemon. + // These are the IANA registered port numbers for use with Docker + // see http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml?search=docker DefaultHTTPPort = 2375 // Default HTTP Port + // DefaultTLSHTTPPort Default HTTP Port used when TLS enabled + DefaultTLSHTTPPort = 2376 // Default TLS encrypted HTTP Port // DefaultUnixSocket Path for the unix socket. // Docker daemon by default always listens on the default unix socket DefaultUnixSocket = "/var/run/docker.sock" // DefaultTCPHost constant defines the default host string used by docker on Windows DefaultTCPHost = fmt.Sprintf("tcp://%s:%d", DefaultHTTPHost, DefaultHTTPPort) + // DefaultTLSHost constant defines the default host string used by docker for TLS sockets + DefaultTLSHost = fmt.Sprintf("tcp://%s:%d", DefaultHTTPHost, DefaultTLSHTTPPort) ) // ListOpts holds a list of values and a validation function. @@ -335,6 +342,17 @@ func ValidateLabel(val string) (string, error) { // ValidateHost validates that the specified string is a valid host and returns it. func ValidateHost(val string) (string, error) { + _, err := parsers.ParseDockerDaemonHost(DefaultTCPHost, DefaultUnixSocket, val) + if err != nil { + return val, err + } + // Note: unlike most flag validators, we don't return the mutated value here + // we need to know what the user entered later (using ParseHost) to adjust for tls + return val, nil +} + +// ParseHost and set defaults for a Daemon host string +func ParseHost(defaultHTTPHost, val string) (string, error) { host, err := parsers.ParseDockerDaemonHost(DefaultTCPHost, DefaultUnixSocket, val) if err != nil { return val, err diff --git a/opts/opts_test.go b/opts/opts_test.go index 237b470b95..f1a4bea9f2 100644 --- a/opts/opts_test.go +++ b/opts/opts_test.go @@ -3,6 +3,7 @@ package opts import ( "fmt" "os" + "runtime" "strings" "testing" ) @@ -423,7 +424,7 @@ func TestValidateLabel(t *testing.T) { } } -func TestValidateHost(t *testing.T) { +func TestParseHost(t *testing.T) { invalid := map[string]string{ "anything": "Invalid bind address format: anything", "something with spaces": "Invalid bind address format: something with spaces", @@ -433,7 +434,14 @@ func TestValidateHost(t *testing.T) { "tcp://invalid": "Invalid bind address format: invalid", "tcp://invalid:port": "Invalid bind address format: invalid:port", } + const defaultHTTPHost = "tcp://127.0.0.1:2375" + var defaultHOST = "unix:///var/run/docker.sock" + + if runtime.GOOS == "windows" { + defaultHOST = defaultHTTPHost + } valid := map[string]string{ + "": defaultHOST, "fd://": "fd://", "fd://something": "fd://something", "tcp://host:": "tcp://host:2375", @@ -450,12 +458,12 @@ func TestValidateHost(t *testing.T) { } for value, errorMessage := range invalid { - if _, err := ValidateHost(value); err == nil || err.Error() != errorMessage { + if _, err := ParseHost(defaultHTTPHost, value); err == nil || err.Error() != errorMessage { t.Fatalf("Expected an error for %v with [%v], got [%v]", value, errorMessage, err) } } for value, expected := range valid { - if actual, err := ValidateHost(value); err != nil || actual != expected { + if actual, err := ParseHost(defaultHTTPHost, value); err != nil || actual != expected { t.Fatalf("Expected for %v [%v], got [%v, %v]", value, expected, actual, err) } }