Sneaking past firewalls to the database



Firewalls are an essential part of any IT setup, however at times a missing rule can cause major issues if it can't be quickly resolved. In very complex networks this is actually sometimes not trivial to fix.

As a short term solution port tunnelling using ssh can offer a solution, to be honest the more i look into ssh tunnelling i wonder if firewall admins really know what they let themselves in for as soon as they allow ssh.....

Lets look at a simple example of what port tunnelling can help with - in the picture below (which i drew all by myself.. :-)) we see 3 servers labelled A, B and C.

There is a database on server A that wants to connect via a database link to a database on server C - in the current firewall rules this is not allowed.

However we know that server B can talk to server C so the rule exists there and server A can freely talk to server B on any port



If we try and connect to the database on C fro A using this tnsnames

SERVERC_DBNAME.WORLD =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = serverC)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
     (SERVICE_NAME = SERVERC_DBNAME.WORLD)
    )
  )


The connection hangs and eventually times out as the firewall blocks it.

You might think initially you could create a double hop db link - i.e. A links to B and then B links to C. This works but requires extra objects and of course a database (including licences etc) to exist on B.

In our case we assume that B is just a simple linux server with nothing installed.

Lets see how tunnelling helps us here - i run the following (this command assume thats server B is able to ssh to itself - i.e certificates have been set up)

ssh -f -N oracle@serverB -L serverB:11521:serverC:1521

Lets translate what this is actually doing - it's basically establishing a tunnel on serverB from port 11521 to serverC on port 1521. Any traffic that arrives on port 11521 on server B is just sent on to 1521 on serverC. Server B acts almost like a router but just for a single port.

Now this is in place we can add some more comments on to the picture to illustrate whats going on.


Now the tunnel is in place we create a new tnsnames entry that points to the forwarded port on server B

SERVERC_DBNAME.WORLD =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = serverB)(PORT = 11521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
     (SERVICE_NAME = SERVERC_DBNAME.WORLD)
    )
  )


The connection now works perfectly even though the firewall is still in place - we just sidestepped it.

A double edged sword though - this is sometimes useful but also could be a nasty security hole......


1 comments:

  1. excellent. nice diagrams as well :-)

    You sure you didn't get a design agency in?

    ReplyDelete