How to ssh tunnel
Contents |
How to SSH Tunneling (linux flavor)
One of the many features of ssh is tunneling. Tunneling (also known as port forwarding) allows us to "encapsulate" any tcp connection under the ssh protocol, securing it exactly as if it where ssh. Let's explain it with one example:
The problem
Imagine that you are at school, and you detect that someone is sniffing the traffic (maybe the teachers, or not...) with a man-in-the-middle attack and you want to connect to your POP server at home, that sniffer will capture the traffic to that server and will find you user and password! But hey! If you connect your ssh tunnel to your POP server that traffic will be encrypted and the sniffer will not be able (at least it will be not so easy) to get your user and pass. Let's see how we do that:
The solution
First the syntax:
- ssh user@server1 -L host:port1:server2:port2
- user@server are the username used to connect and the server to connect to
- host:port1 are the local ip or hostname and port in which the ssh will listen to. If you leave an empty host like port1:server2:port2 it will take all the hosts on the local machine.
- server2:port2 are the server and port where the packet will be forwarded.
The net picture:
Ok, our command line must look like this:
~$ ssh cascara@ssh_server -L 127.0.0.1:110:pop_server:110
And as long as the ssh connection remains open the tunnel will forward all the connections to the ip 127.0.0.1 and port 110 to the foreign host pop_server and port 110.
Just notice that the ip of the pop_server is the ip from the ssh_server and that the connection from the ssh_server to the pop_server is not encrypted (is out of the tunnel), except if the pop_server is the same machine as the ssh_server, that is, localhost or 127.0.0.1.
Reverse Forwarding
Reverse forwarding ports can be very useful if you are behind a firewall and you want to bypass the port filtering for incoming connections. A lot of firewalls only let you connect to the www port, but you just want to get some files from your favorite ftp server, what will you do?
Well, with port forwarding you just need one ssh server listening at the www port. Then you will make a first tunnel for connecting to the ftp_server:
~$ ssh -p 80 cascara@ssh_server -L 127.0.0.1:21:ftp_server:21
And you will need a second one for the active ftp connection (port 20):
~$ ssh -p 80 cascara@ssh_server -R 20:127.0.0.1:20
Ok, let's see what this means:
The first tunnel connects our port 21 to the ftp_servers's port 21 through the ssh_server port 80 (so the firewall lets us go through). This allows us to start the connection, but ftp connections (active mode) need the client's port 20 to be open, so we made the second tunnel.
The second tunnel connects the ssh_server's port 20 to our local port 20 through the ssh_server's port 80 (the ssh connection is made from localhost to ssh_server, so the firewall will let us too), making the full ftp connection and allowing us to download those necessary files XD.
Dynamic Port Forwarding
Now you are thinking "that's cool, but if i want to redirect more than one port it's not useful...", maybe you are right, but there's another option that allows you to redirect all the ports that you will use! Dynamic Port Forwarding!
Let's take a closer look. What really happens here is that ssh does a standard port forwarding but only for SOCKS traffic, and starts a SOKCS proxy at the given port to forward all the connections through the ssh connection, so if our application does not support SOCKS we need to use a "SOCKS filter", for example tsocks, to get your connection through, see the "Configuring tsocks" section below.
Ok, the syntax:
- ssh -D host:port user@server
- host:port host or ip and port where the SOCKS proxy will listen
- user@server username and server to establish the ssh connection
For example, if you want to get all your ftp (passive mode) traffic through the port 80 (you need one ssh server listening at home) your command line should look like this one:
~$ ssh -p 80 -D 1234 cascara@ssh_server
and then launch your favorite ftp client with tsocks:
~$ tsocks ftp
Configuring tsocks
To successfully set up a dynamic port forwarding we need to configure tsocks to use the ssh SOCKS proxy. The configuration file for tsocks is installed by default at /etc/tsocks.conf. It has three parts, local nets definition, paths and default server configuration. With the local nets definition we define those nets or hosts who will not use the SOCKS proxy. The path define some ip-ranges server-config pairs, telling sock to use those server configs when accessing those ips. And the last, the server default config, isthe one that tsocks uses when accessing ips that were not in the previous sections. Let's see how it must be (one of the many possibilities) for the upper connection to work:
#our local range
local = 192.168.0.0/255.255.255.0
#custom server configuration, if you have more than one tunnel you could select it here
#in this example the connections to the ip 12.23.34.45 will be passed throug the local SOCKS proxy
#not really useful, it's an example
path {
reaches = 12.23.34.45
server = 127.0.0.1
server_type = 5
server_port = 1235
}
#it must use the ssh SOCKS proxy as the default server
server = 127.0.0.1
server_type = 5
server_port = 1234
That will not only get ftp traffic but all the traffic not going to the local net through the socks proxy (remember that is the launched application the one who gets proxyfied, not all the system).
Now we have out tsocks ready!
mini FAQ
- Can I tunnel SSH through SSH?
- Of Course you can!
- Can I tunnel a tunnel ?
- Yes!
- Can I ask you another question?
- I'll be glad to answer as soon as I can! Don't be shy, asking is the only way to learn.
Configuring your browser for a Socks Proxy
It is fairly simple to set up a socks proxy for your browsers. Here is how to set it up for a few of the browsers out there
Firefox
- Under the "Tools" menu, click "Options."
- In the dialogue that pops up, click the "Advanced" tab
- In the advanced tab, click "Network"
- Click the "Settings" button under the "Connections" box
- Select the raido button "Manual proxy configuration"
- In the "SOCKS host" box, put "localhost", and the port box is filled with the port number you have forwarded (7070 in the PuTTY method)
- Press OK and you are done.
Internet Explorer
- In the "Tools" menu click "Internet Options"
- Click on the "Connections" tab
- Click the "LAN Settings" at the bottom
- Check the "Use a proxy server for your LAN" option in the "Proxy server" box
- Click the "Advanced" button
- In the "Socks:" box put "localhost" and the port box is filled with the port number you have forwarded (7070 in the PuTTY method)
- Click OK and you are done
Google Chrome
- Click the Wrench Icon in the top right (Customize and control google chrome)
- Click "Options" from the drop down menu
- Scroll down to the "Network" heading and click "Change proxy settings"
- Click the "LAN Settings" at the bottom
- Check the "Use a proxy server for your LAN" option in the "Proxy server" box
- Click the "Advanced" button
- In the "Socks:" box put "localhost" and the port box is filled with the port number you have forwarded (7070 in the PuTTY method)
- Click OK and you are done
Windows Flavor - with Putty
In the PuTTY Configuration Menu, go to Connection->SSH->Tunnels.
- For Source port, enter the local port for SSH to listen to
- For Destination, enter the server and port to forward the connection to, eg shellium.org:4200
- Click Add so that the new tunnel is added to the list of tunnels above
After configuring tunnels, connect to the server as usual.
It is also a good idea to create a profile in PuTTY with the tunnels you want to use. To do this, go to Session panel back, type in the session name in the Saved Sessions field and click Save. After that you can just always doubleclick the session name and putty will connect automatically. Combined with HOWTO SSH without a password it is an easy way to tunnel things.
Alternative Method - with PuTTY
Now you can use 7070 as a socks proxy on localhost for any ssh tunneling you want. In the PuTTY configuration menu, go to Connection->SSH->Tunnels. Enter a port of your choosing in source port, leave destination blank. On the first row of radio buttons, click dynamic. Leave the second row at auto. Click Add, save the connection, and login.
Persistent SSH tunnels on Windows
Wkocjan's website Using Tcl to tunnel connections over SSH contains a good tool for automatic tunnelling on Windows using PuTTY. It includes things like reconnecting after network is down, which is useful for people using WiFi or moving across locations.
You can get instructions on how to set up an utility that tunnels SSH connections and registers as a Windows service. You only need to define hosts and tunnels in an ini file, for example for SHellium it will be:
[host1] hostname=shellium.org username=wkocjan keyfile=C:/SSH/mykey.ppk tunnel1=local:127.0.0.1:6669:irc.freenode.net:6667 tunnel2=local:127.0.0.1:1110:localhost:110
This configuration will keep a permanent connection to shellium and tunnel connections from your computer's port 6669 to port 6667 on irc.freenode.net. It will also tunnel connections from your computer's port 1110 to port 110 of the server, which can be used for tunneling POP3 connections. While I'm not sure if SHellium offers POP3, it's a good example.
Details on setting up the binary are available on the page mentioned above.
