Comments on Reverse SSH Tunneling
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.
45 Comment(s)
Comments
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 [email protected]
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 [email protected]
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.
Great suggestions, Fred.
Thanks
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 [email protected] 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
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 [email protected]
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 !
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 ?
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 [email protected] -fN
Hi, maybe the 127.0.0.1 is not the default unless you specify the "GatewayPorts yes" options in your /etc/ssh/sshd_config and restart the sshd service.
So if you have only "GatewayPorts no" (even if commented) then the reverse tunnel bind just on 127.0.0.1 even using -R *:19999:localhost:22 [email protected] or nothing like -R 19999:localhost:22 [email protected].
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.
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.
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.
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 [email protected]
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!
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.
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.
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...
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.
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.
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
Helpful information, thanks!
Using ports below 1024 for anyone other than root will result in this error:
"remote port forwarding failed for listen port"
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.
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.
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.
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.
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
what if both source and destination are behind NAT?
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 [email protected]
-Now from the Client PC pull the port down from the middleman:
ssh -L {PortOnClientPC}:localhost:{PortOnMiddlePC} {UserOnMiddlePC}@{IPofMiddlePC}
ssh -L 19999:localhost:19999 [email protected]
-Now you can ssh the Target PC from the Client PC:
ssh localhost -p {PortForwardedFromTargetPC}
ssh localhost -p 19999
Does not seem to work unless the Target PC is also running a ssh server.
You are kidding, right? Needless to say in any circumstances a sshd is required running on the target PC, that is the whole point.
none of this is Linux specific. It will work for FreeBSD as well. please fix the article
Thanks, I really needed it.
thank you for the guide!
What if I don't want to give Bob an access to the Source? is it possible to forward his request via Source's 19999 port to the Destination?..
That divine *: was the missing link to get my configuration complete. Many thanks for the hint.
Nice explanation , I finally understand how it works after searching on this topic for 2 days ,but is it possible that I can use Windows as my Source platform ?If possible , Which software should I use ?
Good and short one! As for me, I am a lazy person, I prefer to use cloudport for tunnels ;)
Great post. Short and sweet. Thanks for sharing.
--Sam SmithTechnology Evangelist and Aspiring Chef.
You need to edit sshd_conf first and set GatewayPorts to yes
If Bob doesn't trust Source, Bob can use ProxyCommand to proxy through Source with end-to-end encryption, see ssh_client_config_example.
I also suggest using SSH keepalives with ServerAliveInterval and ServerAliveCountMax and something to restart ssh. I'm doing this with sidedoor, a Debian/Raspbian/Ubuntu SSH connection daemon, basically a wrapper script.
I am trying to setup a reverse ssh tunnel for https protocol (well, actually I am using this to host a small intranet web server which I like to use Let's Encrypt certificate). It worked well, but some proxy/firewall did not like that, and they cannot complete the hand-shake because some mystery causes:
~$ curl -s -v https://XXX:4334/
* Trying PPPP...
* Connected to PPPP (PPPP) port ppp (#0)
* Establish HTTP proxy tunnel to XXX:4334
> CONNECT XXX:4334 HTTP/1.1
> Host: XXX:4334
> User-Agent: curl/7.47.0
> Proxy-Connection: Keep-Alive
>
< HTTP/1.1 200 Connection established
<
* Proxy replied OK to CONNECT request
* found 149 certificates in /etc/ssl/certs/ca-certificates.crt
* found 602 certificates in /etc/ssl/certs
* ALPN, offering http/1.1
* gnutls_handshake() failed: The TLS connection was non-properly terminated.
* Closing connection 0
Interestingly, squid would not make any mistake by this situation
Is it possible for a private web server running connected to the internet with a SIM 4G? IP is dynamic, it is behind NAT. Thank you
is this executed from the destination computer or the source comptuer ?
1. SSH from the destination to the source (with public IP) using the command below:
ssh -R 19999:localhost:22 [email protected]
Great great article, thanks very much
can you please help me for remote access. i want to connect destination using remote connectivity.
source_IP: 192.168.3.212
Source_public_IP: 106.0.38.146
Destination_IP : 172.16.1.198
Destination_Public: 49.206.30.118
and Destination_username: debian.
please help me on how to connect.
This is a great article!
Confusing