Tunnelling RDP over ssh using Putty and Private Keys
Well this post is about several things rolled together. First let me introduce the "why".
RDP is very useful for managing Windows remotely but is not secure so should not be used directly across the interwebs. I want to tunnel the RDP across a secure protocol, in this case ssh makes a nice choice because tunnelling is something it does quite easily. In fact you can tunnel most protocols over most others but there isn't normally a reason to do that! The tunnel provides protection for my RDP protocol.
What tunnel involves is pointing your client (in my case a Remote Desktop session) to a port on my local machine and then have ssh listening on that port. ssh then talks to an ssh port on the foreign machine and then redirects the other end of the tunnel onto whatever port my client actually needs to talk to, in my case 3389 which is the standard RDP port. The advantage here is that I get ssl type security for the connection but also, I do NOT have to open 3389 on the firewall on my foreign machine.
In my case, I have made another subtle adjustment in that rather than using the default port 22 for ssh on my foreign machine, I have decided to move it. Quite simply, ssh ports are often hammered by attackers so moving it away from port 22 avoids the potential denial of service. I have chosen 7888 but you can choose whatever you want.
Now onto the implementation. Because I am running Windows, there are a few choices in how to get ssh functionality (it is not built in). I enjoyed running something called Cygwin which is a linux style prompt running under windows and which allows me to set these things up in the same way as I would on Linux. Unfortunately, it seems to have stopped working properly so I now use Putty which is a very common tool and runs well on Windows, the only slight downside is that I am using a private key to access my remote system and putty has its own slightly different format for keys which means I have a few more steps to perform before a simple setup in Putty can be carried out. If you are not using private keys for ssh access to your foreign machine, ignore the steps involving putty gen and the private key settings in Putty.
RDP is very useful for managing Windows remotely but is not secure so should not be used directly across the interwebs. I want to tunnel the RDP across a secure protocol, in this case ssh makes a nice choice because tunnelling is something it does quite easily. In fact you can tunnel most protocols over most others but there isn't normally a reason to do that! The tunnel provides protection for my RDP protocol.
What tunnel involves is pointing your client (in my case a Remote Desktop session) to a port on my local machine and then have ssh listening on that port. ssh then talks to an ssh port on the foreign machine and then redirects the other end of the tunnel onto whatever port my client actually needs to talk to, in my case 3389 which is the standard RDP port. The advantage here is that I get ssl type security for the connection but also, I do NOT have to open 3389 on the firewall on my foreign machine.
In my case, I have made another subtle adjustment in that rather than using the default port 22 for ssh on my foreign machine, I have decided to move it. Quite simply, ssh ports are often hammered by attackers so moving it away from port 22 avoids the potential denial of service. I have chosen 7888 but you can choose whatever you want.
Now onto the implementation. Because I am running Windows, there are a few choices in how to get ssh functionality (it is not built in). I enjoyed running something called Cygwin which is a linux style prompt running under windows and which allows me to set these things up in the same way as I would on Linux. Unfortunately, it seems to have stopped working properly so I now use Putty which is a very common tool and runs well on Windows, the only slight downside is that I am using a private key to access my remote system and putty has its own slightly different format for keys which means I have a few more steps to perform before a simple setup in Putty can be carried out. If you are not using private keys for ssh access to your foreign machine, ignore the steps involving putty gen and the private key settings in Putty.
- Download putty and puttygen
- Run up puttygen and select Conversions->Import key from the menu. Select your private key file which will probably be in .pem format.
- Once the key imports, click save private key and this will save a .ppk file which is putty format
- Run up putty, I would suggest immediately saving a named session - like "Webserver Tunnel" and then remembering to save it as you make other changes. This is just to avoid mucking something up and having to start from scratch.
- Choose ssh on the first page and then enter the url for your remote ssh machine and the port to use (remember I used 7888). The ssh machine in my case is NOT the same as the windows box I am connecting to, I use this ssh proxy because it is a Linux box and is easier to setup for ssh.
- Click on the Connection/ssh/auth link and choose your ppk private key (if applicable)
- Click on the Connection/ssh/tunnels link and add a new entry. The source port is the port on your local machine that you want to tunnel from. This can be whatever you want but keep the number high to avoid other ports that might be in use. The destination is then the ip address and port to use at the foreign end of the link. This might be the ip address of the foreign ssh server but in my case it is the ip address of the windows box and port 3389. Once the ssh tunnel has been created, this forward works because the proxy ssh server has been given specific firewall access to the windows box port 3389 - I would not be able to connect to it directly.
- Save the settings and then click Open. This will log you in and you should see a window even though you are actually tunnelling. If you did not use a private key, you will be able to login here with your credentials. Once the window is open, the tunnel will be running and you can connect your client, in my case an RDP session, to localhost:localport