Building Tunnels with SSH

From docwiki
Jump to: navigation, search


Motivation

We have learnd to use ssh to pipe data between local machines and remote machines. But ssh also allows to create network tunnels where we can transport other data. If you are not familiar with networking and server commands: You might want to look into the Server Basics and the Networking Basics first and skip this part.

You will also learn how to forward the output of graphical (X11) programs and to build a socks-proxy for web browsing.

use graphical tools from a remote server

Assume there is some tool on your remote server that you do not have locally. And you want to start that graphical program with its graphical output on your local screen. That is actually pretty easy with ssh.

$ ssh -X myserver.at
myserver.at$ firefox &

If you run this on a terminal in a graphical X11 unix environment it will build a tunnel that allows the programs from remote to display something on your screen. In order to be allowed to connect to your screen the programs need a key. The ssh -X also takes care about this and forwards that key.

You can check the name of your display and see the keys by using:

echo $DISPLAY
xauth list

Try that on your local terminal and an a remote server after you have used ssh -X

ATTENTION: You need to trust the remote side here because an attacker could listen to your keystrokes by putting an invisible window over your screen.

build a local tunnel to reach a remote server

Lets assume you are behind a firewall that only allows you to do a ssh connection to one server. E.g. myweb. Now have some tool that needs to connect to port 1234 of server tools.exmaple.org but your firewall does not allow it. What you could do is:

$ ssh  -L 7777:tools.example.org:1234  myweb 

The -L option tells ssh to listen on port 7777 of your local machine for incoming connections. Any connection will then be forwarded through the ssh tunnel and a connection will be originated from the remote side to the specified server and port. In our case server tools.example.org and port 1234.

If you start your tool and tell it to connect to localhost port 7777 it will be connected to the tools server. The tools server will see the connection coming form the myweb server.

$ ssh -L 8443:someserver.at:443 anna@tinbox.example.org

If the someserver.at is censored by your firewall and you want to access it you can do so after you build up the tunnel above. Then point your web browser to https://localhost:8443 and you will be talking to the someserver.at on the https port (443), where the connection originate from the tinbox.

Sshtun.png

In the above image someone connects from "client" to "server" and creates one ssh tunnel with a local -L listen socket on 7777 that will build connections from server to box3. In the second command a listen socket is created on the remote host on port 5555 where connections are created from the client to box2. (This could also be done in one command).

The Other Way Around

The capital -R option does the same thing but the other way around. It establishes a listing socket (server port) on the remote end of the ssh side and then forwards anything that connects there to your local machine.

E.g.: Assume you have built a website on your local laptop and you want to show it to a friend of yours without installing it on a public server. Also you sit behind you your NAT router at home and your laptop is not reachable from the outside. What do you do?

You can use the ssh -R to log into some public server and forward the port. E.g. like this:

$ ssh -R 8123:localhost:80  myweb

The only downside of this is that the port 8123 will only be accessible from the myweb. In order to have this port accessible from outside, the remote server needs to have a configuration option in its sshd_config and/or the client must specify that it want this port to be available.[1]

Much simpler: The Builtin Socks Proxy

Proxy Setting

Before NAT was invented people used a special protocol on their firewall to allow connections from inside the firewall to the outside. This was the socks protocol. While you do not find many socks servers these days, all web-browsers are still able to use it. And it is also built into ssh.

When you run

$ ssh -D 9999 myserver.at

You open a socks port on your local machine where you can connect but all connections will go through the ssh connection and come out of the remote end (in this case "myserver.at"). When you configure your browser to use socks proxy localhost 9999 then your browser connections will go through the tunnel and originate at the remote end. So if you are behind a firewall that censors certain sites you could use them. Or if you sit in starbucks and use the public Wifi but you are worried that the thirteen year old kids on the other table listen on your connections you have a poor-mans VPN.

Exercises

  • Try out the socks proxy. Google for whats my ip address to find a site that tells you your IP address. When you are connected via the socks proxy then it should tell you that you are coming from the remote end.

Footnotes

  1. GatewayPorts clientspecified/yes/no