Connecting to a remote GUI using VNC over an SSH tunnel
Sometimes, despite my preference for text based interfaces because of their simplicity, it is necessary to connect to a remote machine in a graphical manner. One way to do this is to use Virtual Network Computing (VNC). A VNC server makes the desktop environment of one machine available to a remote machine and receives keyboard and mouse events from the remote machine. In effect, you can control a distant machine from your desktop in a graphical manner.
To ensure that my session is encrypted over the public network, I make the VNC connection over an SSH tunnel.
The method for this is to start a vncserver instance on the destination, to make an ssh tunnel from my client to my server and then to connect.
Start vncserver
The number after the colon indicates which display to use, '-localhost' indicates that the client connection will come from a localport; this is ok because we're tunneling over SSH. There are a number of other options, see the manpage for vncserver(1).
vncserver :1 -localhost
If you are accessing the server over a WAN, you might want to specify geometry and/or color bitdepth:
vncserver :1 -localhost -geometry 1024x768 -depth 16
Setup the tunnel
This is initiated on the client:
ssh -N -T -L 5901:<server's IP address>:5901 &
- -N specifies that we're merely forwarding traffic not running a command on the remote machine.
- -T disables pseudo-tty allocation.
- -L indicates that the first port is a local port
Connect the client
Connecting the viewer client is simple, you merely connect to the local machine's listening port that you created in the previous step and traffic is automatically sent to the remote machine for you over the tunnel.
vncviewer localhost:5901
If you accessing the remote machine over a WAN connection, then you might want to specify the encoding for better performance.
Stop the server
You should probably stop the server when you no longer need it so that it's not just taking up valuable resources:
vncserver -kill :1
TightVNC
If you are using the TightVNC client, it will take care of the SSH tunnel for you with:
vncviewer -via <server's IP address>
The ssh connection attempt can be modified with the environment variable 'VNC_VIA_CMD', for example:
export VNC_VIA_CMD='/usr/bin/ssh -x -p 3022 -l duncan -f -L %L:%H:%R %G sleep 2'