SOCKS proxy over SSH

Here goes a quick and valuable tip people don’t usually know, or at least a couple of friends of mine were not aware of. The two keywords will be SOCKS and SSH.

Connecting over to a remote server, one can bypass unauthorized access blocked by usually our network firewall. The most common examples given are restricted access to Facebook, MSN or torrents. We can also have unlimited access to all kinds of contents thanks to the nice sysadmin managing the network who puts no barriers whatsoever, but we may not trust him or the network users to permit unencrypted data flowing openly. Having some way to establish an encrypted connection to a known network who we trust, or distrust less, and tunneling over it would be safer. This is where SOCKS and SSH can be much of helpful!

SOCKS is an Internet protocol that routes network packets between a client and server through a proxy server. – via Wikipedia

I’m certain as most, if not all, of our daily applications implement themselves some way of proxying (mostly HTTP, HTTPS and SOCKS) or use the system-wide configured network proxy server. Now all we need is a remote and secure server to proxy and tunnel. This is the part where SSH enters:

Secure Shell (SSH) is a network protocol for secure data communication, remote shell services or command execution and other secure network services between two networked computers that it connects via a secure channel over an insecure network: a server and a client (running SSH server and SSH client programs, respectively). – via Wikipedia

What this means is if we have a SSH-enabled server we can take advantage of it because typically no further configurations or tweaks are needed. Let’s take a look at the SSH client manual:

-D [bind_address:]port Specifies a local ``dynamic’’ application-level port forwarding. This works by allocating a socket to listen to port on the local side, optionally bound to the specified bind_address. Whenever a connection is made to this port, the connection is forwarded over the secure channel, and the application protocol is then used to determine where to connect to from the remote machine. Currently the SOCKS4 and SOCKS5 protocols are supported, and ssh will act as a SOCKS server. Only root can forward privileged ports. Dynamic port forwardings can also be specified in the configuration file.

Got it? Great! Let’s combine SSH+SOCKS:

ssh -C2qTnN -D <PORT> <USER>@<IP>

I will not provide the details of what each option features - run ‘man ssh’ and find by yourself. The result is a SOCKS proxy over SSH. Now let’s wrap it in a bash script:

#!/bin/bash
if [[ `uname` == 'Darwin' ]]; then
  trap " {
  echo \"Setting SOCKS proxy down...\" ; \
  networksetup -setsocksfirewallproxystate ethernet off ;
  networksetup -setsocksfirewallproxystate wi-fi off;
  exit 1;
  }" ERR INT TERM EXIT
  networksetup -setsocksfirewallproxystate ethernet on
  networksetup -setsocksfirewallproxystate wi-fi on
fi
ssh -C2qTnN -D 1080 <USER>@<IP>

Replace @ by your username and IP address. This bash script, in case you are a Mac user, will automatically turn SOCKS on upon execution and turn it off when shutting down (Mac users using an OS X version prior to Lion should replace "wi-fi" by "airport"). Other Unix users (Linux, BSD, etc) should set SOCKS host as "localhost" and SOCKS port "1080" in either your system network configurations or in each application you want to tunnel over.