In one of my previous post I made a tutorial how to bypass corporate firewalls and gain access into your office computer. It work well if you are at your home and you need ssh access (or any other service) to your office computer. However if the situation is reversed, and you need to access some outside service which your firewall is blocking then you would use this little tutorial with explanations. Although all this is covered in the ssh man pages, one always learn best by real life examples, so here I'll try to cover few of them.
To better explain our first problem look at the picture below:
We are located at our office computer which is behind very restrictive firewall, and we want to get to the non-standard service running on remote server.
Normally I'll use Mysql Administrator for example, to connect on my MySql database on a remote server. That communication would happen on port 3306, and for this to work Mysql Administrator must have appropriate rules set in our firewall to allow that traffic.
But what if traffic on that port is blocked?
Here is where we come to ssh port forwarding. If we have ssh access on any outside computer we can route our traffic through the tunnel and gain access to the service via standard ports.
Ssh tunnel can be also used to establish connection from insecure networks to standard and non-standard services inside secured firewalled network as shown in picture bellow:
As you can see here, server is behind firewall and all the standard ports on that server (like http, pop, imap...) are allowed. Server is also running MySQL service which is listening on port 3306. To connect to it server's firewall should allow this incoming connection.
But what if it doesn't?
What if the network from which we are connecting is insecure and we wish to maintain our data private while communicating with our trusted, firewalled network?
Again we can solve this problem with ssh port forwarding. If we have clear and working ssh access on server or any other machine in the firewalled network, we can route our traffic through that ssh connection.
Solving the first problem
If our firewall is very restrictive (inbound and outbound), and you don't have control over it, you can use ssh port forwarding to your advantage. Essential things you will need are:
- allowed ssh traffic on your restrictive firewall, port 22 by default
- a remote server to which you can connect via ssh, and preferably control over that remote server's firewall.
If even port 22 is blocked in your restrictive firewall you can setup your outside ssh server to listen on some other port that is allowed through your firewall. You can than use -p switch in your ssh command to connect on your server. If you don't really know anything about ssh, you can always read ssh basics and than come back here.
So in our real example we want to connect to mysql service running on remote server and our firewall won't allow it. We have ssh access on that server so we will use it to tunnel this traffic.
To start up this tunnel this command will be used:
ssh -L 3306:localhost:3306 username@server
This will actually open up a port 3306 on our local computer listening on loopback interface through established ssh connection on to server's port 3306. If we already have mysql server running on local machine then the port 3306 is already in use, so we need to use another port on our loopback interface, so the command would look like:
ssh -L 3307:localhost:3306 username@server
Then we use our service client, in this case Mysql administrator and instruct it to connect to 127.0.0.1 at our specified port. We can use the same command to tunnel any other port and or service this way.
Extending this example
We can also use this connection method to our remote server for routing traffic to some other servers. Of course our remote server must to be able to connect to that remote service. This is usually very popular to forward traffic to some online games running on non standard ports, EvE, Warcraft, and any other game (this might produce additional lag on FPS games).
As shown on picture, for example we have outside gaming server running at port 66732, and that port is blocked in our firewall. We can use our remote server with ssh connection to establish a ssh tunnel and then route that traffic to our local computer.
To do so we would use this command:
ssh -L 66732:remote.gameserver:66732 firstname.lastname@example.org
On our loopback interface (127.0.0.1), this will create a listening port 66732 which will then be forwarded to remote.gameserver's port 66732 through our ssh connection on port 22. All you need to do is instruct your game client to connect on localhost. This can also be used in constructive purposes, like using your remote shell server to route traffic this way to remote mysql server on which you don't have ssh access but is available to your remote server via 3306 port. Bare in mind that your remote ssh server will have to be able to connect to remote.gameserver/mysql server on appropriate port, it your remote server have any outbound firewall rules filtering this traffic, this example will not work until you open that port.
As with reverse ssh port forwarding we can make this connection available to other computers on our LAN by specifying listening interface while establishing the tunnel. I'll go with remote gameserver example and enable our co-workers to connect via same ssh tunnel to remote gameserver without them needing to create their own tunnels.
If you have multiple network interfaces on your computer you will specify the one whit which you are connected to your co workers, but you can also enable it on all interfaces like this:
ssh -L 0.0.0.0:66732:remote.gameserver:66732 email@example.com
when you do netstat -ntl on your machine you will see it's listening on 0.0.0.0:66732. Your co-workers can now connect to your's office pc ip on that port and their connections will be also tunneled via this established ssh connection. Bare in mind that the remote.gameserver will see all the connections comming from our.server so if the remote.gameserver have any per ip connection count limit this will obviously be a problem.
Solving the second problem
How is this problem different form the first one. In essence it's not, only differences is that our firewall is permitting the non standard traffic, or we don't even have a firewall to worry about, but the server's firewalled network is very restrictive and its blocking our non standard ports. Ssh tunnel commands used in this example will be the same. However I can use this example for demonstrating why ssh tunnel can be useful for.
Say we don't have firewall and port limitations, but we are temporary on insecure network and server is on secured/trusted network. If we were to use any of the old plain test services like ftp, pop3, imap, synergy, etc... malicious hosts/users can sniff out that traffic and find out any usernames and passwords sent via plain text. Even the contents of the connection. So here's were ssh tunnel steps in again.
We can start an ssh tunnel from our insecure network to our secured server's network and tunnel any plain text/insecure traffic through it. By default ssh tunnel binds its self to loopback interface on our computer, which malicious network user doesn't have the access to, and as the ssh is encrypted, all the traffic passing through this tunnel will be plain gibberish to any malicious user sniffing our traffic on this insecure network.
Just like in one of the previous posts (secure synergy setup) we will use this tunnel to secure our traffic from eavesdropping. Ftp actually has sftp (ftp over ssh) so if you already have ssh you will want to use that instead of tunneling ftp traffic, but if for any reason you are not able to use it then this should work as well.
I'll take my example on pop3:
We establish ssh connection to secured remote server and tunnel the port 110 on our loopback interface to server's 110 through established ssh session. Then we connect with our mail client to localhost and preform plain text pop3 authentication through secure ssh tunnel.
ssh -L 110:localhost:110 firstname.lastname@example.org
If you don't have access to the mail server's ssh then you can use another ssh host on secured network to route traffic with this:
ssh -L 110:mailserver:110 email@example.com
Few useful tips
As mentioned few times before, perhaps the firewall will not allow standard ssh ports through, or your ssh server is running on different port in which case you should use -p switch with ssh. For example your ssh server is running on port 2210 then to forward pop3 traffic you would use:
ssh -p 2210 -L 110:mailserver:110 firstname.lastname@example.org
And of course if you wish to use your ssh connection only for port forwarding an wish to put it into background you would use:
ssh -N -f -L 110:mailserver.110 email@example.com
And from here it's all combinations of above used commands.