Reverse SSH Tunneling

Want to support HowtoForge? Become a subscriber!
 
Submitted by kcharoen (Contact Author) (Forums) on Thu, 2008-09-18 11:30. :: Linux

Reverse SSH Tunneling

Have you ever wanted to ssh to your Linux box that sits behind NAT? Now you can with reverse SSH tunneling. This document will show you step by step how to set up reverse SSH tunneling. The reverse SSH tunneling should work fine with Unix like systems.

Let's assume that Destination's IP is 192.168.20.55 (Linux box that you want to access).

You want to access from Linux client with IP 138.47.99.99.

Destination (192.168.20.55) <- |NAT| <- Source (138.47.99.99)

1. SSH from the destination to the source (with public ip) using command below:

ssh -R 19999:localhost:22 sourceuser@138.47.99.99

* port 19999 can be any unused port.

2. Now you can SSH from source to destination through SSH tuneling:

ssh localhost -p 19999

3. 3rd party servers can also access 192.168.20.55 through Destination (138.47.99.99).

Destination (192.168.20.55) <- |NAT| <- Source (138.47.99.99) <- Bob's server

3.1 From Bob's server:

ssh sourceuser@138.47.99.99

3.2 After the sucessful login to Source:

ssh localhost -p 19999

* the connection between destination and source must be alive at all time.

Tip: you may run a command (e.g. watch, top) on Destination to keep the connection active.


Please do not use the comment function to ask for help! If you need help, please use our forum.
Comments will be published after administrator approval.
Submitted by Anonymous (not registered) on Thu, 2014-04-10 18:55.

none of this is Linux specific. It will work for FreeBSD as well. please fix the article

Submitted by fkasmani (not registered) on Tue, 2012-09-18 17:48.
what if both source and destination are behind NAT?
Submitted by Jay P (not registered) on Wed, 2012-11-28 19:18.

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@188.88.88.88

 

-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@188.88.88.88

 

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

ssh localhost -p {PortForwardedFromTargetPC}

ssh localhost -p 19999

Submitted by Anonymous (not registered) on Sat, 2013-01-19 21:10.
Does not seem to work unless the Target PC is also running a ssh server.
Submitted by meow (not registered) on Sun, 2014-08-31 16:55.
You are kidding, right? Needless to say in any circumstances a sshd is required running on the target PC, that is the whole point.
Submitted by Anonymous (not registered) on Thu, 2011-08-04 19:49.

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

3rd party servers can also access 192.168.20.55 through Destination Source (138.47.99.99).

Destination (192.168.20.55) <- |NAT| <- Source (138.47.99.99) <- Bob's server

Submitted by Anonymous (not registered) on Mon, 2011-01-31 21:47.

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.

 

Submitted by Anonymous (not registered) on Mon, 2011-02-14 21:40.

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.

Submitted by Anonymous (not registered) on Tue, 2010-08-17 15:45.

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.

Submitted by Anonymous (not registered) on Mon, 2009-01-12 00:48.

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

"remote port forwarding failed for listen port"

Submitted by Anthony (not registered) on Thu, 2011-03-24 02:54.
Is there some way to get a linux box (not multi-user) to permit non-root processes to open restricted low ( < 1024) ports? Windows machines have no such restrictions, and it is a silly restriction for private single user linux machines to require root for that task. I know about a kludge-hack involving using a suid program and LD_PRELOAD to fake a library so as to pre-open a restricted port. See 'user_lowport' program creating in this development package... http://www.semicomplete.com/projects/liboverride/ But I am looking for a more general relaxation of the rules.
Submitted by Anonymous (not registered) on Tue, 2008-12-16 09:37.
Helpful information, thanks!
Submitted by Anonymous (not registered) on Fri, 2009-11-27 15:39.
Thank a lot!!!!
Submitted by Fred Feirtag (not registered) on Mon, 2008-09-22 18:48.

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 138.47.99.99 sudo /usr/sbin/pppd notty 192.168.254.254:192.168.254.253"

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

--Fred Feirtag

Submitted by Anonymous (not registered) on Sun, 2008-09-21 14:53.
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.
Submitted by Anonymous (not registered) on Sun, 2008-09-21 12:54.

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!

Submitted by Anonymous (not registered) on Sun, 2008-09-21 02:53.

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
  Hostname remotehost.org
  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...

 

 
Submitted by Anonymous (not registered) on Sat, 2008-09-20 13:00.
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.
Submitted by Anonymous (not registered) on Sat, 2008-09-20 19:44.
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.
Submitted by Anonymous (not registered) on Mon, 2013-06-24 11:59.

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.

Submitted by Anonymous (not registered) on Sun, 2008-09-21 06:56.

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.

 

Submitted by Anonymous (not registered) on Sat, 2008-09-20 07:39.

http://www.harding.motd.ca/autossh/

 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
HostName 123.123.123.123
        KeepAlive yes
        User roprint
        IdentityFile    ~roprint/.ssh/specialkey1
        LocalForward    9102    192.168.101.14:9100
        LocalForward    9103    192.168.103.22:9100
        LocalForward    9104    192.168.100.220:9100
        LocalForward    9105    192.168.101.229:9100
        LocalForward    9106    192.168.101.228:9100
        LocalForward    9107    192.168.101.225:9100
        LocalForward    9108    192.168.101.24:9100
        LocalForward    9109    192.168.101.15:9100
        LocalForward    9110    192.168.107.17:9100
        LocalForward    9111    192.168.103.60:9100
        LocalForward    9120    192.168.102.40:9100
        LocalForward    9127    192.168.101.221:9100

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.

Submitted by dietrich (not registered) on Sat, 2008-09-20 01:05.

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.

Submitted by Fred (not registered) on Thu, 2008-09-18 13:28.

Step 1

I recommand to use ssh option -f to detach ssh process from the tty and -N to not execute any command over ssh (the connexion 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 sourceuser@138.47.99.99

Step 3

In your example, you have to give a shell access to 138.47.99.99 to a foreign user (bob) in order to let him connect to destination.

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

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

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

Submitted by Samat (not registered) on Sat, 2008-09-20 05:55.

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/tunnel.sh:

 #!/bin/bash
HOSTNAME=$(hostname)
SSH_OPTIONS="-i /etc/tunnel/$HOSTNAME.key"
# Always assume initial connection will be successful
export AUTOSSH_GATETIME=0
# Disable echo service, relying on SSH exiting itself
export AUTOSSH_PORT=0

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

Submitted by kcharoen (registered user) on Fri, 2008-09-19 22:48.

Great suggestions, Fred.

 Thanks

Submitted by Anonymous (not registered) on Sun, 2008-09-21 06:52.
if the gateway has openssh running, and you have access to it, this works nicely: Host internal.hostname.tld internal User jsmith HostName internal.hostname.tld ProxyCommand ssh jsmith@gateway.hostname.tld nc %h %p 2> /dev/null than just `ssh internal' gets you in without need for tcp forwarding, nor reverse ssh port forwarding. it just works. http://undeadly.org/cgi?action=article&sid=20070925181947
Submitted by Anonymous (not registered) on Fri, 2011-06-10 06:24.

Hi,

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 127.0.0.1 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
HostName home.dyndns.org
User babylon
RemoteForward 20023 127.0.0.1:22

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@127.0.0.1 

 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 id_rsa.pub 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/id_rsa.pub
THEN
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 !

Submitted by Anonymous (not registered) on Fri, 2011-10-28 10:31.

I've reversessh working on a openwrt device but now i like to connect to the webbrowser on the remote router.

Situation: I've two routers with openwrt. From router A i already have a reverse ssh connection to router B.

At the router A i can connect to B with the command: ssh -p5014 localhost

How can i connect to a webserver running on router B using the tunnel ?