Recently I had the privilege of working on a short term contract in the Middle East, and the Internet access where I was based was severely filtered.
The extent of the filtering was not just at web browser level but also across other common protocols such as email, FTP and even some socket level applications. This posed a problem for me in several ways, one of the main ones being that I was having difficulty sending and receiving updates for a website that I’m the technical lead for, because words matched the filters in my emails, and certain articles posted to said site by its users stopped pages from being browsed.
This got me to thinking about using some kind of encryption to prevent the filters picking up my traffic and effectively bypassing the filters, thus allowing my traffic to get through unaffected.
The solution to my problem was to use SSH tunnels.
“What is an SSH tunnel?” I hear you ask. Put simply, an SSH tunnel is a direct link from your PC that you sit in front of (we shall call this the Client) and a remote machine at an entirely different location preferably outside the control of the filtered zone.
In order to build this solution, you’ll need the following:
- A private server to which you have super user access either via console, or SSH
- A client PC onto which you have permission to install software
- Public Internet connections in the 2 respective locations
Step 1 – Setting up the server
Set your server up with any software you require to perform the tasks you wish to achieve. For me, this meant I wanted to send and receive my email, I wanted to access my development host and databases, and I wanted unfiltered access to the web in general.
To achieve this, I installed the following packages onto a Dell PowerEdge server running Ubuntu Linux 7.10 server addition:
I also made sure that my copy of Apache had PHP capabilities, and installed phpMyAdmin into the web server root to allow me to access my database servers. I also installed “webmin” to allow general admin of the server.
Once you have the required packages installed, set up the server packages to operate locally (As though you where using the server from your location), for me this meant the following:
Setting up sshd (the open SSH Daemon) to listen on standard SSH port 22 ready to accept interactive command line logins.
Setting up Postfix, listening on the standard SMTP port of 25 and accepting email for a local addresses within it’s domain.
Setting up Dovecot to listen on the standard POP3 port of 110, and to make available the standard mailboxes of any user registered on the system.
Setting up Squid to allow unauthenticated web proxy access via the server’s public internet connection from clients connecting to port 8080.
Setting Apache to listen on standard web port 80, and installing PHP MyAdmin in a folder on the web server called DBA.
Installing webmin, and having it listen on its default port of 10000.
Finally once you have all your software set up, you need to ensure there is ONE single inbound port forward of your choice to the SSH port on your server machine. For this solution, I picked a random high port of 9000 (when doing things like this, it’s always a good idea to stay away from common port ranges that script kiddies will use automated tools to find). I punched a port forward through the routers firewall from port 9000 on my inbound IP to port 22 on the servers IP address inside the network.
Page 2: Setting up the client
Step 2: Setting up the client
Once your server is up and running and connected to the Internet, we then turn our attention to the client, for me this was a fairly standard PC running Windows XP. This could however be any OS you choose to use as PuTTY is available for just about every platform available. Most *nix’s, in fact, have it available to install in the package manager.
The SSH terminal we will be using in this article is called PuTTY written by Simon Tatham (if you’re reading this Simon, thanks for such a wonderful piece of useful software).
Download and install PuTTY SSH, and/or one of its automated tools such as PuTTY Shell or PuTTY Link. You can find all of these at http://www.chiark.greenend.org.uk/~sgtatham/putty/.
Once you have PuTTY, click on the binary for the putty.exe terminal to run it. The reason we run the terminal first, and not one of the automated tools, is because the setup GUI in the terminal program makes configuring these things really easy, the setup is then stored in your system registry and can be used in the other programs in the suite.
On the main PuTTY interface fill in the hostname and port number that your remote SSH server is listening on (remember the port number is the one on your router!), and set the protocol type to SSH.
NOTE: If you are connecting from behind a firewall then you must make sure that the port you setup on your server is open for outbound communication on the system you are connecting from, in this example, your outgoing firewall would have to allow outbound communications on port 9000, if not, then you’ll need to change the open port in your remote router to match a port that you can originate traffic on. This was not a concern for me as I was connecting from a home ISP connection within the country.
The next thing to do is to ensure that your profile has a saved name. To do this put a name in the Saved Sessions box, and click the save button. This records the profile in the system registry, so you can then later use the profile with plink or another tool in the PuTTY set.
Once you’ve saved the profile, Look in the config section down the left side, and go down to Connection -> SSH -> Tunnels.
In the tunnels section, the two important fields are the source port and destination.
The source port box holds the port number you would like to be opened on your local PC, in this scenario (and as I often do) i used the base port, plus 1000 for everything except the Apache web server and webmin. Place your local port number into the source box which for our little exercise this is going to be:
1025 for the smtp port
1110 for the pop3 port
9080 for the proxy port
80 for apache
10000 for webmin
Why did I not add 1000 to Apache and webmin?
Well first off, webmin is sufficiently high to be well out the road of any running Windows services. For Apache, however, it makes sense to put it on 80, because it then looks like your development web server is local to your client machine, and it makes setting up the proxy really easy.
Still in the tunnels section, target the destination box add a localhost:port entry for each of your services, so for this article SMTP = localhost:25, POP = localhost:110, Squid = localhost:8080, apache = Localhost:80, webmin = localhost:10000. Once this entry is placed in, then click the add button to save it. Continue doing this until you’ve added all the ports you need.
A good point to note is that you don’t have to use localhost, you can use any fully qualified domain name (FQDN) of any machine that’s reachable from the SSH server you’re connecting to, technically this means you could run your email off one server, your web development off another and your proxy access on a third, and then just replace the destinations with ‘another.remote.machine:port’.
As an example on my setup in the Middle East, I also had a remote VNC tunnel setup to my wife’s PC so that if she ran into difficulties with anything, I could log in and sort it out, the possibilities are endless.
Once you finish adding your ports, go back to the session config entry at the very top of the config list, and click save again. If all has gone according to plan at this point, then you should now be ready to hit the open button and test it.
Once you hit the open button, you should hopefully get a terminal screen asking you to log in. If not, then the first thing to check is that you’re connecting to the correct host, with the correct port and SSH protocol. The second thing to check would be your port forward settings, and third, the aforementioned firewall outbound scenario.
All being well, enter your Linux username and password to log in.
If your tunnels are set correctly, then as long as that account remains logged in and connected, all your source ports that you specified on your local machine should point to the destination ports on your server for the lifetime that PuTTY remains open and connected.
You can now proceed to set up your mail client to point to the appropriate POP and SMTP ports, you can set your PC’s proxy settings to point to the local squid port, but bypass local addresses so that localhost goes to apache and webmin.
SSH tunnels are a very powerful tool in the right hands and can be used for a great many things. To give you some ideas, I’ve used them for secure VoIP connections, remote monitoring of security cameras, Windows for workgroups/samba access and all manner of strange socket-based connections. It’s even possible to point a tunnel to a tunnel to a tunnel, or tunnel hidden traffic inside a local network from one PC to another.
The possibilities are endless.
Some other ideas of possible interest involve using the command line utility such as puttytel, plink and others available on the website. You could set up a shared key system, then use plink for example in a batch file to load and open a tunnel profile and automatically log in. This batch file could then be added to the startup group on your laptop for example, so that every time you switched your laptop on and where connected to the internet, your tunneled services would be automatically available.
I hope this article is of some interest to those who are dabbling with SSH, and once you’ve used the power SSH can provide, you’ll pretty much want to use it for everything.