-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
support SSH connection #1014
support SSH connection #1014
Conversation
9fbd086
to
e1624b5
Compare
Design LGTM! cc @tonistiigi for design as well. I did notice that this:
Doesn't echo anything to my term when using the ssh connector. |
@cpuguy83 The issue can be mitigated by increasing this However, increasing this value introduces extra sleep. I'll try to find a more robust way |
Design LGTM too, this is cool 😻 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall design LGTM. I don't understand the timeout logic on handling EOF
though.
cli/command/system/dial_stdio.go
Outdated
if !ok { | ||
return errors.New("the raw stream connection does not implement halfCloser") | ||
} | ||
stdio := &cliHalfCloser{dockerCli} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It may be confusing to use dockerCli
here. I'd just use os
pkg.
cli/command/system/dial_stdio.go
Outdated
}() | ||
select { | ||
case err := <-stdin2conn: | ||
logrus.Debugf("stdin2conn: %v", err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this wip?
cli/connhelper/connhelper.go
Outdated
// ConnectionHelper allows to connect to a remote host with custom stream provider binary. | ||
type ConnectionHelper struct { | ||
Dialer func(ctx context.Context, network, addr string) (net.Conn, error) | ||
DummyHost string // dummy URL used for HTTP requests. e.g. "http://docker" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just Host
. We can also leave a sane default here if WithHost
is not called. So connection helper case doesn't need to call it at all (or even better if connectionhelper just returns the client options directly instead of a struct).
clientOpts = append(clientOpts, client.WithHost(host)) | ||
} else { | ||
clientOpts = append(clientOpts, func(c *client.Client) error { | ||
httpClient := &http.Client{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should just add WithDialer
instead of overriding client and remove WithHijackDialer
. Using it would create a new client with a transport pointing to the current dialer and set it to hijack as well.
cli/command/system/dial_stdio.go
Outdated
func runDialStdio(dockerCli command.Cli, opts dialStdioOptions) error { | ||
ctx, cancel := context.WithCancel(context.Background()) | ||
defer cancel() | ||
conn, err := dockerCli.Client().DialRaw(ctx) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this would be slightly better as a Dialer() func(ctx) (net.Conn, error)
. Otherwise, it seems like a method that calls to the remote side. We could also solve this by breaking up NewClientWithOpts
so that we always get access to dialer in cli before creating the client and store the dialer so we can reuse it.
cli/command/system/dial_stdio.go
Outdated
} | ||
|
||
flags := cmd.Flags() | ||
flags.DurationVarP(&opts.timeout, "timeout", "t", 500*time.Millisecond, "After EOF from one of inputs, wait for this duration before exit") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I understand this timeout. Why isn't the close of connection handled cleanly? This could be just a connection timeout but then it should be much bigger (20 sec) and increasing it shouldn't have any downsides when timeout isn't reached.
cli/command/system/dial_stdio.go
Outdated
stdin2conn := make(chan error) | ||
conn2stdout := make(chan error) | ||
|
||
go func() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These might be better handled with a wrapper around conn. But I guess I don't understand the need for the current timeout atm.
Any update here? |
Sorry still stuck at the stream connection issue #1014 (comment) Will try to look into this again ASAP |
No worries I just thought this was already merged and realized it wasn't! |
5cd375a
to
e6fc199
Compare
Codecov Report
@@ Coverage Diff @@
## master #1014 +/- ##
=========================================
- Coverage 54.29% 54% -0.29%
=========================================
Files 268 272 +4
Lines 17843 18068 +225
=========================================
+ Hits 9687 9758 +71
- Misses 7546 7694 +148
- Partials 610 616 +6 |
Thanks for your reply. Will it not accept parameters passed through command
line ? This is very convenient for portability (when using through
different laptops, etc).
Secondly we have more -o options that we pass.
…On Mon, 20 Aug, 2018, 09:15 Akihiro Suda, ***@***.***> wrote:
@sandys <https://github.com/sandys> ~/.ssh/config should work
Host foo
Hostname gcp.red.com
PKCS11Provider /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1014 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAEsU0WZDcoIQ79_eUWMRCJMA12QJgdTks5uSjDWgaJpZM4TdNDQ>
.
|
Currently no, could you open a github issue?
Any option that cannot be configured via ~/.ssh/config? |
From ops and sysadmins everywhere, we thank you for this fantastic and unexpected feature. I'm hoping this will seriously cut down the number of times I see people opening dockerd TCP w/o TLS and just opt for SSH endpoints for remote mgmt. 👍 😂 |
is this possible to use in docker golang client rather than cli? just like docker-py understand the ssh:// DOCKER_HOST |
@overmike No, none of the client helpers will set this up for you. Nothing is stopping someone from doing this themselves with the client, though. The CLI is using a helper subcommand (hidden from |
@cpuguy83 , thanks for your feedback. It clarifies I need to add connhelper code in our golang client. I think you meant "docker system dial-stdio" for the hidden subcommand. And seems like docker-py 3.6.0 is going to support ssh DOCKER_HOST. |
How does it handle authentication? Does it support signed SSH certificate? What about revocation? |
It just shells out to the ssh bin. You can add whatever options for the host to your ssh config. I think there is another pr to support passing ssh opts through an environment var as well. |
// GetConnectionHelper returns nil without error when no helper is registered for the scheme. | ||
// URL is like "ssh://me@server01". | ||
func GetConnectionHelper(daemonURL string) (*ConnectionHelper, error) { | ||
u, err := url.Parse(daemonURL) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can actually get a unparsedHost here which is not parseable - has no schema.
Like 127.0.0.1:2364
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GetConnectionHelper returns nil without error when no helper is registered for the scheme.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think, this is actually unrelated to what I'm talking about. Just a line below you check for err
from url.Parse()
and since there is a possibility the passed daemonURL
is in 127.0.0.1:2345
format url.Parse()
will rightfully return an error per its specification - no protocol scheme. I am not sure where should the scheme be added - here or higher in the call stack but this line in particular introduced a regression in the newest stable release of docker engine - 18.09.0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well it might have been addressed but is not fixed 😅 I will file a new issue shortly then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's fixed on master, which is what this repository is tracking.
A backport PR is open to include it in the 18.09 codebase
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we expect it to end up in some kind of 18.09.01 release then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that's what the backport is for. In the meantime you could either modify your configuration (use tcp://<IP|host>:<port>
), or download the static binaries for Docker 18.06 (or "nightly", which has the latest changes from "master") https://download.docker.com/linux/static/
Signed-off-by: Akihiro Suda [email protected]
- What I did
Added support for SSH connection. e.g.
docker -H ssh://me@server
- How I did it
Followed @tonistiigi 's suggestion: #889 (comment)
- How to verify it
docker -H ssh://me@server run -it --rm busybox
- Description for the changelog
support SSH connection
- A picture of a cute animal (not mandatory but encouraged)
https://commons.wikimedia.org/wiki/File:Manchot_Ad%C3%A9lie_juv%C3%A9nile.jpg
Vendor: moby/moby#36630 (merged)
Tests (currently tested manually):
echo hello | ./docker -H ssh://10.2.54.48 run -i --rm busybox cat; echo world
./docker -H ssh://10.2.54.48 run --rm busybox echo hello; echo world
./docker -H ssh://10.2.54.48 run -i --rm busybox echo hello; echo world