Using SSH as a SOCKS Proxy to route HTTP traffic
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:
-f
sends SSH to the background-N
tells SSH you won’t run a remote, interactive shell, it is useful for tunnels-D
tells SSH to setup a SOCKS5 tunnellocalhost:9999
is thehost:port
on the local end of the tunnel you will point your browser atuser@remote-server
is theuser@host
of the remote SSH server you will route HTTP traffic through
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:
- open preferences
- select the advanced tab
- select the network tab
- click Settings… next to Configure how Firefox connects to the Internet
- select Manual proxy configuration
- add
localhost
and9999
into SOCKS Host and Port in the form - save and happy proxied browsing!
Why would you do this?
There are lots of reasons, here are a few I run into periodically:
- You’ve run into the craziest VPN connection issue of your life, but it works fine when you run the VPN from an EC2 instance in the cloud… setup a SOCKS proxy on the EC2 instance to route some of your HTTP traffic thru the VPN (via the SOCKs proxy).
- You’ve deployed a bunch of management web services (UIs) in a secure network, you have SSH access to the network, but do not want to make those management services publicly available (and a VPN is too heavy to run).
- You trust SSH more than a VPN secured by OpenSSL.
- You don’t want to expose your local IP to X or Y website.
- You need to circumvent some restrictive firewall (in a school or corporate network).