Home Switchboard Unix Administration Red Hat TCP/IP Networks Neoliberalism Toxic Managers
May the source be with you, but remember the KISS principle ;-)
Bigger doesn't imply better. Bigger often is a sign of obesity, of lost control, of overcomplexity, of cancerous cells

Reverse SSH Tunnels

Sometimes you need to access server behind firewall or proxy that do not have VPN facility or this facility is to beuracratized to use.

In this case creation of reverse tunnel can help. Port 443 (HTTPS) is usually open.

So the steps to create a reverse SSH tunnel are as follows:

  1. From server behind firewall machine: ssh -R -nNT 443:localhost:22 JoeUser@outside_server_name
    ex: ssh -R -nNT 443:localhost:22

    The "-n" option tells ssh to associate standard input with /dev/null, "-N" tells ssh to just set up the tunnel and not to prepare a command stream, and "-T" tells ssh not to allocate a pseudo-tty on the remote system. These options are useful because all that is desired is the tunnel and no actual commands will be sent through the tunnel, unlike a normal SSH login session. The "-R" option tells ssh to set up the tunnel as a reverse tunnel.

    Login as support engennere. You will get regular session with this remote host. 
  2. From the outside server (to re-establish the tunnel) run the command : ssh -p 443 localhost  and you are in  


Use ssh option -f to detach ssh process from the tty and -N to not execute any command over ssh (the connection is just used for port forwarding)

Using key authentication (option -i) is quite better too and make this command to be run within a boot script (like /etc/rc.local) :

ssh -i /path/to/priv/key/id_rsa -f -N -R 19999:localhost:22  JoeUser@outside_server_name

You have to give a shell access on  outside_server_name to a foreign user (JoeUser) in order to let him connect to destination.

If  he does not need any shell access to outside_server_name, you can specify the remote port forwarder to listen on one specific interface or any (instead of by default) :

ssh -i /path/to/priv/key/id_rsa -f -N -R *:443:localhost:22 sourceuser@outside_server_name

But take care this last command makes the destination UNIX system being exposed to Internet via  outside_server_name. IP filtering and/or a knockd daemon are recommended on outside_server_name if you do not want an internal server being scanned.

Top Visited
Past week
Past month


Old News ;-)

From: Anonymous



first of all, thanks for this great tutorial. I ran into some trouble first, and I got this "Address family not supported by protocol" when I tried to use the reverse tunnel to go from HOME back into the LABNODE, which is behind the firewall. It's because the LABNODE didn't know about 'localhost'. I changed it to and now it works.

Here's my setup for user 'labuser' on the LABNODE from which I open the initial (reverse) tunnel to my HOME node.

I'm using a config file which lives in $HOME/.ssh/config - this file is only readable/writeable by the owner itself ( chmod 600 $HOME/.ssh/config ). This is how the file looks - 'babylon' is the username on my HOME computer.

Host myHome
User babylon
RemoteForward 20023

First I open the reverse tunnel on LABNODE :

ssh myHome
<enter password for babylon on HOME computer>

Then i drive home, have a coffee and use my HOME computer to reconnect trough the firewall into the LABNODE:

ssh -p20023 labusername@

After entering the password, I am back on my LABNODE.

If you get bored of always typing your password, you can generate ssh-keys on LABNODE and HOME. Then you copy the content of the public key files into the authorized_keys files on the other host. Do NOT copy your private key id_rsa file.

babylon@HOME> ssh-keygen -t rsa
(do not enter a passphrase)
babylon@HOME> cat $HOME/.ssh/
labuser@LABNODE> vi $HOME/.ssh/authorized_keys
(copy-and-paste key into authorized_keys)
labuser@LABNODE> chmod 400 $HOME/.ssh/authorized_keys

Now run this for the other host as well and you're set !

From: Samat Reply

This can be combined autossh to make sure the connection is restarted if it ever dies. I run the following from my Debian's /etc/rc.local, called /etc/tunnel/

SSH_OPTIONS="-i /etc/tunnel/$HOSTNAME.key"
# Always assume initial connection will be successful
# Disable echo service, relying on SSH exiting itself

autossh -f -- $SSH_OPTIONS -o 'ControlPath none' -R 19999:localhost:22 sourceuser@ -fN

From: Anonymous

Reverse tunneling is very, very useful but only in quite specific cases. Those cases are usual the result of extreme malice and or incompetence of network staff.

From: Anonymous

The only difficult part here is to determine what's the most common attribute of most IT/networking departments: Malice or incompetence. My last IT people had certainly both.

From: Anonymous Reply

Not if you build appliance products which you sell to others which, when you need to support them, will generally be running behind NAT. You need the appliance to, when the customer clicks the button when asked to by support, create a reverse tunnel that allows support to connect in without the customer having to port forward through their firewall reducing their security.

Same for companies moving equipment between buildings that have no on-site IT staff: Rather than punch holes through a firewall to allow anyone to connect and play, it might be more secure to make equipment tunnel back to HQ and remain connected instead of sitting there ready for anyone to connect. At least in this instance, you don't have an open port in your firewall, and the box with reverse tunnel configured won't accept connections from anyone but the host it's reversing for.

This said, there are myriad other ways of achieving security even if you do punch holes in the firewall, eg. Port Knocking, but if you do punch holes through the firewall if it's not properly configured your open ports will be visible to anyone who knows how to use nmap.

From: Anonymous Reply

Nothing to do on the iPhone. Most jailbreaks include OpenSSH or you can download (Cydia) OpenSSH onto your iPhone.

After joining iPhone to Mac over WiFi on unsecured 40-bit WEP connection. We write down the iPhones IP# (169.254.x.y) and then don't even touch the iPhone again, instead we just reverse proxy a secure (SSH) SOCKS proxy back into the iPhone and gain access to the internet through the now tethered iPhone. (No need for any Apple banned applications from the App Store)...

MacbookPro17$ ssh -ND 9999 root@169.254.x.y

I've changed my iPhone root password, but if you have not, the default password is Alpine (change it right away after your first SSH into your phone).

Now on the MacbookPro17 laptop I just use localhost and port 9999 as the SOCKS proxy and a simple browse in iPhone Safari or checking of Mail will flip the iPhone into accessing the internet which is now wide open for use by the MacbookPro17 laptop to use.

SSH, freeing the masses everywhere!

From: Anonymous Reply

Make sure you are not in violation of a company security policy when doing this. At the company I work for you can be fired for violating the security policy and I know that is true elsewhere.

From: dietrich Reply

If you add to your /$HOME/.ssh/config the following directive TCPKeepAlive=yes or add an 'o'ption switch on the command line ssh -o TCPKeepAlive=yes

you'll be able to maintain your reverse tunnel connection.

From: Anonymous Reply

Those one liners are OK until multiple ports need to be opened. A better way is to set it up in your ~/.ssh/config file:

Host remotehost
  User remoteuser
  HostKeyAlias remotehost
  ConnectionAttempts 3
  TCPKeepAlive no
  CheckHostIp no
  RemoteForward 20023 localhost:22
  RemoteForward 2221 lhost1:22
  RemoteForward 2222 lhost2:22
  RemoteForward 2389 lhost3:389
  RemoteForward 2390 lhost4:389
  RemoteForward 2391 lhost5:389
  RemoteForward 20080 lhost6:80
  RemoteForward 20443 lhost6:443
  LocalForward 3001 remotehost:3000
  LocalForward 8001 remotehost:8000
  ForwardAgent yes
  ForwardX11 yes
  Protocol 2

What we have above is a two way tunneling:

- RemoteForward - reverse tunneling from the remote host to the source the tunnel is initiated from

- LocalForward - enabling reverse local foward to local system from a system that is behind a firewall we are making connection to.

SSH tunneling is a blessing and a curse at the same time. The blessing because I can walk around NAT and firewalls and a curse of all Network admins who want to keep their networks under tight control...


From: Anonymous Reply

I use this program for a remote printing setup.

I do a config for about 12 localhost ports that cups prints to and they goto the corresponding ip addresses at the branch office. I have multiple configs for each of our branches and its really a cheap way to do remote from server printing with out costly VPN hardware and problems.

Some like this for my dedicated user's $HOMEDIR/.ssh/config

Host remoteofficeprint1
KeepAlive yes
User roprint
IdentityFile ~roprint/.ssh/specialkey1
LocalForward 9102
LocalForward 9103
LocalForward 9104
LocalForward 9105
LocalForward 9106
LocalForward 9107
LocalForward 9108
LocalForward 9109
LocalForward 9110
LocalForward 9111
LocalForward 9120
LocalForward 9127

Then I use this command from a screen session (as roprint):

autossh -M 17004 remoteofficeprint1

of course there has to be a proper setup on the destination to accept the pubkey auth. Autossh keep the connection up, if it can connect and login the tunnel is UP, never down, except when there is a real traffic problem on the internet. Some of our tunnels are between continents, the simplicity of autossh is what makes its so great!

It could just as easily be used for reverse tunnels. And can be configured to run from an init process, so its even possible to do more stuff.

From: Anonymous Reply

Another option that would end up being more scalable would be to just setup a VPN service on your NAT router at home. If your router can run the dd-wrt firmware, this is pretty easy to setup. Otherwise you could run the VPN service on your linux box, and just forward the ports.

From: Fred Feirtag Reply

I've looked at reverse ssh tunnelling, but I think what most people really want is ppp-over-ssh. Reverse ssh tunnelling presupposes that the firewalling allows ports like 19999 through. In many cases it's going to be better to go exclusively through whatever port is being used for ssh, 22 or otherwise. An example of ppp-over-ssh would be:

sudo /usr/sbin/pppd updetach pty \
"sudo ssh sudo /usr/sbin/pppd notty"

which provides a ppp0 interface on each of the two machines.

--Fred Feirtag

From: Anonymous Reply

Using ports below 1024 for anyone other than root will result in this error:

"remote port forwarding failed for listen port"

Just wrt point 2 if you keep getting your password refused try changing point 2 to be:

ssh root@localhost -p 19999

where you know the root password and enter the password when prompted. Obviously root can be changed to some other username too as long as you know that username's password.

From: Anonymous Reply

I don't get what is supposed to be reverse about this normal plain ssh tunnel.

The name is misleading in my eyes, it is just a vanilla ssh tunnel, port forwarding.

From: Anonymous Reply

This is 'reverse' because most ssh tunneling opens a port on the local machine an forwards connections from that port on the originating machine to somewhere on the other end of the connection.

The 'reverse' connection here opens port(s) on the remote machine, and forwards it to a port on the local machine.

The direction of the connections has been reversed.

From: Anonymous Reply

Should bullet 3. read like this instead?...

3rd party servers can also access through Destination Source (

Destination ( <- |NAT| <- Source ( <- Bob's server

From: fkasmani Reply

what if both source and destination are behind NAT?

From: Jay P Reply

Then you'd have to use another computer/server as an intermediary(aka:middleman).

-Reverse SSH from the Target PC to the middleman:

ssh -R {PortOnMiddlePC}:localhost:{PortOnTargetPC} {UserOnMiddlePC}@{IPofMiddlePC}

ssh -R 19999:localhost:22 middleman@

-Now from the Client PC pull the port down from the middleman:

ssh -L {PortOnClientPC}:localhost:{PortOnMiddlePC} {UserOnMiddlePC}@{IPofMiddlePC}

ssh -L 19999:localhost:19999 middleman@

-Now you can ssh the Target PC from the Client PC:

ssh localhost -p {PortForwardedFromTargetPC}

ssh localhost -p 19999

I love explaining this kind of thing through visualization. :-)

Think of your SSH connections as tubes. Big tubes. Normally, you'll reach through these tubes to run a shell on a remote computer. The shell runs in a virtual terminal (tty). But you know this part already.

Think of your tunnel as a tube within a tube. You still have the big SSH connection, but the -L or -R option lets you set up a smaller tube inside it.

Every tube has a beginning and an end. The big tube, your SSH connection, started with your SSH client and ends up at the SSH server you connected to. All the smaller tubes have the same endpoints, except that the role of "start" or "end" is determined by whether you used -L or -R (respectively) to create them.

(You haven't said, but I'm going to assume that the "remote" machine you've mentioned, the one behind the firewall, can access the Internet using Network Address Translation (NAT). This is kind of important, so please correct this assumption if it is false.)

When you create a tunnel, you specify an address and port on which it will answer, and an address and port to which it will be delivered. The -L option tells the tunnel to answer on the local side of the tunnel (the host running your client). The -R option tells the tunnel to answer on the remote side (the SSH server).

ssh tunnel directions

So... To be able to SSH from the Internet into a machine behind a firewall, you need the machine in question to open an SSH connection to the outside world and include a -R tunnel whose "entry" point is the "remote" side of his connection.

Of the two models shown above, you want the one on the right.

From the firewalled host:

ssh -f -N -T -R22222:localhost:22

This tells your client to establish a tunnel with a -Remote entry point. Anything that attaches to port 22222 on the far end of the tunnel will actually reach "localhost port 22", where "localhost" is from the perspective of the exit point of the tunnel (i.e. your ssh client).

The other options are:

  • -f tells ssh to background itself after it authenticates, so you don't have to sit around running something on the remote server for the tunnel to remain alive.
  • -N says that you want an SSH connection, but you don't actually want to run any remote commands. If all you're creating is a tunnel, then including this option saves resources.
  • -T disables pseudo-tty allocation, which is appropriate because you're not trying to create an interactive shell.

There will be a password challenge unless you have set up DSA or RSA keys for a passwordless login.

Note that it is STRONGLY recommended that you use a throw-away account (not your own login) that you set up for just this tunnel/customer/server.

Now, from your shell on yourpublichost, establish a connection to the firewalled host through the tunnel:

ssh -p 22222 username@localhost

You'll get a host key challenge, as you've probably never hit this host before. Then you'll get a password challenge for the username account (unless you've set up keys for passwordless login).

If you're going to be accessing this host on a regular basis, you can also simplify access by adding a few lines to your ~/.ssh/config file:

host remotehostname
    User remoteusername
    Hostname localhost
    Port 22222

Adjust remotehostname and remoteusername to suit. The remoteusername field must match your username on the remote server, but remotehostname can be any hostname that suits you, it doesn't have to match anything resolvable.

[Aug 26, 2015] Setting up a reverse SSH tunnel by Vincent Danen

... ... ...

To set up the reverse tunnel, use:

$ ssh -nNT -R

What this does is initiate a connection to and forwards TCP port 1100 on to TCP port 1100 on The "-n" option tells ssh to associate standard input with /dev/null, "-N" tells ssh to just set up the tunnel and not to prepare a command stream, and "-T" tells ssh not to allocate a pseudo-tty on the remote system. These options are useful because all that is desired is the tunnel and no actual commands will be sent through the tunnel, unlike a normal SSH login session. The "-R" option tells ssh to set up the tunnel as a reverse tunnel.

Now, if anything connects to port 1100 on the remote system, it will be transparently forwarded to port 1100 on the local system.

About Vincent Danen

Vincent Danen works on the Red Hat Security Response Team and lives in Canada. He has been writing about and developing on Linux for over 10 years and is a veteran Mac user.

urbonkers , Apr 9, 2015

Using the same port on the local and remote machine reduces the value of the example. The learner will have to use additional resources to figure out which of ####: or :#### represents the local and remote compu's.

For the record ####: is the listening address (on the remote server during a reverse forward) and :#### is the destination address, on the local machine.

Reverse Tunneling with remote port forwarding

Let's say it is required to connect to an internal university website from home.
The university firewall is blocking all incoming traffic. How can we connect from 'home' to internal network so that we can browse the internal site? A VPN setup is a good candidate here. However for this example let's assume we don't have this facility. Enter SSH reverse tunneling..

As in the earlier case we will initiate the tunnel from 'work' computer behind the firewall. This is possible since only incoming traffic is blocking and outgoing traffic is allowed. However instead of the earlier case the client will now be at the 'home' computer. Instead of -L option we now define -R which specifies
a reverse tunnel need to be created.

ssh -R home (Executed from 'work')

Once executed the SSH client at 'work' will connect to SSH server running at home creating a SSH channel. Then the server will bind port 9001 on 'home' machine to listen for incoming requests which would subsequently be routed through the created SSH channel between 'home' and 'work'. Now it's possible to browse the internal site
by visiting http://localhost:9001 in 'home' web browser. The 'work' will then create a connection to intra-site and relay back the response to 'home' via the created SSH channel.

As nice all of these would be still you need to create another tunnel if you need to connect to another site in both cases. Wouldn't it be nice if it is possible to proxy traffic to any site using the SSH channel created? That's what dynamic port forwarding is all about.

Recommended Links



Groupthink : Two Party System as Polyarchy : Corruption of Regulators : Bureaucracies : Understanding Micromanagers and Control Freaks : Toxic Managers :   Harvard Mafia : Diplomatic Communication : Surviving a Bad Performance Review : Insufficient Retirement Funds as Immanent Problem of Neoliberal Regime : PseudoScience : Who Rules America : Neoliberalism  : The Iron Law of Oligarchy : Libertarian Philosophy


War and Peace : Skeptical Finance : John Kenneth Galbraith :Talleyrand : Oscar Wilde : Otto Von Bismarck : Keynes : George Carlin : Skeptics : Propaganda  : SE quotes : Language Design and Programming Quotes : Random IT-related quotesSomerset Maugham : Marcus Aurelius : Kurt Vonnegut : Eric Hoffer : Winston Churchill : Napoleon Bonaparte : Ambrose BierceBernard Shaw : Mark Twain Quotes


Vol 25, No.12 (December, 2013) Rational Fools vs. Efficient Crooks The efficient markets hypothesis : Political Skeptic Bulletin, 2013 : Unemployment Bulletin, 2010 :  Vol 23, No.10 (October, 2011) An observation about corporate security departments : Slightly Skeptical Euromaydan Chronicles, June 2014 : Greenspan legacy bulletin, 2008 : Vol 25, No.10 (October, 2013) Cryptolocker Trojan (Win32/Crilock.A) : Vol 25, No.08 (August, 2013) Cloud providers as intelligence collection hubs : Financial Humor Bulletin, 2010 : Inequality Bulletin, 2009 : Financial Humor Bulletin, 2008 : Copyleft Problems Bulletin, 2004 : Financial Humor Bulletin, 2011 : Energy Bulletin, 2010 : Malware Protection Bulletin, 2010 : Vol 26, No.1 (January, 2013) Object-Oriented Cult : Political Skeptic Bulletin, 2011 : Vol 23, No.11 (November, 2011) Softpanorama classification of sysadmin horror stories : Vol 25, No.05 (May, 2013) Corporate bullshit as a communication method  : Vol 25, No.06 (June, 2013) A Note on the Relationship of Brooks Law and Conway Law


Fifty glorious years (1950-2000): the triumph of the US computer engineering : Donald Knuth : TAoCP and its Influence of Computer Science : Richard Stallman : Linus Torvalds  : Larry Wall  : John K. Ousterhout : CTSS : Multix OS Unix History : Unix shell history : VI editor : History of pipes concept : Solaris : MS DOSProgramming Languages History : PL/1 : Simula 67 : C : History of GCC developmentScripting Languages : Perl history   : OS History : Mail : DNS : SSH : CPU Instruction Sets : SPARC systems 1987-2006 : Norton Commander : Norton Utilities : Norton Ghost : Frontpage history : Malware Defense History : GNU Screen : OSS early history

Classic books:

The Peter Principle : Parkinson Law : 1984 : The Mythical Man-MonthHow to Solve It by George Polya : The Art of Computer Programming : The Elements of Programming Style : The Unix Haterís Handbook : The Jargon file : The True Believer : Programming Pearls : The Good Soldier Svejk : The Power Elite

Most popular humor pages:

Manifest of the Softpanorama IT Slacker Society : Ten Commandments of the IT Slackers Society : Computer Humor Collection : BSD Logo Story : The Cuckoo's Egg : IT Slang : C++ Humor : ARE YOU A BBS ADDICT? : The Perl Purity Test : Object oriented programmers of all nations : Financial Humor : Financial Humor Bulletin, 2008 : Financial Humor Bulletin, 2010 : The Most Comprehensive Collection of Editor-related Humor : Programming Language Humor : Goldman Sachs related humor : Greenspan humor : C Humor : Scripting Humor : Real Programmers Humor : Web Humor : GPL-related Humor : OFM Humor : Politically Incorrect Humor : IDS Humor : "Linux Sucks" Humor : Russian Musical Humor : Best Russian Programmer Humor : Microsoft plans to buy Catholic Church : Richard Stallman Related Humor : Admin Humor : Perl-related Humor : Linus Torvalds Related humor : PseudoScience Related Humor : Networking Humor : Shell Humor : Financial Humor Bulletin, 2011 : Financial Humor Bulletin, 2012 : Financial Humor Bulletin, 2013 : Java Humor : Software Engineering Humor : Sun Solaris Related Humor : Education Humor : IBM Humor : Assembler-related Humor : VIM Humor : Computer Viruses Humor : Bright tomorrow is rescheduled to a day after tomorrow : Classic Computer Humor

The Last but not Least Technology is dominated by two types of people: those who understand what they do not manage and those who manage what they do not understand ~Archibald Putt. Ph.D

Copyright © 1996-2018 by Dr. Nikolai Bezroukov. was initially created as a service to the (now defunct) UN Sustainable Development Networking Programme (SDNP) in the author free time and without any remuneration. This document is an industrial compilation designed and created exclusively for educational use and is distributed under the Softpanorama Content License. Original materials copyright belong to respective owners. Quotes are made for educational purposes only in compliance with the fair use doctrine.

FAIR USE NOTICE This site contains copyrighted material the use of which has not always been specifically authorized by the copyright owner. We are making such material available to advance understanding of computer science, IT technology, economic, scientific, and social issues. We believe this constitutes a 'fair use' of any such copyrighted material as provided by section 107 of the US Copyright Law according to which such material can be distributed without profit exclusively for research and educational purposes.

This is a Spartan WHYFF (We Help You For Free) site written by people for whom English is not a native language. Grammar and spelling errors should be expected. The site contain some broken links as it develops like a living tree...

You can use PayPal to make a contribution, supporting development of this site and speed up access. In case is down you can use the at


The statements, views and opinions presented on this web page are those of the author (or referenced source) and are not endorsed by, nor do they necessarily reflect, the opinions of the author present and former employers, SDNP or any other organization the author may be associated with. We do not warrant the correctness of the information provided or its fitness for any purpose.

The site uses AdSense so you need to be aware of Google privacy policy. You you do not want to be tracked by Google please disable Javascript for this site. This site is perfectly usable without Javascript.

Last modified: March, 12, 2019