From 50f0906007bdec83dd23b6ae5216769ab65bbf59 Mon Sep 17 00:00:00 2001 From: Sven Dowideit Date: Fri, 21 Aug 2015 23:28:49 +1000 Subject: [PATCH] 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 --- api/client/cli.go | 16 +++++++++------- docker/daemon.go | 12 +++++++++--- docs/articles/basics.md | 8 ++++++-- docs/installation/ubuntulinux.md | 8 +++++--- docs/reference/commandline/cli.md | 2 +- man/docker.1.md | 6 ++++-- opts/opts.go | 18 ++++++++++++++++++ opts/opts_test.go | 14 +++++++++++--- 8 files changed, 63 insertions(+), 21 deletions(-) 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) } }