[vnet] feat: add transparent SSH proxy#54525
Conversation
| log = log.With("request_layer", "channel") | ||
| sendRequest := func(name string, wantReply bool, payload []byte) (bool, []byte, error) { | ||
| ok, err := targetChan.SendRequest(name, wantReply, payload) | ||
| // Replies to channel requests never have a payload. |
There was a problem hiding this comment.
Worst protocol decision ever btw. 😔
| ctx, cancel := context.WithCancel(ctx) | ||
| defer cancel() | ||
| go func() { | ||
| defer wg.Done() | ||
| <-ctx.Done() |
There was a problem hiding this comment.
Doesn't the wg.Wait() below block forever (or rather until ctx is externally cancelled, which might be never) since nothing else will call cancel() and the waitgroup is waiting on this wg.Done()?
There was a problem hiding this comment.
yeah my bad and my test conveniently missed this 🤦 I think context.AfterFunc solves it by avoiding a goroutine
| serverConn sshConn, | ||
| clientConn sshConn, | ||
| ) { | ||
| closeConnections := func() { |
There was a problem hiding this comment.
I wonder if we can split the responsibilities of this by mutually closing the connections after waiting on each one (as in (ssh.Conn).Wait), so each "side" only needs to close its own side on error.
There was a problem hiding this comment.
I considered it but I also realized that each connection or channel should really only be closed once and I think in the latest I got a somewhat cleaner solution here
There was a problem hiding this comment.
At which point it becomes easier to fork x/crypto to copy SSH packets rather than deal with the high level API? 🥴
edit: not gonna lie, this looks pretty easy
i'd rather not fork x/crypto/ssh if we don't have to, especially a fork that's not likely to ever be upstreamed. but let me know what you think of the latest changes 😅 |
rosstimothy
left a comment
There was a problem hiding this comment.
While this is a bit verbose as a result of the SSH API, I agree with Nic that we probably don't want to fork x/crypt/ssh just to make the code for this use case simpler.
|
@nklaassen See the table below for backport results.
|
Part of RFD 207: VNet SSH
This PR adds a transparent SSH proxy that takes an established incoming SSH connection from the client and an outgoing SSH connection to the target, and proxies all SSH requests, channels, and channel requests between the two.