SSH Tunnel for VNC that autocloses when idle

In the category of "Things I pieced together with help from users on the Internet..."

Task: run vnc remote display through a ssh tunnel to encrypt traffic from a localhost to a remote VNC (in this case, from my work laptop to my home Mac mini).  I'll leave how to configure your home Internet service to allow incoming external connections to vncserver as an exercise for the reader.

-- From: https://unix.stackexchange.com/questions/83806/how-to-kill-ssh-session-that-was-started-with-the-f-option-run-in-background

Using this advice, create a one line command to create the ssh tunnel, launch the VNC client, and destroy the tunnel after disconnecting the VNC client

Before setting this up, setup ssh key-based logins from the localhost to the remote host so there are no login details to exchange.

Localhost: ssh-keygen
localhost: sftp remote host : transfer public key
Remotehost: cat .pub >> ~/.ssh/authorized_keys

The following one line command creates the SSH tunnel on localhost port 5901 to remote host 5900 which is the default port for VNC.  Screenshare on the Mac, at it's core, is Apple's implementation of VNC.

ssh -f -L 5901:localhost:5900 me@remotehost.example.org sleep 10; open vnc://localhost:5901

This creates the tunnel, and executes the "sleep 10" command on the remote host, suspends the SSH session and then executes the localhost application, in this case the native vnc app on the Mac. As long as the vnc app connects before the 10 seconds that sleep is waiting, it should connect. See the StackExcahnge post linked above for the technique, relevant comment pasted below:

--

As it has been mentioned previously, instead of using the -f -N switch combination, we can just use -f alone, but also execute a command on the remote machine. But, which command should be executed, since we only need to initialize a tunnel?

This is when sleep can be the most useful command of all! In this particular situation, sleep has two advantages:

  • it does nothing, so no resources are consumed
  • the user can specify for how long it will be executed

How these help in auto-closing the ssh tunnel is explained below.

We start the ssh session in the background, while executing the sleep command for 10 seconds on the remote machine. The number of seconds is not crucial. At the same time, we execute vncviewer exactly as before:

[me@local]$ ssh -f -L 25901:127.0.0.1:5901 me@remote.example.org sleep 10; \
          vncviewer 127.0.0.1:25901:1

In this case, the ssh client is instructed to fork the ssh session to the background (-f), create the tunnel (-L 25901:127.0.0.1:5901) and execute the sleep command on the remote server for 10 seconds (sleep 10).

The difference between this method and the previous one (-N switch), basically, is that in this case the ssh client’s primary goal is not to create the tunnel, but rather to execute the sleep command for 10 seconds. The creation of the tunnel is some kind of side-effect, a secondary goal. If vncviewer was not used, the ssh client would exit after the 10 sec period, as it would have no more jobs to do, destroying the tunnel at the same time.

During the execution of the sleep command, if another process, vncviewer in this case, starts using that tunnel and keeps it occupied beyond the 10 sec period, then, even if the ssh client finishes its remote job (execution of sleep), it cannot exit because another process occupies the tunnel. In other words, the ssh client cannot destroy the tunnel because it would have to kill vncviewer as well. When vncviewer stops using the tunnel, then the ssh client exits too, as it has already accomplished its goal.

This way, no ssh processes are left running in the background.

Comments