SSH-protected VNC: the case of the Windows client and the Unix server
Given that SSH is such a versatile and flexible program, and given that port forwarding is sufficiently clever that one easily gets one's brain entangled trying to figure out what goes where, I thought I'd provide a simple step-by-step recipe for the common case in which one uses a Windows machine as a VNC client to a Unix desktop. I used the free SSH client which was provided by Cedomir Igaly at http://www.doc.ic.ac.uk/~ci2/ssh/ . Unfortunately this site seems to have disappeared, but there is a copy of it at http://linuxmafia.com/pub/ms-windows/igaly-ssh. We've also been told you can get one at http://akson.sgh.waw.pl/~chopin/ssh/index_en.html or http://marvin.criadvantage.com/caspian/Software/SSHD-NT/default.php, but we haven't tried either of them. An alternative is to use the TTSSH extension to Teraterm Pro.
The scenario is as follows: I am not at my laboratory and I am using my own Windows laptop, called Alice, connected as a guest machine to the network of the university I am visiting. My laboratory runs an SSH daemon on Unix machine Bob, which is connected through the lab's network to Unix machine Charlie, which runs my Unix VNC desktop as, say, Charlie:4. I wish to run a VNC client on Alice that will connect using SSH to Bob over the insecure wide area network, and from there without encryption to Charlie over the secure local area network.
Without any of this encryption business, the VNC client on Alice would connect straight to port 5904 on Charlie.
With the encryption, it will end up connecting to Alice itself (localhost) on an arbitrary port, say 5954, which SSH will tunnel through Bob to Charlie's 5904.
The difficult question for the newcomer, when faced with something like the opening dialog box of Cedomir Igaly's SSH Windows client, is where to put all those machine names and port numbers: are they local or remote forwards? Which host goes where? Do I need one forward from Alice to Bob and then another from Bob to Charlie, or do I do everything in one move?
In the terminology of the SSH man page, what we want to do is called a local forward, because the fake port is created on the local host. The whole route from Alice to Charlie is covered in just one forward operation, corresponding to the two command line arguments
-L 5954:Charlie:5904 Bob
The first argument is the local forwarding option which says that the local fake port 5954 should be created and connected to the genuine port Charlie:5904. The second argument is the main non-option parameter to SSH, which tells it the machine to which it should connect, i.e. the one that runs the SSH daemon.
As far as the Windows client is concerned, Bob goes in the "host name" entry field. The other three items (5954, Charlie, 5904) should be inserted in the dialog box that pops up when you press the "local forwards" button, as "local port", "host" and "remote port" respectively, making up one line of the "forwarded ports" listbox.
Having done this you should type a profile name in the main window, for example VNC, add your user ID (the one on Bob) in the appropriate field and hit save.
On hitting ok you will proceed to authentication. In the simple case of password based authentication, you just type in your Bob password and you get a "host is not known" window with the public key of computer Bob. At this point most impatient users would just hit "accept key" or "accept once" but you, being careful, will instead verify that it corresponds exactly to the one you copied from Bob's /etc/ssh_host_key.pub when you were still at your lab. This will safeguard you from man in the middle attacks where another computer pretends to be Bob. Once you are happy that the key being presented to you is indeed Bob's, you can click on "accept key", which causes the key to be recorded on Alice's known.hosts file, the exact location of which may be specified from the menu entry "setup/file locations". (Of course you could manually put the key in that file before even starting the client the first time, which would save you from performing the tedious verification; but then you would run the risk of getting the format wrong and so on.) Having done this once, you will never have to perform that verification again.
At that point you should have a shell connection to Bob. You can now iconify that and start your VNC client on Alice, pointing it at "localhost:54", and everything should work. Don't forget to follow the official advice on using VNC's hextile encoding rather than raw: raw is more efficient for a local (same machine) connection, so some viewers will choose it by default seeing that you connect to localhost; but you are not really on a local connection, so you should manually select hextile, which is more efficient for connections that go across the network.
Note that if you wish to use the Java viewer, you'll also need to forward port 58xx in the same way as the 59xx examples above, because the Java applet is downloaded via ports 58xx. For the above example, you would forward port 5854 to Charlie:5804 as well as 5954 to Charlie:5904.
For comments, feedback, etc, please see the 'Keeping
in touch' page.