# Reverse tunneling and ssh.

## dE_logics

I'm facing a classic scenario of trying-to-ssh to a server which's behind a router which cant be configured.

So I run this command from the server to form a reverse tunnel to the client from the server - 

ssh -nNT -R 1100:localhost:5000 <client>

Here the client is fusionswift.com which's an online ssh client, but unfortunately despite the presence of switches -nNT, this command asks for the username and password on fusionswift.com. Same is the case with site www.tucs.org.au

Then I cant ssh using the online client ... connection timed out.

----------

## erik258

 *Quote:*   

> 
> 
> ```
> ssh -nNT -R 1100:localhost:5000 <client> 
> ```
> ...

 

Hmmm..  is your local sshd daemon on the 'server' truly listening on port 5000?  And are you running this on what you call the 'client'? Although technically, both are ssh servers since they both run ssh daemons.  

Here's what I did.  And by the way, I'm sitting at a coffeeshop right now, so I am reproducing your situation pretty accurately I expect.  For clarity:

leroy: my laptop behind the firewall

ebony: my server behind only its own firewall. 

```

# on the computer behind the firewall I make a connection through the router with your exact command

# with 2 differences - leroy listens on port 22 so I'm using that for the destination port, and I'm 

# connection to ebony.  

dan@leroy $ ssh -nNT -R 1100:localhost:22 ebony 

# this stayed running at the terminal - which makes sense, why wouldn't it? - 

# but since dan@leroy has an SSH key for dan@ebony, it didn't prompt for password

# now I log into ebony, which isn't behind a firewall remember.  

dan@leroy ~ $ ssh ebony.farrellit.net

# now I'm in ebony, and I'm logging back into my laptop through the tunnel I created.  

dan@ebony ~ $ ssh localhost -p 1100

The authenticity of host  [ ... snip ... ]

Password: 

Last login: Fri Dec  3 21:01:41 CST 2010 on tty1

dan@leroy ~ $     

# here it asked for my password because dan@ebony doesn't have a key for leroy.  

```

So for statrers this verifies your tunnel creation command works, so it's likely you're not using it quite right.  Are you:

* typing in your password (how else are you supposed to authenticate with the 'client' as you call it?) or do you  need to fix something with your private key (permissions?  they must be 600!)

* leaving ssh -nNT ...  running on the host behind the firewall?  The way you have it written it will   never return, so make sure it keeps running.

* logging into the 'client'  - the remote, web accessible tunnel endpoint - first?  The way you create the tunnel, it's listening on localhost:5000 on the 'client', so you'll have to be logged in - or forward some external port to localhost:5000.  

use nmap to figure out who's listening to which port where!  From what I've done and seen myself, reversing port numbers is the most common mistake people make with ssh forwarding.  netstat -lnp4 can also be helpful to show programs which are currently listening on ipv4 ports.  

Now let's look at improving your command.  You have chosen -nNT -R for flags.  Let's look closer at what they do.  

-n : Redirects stdin from /dev/null (actually, prevents reading from stdin).  (This does not work if ssh needs to ask for a password or passphrase; see also the -f option.)

note this doesn't actually put the command in the background, just tells it to ignore stdin.  And as it says, it doesn't do anything if it needs to ask for a password, which you seem to report it does.  So this flag essentially does nothing for you.  

-N : Do not execute a remote command.

Well that is just fine.  

-T : Disable pseudo-tty allocation.

Sure, there's no point to allocating a pseudo-tty on the remote side if you're just forwarding.  But I wonder if ssh can figure this out itself?  If you're not running a program on the remote side, I bet it doesn't bother, since it would be totally pointless anyway.  

-R : Specifies that the given port on the remote (server) host is to be forwarded to 

                the given host and port on the local side.  

That one's clearly right.  

Now let's look at another option, -f.  

-f  Requests ssh to go to background just before command execution.. This is useful if ssh is going to ask for passwords or passphrases, but the user wants it in the background.  This implies -n.

So here's how I would have invoked your command, assuming you have the ports right.

```
ssh -f -R 1100:localhost:5000 <client>  -N
```

I would then type in a password, if I needed to : )    Then my terminal will return and my ssh tunnel will run in the background, essentially invisible to the 'outside world'.

Two other thoughts.  Firstly, if you can open ports on the public side of the 'client', you can replace localhost in your invocation with the public hostname/IP address.  The downside to this is that your firewalled host (the 'server' in your nomenclature) is now listening on a public IP and port.  However, its unlikely that anybody's going to notice you're SSH server is listening on a nonstandard port, and there's more than enough servers listening on standard ports to keep the bots busy, I think.  Besides, if you're worried, your security scheme isn't good enough.  Access shouldn't be enough to break in!  Anyhow, the upside is that you will be able to log straight into your firewalled box without first logging into your 'client' - which is convenient for future auditing, because then you see the external IP connecting rather than "localhost".  

Second thought.  If you find yourself in this position often, you should consider using OpenVPN.  A VPN surpasses the functionality of a ssh tunnel in the following ways.  You can get through the tunnel to the entire remote lan without logging into anything.  You can also connect to the remote machines on any port, not just 22.  In your scenario, you'd have to keep forwarding every port you wanted to use.  With a VPN, weird protocols like FTP work fine.  Whereas an SSH tunnel is a port tunnel, a VPN is like having an ethernet cable running from one machine to the other.  You can then route/bridge the other lans and now your remote subnets are connected all the time, to the fullest possible extent!  [/code]

----------

## dE_logics

I think I'll consult the man page first, but it's partially going over my head (since I'm not a network veteran).

----------

## Hu

 *dE_logics wrote:*   

> ssh -nNT -R 1100:localhost:5000 <client>
> 
> Here the client is fusionswift.com which's an online ssh client, but unfortunately despite the presence of switches -nNT, this command asks for the username and password on fusionswift.com. Same is the case with site www.tucs.org.au

 Authentication is not suppressed by those switches.  You still need a valid username+password or username+key.  You can use -oBatchMode=yes to force the client to exit if it cannot proceed without user input.

----------

## dE_logics

How about using port 80? If I do use it, how will the router know whom to transfer the data to?

Another question (related), if I'm behind a router, can I ssh myself?

----------

## Hu

Aside from the requirement that you tell ssh if you use a non-default port, it does not care about what port the remote end uses.  If you are behind any sort of NAT device, which home routers typically are, you must inform that device that it shall forward traffic from an external IP:port to an internal IP:port of your choosing.  For ssh, this probably means forwarding to port 22 on the internal machine.  Different home routers vary in their ability to handle this.  Some are so utterly useless that you cannot create static port forwarding rules.  Most have at least some capability, but the presentation may vary.

----------

## dE_logics

 *Hu wrote:*   

> Aside from the requirement that you tell ssh if you use a non-default port, it does not care about what port the remote end uses.  If you are behind any sort of NAT device, which home routers typically are, you must inform that device that it shall forward traffic from an external IP:port to an internal IP:port of your choosing.  For ssh, this probably means forwarding to port 22 on the internal machine.  Different home routers vary in their ability to handle this.  Some are so utterly useless that you cannot create static port forwarding rules.  Most have at least some capability, but the presentation may vary.

 

I don't have the permission to configure the router, that's why I chose port 80, it's the standard http port, so I was wondering it wouldn't pose any restrictions.

----------

## Hu

That will be fine, as long as someone who does have permission to configure the router configures it to forward external port 80 to some port on your system, where you then listen.  Absent any configuration, the router will likely drop all incoming connection requests.

----------

## dE_logics

 *Hu wrote:*   

> That will be fine, as long as someone who does have permission to configure the router configures it to forward external port 80 to some port on your system, where you then listen.  Absent any configuration, the router will likely drop all incoming connection requests.

 

No. The router doesn't even have that feature. So even on port 80 the request will be blocked. Also both server and clients are behind routers.

How about making an http or ip tunnel on port 80?

----------

## Hu

You can send whatever you like on whatever port you want.  However, if the receiving system, which is apparently a "home router" is not configured to handle that traffic locally or forward it to another system that can handle it, you will not make any progress because the recipient will either RST it or ignore it.  If both ends are behind braindead home routers, then your only solution is to get a home router that is not braindead and install it instead.

----------

## dE_logics

I knew it!!

Thanks for clarifying.

----------

## dE_logics

Ok, now I got a direct (external) IP on my box, the other is behind the router. I have sshd running on by box, and the remote box (which's behind a router), I issue the following commands from the remote box - 

ssh -NTn -R 45922:localhost:45922 safe@<IP of my box>

And it says timed out...

----------

## dE_logics

Now, that problem is solved. I can log in from the 'other' box which's behind the firewall... or actually I made the filrewall simulate a router by configuring it to drop all new TCP or any other type of new connection on top of TCP.

So I do ssh -X -C -p 1500 username@localhost on my box, where 1500 is the port forwared from the 'other' box... however I get "ssh_exchange_identification: Connection closed by remote host."

----------

## dE_logics

Ok, done. I had 2 notorious lines (which I copied to solve this problem itself) - 

#GatewayPorts yes

#PermitTunnel yes

Which I hashed out now. Every thing looks ok for now, and it works through Ip tables.

----------

