Anyone who grew up or lives in Ireland is familiar with BBC television thanks to cable and satellite TV. Because of our proximity to Wales and especially Northern Ireland, we in the east and north of the country have been able to receive BBC broadcasts for decades despite not paying a license fee in that country. I’ve long felt that this state of affairs should continue even into the Digitial Era despite BBC’s best efforts to lock iPlayer down to only those people who live in the United Kingdom (a.k.a., license fee payers). My attempts to circumvent their geo-location recognition mechanisms have always been fruitless until one day lest week when I was reading through the man page for SSH.
As I scanned the various command line flags for whatever it was that I was looking for my eyes settled for a moment on the description of the -D parameter and I had a minor epiphany. When you ssh to a remote host using the -D flag, ssh establishes an encrypted tunnel that listens on a TCP port on your local host. You can then direct traffic across this tunnel by specifying the port as a SOCKS proxy. Traffic pops out the other side and is forwarded to its destination, where it looks as though it originated on the device to which you SSHed. Clear as mud, so let’s try an example:
This will establish an SSH session on remotehost and will open port 8080 on localhost. What you then do is open your web browser and set localhost:8080 as your SOCKS proxy server. All of your web traffic will be sent across the SSH session and will appear to originate on remotehost.
A few years ago a colleague of mine gave me a shell account on a server he runs in the UK. Up to now I haven’t had much use for the account other than for testing my routing configurations from an offnet server. Not any more!
Now, I don’t necessarily want to send all of my traffic across the SSH tunnel. For one thing, the encryption and compression inherent in the SSH connection limits the amount of bandwidth that I can send/receive. For another, if the SSH tunnel goes down for any reason (for example, if I close the lid on my laptop then the SSH session times out) all of my web traffic is being sent to a non-existant web proxy. Carnage, especially when my wife is trying to browse the Asos catalogue or watch ‘Home & Away’ in the RTE Player. Nor do I want to have to reconfigure my browser’s proxy settings every time I feel like looking at an episode of ‘Seven Ages of Britain’ or ‘QI XL’.
One of the neat things about the -D flag is that other PCs can use the tunnel that it creates as a SOCKS proxy. The neat thing about my router is that it runs Linux (OpenWRT to be exact). So I got to thinking: is there any way that I can use my router to selectively redirect web traffic into my SSH tunnel? Of course there is!
The first thing to do was to install Screen on my router. Screen is a terminal multiplexer – a program that acts as a wrapper around Linux/Unix shells, allowing you to attach and de-attach from them without losing your shell sessions. I start my SSH session in a Screen and then de-attach, leaving the session running in the background (and meaning that I don’t need to remain logged into my router from my laptop).
I then installed Privoxy, a proxy server. Privoxy has lots of great features but I chose it over Squid (which I’m more familiar with) for one reason: Privoxy supports forwarding into SOCKS proxies whereas Squid doesn’t. Privoxy seems to be lighter as well, always a concern on a device with limited memory. I’ve configured Privoxy to listen on port 8118 and to accept intercepted connections.
This last configuration point is the final and key piece in this puzzle. I added the following rule to my iptables ruleset:
iptables -t nat -A PREROUTING -i br-lan -p tcp -d 184.108.40.206/20 --dport 80 -j REDIRECT --to-ports 8118
This command is straightforward. Any traffic received on br-lan (i.e., any of my LAN interfaces) destined for BBC’s network (212.58.240/20) and with a destination TCP port of 80 (the port that webservers listen to) should be redirected (i.e., intercepted) to port 8118 on the router (8118 as I mentioned above is the port that Privoxy is listening on).
Now when I want to watch BBC iPlayer I don’t have to do anything – my BBC-destined web traffic is redirected to the SSH tunnel via Privoxy and my non-BBC traffic is allowed to exit via the router’s WAN interface unmolested. Sweeeeeeeet.