SSH port-forwarding (Intermediate)

In my previous blog entry I described some basic functionality of SSH in terms of port-forwarding. Now it’s time for a little bit more complex stuff.

In this article I will highlight:

Forward firewall piercing

Let’s start with the forward firewall piercing, since it is the easiest and was somewhat already described in my previous blog entry on this topic. Now, imagine that you already have SSH access to some host which is multi-home connected (e.g. the host is connected to more than one network). Let’s also assume that the host is a firewall and is masquerading other hosts in the internal network and is translating just a handful set of ports to the servers (looks familiar, doesn’t it? :) ). In other words, we are speaking of a standard firewall/NAT router.

Now, how can you access port 12345 on host behind the firewall given that this port is not “exported” by the NAT on the firewall? This is quite simple. Open a terminal window on your local computer and type the following:

[user@localhost ~] ssh -L12345:192.168.1.2:12345 joe@firewall.domain.tld

From now on, as long as your SSH session is up and running you will be able to reach 192.168.1.2:12345 by connecting to localhost:12345 (i.e. the 12345 port on your local computer). Indeed, for this to work you need SSH access anywhere inside the protected network (not necessarily on the firewall itself) and if the firewall blocks any SSH access, you are out of luck.

Dynamic port-forwarding

There are at least two usage patterns where I find SSH’s ability to forward requests to many ports useful:

In both cases, you use the following SSH command in your terminal window:

[user@localhost ~]$ ssh -D3128 joe@relay.domain.tld

As long as you SSH session is active, you can use port 3128 on your local machine as SOCKS4/SOCKS5 proxy (e.g. you can configure proxy settings in your browser to use localhost:3128) and browse the Net through your SSH connection, and all your requests will look like they are coming from relay.domain.tld.

There are many uses for this: for example, some payment processors won’t allow you to pay for goods if you are trying to pay through them from some countries even if you are a legitimate user, another use case is when you are concerned re: your privacy – you can conceal your actual location by building a chain of SSH tunnels and access the desired web site through this chain :) .

Reverse firewall piercing

Finally, what if you are behind a very strict firewall that limits almost everything, but you need to provide some services to the outside world from your computer (e.g. sharing your access to company’s confidential information to folks from WikiLeaks… just kidding :) )?

To achieve this you need to have an SSH account somewhere in the Net – just Google for “free ssh account” and you will surely find one for yourself).

Now, when you have the account, you can execute the following on your local computer (which is inside that highly secure network :) ):

[user@localhost ~]$ ssh -R:60000:127.0.0.1:22 joe@friendly.domain.tld

The above command will setup such a configuration that connecting on port 60000 at friendly.domain.tld will forward traffic to your local machine’s port 22 (which is behind a firewall) – this will work as long as your SSH session to the friendly.domain.tld is active. Unfortunately, there are several pitfalls in this approach, but they are all resolvable.

Firstly, you need to ensure that friendly.domain.tld is using a recent version of SSH daemon, otherwise you will be limited to bind only to the loopback interface on the remote host.

Secondly, even if they are using a recent version of the SSH daemon, they can disallow such binding (e.g. setting “GatewayPorts no” in /etc/ssh/sshd_config), and, again, you will be restricted to the loopback interface only.

Finally, you need to find such a friendly host which allows you to connect to the bound ports from the outside (many public ones have a firewall rule preventing such access in order to prevent abuses of their services).

All in all, the best option to try this is to have your own host somewhere (e.g. purchase a small virtual environment from some hosting provider or create an instance on AWS EC2), then you will be able to configure the remote side the way you want it!

Anyway, even if you fail to find a host that allows you to expose your service to the public, you still should be able to access it yourself – using the forward firewall piercing technique described at the beginning of this post:

# from your home computer
[user@localhost ~]$ ssh -L60000:127.0.0.1:60000 joe@friendly.domain.tld

Once it is done your computer in the highly secure network should be reachable via SSH on your localhost:60000, e.g.

[user@localhost ~] ssh -p6000 my_account@localhost

Where my_account is a user allowed to SSH into your computer in the highly secure network.