Using SSH as a SOCKS Proxy to route HTTP traffic

Posted on January 10, 2017

Let’s say that, for one reason or another, you want to open a website in the browser running on your local laptop/desktop, but you want that HTTP traffic to pass through some server/VM running in the cloud.

+--------+
| Laptop |
| +----+ |
| | FF | |
| |    | |        +-----+       +-------+
| +----+ | tunnel |Cloud| HTTP  | Some  |
|   \____|=======>| VM  |------>|Website|
+--------+        +-----+       +-------+

This is a proxy.

How do you set this up?

Create an SSH tunnel that supports SOCKS5

ᐅ ssh -fN -D localhost:9999 user@remote-server

In this case:

Caveat: ensure AllowTcpForwarding is enabled

It’s on by default, but in case you run into issues, check that /etc/ssh/sshd_config has AllowTcpForwarding yes to allow the proxy.

Testing with cURL

OK, with the SOCKS proxy tunnel setup, let’s use it. The simplest test from the command line is to use curl to send an HTTP request through the tunnel. There are a few ways to tell curl about the tunnel, but for our purposes, the --proxy cli flag will do:

ᐅ curl --proxy socks5h://localhost:9999 -v https://duckduckgo.com

--proxy references the host:port we told SSH to use when setting up the tunnel, and curl will send the request thru that tunnel.

Configuring Chromium

This doc has the details, but here they are in short:

--proxy-server="socks5://localhost:9999" --host-resolver-rules="MAP * 0.0.0.0 , EXCLUDE myproxy"

Pass those to chromium when opening it from the shell.

Configuring Firefox

There are other ways, but to configure a specific profile:

Why would you do this?

There are lots of reasons, here are a few I run into periodically:

If it matters, beware of leaking DNS!