Using SOCKS5 Over SSH for Web Browsing
You’re on the road, connected to a wi-fi network you don’t trust, and you want to do some web browsing without having your traffic sniffed. A VPN connection would solve the problem, but all you really want is to keep your web session from prying eyes.
If you have three things, you’re in luck:
- OpenSSH installed on your local system
- A remote system to which you can establish an SSH connection
- Firefox
Setting up the SSH tunnel
Modern versions of OpenSSH can emulate a SOCKS5 server and tunnel
the proxied traffic over your encrypted SSH session. You can see
the gory details in the ssh(1) man page; look for the -D
option.
For the sake of example, I’ll assume you have an account on a machine
named your.remote.host
. The init-style script below takes care
of starting and stopping the proxy.
#!/bin/sh
#
# control an SSH-managed SOCK5 proxy
#
# This script works on MacOS; the lsof invocation needs changing
# to work on Linux or other platforms.
#
# ======================================================================
# grab a PID for any process listening on 1080/tcp and see if
# we get a return value that passes for a positive integer
PROXYPID=$(lsof -Fp -i 4:1080 -s TCP:LISTEN | grep '^p' | sed 's/^p//')
(($PROXYPID))
RETVAL=$?
# set PROXYPID to 0 if it's non-existent or not an integer
if test $RETVAL -eq 1; then
PROXYPID=0
fi
# test the command-line argument: start, stop, or status
case "$1" in
start)
if test $PROXYPID -gt 0; then
echo "SOCKS proxy already running. Exiting now!" 1>&2
else
/usr/bin/ssh -f -N -C -D 1080 your.remote.host
fi
;;
stop)
if test $PROXYPID -gt 0; then
kill $PROXYPID
else
echo "SOCKS proxy doesn't appear to be running." 1>&2
fi
;;
status)
if test $PROXYPID -gt 0; then
echo "SOCKS proxy running as PID $PROXYPID"
else
echo "SOCKS proxy doesn't appear to be running."
fi
;;
*)
echo "usage: $(basename $0) {start|stop|status}"
;;
esac
# eof
A couple notes on the script:
- If you don’t have, or don’t want to use, a sh-compatible shell for this, the only really important bit in the whole script is line 24, which invokes ssh.
- The ssh
-D
option can also take an address or hostname, but the default (which I use) is the loopback address, akalocalhost
. - I use port 1080 in the script because it’s called the
socks
port in/etc/services
, but the number is basically arbitrary; you can use most any valid port number. (If you use another number, be sure to make the corresponding adjustment in the Firefox configuration below.)
If you install the script as socks-proxy
, then you can start the proxy tunnel by invoking it with the start option:
socks-proxy start
Configuring Firefox to use the tunnel
Launch Firefox and enter about:config
where you’d normally the address of the site you want to visit. You’ll probably see a sinister warning advising you that This might void your warranty! Oh, well! March on!
In the search box just above the long list of configuration options, type proxy
. You’ll be rewarded with a much smaller list of options. Here are the ones you want to change and their new values:
- network.proxy.socks: localhost
- network.proxy.socks_port: 1080
- network.proxy.socks_remote_dns: true
- network.proxy.type: 1
Assuming your SSH tunnel/proxy is already running, you should be able to browse the web safely at this point. You can verify your setup by asking Google what is my ip address. It should display the address for your.remote.host
. (Note: it may display an IPv6 address if you’ve got it configured on your local host and your remote host.)