* How To Set Up VNC Over SSH On Windows XP

Step-by-step instructions for setting up an SSH server, a VNC server, and an SSH client in order to VNC securely from one computer to another.

Introduction – RTFM or WTFM.

My new year’s resolution this year was RTFM. When there are (ahem) fine manuals, one can save time by reading them. But in many cases, manuals do not exist, or are not so fine. So I periodically write stuff down (WTFM, as it were) to document stuff. This article provides step-by-step instructions, with lots of screen shots, for setting up an SSH server, a VNC server, and an SSH client in order to VNC securely from one computer to another. All of this can be done with free open-source software.

VNC is a remote-control client/server application that allows a local client computer to connect to a remote server computer over a network. Keyboard and mouse inputs are sent from the local computer to the remote computer, and screen output is sent from the remote computer to the local computer. In this way, a PC can be used to remote-control a Macintosh computer or vice-versa. There are VNC clients and servers for numerous operating systems, including Windows, Macintosh, and Linux. A problem with VNC is that traffic is typically sent in plain text. This can include the username and password of the VNC service itself or of any services you are using via the remote computer.

When a website operator wants to provide a way for users to enter information (such as credit card numbers) securely, the website operator can provide those pages via the HTTPS protocol. HTTPS is the secure version of HTTP, and HTTPS (unlike HTTP) encrypts session data using either a version of the SSL (Secure Socket Layer) protocol or the TLS (Transport Layer Security) protocol.

A VNC session can be made secure by having the client and server connect via an SSH tunnel. All SSH data is encrypted, so all data passing through the tunnel is also encrypted. The resultant secure VNC connection is analogous to the HTTPS connection discussed above.

Step 1 – Install an SSH Server on the Remote Computer.

Step 1.1 – Download and Run Cygwin’s Installer.

Cygwin allows you to run Linux programs on a Windows PC.

Cygwin is not technically an emulation of Linux, it’s a Linux API emulation layer. For more information, see the Cygwin website (http://www.cygwin.com/). Cygwin is free open-source software created by Red Hat, the leading distributor of Linux. Support is available from Red Hat (http://www.redhat.com/software/cygwin/).

To install Cygwin, click on the “Install Cygwin now” icon on the Cygwin website (http://www.cygwin.com/).

Save the file “setup.exe” as “c:\cygwin\setup.exe”.

Then run “c:\cygwin\setup.exe” from the Windows “Start” menu.

Cygwin’s setup.exe program is designed to be very powerful, which it is. It also happens to be extremely non-intuitive, especially for first-time users. Here is a screen-by-screen step-by-step approach of what to do.

When you first launch the setup program, click the “Next” button.

When you select “Install from Internet,” you are actually downloading packages that setup.exe can install now or later. Select “Install from Internet” for now.

Next, install Cygwin in the “c:\cygwin” directory, install for all users, and use Unix-style text files.

Next, select “c:\cygwin” as the local package directory.

Next, set up your Internet connection type (“Direct Connection” in this example).

Next, select a download site. You can download by FTP or HTTP and there are lots of sites to choose from. If it’s daytime when you are doing your installation, it probably makes sense to choose a download site where it is nighttime.

Next, you have to choose which packages to download and install. There are 25 packages from which to choose. You only need to install the Admin package and a few programs from the Net package. I also like to install the Archive package. For all other packages, the default settings should suffice. To expand a package to see its contents, click on the “+” icon next to its name. To change the default settings, click on the icon the the left of the word “Default.” You can choose to install the source (the “Src?” column) or the binary (the “Bin?” column”) for each package, but you will not need the source code for this exercise.

Admin – Install cron, cygrunsrv, shutdown

Archive – Install cabextract, sharutils, unzip, zip (note that these are not necessary, but I like to have them)

Base – Default

Database – Default

Devel – Default (note that “gcc” and “make” can be installed from here)

Doc – Default

Editors – Default (note that Emacs (for East Coast Linux hackers) and Vi (for West Coast Linux hackers) can be installed from here)

Games – Default

Gnome – Default

Graphics – Default

Interpreters – Default (note that “perl” can be installed from here)

Libs – Default

Mail – Default

Math – Default

Mingw – Default

Net – Install autossh, openssh, openssl, ping, rsync (note that ping and rsync are not necessary, but I like to have them)

Publishing – Default

Shells – Default

System – Default

Text – Default

Utils – Default

Web – Default

X11 – Default

ZZZRemovedPackages – Default

_PostInstallLast – Default

If you get a “download incomplete” error, select another server and try again. Once your packages have started to download, a progress dialog appears like the following. Downloading make take a few minutes.

Next, your are prompted to create various Cygwin icons. You may not want an icon on the desktop for all users.

Next, Cygwin optimistically tells you that the installation is complete. Well, not exactly.

Step 1.2 – Configure Windows Environment Variables.

Cygwin relies on a couple of Windows environment variables. To set those variables to their proper values, right-click on the “My Computer” icon, select Properties, then select the “Advanced” tab.

Click the “Environment Variables” button. Under “System Variables” (NOT “User Variables”), click the “New” button. In the “Variable name” field, enter “CYGWIN”. In the “Variable value” field, enter “ntsec tty”.

Again under “System Variables” (NOT “User Variables”), select the “Path” variable and click the “Edit” button.

In the “Variable value” field, append “;c:\cygwin\bin” at the end of the current value, which will look something like this:

C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;c:\cygwin\bin

Step 1.3 – Setup the sshd.exe Service.

Next, start Cygwin from the “Cygwin Bash Shell” icon and enter “ssh-host-config” at the “$” command-line prompt:

$ ssh-host-config

If cygwin complains that you are missing a program (i.e. a “.dll” file), you’ll have to install the appropriate cygwin package containing the file. You can search for the appropriate package to install at the Cygwin website (http://www.cygwin.com/packages/).


If the “ssh-host-config” program runs properly, you’ll be prompted for various settings.

When you see “Should Privilege separation be used?” enter “yes”.

When you see “Should this script create a local user ‘sshd’ on this machine?” enter “yes”.

When you see “Do you want to install sshd as a service?” enter “yes”.

When you see “CYGWIN=” enter “ntsec tty”.

Step 1.4 – Test the sshd.exe Service.

To test the service, I like to start it, stop it, and re-start it as follows:

$ net start sshd
The CYGWIN sshd service is starting.
The CYGWIN sshd service was started successfully.
$ net stop sshd
The CYGWIN sshd service is stopping.
The CYGWIN sshd service was sopped successfully.
$ net start sshd
The CYGWIN sshd service is starting.
The CYGWIN sshd service was started successfully.

Alternately, you can use “cygrunsrv –start sshd” to start the SSHD service and “cygrunsrv –stop sshd” to stop it.

To ssh to your computer as the current user, enter the following command:

$ ssh 127.0.0.1

The first time you connect to a host computer, you will be told that the authenticity of the host cannot be established and prompted if you want to continue connecting. If you are certain that have entered the address correctly, enter “yes”; otherwise enter “no”.

To ssh to your computer as a different user, enter the following command:

$ ssh "John Q. Public"@127.0.0.1

If your computer has a private IP address, you can also use that IP address instead of 127.0.0.1 (which is “localhost,” your current computer).

Next, test the connection from another computer on your network using your private IP address (“192.168.10.29” in this example). If you are using a software firewall such as Windows Firewall or Zone Labs ZoneAlarm, you’ll have to configure those programs to allow ssh traffic through.

$ ssh "John Q. Public"@192.168.10.29

Step 1.5 – Run sshd.exe on a Non-standard Port.

By default, ssh runs on port 22. This, unfortunately, is a popular port for script kiddies and malicious hackers (note that a true hacker, by default, is not malicious) to probe.

To change the default sshd port, edit the file “C:\cygwin\etc\sshd_config” and change the line that says “Port 22” to “Port 22000” (or some other private port). For more info on port numbers, see http://www.iana.org/assignments/port-numbers.

You may need to copy the file “sshd_config” to another directory, edit it, and copy it back. You’ll also need to use a text editor that properly displays Unix-style text files (unlike Notepad, which comes with Windows). TextPad (http://www.textpad.com/) and OpenOffice (http://www.openoffice.org/) both do the right thing.

Then restart the sshd daemon by re-starting the computer or running this command from the Cygwin shell:

$ net stop sshd
$ net start sshd

Now you can access your ssh server by it’s non-standard port number as follows:

$ ssh -p 22000 "John Q. Public"@192.168.10.29

Step 2 – Port-Forward SSH Traffic from your Router to your SSHD Server.

You’ll need to configure port-forwarding on your router to send incoming ssh traffic to your newly created sshd server computer. Check the support website for your router’s vendor for details of how to set this up on your router. The basic steps are 1) assign a static IP address to each computer that you need to address from outside of your network, and 2) forward traffic on certain port numbers to the pre-defined static IP addresses.

If you have multiple SSH servers sitting behind a single NAT device, then you can access each of them from outside of your network by running each SSH server on its own unique non-standard port.

For example:

For IP address 192.168.10.29, you could run sshd.exe on port 22000.

For IP address 192.168.10.30, you could run sshd.exe on port 22001.

For IP address 192.168.10.31, you could run sshd.exe on port 22002.

Etc.

Step 3 – Install a VNC Server.

Step 3.1 – Download and Run the RealVNC Installer.

Install RealVNC 4.0 (http://www.realvnc.com/) as a system service. Under “VNC Server configuration” section, select both “Register and configure VNC Server for Service-Mode” and “Start the VNC Server in Service-Mode”. Then click the “Next” button.

Under the Authentication tab, click the “Set Password” button to set a password. Note that this is the password that all clients will use to connect to this computer’s VNC server.

Under the Connections tab, choose your VNC server’s port number. By default, VNC listens for incoming connections on port 5900. It also listens on port 5800 for Java-based users, which can be accessed by clients from a web browser. I don’t like the Java server, so I disable that. And I run multiple VNC clients, each on a unique port, so I never use the default port. In this example, I have set up the VNC server to run on port 5901.

For the rest of the settings, the defaults should suffice. Click “OK” and your VNC server should be set up and running.

Step 3.2 – Test the VNC Server from Another Client Computer on your Network.

From another computer on your network, open the VNC Viewer application and enter your server’s IP address, followed by a colon, followed by the port number on which the server is running. In this example, I entered “192.168.10.29:5901” in the Server field.

If everything is set up properly, you’ll get a login prompt:

Enter the password for the VNC server (the same password that you just selected in the previous step) and click the “OK” button. You should now see a window showing the remote computer. You can right-click on the VNC icon in the Windows taskbar to configure the VNC Viewer application, switch to full-screen view, etc. You can switch out of full-screen view by typing CTRL-ESC (simultaneously) to access the VNC icon in the Windows taskbar.

You can also make a shortcut for this connection. Copy the VNC Viewer shortcut to your desktop, and edit the “target” line to include the address of your VNC server. The “Target” field should contain something like the following:

“C:\Program Files\RealVNC\VNC4\vncviewer.exe” 192.168.10.29:5901

Step 4 – Make VNC Secure by Tunneling it Over an SSH Connection.

Now that you have 1) an SSH server running on a unique non-standard port and 2) a VNC server running on a unique port, you can access your VNC server securely from a remote computer. The final step is to configure an SSH client to create a tunnel and point the VNC Viewer application at the tunnel created by the SSH client.

Now you’ll need the public IP address of your router. You can find out your public IP address by going to http://www.whatismyip.com/.

Step 4.1 – Configure DynDNS (For Dynamic IP Addresses).

If your ISP does not provide you with a fixed (static) IP address, you can still access your network, but one more step will be required. For networks that have dynamic IP addresses, you can sign up for a free account with DynDNS.org (http://www.dyndns.org/services/dns/dyndns/) and install a software client on your server computer, such as DynDNS Updater from Kana Solution (http://www.kanasolution.com/). DynDNS Updater periodically sends your computer’s public dynamic IP address to the dyndns.org server, which then associates a domain name (such as remotecomputer.dyndns.org) with your IP address. Whenever your IP address changes, the new information is communicated to the dyndns.org server. In this manner, you can always access your remote computer by domain name (remotecomptuer.dyndns.org), even if you don’t know its IP address.

Step 4.2 – Try One SSH Client – Cygwin.

This example assumes the the public IP address of the remote network is 66.42.17.88 (which is an IP address that I pulled out of my hat). Note that we have set up the SSH server to run on non-standard port 22000 (port 22 is the default) and that VNC is running on port 5901 (5900 is the default).

One ssh client is the one included with Cygwin. From the Cygwin command line, you would enter the following command to ssh to your remote computer on port 2200 and establish a tunnel on port 5901 for VNC traffic:

$ ssh -p 22000 "John Q. Public"@66.42.17.88 -L 5901:127.0.0.1:5901

Step 4.3 – Try Another SSH Client – PuTTY.

Another ssh client is PuTTY (http://www.chiark.greenend.org.uk/~sgtatham/putty/). PuTTY has a graphical user interface and can store multiple configurations for different SSH sessions.

From the Session window, enter:

– your remote computer’s host name or IP address (“66.42.17.88” in this example),

– the port for your SSH server (“22000” in this example),

– the protocol (“SSH” in this example)

– the session name (“SSH to RemoteComputer” in this example)

Don’t load or save the session yet.

Select the Tunnels window (under Connection/SSH/Tunnels). In the “Source port” field, enter the port for your VNC server (“5901” in this example), and in the “Destination” field, enter 127.0.0.1, a colon, and the port for your VNC server (“127.0.0.1:5901” in this example).

Then click the “Add” button. Now you have a tunnel set up.

Return to the Session window and click the “Save” button. Your session should now be in the list of saved sessions (along with the “Default Settings” session).

To load a session, select it from the list and click the “Load” button. To start the loaded session, click the “Open” button.

Once you have logged in to your SSH server, whether via the Cygwin SSH client or the PuTTY SSH client, you are almost done.

Step 4.4 – Point VNC Viewer at the SSH Tunnel.

The final step is to connect to your VNC sever via the SSH tunnel you just created. To do this, open the VNC Viewer application (or the VNC client of your choice), and enter an address of the following form (“127.0.0.1:5901” in this example):

If everything is set up properly, you’ll get a login prompt:

If you close your SSH session, the VNC session will terminate, since all of the VNC traffic is being sent securely over the SSH tunnel.

As before, you can create a shortcut to your secure VNC session. Copy the VNC Viewer shortcut to your desktop, and edit the “target” line to include the address of your VNC server. The “Target” field should contain something like the following:

“C:\Program Files\RealVNC\VNC4\vncviewer.exe” 127.0.0.1:5901

Remember that whenever you want to start a secure VNC session, it’s a two-step process.

– First, establish the SSH session (via Cygwin’s SSH client, the PuTTY SSH client, or any other SSH client).

– Second, start VNC Viewer (or any other VNC client).

That’s it. Happy and secure VNCing!

56 Replies to “* How To Set Up VNC Over SSH On Windows XP”

  1. Hi,

    I am trying to install Cygwin on a WinXP Home Edition machine. In step 1.3, before the question “Should this script create a local user ‘sshd’ on this machine?”, the process halts with an error:
    *** Warning: The permissions on the directory /var are not correct.
    *** Warning: They must match the regexp d..x..x..[xt]
    *** ERROR: Problem with /var directory. Exiting.

    I suspect this has something to do with the Home Edition part? I am stuck here.

  2. Again, excellent tutorial.

    On my remote office I do a reverse port forwarding
    “ssh -N -f -R 42563:localhost:22 myself@home_pc.com”

    and at home I do
    “ssh -p 42563 myself@localhost

    and I have been able to view all my files on my office computer (which is behind a firewall) from my home computer.

    The problem is when my office PC reboots (OS is XP) to install updates or for any other reasons (power failure eg). How do I ensure that I have a fail safe system in such a way that whenever my office PC reboots, it will be able to establish a reverse port forwarding everytime?

    Something done automatically like:
    1. XP reboots successfully,
    2. Open (cygwin) bash shell,
    3. ssh -N -f -R 42563:localhost:22 myself@home_pc.com
    4. password is entered automatically

    Thank you.

  3. Greetings olsfw,

    You point about the known hosts file is correct. I have a script that nukes that file each time. Minor inconvenience.

    As for you Vista problem, sorry, can’t help. I’ve chosen never to use Vista. My next Windows machine will be a Mac running Parallels. I’ve got five boxed versions of Windows XP ready to load.

    Regards,
    Erik

  4. Hello Erik,

    Excellent Article.

    If you are SSH-ing to multiple machines behind a NAT, each running SSHD on a unique port, your known_hosts file will get confused, since each of those machines has the same PUBLIC IP address but has a unique private IP address. In this case, you can simply delete the known_hosts file before initiating a new SSH session. Since I routinely SSH to multiple machines at work from home, I have script files that look like this:

    #!/bin/sh
    rm /Users/erikjheels/.ssh/known hosts
    ssh -l “Erik J. Heels” 123.123.123.123 -L 5900:127.0.0.1:5900 -p 20

    I followed above instructions, SSH is fine, but when I open VNC viewer from ubuntu. It returned me error messages, “buffer_get_ret: trying to get more byte 4 than in buffer 0
    buffer_get_int: buffer error
    xtightvncviewer: VNC sever closed connection”

    If I open VNC viewer from Vista, it said “connection established”, and after 1 second, it said “connection closed”.

    Any suggestions?

  5. Hi,

    indeed the information posted here is awesome.
    I would like some advise regarding VNC …
    We have some users accessing a single server (where VNC server is also running). They would like to access a set of applications on the system, but one user wants his own desktop and another user wants another desktop. However, each user would like to be able to share and keep the state of the desktop he opened !!!
    From what I’ve tried so far, I concluded the following:

    1) if VNC runs from xinetd, each user can have his own desktop, BUT would loose state and would not be able to share

    2) run VNC as a deamon (basically run multiple daemons listening on multiple ports, e.g. 5906, 5907, 5908) so one user who wants to access the “foo” application would connect to VNC running on 5906, while another user who wants to access the “moo” application would connect to VNC running on 5907, etc. (of course this will not prevent anyone to connect to someone else’s desktop”).
    This way each user would keep the state of the VNC session (for the specific VNC port they connected to) and would be able to share it as well.

    What do you think this ? Any ideas, suggestions ???

    To add a bit more to the complexity, the users are using windows systems and are behind a firewall, but we are not allowed to open more ports !!!
    So, I am thinking of “tunneling” all this VNC sessions (5906, 5907, 5908, etc. through SSH and have something like this in my putty:

    L5906 localhost:5906
    L5907 localhost:5907
    L5908 localhost:5908

    then ssh to the remote server (+VNC server) and then connect to localhost:5906 with my vncviewer.

    Sorry, for the long writing !!!

    Cheers and thanks in advance.

    –Y

  6. Hi Erik,

    I have a very basic query.Is it possible to access the one machine vnc session in other machine in different location with internet connection in both PCs.

    for example: Is it possible to access all files in my linux machine which is in india provided broadband connection at both locations and vncserver installed in both systems

    Thanks,
    mohan.

  7. Hi Erik
    Thanks for your nice how-to.
    Titles 4.2 and 4.3 should read “ssh client” instead of “vnc client”.
    Best
    Dan

  8. Greetings Nikhil,

    The sshd_config is a plain text file, but it might be locked. Try rebooting in safe mode (hold down the F8 key while you reboot). You might need to rename to the to sshd_config.txt, edit it, then rename it back to sshd_config. Then reboot in normal (un-safe?) mode.

    Regards,
    Erik

Leave a Reply

Your email address will not be published. Required fields are marked *