Skip to content
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

proposal: x/crypto/ssh: implement ControlMaster transport support #31874

Closed
y3llowcake opened this issue May 7, 2019 · 9 comments
Closed

proposal: x/crypto/ssh: implement ControlMaster transport support #31874

y3llowcake opened this issue May 7, 2019 · 9 comments

Comments

@y3llowcake
Copy link

@y3llowcake y3llowcake commented May 7, 2019

What version of Go are you using (go version)?

$ go version
go version go1.12.2 linux/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/cy/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/cy/go"
GOPROXY=""
GORACE=""
GOROOT="/home/cy/go/go1.12.2"
GOTMPDIR=""
GOTOOLDIR="/home/cy/go/go1.12.2/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/home/cy/co/crypfork/crypto/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build098365928=/tmp/go-build -gno-record-gcc-switches"

Feature Request

I am trying to establish SSH sessions over a ControlMaster socket.
ControlMaster reference: https://linux.die.net/man/5/ssh_config
Protocol reference: https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.mux

I see two options to make this possible:

  1. Implement ControlMaster socket handshake and transport inside this library.
  2. Export a Transport interface and methods for reading and writing raw packets, and allow the ControlMaster details to be implemented outside the library.
@gopherbot gopherbot added this to the Unreleased milestone May 7, 2019
@andybons andybons changed the title x/crypto/ssh: implement ControlMaster transport support proposal: x/crypto/ssh: implement ControlMaster transport support May 8, 2019
@andybons
Copy link
Member

@andybons andybons commented May 8, 2019

@andybons andybons added the Proposal label May 8, 2019
@hanwen
Copy link
Contributor

@hanwen hanwen commented May 9, 2019

why?

controlmaster sockets are exposed by the openssh client. You could just write a client in Go directly that stays in the background, and use an RPC mechanism of your choosing to interact with it.

@y3llowcake
Copy link
Author

@y3llowcake y3llowcake commented May 9, 2019

Not sure I understand your question. Why do I want to use controlmaster sockets, or, why do I need to change this library, or something else?

I want to use controlmaster sockets because I am operating in an environment that already uses them extensively and would like the go tooling to interop with the OpenSSH tunnel that is already established.

@hanwen
Copy link
Contributor

@hanwen hanwen commented May 9, 2019

Yes, my question is why you can't establish an tunnel from Go.

@y3llowcake
Copy link
Author

@y3llowcake y3llowcake commented May 10, 2019

My goal is to inter-operate with OpenSSH as opposed to implementing it's entire capability set, including it's non-trivial client configuration options (https://linux.die.net/man/5/ssh_config).

Assuming I did take the approach you suggest I'd probably end up back here in the spirit of compatibility; Instead of defining a new IPC/RPC mechanism, I'd want the OpenSSH command line client to be able to inter-operate with my golang based tunnel daemon.

I can understand why having OpenSSH specific stuff in the library may be undesirable. This is why I have also suggested the alternative to expose a transport interface that allows me to do RFC 4253 on my own.

@hanwen
Copy link
Contributor

@hanwen hanwen commented May 10, 2019

Which non-trivial client configurations specifically? Alternatively, why do you need a Go tool to operate with the ControlMaster server? What's stopping you from calling out to ssh to connect to the existing tunnel?

I'm sorry for all these questions, but I can't place this feature request, because you both want to not use OpenSSH (ie. need something in Go) and do want to use OpenSSH (control master) at the same time.

@y3llowcake
Copy link
Author

@y3llowcake y3llowcake commented May 10, 2019

Apologies for the confusion.

I am trying to write go programs that inter-operate with OpenSSH via control master sockets. I want this capability so that I can make use of pre-exiting OpenSSH sessions, instead of establishing new sessions. I am trying to avoid establishing new sessions to avoid:

  • Requesting additional input or action from the user (passwords, 2FA prompts).
  • Additional round-trips/handshaking.
  • Parsing most/all of a non-trivial client configuration that is a moving target and is canonically represented as a OpenSSH config file. (see a substantially abridged example below).

The go programs I am writing require most of the SSH Protocol be available to them; starting and managing sessions, running commands remotely, passing around Dial()'ers that do remote TCP dialing via "direct-tcpip" global requests. Additionally, they need to have this capability available in-process without forking out to OpenSSH.

My request may have been better framed, by ignoring OpenSSH and the ControlMaster protocol and focusing on the smallest change I am hoping to get from this library: An interface that separates the SSH connection protocol (RFC 4254) from the SSH transport protocol (RFC 4253).

HashKnownHosts no
ServerAliveCountMax 4320
ServerAliveInterval 10
TCPKeepAlive no

Host *
  HashKnownHosts no
  ServerAliveInterval 10
  TCPKeepAlive no

Host bastion*.*.acme-inc.biz *-bastion.acme-inc.biz bastion*.acme-inc-ponies.com
  ControlMaster auto
  ControlPath /tmp/ssh-control-%r@%h:%p
  ControlPersist 43200
  HostName %h
  ProxyCommand none
  SendEnv 2FA_PROVIDER_ABC_PASSCODE

Host *.xyz.acme-inc.biz *.flowers.acme.com
  ControlMaster auto
  ControlPath /tmp/ssh-control-%r@%h:%p
  ControlPersist 10000
  ProxyCommand none
  SendEnv ABC_DEF
  SendEnv XYZ

Host dev* qa*
  CanonicalizeHostname yes
  CanonicalDomains acme.com

Host !*.* *
  CanonicalizeHostname yes
  CanonicalDomains fuzzbizz.acme-inc.biz cloud-provider1.acme-inc.biz cloud-provider2.acme-inc.biz acme-inc-tools.com

Host !*.cloud-provider2.acme-inc.biz *.acme-inc.biz acme-other-things.com staging.acme-other-things.com *.acme.com cloud-provider1-* 10.* *.acme-inc-tools.com
  ProxyCommand ssh cloud-provider1-bastion.acme-inc.biz nc -q0 %h %p

Host *.cloud-provider2.acme-inc.biz
  ProxyCommand ssh cloud-provider2-bastion.acme-inc.biz nc -q0 %h %p

Host cloud-provider3-* cp3-ip-*
  UserKnownHostsFile /acme/known-hosts
@y3llowcake
Copy link
Author

@y3llowcake y3llowcake commented Jun 13, 2019

Hey @hanwen did my explanation make sense?

@y3llowcake
Copy link
Author

@y3llowcake y3llowcake commented Sep 3, 2019

Closing this out in favor of #32958

@y3llowcake y3llowcake closed this Sep 3, 2019
@golang golang locked and limited conversation to collaborators Sep 2, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
4 participants
You can’t perform that action at this time.