linguistics, computers, and puns

OpenSSH as a SOCKS proxy

Tim Hammerquist May 08, 2008 #network #security #ssh #sysadmin

From the OpenSSH's ssh_config(5) manpage, the DynamicForward keyword (and associated command-line switch -D):


Specifies that a TCP port on the local machine be 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(1) will act as a SOCKS

What can we do with this?

HTTP proxies can offer some of the same benefits. They can provide access to some sites that may be blocked from your LAN/hotspot. Some proxies can even proxy SSL traffic or DNS lookups. On the other hand, the connection from your client to the proxy is often unencrypted. In many cases, this hole can be plugged by vanilla SSH port forwarding.

If your HTTP proxy can't tunnel DNS or SSL, or if you can't SSH to your HTTP proxy server to tunnel the connection, it gets complicated. Moreover, what if you don't have an HTTP proxy to tunnel to?

Finally, what if you don't want to surf? Email, telnet, and ftp are also common destinations for hotspot users. Several common protocols (telnet, FTP, SMTP AUTH, POP3, IMAP4) send messages and passwords in either plaintext or minimally encrypted, and many proxies can't be used to proxy these connections.

We can solve (or at least offload) many of these problems using one single connection to a machine running an OpenSSH server.

SOCKS proxies are much more flexible than standard HTTP proxies because they can proxy arbitrary TCP connections. Enter OpenSSH's DynamicForward feature. It slices. It dices. It provides a fully authenticated, encrypted tunnel between you and a trusted server with open Internet access running an OpenSSH server. Best of all, it's simple and free.


For this activity you'll need:

Step 1: Establish tunnel

OpenSSH SOCKS tunnels can be established by using either the DynamicForward directive in your ~/.ssh/config or by passing the -D switch. Be sure to follow each with a TCP port for ssh to listen on for SOCKS connections. Which port you choose is entirely up to you; for this article, I'll use 1080.

$ ssh -D1080 joe@remote_server

Once you've finished authenticating with the OpenSSH server, you should have a fully functional SOCKS proxy server.

Step 2: Configure client(s)

A proxy is no good if clients don't know to use it. Many network clients already know how to use SOCKS proxies. Some operating systems can use the proxies transparently behind the scenes. And still more clients can be made to use them without their knowledge using a simple, ingenious hack known as tsocks.

For this demonstration, we'll use Firefox. The setup is straight-forward. Open the Preferences and browse to Advanced -> Network -> Connection -> Settings.

Select Manual proxy configuration and enter in the text field next to Socks host. In the Port field, enter the port you passed to ssh.

If you want to ensure all of Firefox's DNS lookups also go over the SOCKS tunnel (and you probably do), there's just one more step. Since this item isn't configurable via Preferences, go to Firefox's URL bar and enter: about:config and hit Return.

This will bring up a long list of configurable items, so let's narrow it down a bit. In the Filter bar at the top of the configuration page, enter dns. The item we want to twiddle should be apparent: network.proxy.socks_remote_dns. Double-click this item to toggle it's value until the last column reads true.

Step 3: Surf!

The changes you made to Firefox should take effect immediately, so try surfing to a site that will tell you your public IP, like If all went well, you should see the public IP of the host you ssh'd to instead of your client's public IP. Browse for a while.


Start packet sniffer

If you want to make sure all important data is passed over ssh's SOCKS tunnel, you can start up a packet sniffer now. Wireshark, the successor to Ethereal, is an excellent choice that's available for all major platforms. Command-line tools such as tcpdump or Wireshark's tshark are also useful.

Check your sniffer

Check back with Wireshark. Assuming no other processes on your client machine are creating network traffic, the only traffic you should see leaving your machine is encrypted SSH packets headed to remote_server. If you see other traffic, it may come from services/daemons on your client machine, or something may have gone wrong in your configuration.


After verifying that your new SOCKS proxy works, you may want to streamline the process. Here are a few ideas:

Host socksproxy
    Hostname remote_server
    Username joe
    DynamicForward 1080

Thereafter, ssh socksproxy serves as a nice shortcut.

Happy (secure) surfing!