diff --git a/client/client.go b/client/client.go index dc2834f1a5..1412377eab 100644 --- a/client/client.go +++ b/client/client.go @@ -212,7 +212,7 @@ func (cli *Client) ClientVersion() string { // by the client, it uses the client's maximum version. // // If a manual override is in place, either through the "DOCKER_API_VERSION" -// environment variable, or if the client is initialized +// (EnvOverrideAPIVersion) environment variable, or if the client is initialized // with a fixed version (WithVersion(xx)), no negotiation is performed. // // If the API server's ping response does not contain an API version, or if the @@ -233,7 +233,7 @@ func (cli *Client) NegotiateAPIVersion(ctx context.Context) { // version. // // If a manual override is in place, either through the "DOCKER_API_VERSION" -// environment variable, or if the client is initialized +// (EnvOverrideAPIVersion) environment variable, or if the client is initialized // with a fixed version (WithVersion(xx)), no negotiation is performed. // // If the API server's ping response does not contain an API version, we assume diff --git a/client/client_unix.go b/client/client_unix.go index 44b575606c..f0783f7085 100644 --- a/client/client_unix.go +++ b/client/client_unix.go @@ -4,7 +4,7 @@ package client // import "github.com/docker/docker/client" // DefaultDockerHost defines OS-specific default host if the DOCKER_HOST -// environment variable is unset or empty. +// (EnvOverrideHost) environment variable is unset or empty. const DefaultDockerHost = "unix:///var/run/docker.sock" const defaultProto = "unix" diff --git a/client/client_windows.go b/client/client_windows.go index 601918a936..5abe60457d 100644 --- a/client/client_windows.go +++ b/client/client_windows.go @@ -1,7 +1,7 @@ package client // import "github.com/docker/docker/client" // DefaultDockerHost defines OS-specific default host if the DOCKER_HOST -// environment variable is unset or empty. +// (EnvOverrideHost) environment variable is unset or empty. const DefaultDockerHost = "npipe:////./pipe/docker_engine" const defaultProto = "npipe" diff --git a/client/envvars.go b/client/envvars.go new file mode 100644 index 0000000000..61dd45c1d7 --- /dev/null +++ b/client/envvars.go @@ -0,0 +1,90 @@ +package client // import "github.com/docker/docker/client" + +const ( + // EnvOverrideHost is the name of the environment variable that can be used + // to override the default host to connect to (DefaultDockerHost). + // + // This env-var is read by FromEnv and WithHostFromEnv and when set to a + // non-empty value, takes precedence over the default host (which is platform + // specific), or any host already set. + EnvOverrideHost = "DOCKER_HOST" + + // EnvOverrideAPIVersion is the name of the environment variable that can + // be used to override the API version to use. Value should be + // formatted as MAJOR.MINOR, for example, "1.19". + // + // This env-var is read by FromEnv and WithVersionFromEnv and when set to a + // non-empty value, takes precedence over API version negotiation. + // + // This environment variable should be used for debugging purposes only, as + // it can set the client to use an incompatible (or invalid) API version. + EnvOverrideAPIVersion = "DOCKER_API_VERSION" + + // EnvOverrideCertPath is the name of the environment variable that can be + // used to specify the directory from which to load the TLS certificates + // (ca.pem, cert.pem, key.pem) from. These certificates are used to configure + // the Client for a TCP connection protected by TLS client authentication. + // + // TLS certificate verification is enabled by default if the Client is configured + // to use a TLS connection. Refer to EnvTLSVerify below to learn how to + // disable verification for testing purposes. + // + // WARNING: Access to the remote API is equivalent to root access to the + // host where the daemon runs. Do not expose the API without protection, + // and only if needed. Make sure you are familiar with the "daemon attack + // surface" (https://docs.docker.com/go/attack-surface/). + // + // For local access to the API, it is recommended to connect with the daemon + // using the default local socket connection (on Linux), or the named pipe + // (on Windows). + // + // If you need to access the API of a remote daemon, consider using an SSH + // (ssh://) connection, which is easier to set up, and requires no additional + // configuration if the host is accessible using ssh. + // + // If you cannot use the alternatives above, and you must expose the API over + // a TCP connection, refer to https://docs.docker.com/engine/security/protect-access/ + // to learn how to configure the daemon and client to use a TCP connection + // with TLS client authentication. Make sure you know the differences between + // a regular TLS connection and a TLS connection protected by TLS client + // authentication, and verify that the API cannot be accessed by other clients. + EnvOverrideCertPath = "DOCKER_CERT_PATH" + + // EnvTLSVerify is the name of the environment variable that can be used to + // enable or disable TLS certificate verification. When set to a non-empty + // value, TLS certificate verification is enabled, and the client is configured + // to use a TLS connection, using certificates from the default directories + // (within `~/.docker`); refer to EnvOverrideCertPath above for additional + // details. + // + // WARNING: Access to the remote API is equivalent to root access to the + // host where the daemon runs. Do not expose the API without protection, + // and only if needed. Make sure you are familiar with the "daemon attack + // surface" (https://docs.docker.com/go/attack-surface/). + // + // Before setting up your client and daemon to use a TCP connection with TLS + // client authentication, consider using one of the alternatives mentioned + // in EnvOverrideCertPath above. + // + // Disabling TLS certificate verification (for testing purposes) + // + // TLS certificate verification is enabled by default if the Client is configured + // to use a TLS connection, and it is highly recommended to keep verification + // enabled to prevent machine-in-the-middle attacks. Refer to the documentation + // at https://docs.docker.com/engine/security/protect-access/ and pages linked + // from that page to learn how to configure the daemon and client to use a + // TCP connection with TLS client authentication enabled. + // + // Set the "DOCKER_TLS_VERIFY" environment to an empty string ("") to + // disable TLS certificate verification. Disabling verification is insecure, + // so should only be done for testing purposes. From the Go documentation + // (https://pkg.go.dev/crypto/tls#Config): + // + // InsecureSkipVerify controls whether a client verifies the server's + // certificate chain and host name. If InsecureSkipVerify is true, crypto/tls + // accepts any certificate presented by the server and any host name in that + // certificate. In this mode, TLS is susceptible to machine-in-the-middle + // attacks unless custom verification is used. This should be used only for + // testing or in combination with VerifyConnection or VerifyPeerCertificate. + EnvTLSVerify = "DOCKER_TLS_VERIFY" +) diff --git a/client/options.go b/client/options.go index 028f61c00a..98d96f792e 100644 --- a/client/options.go +++ b/client/options.go @@ -20,15 +20,15 @@ type Opt func(*Client) error // // FromEnv uses the following environment variables: // -// DOCKER_HOST to set the URL to the docker server. +// DOCKER_HOST (EnvOverrideHost) to set the URL to the docker server. // -// DOCKER_API_VERSION to set the version of the API to +// DOCKER_API_VERSION (EnvOverrideAPIVersion) to set the version of the API to // use, leave empty for latest. // -// DOCKER_CERT_PATH to specify the directory from which to +// DOCKER_CERT_PATH (EnvOverrideCertPath) to specify the directory from which to // load the TLS certificates (ca.pem, cert.pem, key.pem). // -// DOCKER_TLS_VERIFY to enable or disable TLS verification (off by +// DOCKER_TLS_VERIFY (EnvTLSVerify) to enable or disable TLS verification (off by // default). func FromEnv(c *Client) error { ops := []Opt{ @@ -82,11 +82,11 @@ func WithHost(host string) Opt { } // WithHostFromEnv overrides the client host with the host specified in the -// DOCKER_HOST environment variable. If DOCKER_HOST is not set, +// DOCKER_HOST (EnvOverrideHost) environment variable. If DOCKER_HOST is not set, // or set to an empty value, the host is not modified. func WithHostFromEnv() Opt { return func(c *Client) error { - if host := os.Getenv("DOCKER_HOST"); host != "" { + if host := os.Getenv(EnvOverrideHost); host != "" { return WithHost(host)(c) } return nil @@ -154,14 +154,14 @@ func WithTLSClientConfig(cacertPath, certPath, keyPath string) Opt { // // WithTLSClientConfigFromEnv uses the following environment variables: // -// DOCKER_CERT_PATH to specify the directory from which to +// DOCKER_CERT_PATH (EnvOverrideCertPath) to specify the directory from which to // load the TLS certificates (ca.pem, cert.pem, key.pem). // -// DOCKER_TLS_VERIFY to enable or disable TLS verification (off by +// DOCKER_TLS_VERIFY (EnvTLSVerify) to enable or disable TLS verification (off by // default). func WithTLSClientConfigFromEnv() Opt { return func(c *Client) error { - dockerCertPath := os.Getenv("DOCKER_CERT_PATH") + dockerCertPath := os.Getenv(EnvOverrideCertPath) if dockerCertPath == "" { return nil } @@ -169,7 +169,7 @@ func WithTLSClientConfigFromEnv() Opt { CAFile: filepath.Join(dockerCertPath, "ca.pem"), CertFile: filepath.Join(dockerCertPath, "cert.pem"), KeyFile: filepath.Join(dockerCertPath, "key.pem"), - InsecureSkipVerify: os.Getenv("DOCKER_TLS_VERIFY") == "", + InsecureSkipVerify: os.Getenv(EnvTLSVerify) == "", } tlsc, err := tlsconfig.Client(options) if err != nil { @@ -201,7 +201,7 @@ func WithVersion(version string) Opt { // the version is not modified. func WithVersionFromEnv() Opt { return func(c *Client) error { - return WithVersion(os.Getenv("DOCKER_API_VERSION"))(c) + return WithVersion(os.Getenv(EnvOverrideAPIVersion))(c) } }