TL;DR head to netflix-proxy on GitHub or subscribe to Unzoner VPN service to un-block:
If you are located outside of the UK and you want to watch a subset of content the British
Broadcast Corporation (BBC) makes available online via BBC iPlayer, you are out of
luck. This content is only available to users based in
the UK (or you could pay BBC for
it).
You could also pay for commercial services, such as Hola, Unblock-Us and Smart DNS Proxy to name a few, which allow you to bypass the geo restriction.
Alternatively, or you can knock together a similar solution quickly yourself for a cost of a cheap Virtual Private Server (VPS). How cheap, depends on where you decide to host your VPS. For my hosting I choose Digital Ocean with the VPS hosted in a London data center for $5 USD per month. If you sign up with the link above, you will receive $10 USD credit, which is enough for two months of hosting. Also, the more friends you have sharing a solution like this, the more cost effective it becomes, since a single VPS can support many individuals watching BBC iPlayer at once.
Update 03/2015: I've now packaged the entire system using Docker images. This reduced the deployment to three easy steps. Head over to GitHub and follow the instructions there: https://github.com/ab77/iplayer-proxy.
However if you would still like to create this system from scratch, please read on..
In essence, the following solution works by selectively proxying certain requests (*.bbc.co.uk and *.bbci.co.uk) via a server located in the UK, thus bypassing BBC iPlayer application level geo-restrictions. This solution, unlike VPN solutions, does not proxy the actual video/audio delivery, which uses different domain(s), so you should still get the benefit of decent bitrates from your local Content Distribution Network PoP.
Note, this won't work on devices which don't support the use of TLS Server Name Indication during SSL handshake (such as WD TV), you'll have to use a more complex system described in this guide or pay for Hola/Unblock-Us/Smart DNS Proxy/etc.
You could also pay for commercial services, such as Hola, Unblock-Us and Smart DNS Proxy to name a few, which allow you to bypass the geo restriction.
Alternatively, or you can knock together a similar solution quickly yourself for a cost of a cheap Virtual Private Server (VPS). How cheap, depends on where you decide to host your VPS. For my hosting I choose Digital Ocean with the VPS hosted in a London data center for $5 USD per month. If you sign up with the link above, you will receive $10 USD credit, which is enough for two months of hosting. Also, the more friends you have sharing a solution like this, the more cost effective it becomes, since a single VPS can support many individuals watching BBC iPlayer at once.
Update 03/2015: I've now packaged the entire system using Docker images. This reduced the deployment to three easy steps. Head over to GitHub and follow the instructions there: https://github.com/ab77/iplayer-proxy.
However if you would still like to create this system from scratch, please read on..
In essence, the following solution works by selectively proxying certain requests (*.bbc.co.uk and *.bbci.co.uk) via a server located in the UK, thus bypassing BBC iPlayer application level geo-restrictions. This solution, unlike VPN solutions, does not proxy the actual video/audio delivery, which uses different domain(s), so you should still get the benefit of decent bitrates from your local Content Distribution Network PoP.
Note, this won't work on devices which don't support the use of TLS Server Name Indication during SSL handshake (such as WD TV), you'll have to use a more complex system described in this guide or pay for Hola/Unblock-Us/Smart DNS Proxy/etc.
Prerequisites
You'll need the
following:
- A working Internet connection at home
- A UK based VPS with root access and clean CentOS x86 6.x image
- Basic knowledge in navigating a Linux console
Configuration
The
configuration depends on the following two
components:
For the
purpose of this demo, we assume your VPS's public
Internet IP is
We also assume your ISP has assigned
Note, if you ISP assigns you a dynamic IP, you will need to update your configuration every time this changes. Better ask them for a static IP address.
When creating your configuration files, please change the place holder IPs to your actual IPs.
- DNS server
- HTTP/SSL proxy
178.62.x.y
and
your host
is called myhost
.We also assume your ISP has assigned
86.50.x.y
to your
home router. You can
check what your IP is by going to http://www.whatismyip.com/.Note, if you ISP assigns you a dynamic IP, you will need to update your configuration every time this changes. Better ask them for a static IP address.
When creating your configuration files, please change the place holder IPs to your actual IPs.
Base VPS Deployment
This step
depends on the VPS provider you choose, but broadly
consists of the following steps:
- Create account with VPS provider
- Deploy a CentOS x64 6.x image to a UK based data centre.
Once
your VPS server is created, you will get a public IP
address and SSH credentials to use to
login. First,
establish an SSH session to your server and install
additional repositories:
Install certain pre-requisites to make your life a little easier:
Install development tools to enable you to build packages later:
Install BIND (chroot package):
Finally, start BIND:
From one of your home machines, run the following quick test:
You should get the IP address of your VPS in the DNS response.
[root@myhost ~]# yum -y install epel-release
[root@myhost ~]# yum -y update
Install certain pre-requisites to make your life a little easier:
[root@myhost ~]# yum install openssl vim git wget curl bind-utils telnet -y
Install development tools to enable you to build packages later:
[root@myhost ~]# yum groupinstall "Development Tools" -y
[root@myhost ~]# yum install rpmbuild autoconf automake curl libev libev-devel pcre pcre-devel perl udns-devel -y
IP Tables (firewall)
Since
our VPS is on a public Internet, we
are going to firewall it off from all the
unpleasantness out there.
Add rules to allow DNS, HTTP and HTTPS inbound from your home's public IP:
Add rules to allow DNS, HTTP and HTTPS inbound from your home's public IP:
[root@myhost ~]# iptables -A INPUT -s 86.50.x.y/32 -p udp -m udp --dport 53 -j ACCEPT
[root@myhost ~]# iptables -A INPUT -s 86.50.x.y/32 -p tcp -m tcp --dport 80 -j ACCEPT
[root@myhost ~]# iptables -A INPUT -s 86.50.x.y/32 -p tcp -m tcp --dport 443 -j ACCEPT
[root@myhost ~]# service iptables save
[root@myhost ~]# service iptables restart
BIND (DNS server)
BIND
is going to be our DNS server. It will respond with our
VPS IP to DNS requests for
Note, we are configuring the DSN server to run in a chroot jail and as a non-root user, to provide added security and minimise the potential effects of a security compromise.
bbc.co.uk
and bbci.co.uk domains.Note, we are configuring the DSN server to run in a chroot jail and as a non-root user, to provide added security and minimise the potential effects of a security compromise.
Install
BIND:
Edit your
Edit your
Edit your
Note, you may need to change the ownership of the new files you created from root to named:
[root@myhost ~]# yum install bind -y
Edit your
/etc/named.conf
and
make it look as follows:options {
listen-on port 53 { any; };
listen-on-v6 port 53 { any; };
directory "/var/named";
dump-file "/var/named/data/cache_dump.db";
statistics-file "/var/named/data/named_stats.txt";
memstatistics-file "/var/named/data/named_mem_stats.txt";
allow-recursion { none; };
allow-transfer { none; };
recursion no;
additional-from-auth no;
additional-from-cache no;
auth-nxdomain no; # conform to RFC1035
dnssec-enable yes;
dnssec-validation yes;
dnssec-lookaside auto;
/* Path to ISC DLV key */
bindkeys-file "/etc/named.iscdlv.key";
managed-keys-directory "/var/named/dynamic";
forwarders {
8.8.8.8;
8.8.4.4;
};
};
acl "trusted" {
any;
};
logging {
channel default_debug {
file "data/named.run";
severity dynamic;
};
};
zone "." IN {
type hint;
file "named.ca";
};
include "/etc/named.rfc1912.zones";
include "/etc/named.root.key";
include "/etc/named/zones.override";
Edit your
/etc/named/db.override
and
make it look as follows:$TTL 86400
@ IN SOA ns1 root (
YYYYMMDD01 ; serial
604800 ; refresh 1w
86400 ; retry 1d
2419200 ; expiry 4w
86400 ; minimum TTL 1d
)
IN NS ns1
ns1 IN A 178.62.x.y
@ IN A 178.62.x.y
* IN A 178.62.x.y
*
Note, change the above IP address to your the public IP of your VPS
and update the datestamp.Edit your
/etc/named/zones.override
and
make it look as follows:zone "bbc.co.uk." {
type master;
file "/etc/named/db.override";
};
zone "bbci.co.uk." {
type master;
file "/etc/named/db.override";
};
Note, you may need to change the ownership of the new files you created from root to named:
[root@myhost ~]# chown named:named /etc/named/zones.override
[root@myhost ~]# chown named:named /etc/named/db.override
Install BIND (chroot package):
[root@myhost ~]# yum install bind-chroot -y
Finally, start BIND:
[root@myhost ~]# rndc-confgen -a -r /dev/urandom -t /var/named/chroot
[root@myhost ~]# chkconfig named on
[root@myhost ~]# service named start
From one of your home machines, run the following quick test:
$ nslookup www.bbc.co.uk 178.62.x.y
Server: 178.62.x.y
Address: 178.62.x.y#53
Name: www.bbc.co.uk
Address: 178.62.x.y
$ nslookup www.bbci.co.uk 178.62.x.y
Server: 178.62.x.y
Address: 178.62.x.y#53
Name: www.bbci.co.uk
Address: 178.62.x.y
You should get the IP address of your VPS in the DNS response.
SNI Proxy (HTTP/SSL proxy)
Build
and install SNI Proxy:
Note: if the RPM fails to install, check the exact name of the file in the /root/rpmbuild/RPMS/x86_64/ directory.
Also, please review the ./configure command output to make sure LIBUDNS or libudns detected, if it hasn't, you will not be able to get SNI Proxy to work with the below configuration file. On a Red Hat/CentOS server, the library should be available from EPEL repository (yum install udns-devel), however for other distributions, you will need to build and install it manually.
Edit your
Note, if the proxy complains about ports being in use, check if you got another web server already running and if so, disable it or move it to a different port.
From one of your home machines, run the following quick test:
The last step is to change the DNS server on the device you are planning to watch BBC iPlayer on. Set it to your VPS public IP (i.e. 178.62.x.y)
Fire up BBC iPlayer and you should be able to play back all the wonderful content they make available - enjoy!
Note, this won't work on devices which don't support the use of SNI during SSL handshake, you'll have no choice but to use a system described in this guide.
[root@myhost ~]# cd /opt
[root@myhost ~]# git clone https://github.com/dlundquist/sniproxy.git
[root@myhost ~]# cd ./sniproxy
[root@myhost ~]# ./autogen.sh && ./configure && make dist
[root@myhost ~]# rpmbuild --define "_sourcedir `pwd`" -ba --nodeps redhat/sniproxy.spec
[root@myhost ~]# yum install $(ls /root/rpmbuild/RPMS/x86_64/sniproxy-[0-9]*.rpm) -y
Note: if the RPM fails to install, check the exact name of the file in the /root/rpmbuild/RPMS/x86_64/ directory.
Also, please review the ./configure command output to make sure LIBUDNS or libudns detected, if it hasn't, you will not be able to get SNI Proxy to work with the below configuration file. On a Red Hat/CentOS server, the library should be available from EPEL repository (yum install udns-devel), however for other distributions, you will need to build and install it manually.
Edit your
sniproxy.conf
and make it
look as follows:[root@myhost ~]# vim /etc/sniproxy.conf
user daemon
pidfile /var/tmp/sniproxy.pid
resolver {
nameserver 127.0.0.1
}
error_log {
filename /var/log/sniproxy_error.log
priority notice
}
listener 178.62.x.y 80 {
proto http
access_log {
filename /var/log/sniproxy_access.log
}
}
listener 178.62.x.y 443 {
proto tls
access_log {
filename /var/log/sniproxy_access.log
}
}
table {
.*\.bbc\.co\.uk *
bbc\.co\.uk *
.*\.bbci\.co\.uk *
bbci\.co\.uk *
}
Finally, install
the start-up script and start SNI Proxy:[root@myhost ~]# cp ./redhat/sniproxy.init /etc/init.d/sniproxy
[root@myhost ~]# chmod +x /etc/init.d/sniproxy
[root@myhost ~]# chkconfig sniproxy on
[root@myhost ~]# service sniproxy start
Note, if the proxy complains about ports being in use, check if you got another web server already running and if so, disable it or move it to a different port.
From one of your home machines, run the following quick test:
$ telnet 178.62.x.y 80
Trying 178.62.x.y...
Connected to 178.62.x.y.
Escape character is '^]'.
^C
Connection closed by foreign host.
$ openssl s_client -servername www.bbc.co.uk -connect 178.62.x.y:443
CONNECTED(00000003)
depth=1 C = BE, O = GlobalSign nv-sa, CN = GlobalSign Organization Validation CA - SHA256 - G2
verify error:num=20:unable to get local issuer certificate
verify return:0
---
Certificate chain
0 s:/C=GB/ST=London/L=London/O=British Broadcasting Corporation/CN=*.bbc.co.uk
i:/C=BE/O=GlobalSign nv-sa/CN=GlobalSign Organization Validation CA - SHA256 - G2
1 s:/C=BE/O=GlobalSign nv-sa/CN=GlobalSign Organization Validation CA - SHA256 - G2
i:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA
---
Server certificate
-----BEGIN CERTIFICATE-----
MII...
You
should get a socket connection on port 80 and get an
SSL handshake with the BBC.
Putting It All Together
The last step is to change the DNS server on the device you are planning to watch BBC iPlayer on. Set it to your VPS public IP (i.e. 178.62.x.y)
Fire up BBC iPlayer and you should be able to play back all the wonderful content they make available - enjoy!
Note, this won't work on devices which don't support the use of SNI during SSL handshake, you'll have no choice but to use a system described in this guide.
References
I've
used the following reference material to prepare
the solution described in this article. Many thanks
to the respective authors.