# How does SSH tunnels work ?

## GentooBox

Hi.

Have you ever got that feeling that you know what a thing do (eg a command) but you dont know how it work?

well, i have that kind of feeling right now, and i was wondering how SSH tunnels work.

ssh -L 666:hell-will-get-u.com:666 <- what does that mean ? and how does it work ?

and whats up with the -R option ?

----------

## meowsqueak

The -R and -L options are different versions of the same thing - port forwarding.

-R does remote port forwarding, which means it makes an association between a particular port and host with another port and host. Therefore you can set up something where connecting to port 80 on the remote host actually connects you to port 2000 on the local host (and it's done invisibly to you).

This is useful for setting up reverse tunnels - you can set up port 12345 on a remote box (server) to be forwarded back to port 80 on the local (client) box. Now if you go over to the remote box, log in, and connect with a browser to localhost:12345 you actually connect to the webserver running on the other box on port 80. Neat eh?

```
$ ssh -R 12345:localhost:80 remotehost
```

-L performs a similar thing, but in the reverse direction. So you connect a local (client) port to a remote (server) one. 

```
$ ssh -L 12345:localhost:80 remotehost
```

Now if you connect to localhost:12345 with a web browser, you'll actually be connecting to the web server running on remotehost listening on port 80.

You can set up reverse ssh tunnels quite easily - these allow you to set up a connection thru a firewall that only allows one-way ssh connections:

```
user@work $ ssh -R 20000:localhost:22 home
```

Note port 22 is the standard ssh port. Now go home:

```
user@home: $ ssh localhost -p 20000
```

and you'll be back on the work box. There's more info in the man page.

As to how it works - it's actually fairly simple - packets are simply received by one end, forwarded over the secure channel, and 'injected' into the appropriate port on the other end. The mechanism is entirely transparent, and the final service doesn't even know it is happening (unless it's specifically looking into the packets for evidence and therefore has some smarts about ssh in it).

----------

## GentooBox

omg..

that means that i can connect to port 22 on a remote server even if port 22 is closed on local lan ?

example:

 :Exclamation:   i have a firewall with port 300 open, and everything else is closed.

 :Exclamation:   i have a box here at home, is called "homebox" port 80 is open.

 :Exclamation:   i have a box behind a firewall, its called "remotebox" port 300 is open and have a webserver on port 300.

now i want to connect to port 300 on the remotebox, so therefor i have to make a transparent tunnel that forwards port 80 on my homebox to port 300 on the remote box:

```
ssh -L 80:homebox:300 remotebox
```

and, if i have the same setup, but port 80 is open on the remotebox, and 300 open on homebox, so i do it like this:

```
ssh -L 300:homebox:80 remotebox
```

right ?

and -R means that if i connect to localhost (homebox) on port 80 then i can setup ssh to tunnel to port 300 on remotebox.

ssh -R 80:homebox:300 remotehost

right ?

why would i use reverse ssh tunnels ?

----------

## Zoltan

Reverse tunne usage:

I have a firewalled workstation at work.

I have a host outside of work firewall.

I have a desktop at home.

At work I ssh through firewall to my host outside of firewall with "-R 8023:localhost:23" and leave connection when I go home.

At home I ssh from my home desktop to the host outside of firewall. Then I do "telnet localhost 8023" and instead of connecting to my host outside of firewall I get connected to my workstation behind firewall.

Now if my manager knew I can access files at work from home I would get in troubles since it isn't allowed by security policy of the company...

----------

## GentooBox

hmm... that makes me think.

do you need 3 computers to do that ?

cant you just make a reverse tunnel to your work computer, and then download files at work ?

----------

## Zoltan

I am using the intermediate host because my home desktop is turned off or is offline when I am at work (I am on dialup at home, holding the connection isn't possible all the time).

But my work workstation is always on as well as the host outside of firewall (it is actually a web server for some internal projects). So I can maintain connection through the firewall between my workstation and the web server for an unlimited time (or else until a power outage happens at work place) and login to the web server from home when I need to access my company intranet.

----------

## GentooBox

nice..  :Smile: 

----------

## meowsqueak

You don't need three computers, but there's usually four involved. Lets give some names to them, to make this easier:

Your work PC (work) with a private LAN IP

Your work firewall (workfire) with a public IP

Your home firewall (homefire) with a public IP

Your home PC (home) with a private LAN IP

This is how I use it:

On homefire (which is OpenBSD) I am running NAT, specifically forwarding all connections on port 22 to an internal machine (home). So, from anywhere on the Internet, if I 'ssh homefire' then I actually end up on 'home'.

Now, from my work PC, I type:

```
user@work $ ssh -R 20000:localhost:22 homefire
```

(I usually run this inside 'screen' and then detach it, just to make sure it stays out of the way - perhaps there's some special ssh option that doesn't open a shell?).

Then I go home, log in to 'home' and type:

```
user@home $ ssh localhost -p 20000
```

This can cause a 'man in the middle attack!' warning message, but clearing out ~/.ssh/known_hosts fixes this. There's probably some option that will help too. Anyway, this gives me a shell which is actually running on 'work'.

SSH is a great tool - you can actually set up a long chain of port forwards to bounce around firewalls and the like. It's quite difficult to stop 'inside' ssh from getting out unless there's a really smart firewall that can pick ssh traffic and drop the packets. If workfire actually blocks outgoing 22, you can use something like 5-loaves or corkscrew to tunnel ssh over HTTP and get out that way.

In answer to your question, GentooBox, yes you can connect to port 22 on a remote server, provided you can ssh to that box. If outgoing 22 is blocked, you'll need to connect to ssh on a different port, which requires running sshd to listen on the new port, and you have a connection anyway. You'd ssh over there and set up a port forward that connects a local port with port 22 on that box. This sort of port forwarding is often used for non-ssh traffic however, since you need an ssh connection to get it working to start with.

Just remember, incoming ports are completely independant from outgoing ports, so if incoming 22 is blocked by the firewall, it doesn't necessarily mean outgoing 22 can't get out.

----------

## GentooBox

oh... sorry, i forgot to write that ssh is listen on port 300 if the forward is to port 300.

and....

SSH is THE coooooolest thing EVER  :Very Happy: 

what is  5-loaves and corkscrew ? some kind of filter that filters http data from ssh data ?

and BTW: man-in-the-middle (ARP) attacks is fun, but evil. - just a note to ssh's warning  :Very Happy: 

EDIT: Thanks to you guys for helping me understand.

----------

## meowsqueak

5-loaves is a windows app IIRC - never needed to use it. Corkscrew is a VERY simply program (take a look at the source) that cleverly packages up ssh as HTTP so the firewall thinks it's merely outgoing HTTP data.

----------

## Zoltan

 *GentooBox wrote:*   

> 
> 
> SSH is THE coooooolest thing EVER 
> 
> 

 

I second that. And you've probably didn't use X forwarding over ssh tunnels yet?... Heh.

And about proxy traversing, after the Dante that is already available in portage there is http://httppc.sf.net that one of my friends is developing and which targets the HTTP proxy traversing only.

----------

## GentooBox

nope.. i havent done X forwarding yet.

i dont know what it does, so i dont use it.

how do i use it ?

sshd_config xforwarding=yes and then ssh -X <hostip> or what ?

 *Quote:*   

> 5-loaves is a windows app IIRC - never needed to use it. Corkscrew is a VERY simply program (take a look at the source) that cleverly packages up ssh as HTTP so the firewall thinks it's merely outgoing HTTP data.

 

oh... so i can use ssh on port 80 ?

thats cool... do i have to install it on the http server, or is it a app i can use on the ssh "server" ? (i think its number 2  :Smile:  )

----------

## professorn

X forwarding = use the xserver on a computer and connect to it with an x client from another compueter over SSH (?)

----------

## meowsqueak

You invoke corkscrew via ssh with a ~/.ssh/config that contains something like this:

```
$ cat ~/.ssh/config

ProxyCommand /usr/local/bin/corkscrew <your firewall IP> 80 %h %p
```

ssh will now use corkscrew automatically. You can specify an alternative config file for ssh if you'd rather not use it all the time.

----------

## bartmank

Will this method work for setting up a 2 tier ssh tunnel?

My sittuation is thus:

I have an application that uses a specific port I want to forward (jabber)

The server I am trying to connect to is behind a firewall, but I have gotten the admin to open port 22 to my desktop computer system.

The connection would look something like this:

*home* <-ssh-> *work_desktop* <-jabber-port-> *jabber_server*

I tried to run the command like this:

```

#ssh -L 55222:localhost:5222 work

```

But when I try to open the connection, the terminal i have the tunnel running in spits out:

```

channel 2: open failed: connect failed: Connection refused

```

Any ideas?

----------

## Zoltan

 *GentooBox wrote:*   

> nope.. i havent done X forwarding yet.
> 
> i dont know what it does, so i dont use it.
> 
> how do i use it ?
> ...

 

X forwarding is a particular case of reverse tunnel only ssh automatically sets the DISPLAY variable for the shell. When you ssh somewhere it will establish a virtual X server on the remove box. Normally the offset is 10, so you will get 

"DISPLAY=localhost:0.10", the 10th screen on localhost which is your remote host. The sshd will listen on port 6010 and forward all TCP connections from X applications through the tunnel to your local box.

On your local box all X connections will be forwarded to your X server or whatever your DISPLAY variable points to, so you don't have to be running ssh with the local X server, you can do it remotely  :Smile: 

----------

