Tuesday, June 10, 2014

How to tunnel everything through SSH


Problem: You don’t trust your Internet connection (public wifi at a café, airport, ..), or perhaps it’s being limited by a firewall (China, your workplace, ..). Sure, many sites offer SSL encryption these days, but many still don’t - and even if they do, others can still see what sites you are contacting. You want to tunnel Firefox/Chrome and other programs through a secure tunnel.
Solution: Use your OpenSSH client to create a tunnel. All you need is a shell account on a remote server. (I SSH to my home server.) There are a few different ways of doing this. I will start with the easiest one.

Simple SOCKS proxy with OpenSSH

OpenSSH can act as a SOCKS server and tunnel traffic securely to a remote machine. All you need to do is the following:
ssh -D 2323 user@server
SSH will ask for your password and then a SOCKS proxy is started on port 2323 on your computer. Any traffic to port 2323 will be forwarded through the secure SSH connection. Note that your DNS traffic is not covered by this, so people can still sniff your DNS lookups (or, if they control the network, do even nastier things). See “Tunnel your DNS lookups” further down on this page.
For programs with native SOCKS support, all you need to do is configure the program(s) to use localhost 2323 as a SOCKS server. A few examples follow.

SOCKS proxy in Firefox

Go to Edit -> Preferences -> Advanced -> Network -> Settings. Check “Manual proxy configuration” and enter localhost as a SOCKS v5 host, with the port 2323.

SOCKS proxy in Pidgin

Go to Tools -> Preferences -> Proxy. Select SOCKS 5 as the Proxy type. Enter localhost as host and 2323 as port. Close the window and restart Pidgin.

SOCKS proxy for programs that don’t support SOCKS

Not all programs support SOCKS proxying natively. A program called tsocks lets you use these programs transparently.
First, install it (Ubuntu/Debian: sudo apt-get install tsocks).
Next, edit the configuration file:
  • If you have root access, edit /etc/tsocks.conf and replace the contents (delete or comment out) with the following:
    server = 127.0.0.1
    server_port = 2323
  • If you don’t have root access, put the two lines above in ~/.tsocks.conf and then create a script with the following:
    #!/bin/sh
    TSOCKS_CONF_FILE=$HOME/.tsocks.conf
    export TSOCKS_CONF_FILE
    exec tsocks "$@"
    Save it as for example runtsocks.sh and make it executable (chmod +x runtsocks.sh).
Now, just prefix any program you want to run with tsocks, e.g.:
tsocks elinks whatismyip.com
tsocks irssi
Or, if you don’t have root access:
./runtsocks.sh elinks whatismyip.com
./runtsocks.sh elinks irssi
(Don’t forget to start the SSH SOCKS proxy first, as outlined above, if you haven’t already done so.)

Tunnel your DNS lookups

Even if you have an SSH proxy running as per the instructions above, your DNS traffic will still be unencrypted. This might be bad - a third party could see for example what web sites you are visiting; in some countries certain sites will be blocked; etc.
In Firefox, the solution is easy. Simply type about:config in the address bar and set network.proxy.socks_remote_dns to true. This will have the remote end (i.e., the machine you are SSH’ing to) handle the DNS lookups.
To verify that DNS lookups in Firefox are indeed handled by the remote machine, use tcpdump or similar to inspect the traffic, e.g. tcpdump port 53.

SSH chains and jumphosts

In the example above, we have A -> encrypted tunnel -> B, where A is your local computer and B is the remote machine. Sometimes you might however need to go through two or more servers to get out of a restrictive network (or into one). E.g.: A can access B. B can access C. C can only be reached by B - but you want to tunnel your traffic from A to C via B.

One way to do it

To tunnel traffic from A through C via B, first run the following on A:
ssh -NL 4343:C:22 B
Traffic to port 4343 on your local computer will be forwarded to B, where it’s sent to port 22 on C. (This will tie up a terminal. If you don’t need to enter a password for B, you could add an & to the end to have it run in the background.)
Next, we use the tunnel above to make a connection from A to C and create a SOCKS proxy on A. Run the following on A:
ssh -o UserKnownHostsFile=/dev/null \
-o StrictHostKeyChecking=no -ND 2323 -p 4343 localhost
Enter your password for C. You now have a SOCKS proxy running on port 2323 and any traffic to it will be sent to C.

Copied from: http://fooninja.net/2010/09/06/how-to-tunnel-everything-through-ssh/