francoismichel / ssh3

SSH3: faster and rich secure shell using HTTP/3, checkout our article here: https://arxiv.org/abs/2312.08396 and our Internet-Draft: https://datatracker.ietf.org/doc/draft-michel-ssh3/
https://arxiv.org/abs/2312.08396
Apache License 2.0
3.19k stars 82 forks source link

ProxyJump support #44

Closed pothos closed 5 months ago

pothos commented 6 months ago

Forwarding the local keys to a remote server is mostly not needed - what people often want is to use a host as jump host and that works without giving it access to the key material in OpenSSH through the -J flag or the ProxyJump config entry.

       -J destination
               Connect to the target host by first making an ssh connection to the jump host described by destination and then establishing a  TCP
               forwarding  to  the ultimate destination from there.  Multiple jump hops may be specified separated by comma characters.  This is a
               shortcut to specify a ProxyJump configuration directive.  Note that configuration directives supplied on the command-line generally
               apply to the destination host and not any specified jump hosts.  Use ~/.ssh/config to specify configuration for jump hosts.
       ProxyJump
               Specifies  one or more jump proxies as either [user@]host[:port] or an ssh URI.  Multiple proxies may be separated by comma charac‐
               ters and will be visited sequentially.  Setting this option will cause ssh(1) to connect to the  target  host  by  first  making  a
               ssh(1)  connection  to the specified ProxyJump host and then establishing a TCP forwarding to the ultimate target from there.  Set‐
               ting the host to none disables this option entirely.

               Note that this option will compete with the ProxyCommand option - whichever is specified first will prevent later instances of  the
               other from taking effect.

               Note  also  that the configuration for the destination host (either supplied via the command-line or the configuration file) is not
               generally applied to jump hosts.  ~/.ssh/config should be used if specific configuration is required for jump hosts.
francoismichel commented 6 months ago

Agent forwarding can be useful to access e.g. github private repos from a remote host. :-)

But yes, proxyjump is a must and is on the list of next "easy" things to do soon.

If someone wants to tackle this in the meantime, that would be great as well but if not I'll end up doing it.

mpiraux commented 6 months ago

We've been discussing this with François.

The way ProxyJump works in ssh is by configuring a ProxyCommand that connects to the jump host, establishes a TCP connection towards the ultimate destination and pipe this TCP connection (i.e. connecting the bystream) into this initial SSH session.

The best way forward, as SSH3 is built atop HTTP/3, is to use HTTP/3 proxies for this purpose. The MASQUE wg is working on a QUIC-aware proxying mode that specifically tackles problems arising from QUIC-in-QUIC in such chains, such as the per-packet encapsulation overhead.

This will bring a Tor-like level of protection regarding the hosts in the chain: A jump host is not able to decrypt packets for the next host in the chain, and a jump host is not able to learn the next hops past its immediate neighbour.

Another way is delegating the establishments of QUIC connections in between jump hosts to these servers. I feel it is a too strong parting of the current security model.

Now, Marten once wrote a MASQUE implem for quic-go, but I've no idea how well it tracks the current specification.

In the meantime, ssh3 is experimental so there is room for experiments! One way to address this use case could be to support reverse proxying, as currently discussed in #67. This implies that the traffic will be intercepted by the reverse proxy, which is a constraint that we can cope with during experiments I believe.

drewwells commented 6 months ago

This is interesting to me. I've written some tcp proxies before but they violated http/2 so were rejected by k8s upstream. @mpiraux Is your comment above related to this topic from cloudflare on a theoretical udp proxy? https://blog.cloudflare.com/unlocking-quic-proxying-potential

drewwells commented 6 months ago

found some references on quic-go's repo to proxy as well. I didn't read the RFC yet but it sounds similar to the cloudflare theories above. I have not found a complete implementation to investigate the feasibility https://github.com/quic-go/quic-go/issues/3756

mpiraux commented 6 months ago

The blog post covers the earlier works of the working group, namely CONNECT-UDP and CONNECT-IP. The former can be used to convey QUIC packets but is not as optimized as the upcoming QUIC-aware proxy. The latter is even more flexible but imposes more overhead.

Side note, CONNECT-UDP could also be used for SSH3 UDP port forwarding. But the support in quic-go/masque-go is lacking as indicated by the referenced issue. François made the choice of directly using the QUIC Datagrams instead for a smaller codebase when undertaking his research work.

francoismichel commented 6 months ago

Hi!

PR https://github.com/francoismichel/ssh3/pull/94 implements classical ProxyJump by tunnelling QUIC using SSH3 UDP port forwarding. The PR is not merged yet as it relies on a currently non-stable quic-go version (commit 1083d1fb) that itself drops support for Go 1.20, but if it appears to work well, we can make ProxyJump part of one of the next SSH3 releases.

I will keep this PR up-to-date with our upstream as the changes are reasonably small.