12 Commits

Author SHA1 Message Date
88d1133224 cli/connhelper: quote ssh arguments to prevent shell injection
When connecting to a remote daemon through an ssh:// connection,
the CLI connects with the remote host using ssh, executing the
`docker system dial-stdio` command on the remote host to connect
to the daemon API's unix socket.

By default, the `docker system dial-stdio` command connects with the
daemon using the default location (/var/run/docker.sock), or the
location as configured on the remote host.

Commit 25ebf0ec9c (included in docker
CLI v24.0.0-rc.2 and higher) introduced a feature to allow the location
of the socket to be specified through the host connection string, for
example:

     DOCKER_HOST='ssh://example.test/run/custom-docker.sock'

The custom path is included as part of the ssh command executed from
the client machine to connect with the remote host. THe example above
would execute the following command from the client machine;

    ssh -o ConnectTimeout=30 -T -- example.test docker --host unix:///run/custom-docker.sock system dial-stdio

ssh executes remote commands in a shell environment, and no quoting
was in place, which allowed for a connection string to include additional
content, which would be expanded / executed on the remote machine.

For example, the following example would execute `echo hello > /hello.txt`
on the remote machine;

    export DOCKER_HOST='ssh://example.test/var/run/docker.sock $(echo hello > /hello.txt)'
    docker info
    # (output of docker info from the remote machine)

While this doesn't allow the user to do anything they're not already
able to do so (by directly using the same SSH connection), the behavior
is not expected, so this patch adds quoting to prevent such URLs from
resulting in expansion.

This patch updates the cli/connhelper and cli/connhelper/ssh package to
quote parameters used in the ssh command to prevent code execution and
expansion of variables on the remote machine. Quoting is also applied to
other parameters that are obtained from the DOCKER_HOST url, such as username
and hostname.

- The existing `Spec.Args()` method inthe cli/connhelper/ssh package now
  quotes arguments, and returns a nil slice when failing to quote. Users
  of this package should therefore check the returned arguments before
  consuming. This  method did not provide an error-return, and adding
  one would be a breaking change.
- A new `Spec.Command` method is introduced, which (unlike the `Spec.Args()`
  method) provides an error return. Users are recommended to use this new
  method instead of the `Spec.Args()` method.

Some minor additional changes in behavior are included in this patch;

- Connection URLs with a trailing slash (e.g. `ssh://example.test/`)
  would previously result in `unix:///` being used as custom socket
  path. After this patch, the trailing slash is ignored, and no custom
  socket path is used.
- Specifying a remote command is now required. When passing an empty
  remote command, `Spec.Args()` now results in a `nil` value to be
  returned (or an `no remote command specified` error when using
  `Spec.Comnmand()`.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-06-24 16:26:17 +02:00
11b53dabc6 cli/connhelper/ssh: add NewSpec utility
This allows creating a spec from an existing url.URL

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-04-23 14:29:42 +02:00
55073c404c cli/connhelper/ssh: tweak error-message (capitalize SSH)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-04-23 14:27:49 +02:00
8c0c1db679 cli/connhelper/ssh: use stdlib errors and improve errors
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-04-17 21:38:52 +02:00
6ca9766897 cli/connhelper/ssh: improve GoDoc for ParseURL
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-04-17 21:34:18 +02:00
126713648e cli/connhelper/ssh: TestParseURL: various improvements
- use designated example domains as example value
- swap "expected" and "actual" values in assertions
- add doc / name for each test
- add test-cases for remote commands
- also test the Spec that's produced, not just the args
- merge two test-cases that could be combined

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-04-17 21:28:09 +02:00
25ebf0ec9c connhelper: Allow socket path when using SSH
Signed-off-by: Jakub Panek <me@panekj.dev>
2023-03-07 00:48:27 +01:00
d30970e3b1 ssh: avoid setting flags through hostname
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2020-05-28 20:08:35 +00:00
2c0e93063b bump gotest.tools v3.0.1 for compatibility with Go 1.14
full diff: https://github.com/gotestyourself/gotest.tools/compare/v2.3.0...v3.0.1

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2020-02-23 00:28:55 +01:00
dbe7afbd04 connhelper: export functions for other projects
Exposed functions are planned to be used by `buildctl`:
https://github.com/moby/buildkit/issues/769

Signed-off-by: Akihiro Suda <suda.akihiro@lab.ntt.co.jp>
2019-03-02 21:11:49 +09:00
a07637ae31 Updates ssh connhelper error messages
Signed-off-by: François Scala <arcenik@github.com>
2019-01-25 23:42:13 +01:00
6f61cf053a support SSH connection
e.g. docker -H ssh://me@server

The `docker` CLI also needs to be installed on the remote host to
provide `docker system dial-stdio`, which proxies the daemon socket to stdio.

Please refer to docs/reference/commandline/dockerd.md .

Signed-off-by: Akihiro Suda <suda.akihiro@lab.ntt.co.jp>
2018-08-02 13:10:06 +09:00