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

Internal SSH client does not support all features of ~/.ssh/config, ProxyJump/ProxyCommand #393

Open
gdevenyi opened this issue Dec 20, 2023 · 9 comments

Comments

@gdevenyi
Copy link

I'm trying to use the session manager to smooth connecting and launching the VNC server via an SSH tunnel.

In my SSH configuration I use a ProxyCommand/ProxyJump command so that I can directly run ssh normally and the connection will be tunnelled.

Host workstation
  #ProxyCommand ssh -W %h:%p mygateway #Old SSH versions
   ProxyJump mygateway #Newer ssh versions

https://en.wikibooks.org/wiki/OpenSSH/Cookbook/Proxies_and_Jump_Hosts

i.e. I can run
ssh user@workstation
which the ssh client will transparently perform:
ssh -> mygateway -> ssh -> workstation
All features such as port forwarding (-L and -R) transparently work as though I am directly connected to workstation, I do not need to add any extra settings.

Thus, I would like to similarly do:
vncviewer user@worksation

Which will honour my ssh configuration and do:
ssh -> mygateway -> ssh -> workstation -> launch vncserver && forward ports

If you go looking around the net, there are loads of documentation on doing this process manually with TurboVNC and similar clients, this would be a massive improvement to the session manager.

@dcommander
Copy link
Member

dcommander commented Dec 20, 2023

I think it would probably be easier to figure out how to make the Session Manager work with external SSH clients, which already support jump hosts, than it would be to figure out how to implement ProxyJump/ProxyCommand with JSch. The original JSch code base is basically abandoned, so I can only really extend it by implementing features from scratch (which is difficult) or borrowing them from the JSch fork.

In fact, referring to #321, you can already use ExtSSH with the Session Manager. It just causes two SSH sessions to be created, one by JSch for the Session Manager itself and a second by the external SSH client for the SSH-tunneled RFB connection. That means that SSH authentication occurs twice, which isn't optimal, and the Via parameter is only honored for the SSH-tunneled RFB connection. Ideally, if ExtSSH is specified, the Session Manager should use the OpenSSH ControlMaster feature to preserve the initial SSH connection for reuse by the SSH-tunneled RFB connection. Then it would be a matter of repurposing the TurboVNC Viewer's Via parameter so that it populates the -J option to OpenSSH. That would probably also trigger me to revisit the legacy VNC_VIA_CMD and VNC_TUNNEL_CMD interfaces and create a more user-friendly interface for customizing the external SSH command.

Conceptually, the setup would work kind of like this (although the actual Session Manager would have to handle multiple sessions rather than assuming only one session on Display :1):

$ ssh -o ControlMaster=auto \
  -o ControlPath=\"~/.ssh/turbovnc-session-manager-%C\" -o ControlPersist=60 \
  -J {gateway-host} {turbovnc-host} \
  "/opt/TurboVNC/bin/vncserver -list | grep \:1 || /opt/TurboVNC/bin/vncserver"
$ ssh -o ControlPath=\"~/.ssh/turbovnc-session-manager-%C\" \
  -o ControlPersist=60 \
  -J {gateway-host} -axf -L {free local port}:localhost:5901 {turbovnc-host} sleep 20

However, I would also want to extend the feature so that it supports SSH forwarding using Unix domain sockets, since TurboVNC 3.1 now has that ability. Conceptually it's straightforward, but it would require a lot of testing, so ideally I would like to secure funding.

Closing this issue in favor of #148, but let me know if, for some reason, my proposal wouldn't solve the problem from your point of view.

@gdevenyi
Copy link
Author

In fact, referring to #321, you can already use ExtSSH with the Session Manager. It just causes two SSH sessions to be created, one by JSch for the Session Manager itself and a second by the external SSH client for the SSH-tunneled RFB connection.

I saw this issue, but I couldn't sort out if this would apply to me as the user failed to ever provide any examples of commands/configurations he was using. I have tried to use -ExtSSH but it always seemed to ignore it (for 3.1-20231117 at least), if I was trying to use the session manager interface, it always directly internal SSH'd to the host.

I agree the enhancements and procedure in general make sense for the Linux/Mac user, my concern about external SSH is a Windows user probably won't have that available, and be locked out of the next-gen features planned.

@dcommander
Copy link
Member

Ideally the feature would work with Microsoft's OpenSSH implementation. I need to play around with it and see if I can eliminate the need for SSH forking (the -f option), since only Cygwin's OpenSSH implementation supports that on Windows (but Cygwin doesn't support ControlMaster.)

Unfortunately extending JSch to handle ProxyJump/ProxyCommand probably won't happen unless someone else adds the feature to the aforementioned JSch fork. Since I don't have a deep familiarity with the JSch code base, figuring out how to implement such a major feature myself would likely take more labor than anyone is willing to pay me for.

@dcommander dcommander reopened this Aug 1, 2024
@dcommander
Copy link
Member

dcommander commented Aug 1, 2024

Reopening because I sort of figured out how to make the Session Manager do a multi-level tunnel using JSch. To back up a bit, the Session Manager opens an SSH connection to the host and uses that connection to execute shell commands (running /opt/TurboVNC/bin/vncserver to list active sessions, start a new session, or kill an existing session.) Once a session is chosen, the Session Manager reuses the same SSH connection, enables port forwarding on it, and connects to the TurboVNC session through that tunnel. It is already possible to establish a multi-level SSH tunnel with JSch for the actual RFB connection, using the TurboVNC Viewer's Via parameter. It's simply a matter of figuring out how to do likewise for the Session Manager's shell connection.

I was able to make it work by forwarding a local port through the gateway to the TurboVNC host's SSH port and creating a second SSH session through that local port in order to execute the Session Manager's shell commands on the TurboVNC host. That's a little messy, though, so further research is needed on my part. It may ultimately be better to support something similar to ProxyCommand, and I notice now that JSch does support setting a proxy command. (It just doesn't currently support the ProxyCommand directive in OpenSSH config files.)

@dcommander
Copy link
Member

Actually, upon closer inspection, the ProxyCommand code in JSch is commented out, so I guess it was never finished. But it seems straightforward to either

  • Use the Session Manager's SSH shell connection to execute, say, ssh {turbovnc_host} /opt/TurboVNC/bin/vncserver instead of /opt/TurboVNC/bin/vncserver and allow the SSH command to be configured by way of a parameter. The main issue there is whether SSH agent forwarding works properly.

or

  • Do the port forwarding trick I mentioned above and allow the TurboVNC host's SSH port to be configured separately from the gateway host's SSH port.

@dcommander
Copy link
Member

My current plan is to go with the SSH port forwarding approach, which seems to be what OpenSSH does when using ProxyJump. My current thinking is to introduce two new parameters, ViaJump (boolean) and ViaSSHPort (integer.) ViaJump will be enabled by default and force-enabled when using Via with the TurboVNC Session Manager. It will cause the built-in SSH client to jump hosts by forwarding the SSH connection through the gateway host to the TurboVNC host, as opposed to forwarding the RFB connection through the gateway host to the TurboVNC host. IOW, it will implement a two-layer SSH tunnel instead of a one-layer SSH tunnel. (In addition to allowing the Session Manager to work properly with Via, this will have the added advantage of not requiring any RFB ports to be open in the TurboVNC host's firewall.) When used with ExtSSH and Via, ViaJump will cause the default external SSH command-line template to change from %S -f -L %L:%H:%R %G sleep 20 to %S -J -f -L %L:localhost:%R %H sleep 20. ViaSSHPort will allow a different SSH port to be specified for the gateway host, if it differs from the SSH port of the TurboVNC host. (Otherwise, if ViaSSHPort is unset, then SSHPort will specify the SSH port for both hosts.) I also intend to try adding support for ProxyJump, so the same result will be achievable with an OpenSSH config file. (IOW, if a jump host is configured, then the TurboVNC Session Manager will work without needing to specify the Via parameter.)

Feedback welcome.

@gdevenyi
Copy link
Author

gdevenyi commented Aug 12, 2024

This sounds pretty great

@ubless607
Copy link

How long will it take to be implemented? Can't wait to see.

@dcommander
Copy link
Member

Please be patient. I maintain three projects, and libjpeg-turbo is a priority right now due to a paying customer needing the next major release of that software by September 15.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants