SSH TCP Port Forwarding aka poor man’s VPN


In today’s world when the IPv4 addresses are a luxury and IPv6 is not wide deployed (yet) more and more servers are running behind NAT-ed addresses. To do remote management on these servers you connect to them using SSH through some port forwarding done on the border gateway. If you need to monitor these servers there are a few alternatives:

  • more ports forwarded from the gateway
  • use a vpn to  connect to the remote network
  • use TCP port forwarding through the SSH connection

This post will show how you can obtain more from the existing SSH connection to the remote system.

SSH’s TCP port forwarding (also known as poor man’s vpn) offers a cheap and secure alternative to full vpns. Using it you can access other hosts and services on the remote network which would be unreacheable otherways. The SSH supports two types of connection forwarding – a local connection to the remote hosts (using -L parameter) or a remote connection to the local host (using -R parameter)

The command for local forwarding looks like (you can use more parameters than the one presented below!):

ssh user@remotesystem -L localport:host:hostport
TCP port forwarding directly on the SSH server

The user@remotesystem part of the command line specifies the user you wish to connect as on the remote system. The -L is activating the local forwarding: any connection to the localport (on the client system) will be forwarded to the remote host / port by the remote system. The host name (if it is a name and not an IP) is resolved by the remote system. It can be either localhost (in which case the connection is forwarded directly to the remote system), an IP address (accessible on the remote network) or a FQDN. Thus the connection can be made either directly to the ssh server or to another server onto remote network.

A word of caution, thought: if the host is a different machine than the remote system – the connection between these two is NOT secured! Only the first part of the connection from the local system to the remote system is secured through the SSH. The second part, on the remote network, is unsecured.

Connection to a remote host through a SSH server
The second part of the connection is unsecured on the remote network.

As a quick example lets say the remote server is running a postgresql database and you need to connect to it to do some maintenance work. A direct access is not possible as the database server is behind a firewall (or NAT) and the connections are blocked. If you have SSH access to the database server the following command will solve your problem:

ssh user@remotesysem -L 5432:localhost:5432 -f

This will open a connection to the remotesystem and will forward the requests to the local port 5432 to the remotesystem port 5432 (where runs the postgresql database). Now you can connect to the database server using localhost as hostname (it is like the database server is running on your local machine). (Please note the localhost from the ssh arguments refers to the remote server “localhost”, not the local

As a second example, if you don’t have SSH  access to the remote database server but you can access a ssh machine on the remote network (and that machine has access to the database server!) you can use:

ssh user@remotesysem -L 5432:remotedatabase:5432 -f

Instead of using the localhost (like in the previous example) we are using the database server address (remotedatabase – as IP or FQDN). The ssh server will forward any connection from the local 5432 port to the remotedatabase 5432 port. To access the database you will still use localhost as hostname (you are connection to your host):

psql -h localhost -p 5432 ....

The same approach can be used for monitoring remote servers and services with Nagios, just forward the local port 5666 to the remote port 5666 and the server will be able to connect to NRPE on the remote machine and do its job. (Actually it is a little bit more complicated than just a direct port forwarding as it involves being able to login passwordless on the remote machine – this it’s done using public key certificates and will be the subject of a future article).

Today we’ve learned that we can access remote services and servers without needing a VPN or complicated settings on routers. While the examples provided are simple you can test with various command line arguments to obtain different behaviors (try -N if you need only the port forwarding not the remote shell). We’ve used the same port number for mapping (5432 to 5432) but you can try a different local port (how about 2345 to 5432?) and it will work the same.  There are many more gems in the SSH (passwordless logins, port forwarding, secure file transfer, X11 forwarding, remote command execution, remote file mounting) but they will be detailed in future articles. If you have a preference and would like to read about a specific topic please leave a comment and we’ll see for it 🙂

Finally, there’s another very important peculiarity of what does Cialis that brings it so high above its alternatives. It is the only med that is available in two versions – one intended for use on as-needed basis and one intended for daily use. As you might know, Viagra and Levitra only come in the latter of these two forms and should be consumed shortly before expected sexual activity to ensure best effect. Daily Cialis, in its turn, contains low doses of Tadalafil, which allows to build its concentration up in your system gradually over time and maintain it on acceptable levels, which, consequently, makes it possible for you to enjoy sex at any moment without having to time it.

16 thoughts on “SSH TCP Port Forwarding aka poor man’s VPN”
  • […] can do a lot with ssh’s fort forwarding features. For more details and examples please see my work blog « Google Code Jam […]

    April 15, 2010 at 12:38 pm
  • Ciprian Radu says:


    Well… I am interested actually on VPN and complicated settings on routers. This article is a nice and pretty simple tutorial to SSH :). I am currently using OpenVPN and while having the VPN connection active, my Internet connection is no longer working. Probably this has something to do with routing. And yes, probably this is a simple problem but, in a sense at least, I am new to this area of expertise. Maybe you can write something about this 🙂 (although probably I will have the answer to my small problem until then).

    April 15, 2010 at 2:18 pm
  • Hi,

    Please provide more details about your issue, which OS version, VPN client version, router, VPN server version, VPN type (PPTP/IPSEC) and how the non-working connection behaves. The VPN is working?

    April 15, 2010 at 2:39 pm
  • Ciprian Radu says:


    I do not know yet what’s on the server side. I’m just using the OpenVPN client (v. 2.1). The VPN works but, while I have the VPN connection active, the Internet is not longer working. From what I’ve read until know this should not happen. The Internet traffic should be routed normally but it seems it is routed through the VPN in my case…

    Actually the VPN is working on Linux. It doesn’t work on Windows 7 64 bit (most probably a Win 7 issue – I am not concerned with this very much).

    Anyway, I will have to do reading about routing first 🙂 because I am not very familiar with networks. If you have encountered a similar case maybe you can give me some hints.

    April 16, 2010 at 8:31 am
  • Please check the default route before and after establishing the vpn connection. They should be the same, otherways the vpn client is overriding it and you’ll have to restore it.

    April 23, 2010 at 9:51 am
  • Ciprian Radu says:

    I did exactly that in the mean time. Thanks anyway.
    Do you think the VPN client is faulty? I thought the VPN server establishes those routing configurations.

    April 23, 2010 at 3:36 pm
  • The VPN server can establish routes for the VPN connection and policies regarding outbound traffic (allow/deny) but the VPN client is setting the local routings. You can route all the traffic through VPN (as Windows default VPN connection works) or only the traffic to the remote network (as Linux VPN works by default). Depending on the vpn client you can have a variety of behaviors and in your case it seems the default route was replaced to use the vpn server only (which denied outbound traffic)

    April 23, 2010 at 3:42 pm
  • Pretty nice post. I just stumbled upon your blog and wanted to say that I have really enjoyed browsing your blog posts. In any case I’ll be subscribing to your feed and I hope you write again soon!

    June 13, 2010 at 4:22 am
  • great information you write it very clean. I’m very lucky to get

    this details from you.

    June 14, 2010 at 11:44 am
  • Rather nice article to spend some time on reading it in my opinion. A small question, why don’t you submit it to social bookmarks? This will bring a lot of traffic here.

    June 19, 2010 at 11:22 am
  • My cousin recommended this blog and she was totally right keep up the fantastic work!

    July 8, 2010 at 4:17 am
  • Wonderful journey and experience!

    July 29, 2010 at 11:29 am
  • Angelskaya says:

    it was very interesting to read
    I want to quote your post in my blog. It can?
    And you et an account on Twitter?

    July 29, 2010 at 8:51 pm
  • wonderful share, great article, very usefull for me…thanks

    July 29, 2010 at 10:57 pm
  • organic tea says:

    A good article Thank you!

    July 30, 2010 at 11:39 pm
  • greyserg says:

    I would like to exchange links with your site
    Is this possible?

    July 31, 2010 at 12:53 pm

Comments are closed.

By continuing to use the site, you agree to the use of cookies. More information

The cookie settings on this website are set to "allow cookies" to give you the best browsing experience possible. If you continue to use this website without changing your cookie settings or you click "Accept" below then you are consenting to this.