Tear down this wall. Reverse Tunneling
The Secure Shell (ssh) is a universal tool when it comes to accessing machines remotely. Mostly known for opening a remote terminal environment there are much more possibilites hidden in its server functionality. One of them is tunneling. Tunnelings allows a remote host to function as a proxy server. This comes in handy when developing on a network infrastructure that has a DMZ.
A gateway server is used to route all incoming traffic. Servers inside the DMZ are effectively unreachable from the outside which is a valid security feature but can be a problem for temporary work. For instance, given a gateway server which runs a web application and another instance inside the DMZ running a PostgreSQL database.
+----------DMZ-----------+
| |
| database.example.com |
| |
+----------DMZ-----------+
Gateway
example.com
|
Local Machine
From a local machine you cannot connect remotely to the database. The DMZ is bypassed by using SSH tunneling. From a local machine with access rights to the gateway server a proxy is set up as follows:
$ ssh -L8888:database.example.com:5432 example.com
This connects to the gateway machine and creates a tunneling to the database instance. All traffic which reaches now port 8888 is forwarded to the database instance on port 5432. This allows us to connect to the database instance from our local machine:
$ psql -h example.com
psql (9.4.4)
Type "help" for help.
postgres=# SELECT * FROM users;
So far, so good. This becomes more tricky when another host from a different network is involved. I was working on a project in which data had to be collected from a remote instance to a web service sitting inside a DMZ as well:
+-----------DMZ------------+
| |
| webservice.example.com |
| |
+-----------DMZ------------+
Gateway
example.com
|
Local Machine
|
Data Store
81.175.76.143
The web service depicted here cannot access the data store on 81.175.76.143. Our local machine is able to access the web service over normal SSH tunneling. Our web service is still unable to access the remote data store. With reverse tunneling we can use our local machine to route the packets to the data store:
$ ssh -L8888:webservice.example.com:20 example.com
$ ssh -R 9999:81.175.76.143:80 localhost -p 8888
All packets which arive on our local machine on port 9999 are now forwarded to the remote data store on 81.175.76.143 through port 80 by establishing a reverse tunnel connection on localhost using the SSH port 8888 which makes effective use of the first tunnel set up.