I want to connect to a remote Linux computer from my Windows laptop. Ideally, I’d like to see the same graphical display (i.e. Unity) from my laptop as if I were sitting as the physical machine. The end goal can be seen in the header image of this post.
I debated not even writing this post, but I get tripped up every time I have to setup remote desktop access to a new machine. There are so many different ways to do this (Remote Desktop, NX, VNC), but some approaches seem to work better than others. In my situation, I found myself commonly using a slow VPN connection to remotely access machines on my work network from home, so I needed something fast and lightweight. In general, I have found that VNC running over an SSH connection works best for me in this scenario.
Disclaimer: Some of you may disagree with me, and that’s ok; I’m simply stating what has worked well for me in the past.
In this section, I’ll walk you through setting up an SSH server, an SSH client, a VNC server, and a VNC client. At the end, you should have a secure VNC connection that tunnels its traffic over SSH to your remote.
In my case, my remote system is running Ubuntu 12.04 Linux, and my local system (i.e. my laptop) is running Windows 7.
Installing SSH Server on Remote
For this part, you will need physical access to the remote system. Basically, we just have to get an SSH server running on our remote system. If you already have that working, skip this section.
To install SSH, login to the remote system and open a terminal. Then install openssh-server:
sudo apt-get install openssh-server
Once the SSH server is installed, feel free to configure it as you like. For now, it’s probably best to make sure PasswordAuthentication is set to ‘yes’. To change this, open /etc/ssh/sshd_config in your favorite editor. Mine is vim, so that’s what I’ll use in my examples:
sudo vim /etc/ssh/sshd_config
Find the line that says PasswordAuthentication, uncomment it, and change the text to “yes”.
Also, uncomment the line that says AuthorizedKeysFile, and change append a random number as a suffix to the default file name. In my case, I use the number 11 as a suffix.
RSAAuthentication yes PubkeyAuthentication yes AuthorizedKeysFile %h/.ssh/authorized_keys11
Close the sshd_config file and restart the SSH server
sudo service ssh restart
Later on, you will either need the name or IP address of your remote system. If you don’t know the name or IP address, now is probably a good time to use ifconfig to figure that out. Save this IP address for later use.
Installing SSH Client on Local
At this point, we have an SSH server running on our remote machine. We therefore no longer need access to this remote machine, so we can go back to our local machine. In this case, that means I’ll jump back on my laptop.
We now just have to install an SSH client on our local machine. There are many SSH clients out there, but I prefer using PuTTY (see my Disclaimer above). Download the latest version of PuTTY for 64-bit Windows and go through the installation process (not shown here). Be sure to grab the version of PuTTY that includes all PuTTY utilities, not just the SSH client binary.
The first thing to do after installing PuTTY is to run the PuTTY Key Generator (PuTTYGen) to generate a public/private RSA key pair for your local system. In the PuTTY Key Generator window, click Generate.
You’ll need to randomly move your mouse over the blank area, as instructed by PuTTYGen to generate some randomness for your key. After doing so, you should be able to save both your public (red) and private (green) keys somewhere on your local system. Remember where you save these keys, because you will need them when logging into the remote system over SSH. Note that you have the option to protect your private key with a passphrase. If you use this passphrase, the private key will be more secure, but you will need to enter it every time you try to SSH into a machine using this key pair.
Next you need to somehow securely copy your public key (which you just generated) over to your remote system, and you need to copy it into ~/.ssh/authorized_keys11, which we specified earlier in the /etc/ssh/sshd_config file on the remote system.
One way to securely copy the public key to the remote system is to just load it onto a flash drive and copy it over. This only works if you have physical access to the remote system though. If you don’t have physical access to the remote system, you can use something like WinSCP to copy the public key from your local system to your remote system.
Note that WinSCP uses the same port as SSH (port 22), so if you have SSH setup, WinSCP should work here. Simply enter the name (or IP address) of your remote system under Host Name, then specify your User name and Password, which is your login info on the remote system. After entering that info, click Login at the bottom of the WinSCP window.
WinSCP opens 2 windows (side-by-side); on one side is your local system and on the other is your remote. In WinSCP, on the local system side, navigate to the directory that contains your id_rsa.pub (which is the public key that you just created in the previous step). Now on the remote side, navigate to the ~/.ssh directory. If that directory does not exist, create it.
Drag and drop your id_rsa.pub from the local side over to the remote side of the WinSCP window to securely copy your public key from your local system to your remote system. Once the copy is complete, simply rename id_rsa.pub to authorized_keys11 (or whatever name you specified in /etc/ssh/sshd_config). After that, you can close WinSCP.
Now it’s time to open PuTTY (Start->PuTTY). You’ll see something that looks like this:
The first thing to do is to specify your auto-login username, which is your username for the remote system. In my case, this is my username for my Ubuntu system.
After specifying your username, we need to specify the location of our private key file, which we created in a previous step. To do this, navigate to Connection->SSH->Auth on the left side of the PuTTY window. Then click Browse and navigate to your private key file.
In our final configuration, we are going to tunnel our VNC traffic through SSH. We therefore need to setup this tunnel in our PuTTY configuration. Navigate to Connection->SSH->Tunnels on the left side of the PuTTY window. Enter 5901 as your Source port (red) and localhost:5901 as your destination (green). VNC traffic by default uses port 5901, so this configuration will take any VNC connection from localhost:1 (on your local system) and route it through SSH to your remote system. The reason that we do this is so we can piggyback off the RSA security provided by the SSH connection, which we cannot easily recreate natively using a VNC client. Make sure that you click the Add button (blue) to actually add the tunnel to your configuration.
Lastly, we need to specify the name (or IP address) of our remote system (see the end of the previous section). Navigate back to the Session screen (on the left side of the PuTTY window) and enter your remote system name or IP address here.
Before doing anything else, give your session a name (in the text box on this same screen below Saved Sessions), and click on Save. Finally, login to the remote system by clicking Open at the bottom.
Assuming everything went ok, you should see a black window pop up and a message on the screen like we see in the 2nd line here.
If you see a message that says something like, “Server refused our key”, stop; something went wrong and you need to fix it before proceeding. If you see a similar message as the one above, continue on.
At this point, we have securely logged into our remote system using SSH with RSA authentication. We now need to disable password authentication, or else attackers can just try to guess our password.
To disable password authentication, use your favorite editor again to open /etc/ssh/sshd_config
sudo vim /etc/ssh/sshd_config
Leave the PasswordAuthentication line uncommented, but change the value to no.
Save and close the sshd_config. Restart ssh
sudo service ssh restart
Installing VNC Server on Remote
Now that we can SSH from our local system to our remote one, we need to setup a VNC server on the remote system; that will let us view the graphical display over a remote connection.
If you aren’t already logged in, log back into the remote system using SSH. Then install vnc4server from the command line
sudo apt-get install vnc4server
Now launch the server. Note that the first time you launch vncserver, it will ask you to create a password to access your desktops. Rememeber this for later use, because you will need it when using your VNC client.
Now kill the VNC server. We only launched it so we could initialize the password and so it would create a default xstartup file. Create a backup of the xstartup file and then use your favorite editor to modify the original.
vncserver -kill :1 cp ~/.vnc/xstartup ~/.vnc/xstartup.bak vim ~/.vnc/xstartup
You only need to modify 1 line of the file. Simply add exec gnome-session immediately after the #!/bin/sh line. Here is what my full ~/.vnc/xstartup file looks like after the changes.
#!/bin/sh exec gnome-session # Uncomment the following two lines for normal desktop: # unset SESSION_MANAGER # exec /etc/X11/xinit/xinitrc [ -x /etc/vnc/xstartup ] && exec /etc/vnc/xstartup [ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources xsetroot -solid grey vncconfig -iconic & x-terminal-emulator -geometry 80x24+10+10 -ls -title "$VNCDESKTOP Desktop" & x-window-manager &
Now that you have your VNC server set to startup correctly, let’s launch it again (for real this time). Note that you may want to set the resolution for your VNC server to the same (or lower) resolution as the monitor for your local system. For example, my laptop uses 1600 x 900 resolution.
vncserver -geometry 1600x900
Installing VNC Client on Local
Now is the easy part. We have already setup an SSH server on our remote system, an SSH client on our local system, and a VNC server on our remote system. All we have left to do is install a VNC client on our local system and connect to our VNC server using our SSH tunnel.
To do this, download and install TightVNC client. After downloading, open the client. Since we already have our SSH tunnel setup, all we have to do is connect to localhost:1 in our TightVNC client.
Click connect, and you should see a new window appear with something that looks like an Ubuntu desktop.
If you see this, you’re all done! If you instead see a gray screen, you may need to install gnome-core.
sudo apt-get install gnome-core
Congratulations! You now have a working remote desktop connection!
Note that the VNC server is not persistent through a reboot. If you reboot your machine, you will have to reconnect to it (using your SSH client) and then you’ll have to rerun the vncserver command (with your desired geometry). It’s possible to setup your remote to automatically launch the VNC server at boot, but we consider that outside the scope of this guide.