Deploying an SSH-based VPN solution

Configuring and deploying VPN remote access solutions can be a complicated and time-consuming, not to mention expensive, exercise. For companies looking to provide a simple, inexpensive, secure remote access solution to staff, then an SSH-based VPN may be the answer.
I have blogged previously about the free OpenVPN software (http://blog.brightpointuk.co.uk/openvpn), which is able to provide SSL-based VPN access, but this solution can require some detailed knowledge of networking on behalf of the administrator, and also (as with most solutions) effectively makes the remote client a host on the local network, with all the security considerations that this entails.

The solution I'm going to look at today works differently: a terminal server is deployed at the office, or specific desktop machines can be deployed on a per-user basis if required. Remote users can remotely log into this Terminal Server and access desktop applications and LAN-based resources via Remote Desktop or VNC. The solution requires only that a single TCP port be opened on the firewall, and a key file be saved onto the user's remote PC.
Because the remote PC is not on the local network, rather a local machine is being remotely controlled, there is no concern of viruses or other malware gaining access to the network from the remote machine, and bandwidth requirements are low.
Although this solution does require that hardware be deployed in the office, it has the advantage of allowing users to use their personal home PCs if desired without undue security concerns - and can work across a wide range of client platforms including Windows, Mac and Linux.

Because this solution involves users remote controlling a LAN-based machine rather than being a virtual host on the remote network, files on the user's real machine cannot simply be transferred to network drives and applications cannot access LAN-based resources directly. But should your users require access to an intranet or a web-based application, and can open and edit files stored on the LAN from the remote desktop, then this should not be an issue. The type of access your users will require should be taken into consideration.

I shall now look at the steps involved in deploying this solution.


Deploy a Terminal Server

Each user that is going to be using the solution will need a machine to remotely control. This might be a Terminal Services machine with the appropriate number of CALs, a VMWare server with multiple virtual machines configured, or real machines (if users have office-based desktop PCs, these could be used - but this is not a very green solution).

Whatever the machine, any required users will need to be added to the Remote Desktop Users group:

Deploying an SSH-based VPN solution

Or you may prefer to simply add 'Domain Users' to the group for ease of administration.


Deploy the VPN Server

In this scenario the VPN server itself is only acting as an SSH server and router and as such does not need to be very powerful, or indeed even a physical machine - a virtualised host would be fine.
In this example I am using the free, open source CentOS Linux distribution (http://www.centos.org).
Install a base configuration of the server - SSH functionality will be installed automatically.
Create a non-root user account, let's call it 'vpn'.
Edit the SSH configuration file located in /etc/ssh/sshd_config
Edit the port that the SSH service will use from the default 22 to a port of your choosing. In this example I am using TCP port 8999, chosen entirely at random:

Deploying an SSH-based VPN solution

The server will need to be assigned an external, Internet-facing IP address, with a DNS entry if desired. The server can be located on the LAN, with the selected port open on the firewall from the Internet to the internal address of the SSH server. If this is not satisfactory, the server can be located in a DMZ or Core network segment, just ensure that the SSH server is accessible from the outside world on the target port, the SSH server 'knows' how to route incoming requests to the LAN subnet(s), and the desired ports are open between the SSH server and the LAN (3389 in the case of RDP or 5900 in the case of VNC).


Generate client SSH keys

Keys can be generated on a Mac or a Linux-based machine at the command line using the ssh-keygen command. The process is simpler on Windows machines using the free PuttyGen utility, available from http://the.earth.li/~sgtatham/putty/latest/x86/puttygen.exe

Deploying an SSH-based VPN solution

Click on the Generate button, then move the mouse across the window to create 'randomness' with which to create the key"

Deploying an SSH-based VPN solution

Once complete the key will be displayed:

Deploying an SSH-based VPN solution

You may find it useful to edit the contents of the Comments field to enter the name of the user that the key was generated for. Copy the whole key:

ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIBQxT0fyUIh1uGPoRRf4Rh8kh4Uq16
qYczeGxC+OrQkeCy0fjW7YO7HCeG5mtFxDyOEXTaBj5AAo4gE2rJQ+4bhGDmcqEmk
XhkjuDW01joBTYx1em+JUbiM3/qLLBAvefsqSL1LhrsiJovIAjvMJsKuH2k6//BlK/7vVr2Y
gZrDBQ== Generated for James Liddiard

On the SSH server, log in as the 'vpn' user, or as root and then issue 'su - vpn' to become that user.
You should be in the /home/vpn/ directory. Create a new directory called '.ssh'

mkdir .ssh

Create a new file called 'authorized_keys'

touch authorized_keys

Edit the file

view authorized_keys

Paste the whole key into the file and save it.

On the Windows client, select the option to save the private key, selecting Yes when prompted to save the key without a passphrase. They key will be saved as a .ppk file, keep it somewhere safe.

The key is now authorised for SSH access to the server. Repeat this process as often as required.


Configure the Windows client

Create a directory on the C drive, or somewhere suitable. Let's call it 'SSH'.
In the directory, save the .ppk file created earlier.

Download and save the file 'plink.exe' in the same directory, available from http://the.earth.li/~sgtatham/putty/latest/x86/plink.exe

We will need to accept and store the key of the SSH server. Run the following at the command prompt:

c:\SSH\plink -v -ssh -2 -P 8999 -l vpn 62.189.60.226

Where c:\SSH is the path to the location of the plink.exe file, 8999 is the port number specified for access to the SSH server, where vpn is the name of the non-root user account created on the SSH server, and where 62.189.60.226 is the external IP address of the SSH server.

This command can be saved in a batch file which can be double clicked to make things simpler, you will be prompted to accept the key and store it:

Deploying an SSH-based VPN solution

You will then be prompted to enter the password for the vpn user:

Deploying an SSH-based VPN solution

At this stage just press CTRL-C to end the batch job, there is no need to authenticate once the key has been stored.

Create a VBS script file, let's call it 'connect_vpn.vbs', use the following text:

Dim WSHShell
Dim WSHShell2
Dim Message
Dim Title

Set WSHShell = WScript.CreateObject("WScript.Shell")

cmdLine = "%comspec% /c c:\ssh\plink -v -ssh -2 -P 8999 -batch -l vpn -C -i c:\ssh\jimbob.ppk -L
127.0.0.2:3389:172.16.196.131:3389 62.189.60.226"
WshShell.Run cmdLine, 2
WScript.Sleep(10000)
WshShell.Run "mstsc /v:127.0.0.2:3389 /f"

where 'jimbob.ppk' is the name of the key file we created earlier and where '172.16.196.131' is the IP address of the internal machine to be remotely accessed.

Double click, or invoke the VBS file. The client will authenticate with the SSH server and forward the RDP request to the internal IP address of the machine to be accessed. After a pause of 10000 counts (as defined by the 'sleep' command), the Windows Remote Desktop client will launch and initiate a connection to 127.0.0.2 (a localhost address which will be forwarded by the plink script).
The 10000 delay command is arbitrary, this is the length of time it should take the SSH client to connect and authenticate. The RDP client will launch after 10000 milliseconds regardless as to whether the connection is established or not, therefore you may need to adjust this value yourself. It may be too long for 3G or DSL-based connections in which case it can be reduced. Don't be afraid to experiment.

If you are using VNC-based connections, then simply substitute the entries for 3389 with 5900 instead, and substitute the entry for 'mstsc' with the appropriate command line path to the VNC Viewer executable you are using, and use suitable switches.


Configure the Mac client

The procedure for configuring a Mac client in terms of keys is slightly different, MacOS not knowing what a 'ppk' file is.
If your administrator has generated a PPK file for you, then you will need to either convert it to an OpenSSH key, or generate key file manually on your Mac using the ssh-keygen command within Terminal:

ssh-keygen -f jimbob -b 1024

This will create 2 files within the directory in which the command was executed: 'jimbob' and 'jimbob.pub'.
Open the file 'jimbob.pub' using a suitable text editor:

Deploying an SSH-based VPN solution

Copy the contents of the file and save the key to the authorized_keys file on the SSH server as before.

On the Mac client we will need to accept and store the key of the SSH server as before. Open the Terminal application and run the following at the command prompt:

ssh -p 8999 -l vpn -i jimbob -L 3389:172.16.196.131:3389 62.189.60.226

You will be prompted to accept the key of the SSH server, type in 'yes' and press Enter.

The key has now been stored on the local Mac client.

Create a text file (with no extension) on the Mac with the following command line:

ssh -p 8999 -l vpn -i jimbob -L 3389:172.16.196.131:3389 62.189.60.226

Let's call it 'ssh_vpn'.

Launch the Terminal application and invoke the command by browsing to the correct directory and issuing:

. ./ssh_vpn

You will be connected to the SSH server as the VPN user (excuse my welcome message, I chose it purely to prove that I was indeed connecting as the correct user):

Deploying an SSH-based VPN solution

You can now launch a suitable RDP client on the Mac and connect to an address of 172.0.0.1, which will be forwarded automatically. Again, if using a VNC client, substitute any entry for 3389 with 5900 as the port number instead.

If you need to convert a supplied PPK file to the OpenSSH format for Mac usage, you will need to install the "MacPorts" version of Putty on your Mac: browse to http://www.macports.org in your browser and install the relevant package for your platform:

Deploying an SSH-based VPN solution

Before you will be able to install MacPorts, you will need to install the XCode tools from your MacOS installation source.

Once installed, run the following commands:

sudo port install putty

The required packages will be downloaded and installed, this process may take a few minutes:

Deploying an SSH-based VPN solution

Once installed, browse to the directory where the PPK file has been saved and convert it with the following command:

puttygen jimbob.ppk -O private-openssh -o jimbob.ssh

Now create a text file as we did before, but this time with the new details of the private key file:

ssh -p 8999 -l vpn -i jimbob.ssh -L 3389:172.16.196.131:3389 62.189.60.226

and run the file with the command:

. ./ssh_vpn

Once connected you can launch either a Remote Desktop or VNC client:

Deploying an SSH-based VPN solution

VPN-tastic!