Mathew McBride's website

Advanced Geoblock evasion with OpenBSD pf and rdomain's

technologySat 21 Jun 2014 10:47:06No comments

Synopsis

Popular Geoblock evasion systems currently consist of browser plugins, or require modifications to DNS or other settings inside the end users network. The effect of these methods is either to restrict the applications that may be used to view Geoblock'ed content, or interfere with other internet applications – for example, by using a 'foreign' DNS server, content delivered from CDNs may come from a non-optimal source for that user.

With some creative routing table manipulation, control traffic for certain applications can be routed into a VPN tunnel, while general internet traffic and video traffic for the geoblocked applications can travel over the regular internet without any VPN performance loss.

For devices that we want to think are always in 'MURICA, a dedicated VLAN is used that drops all traffic from it to the VPN. Similar to the non-VLAN case, video traffic for geoblocked applications can be routed over the default internet route to avoid performance loss from VPN tunnels.

System Components

  1. An OpenBSD 5.x based router
    It is possible to use Linux or another OS with separate routing tables to achieve the same outcome, but for this example, I will focus on OpenBSD
  2. A VPN end point in 'MURICA, such as a VPS running OpenVPN.
    I use a 'LowEndBox' style provider to achieve this. The VPN end point does not need to be running OpenBSD, but must be able to do NAT
  3. VLAN capable hardware (Ethernet switches) (Tip: Unmanged Ethernet switches are generally transparent to VLAN-tagged frames).

Network Components

Network Diagram
Figure: Can you taste the FREEDOM?

Central to this method is the use of OpenBSD rdomain's. Our geoblock evasion routing domain is separate from the main system routing table, only traffic that is to be routed onto the VPN is on the geoblock domain. Rules can be defined in the OpenBSD packet filter (pf) to direct traffic between the default rdomain and the geoblock rdomain when required.

As the DNS subdomains used by some applications can change, or return multiple entries, depending on the time of day, the phase of the moon and other operational reasons on their part, the hostnames required to get these services to work are 'pinned' in the local DNS resolver (dnsmasq) configuration, and set up to be routed into the VPN tunnel.

Configuring the Geoblock Evader

The following files need to be edited:
  • /etc/pf.conf - Packet Filter rules
  • /etc/rc.local - Launch VPN tunnel and reload the packet filter ruleset after it becomes active

Additionally, I have created a script (/usr/local/sbin/netflix.sh) which resolves the frontend hosts for Netflix, and sets up the DNS pinning as described above.

Interface names

In my set up, my wan interface is "pppoe0", the VPN tunnel is on tun0. The 'MURICA VLAN is on vlan3.

Configuration

/etc/pf.conf
I added this to pf.conf AFTER the NAT rules for my WAN connection. Ensure there are no quick bypass ("match out quick") before this ruleset.
# Netflix
# 108.175.46.0/22 is the Netflix CDN in LA (the best CDN location in my case).
# If a packet arrives on 'MURICA VLAN to the Netflix CDN, route it over the default (non-VPN) connection
pass in quick on vlan3 to 108.175.46.0/22 rtable 0
match out on pppoe0 from 192.168.21.0/24 to 108.175.46.0/22 nat-to (pppoe0)
pass out quick on pppoe0 from 192.168.21.0/24 to 108.175.46.0/22 nat-to (pppoe0)

# Any Traffic on the VPN tunnel is to be NAT'ed here to the local end point address
match out on tun0 from 192.168.21.0/24 to any nat-to (tun0)
pass out on tun0 from 192.168.21.0/24 to any

# This is a set of Netflix (frontend) web ranges I had previously defined,
# before I created the autoresolve script.
# Always pass these out over VPN
netflix_web_ranges = "{ 69.53.236.0/24, 23.21.207.0/24, 50.16.197.172,
	23.21.109.82,23.21.47.225,107.20.224.179,50.19.235.7,50.16.234.150,
	23.21.55.166,204.236.231.19,107.21.242.138,107.20.195.216,
	23.23.164.73,107.21.217.0/24,174.129.204.0/24,23.21.194.0/24 }"
pass in quick on vlan2 to $netflix_web_ranges rtable 1
match out on tun0 from 192.168.8.0/24 to any nat-to (tun0)

# Load our autoresolved host table from /etc/pf.netflix.conf.
# As with the above, always pass this out over VPN
include "/etc/pf.netflix.conf"
pass in quick on vlan2 to $netflix_front_hosts rtable 1
match out on tun0 from 192.168.8.0/24 to any nat-to (tun0)

# END 'MURICA RULES
/etc/rc.local
# Start OpenVPN
cd /etc/openvpn
/usr/local/sbin/openvpn --config openvpn.conf --daemon usvpn
# Wait for the VPN to become active
sleep 10
# Move the VPN into the 'MURICA rdomain
ifconfig tun0 rdomain 1
ifconfig tun0 10.8.0.2 10.8.0.1
# Define a default route for it. We need to use -T to operate on the 'MURICA rdomain
route -T 1 add default 10.8.0.1
# Wait for things to stabilize 
sleep 5
# Reload PF
pfctl -f /etc/pf.conf
# For traffic from the 'MURICA VLAN that goes over the regular connection, we need to define a route in the system default rdomain so it is routed properly.
route -T 0 add 192.168.21.0/24 -iface 192.168.8.1
# Set up a DNS/DHCP server with dnsmasq on the 'MURICA VLAN.
cd /etc/usvpn
route -T 1 exec /usr/local/sbin/dnsmasq -C dnsmasq.conf
# Run the Netflix resolver script

/usr/local/sbin/netflix.sh
# Once the Netflix frontend hosts are resolved, reload dnsmasq and pf
/etc/rc.d/dnsmasq restart
pfctl -f /etc/pf.conf
/usr/local/sbin/netflix.sh
#!/bin/sh

API_NET=`host -t a -4 api.netflix.com  | awk '{print $4}' | grep ^[1-9]`
MOVIES=`host -t a -4 movies.netflix.com | awk '{print $4}' | grep ^[1-9]`
PRESENT_TRACK=`host -t a -4 presentationtracking.netflix.com | awk '{print $4}' | grep ^[1-9] | head -n 1`
CBP_US=`host -t a -4 cbp-us.nccp.netflix.com | awk '{print $4}' | grep ^[1-9]`
CBP=`host -t a -4 cbp.nccp.netflix.com | awk '{print $4}' | grep ^[1-9]`
CUST_EVENTS=`host -t a -4 customerevents.netflix.com | awk '{print $4}' | grep ^[1-9] | head -n 1`
API_GLOBAL=`host -t a -4 api-global.netflix.com | awk '{print $4}' | grep ^[1-9]`
NETFLIX=`host -t a -4 netflix.com | awk '{print $4}' | grep ^[1-9]`
WWW_NETFLIX=`host -t a -4 www.netflix.com | awk '{print $4}' | grep ^[1-9]`
SIGNUP=`host -t a -4 signup.netflix.com | awk '{print $4}' | grep ^[1-9]`

echo "address=/api.netflix.com/$API_NET" > /etc/dnsmasq.d/netflix
echo "address=/movies.netflix.com/$MOVIES" >> /etc/dnsmasq.d/netflix
echo "address=/presentationtracking.netflix.com/$PRESENT_TRACK" >> /etc/dnsmasq.d/netflix
echo "address=/cbp-us.nccp.netflix.com/$CBP_US" >> /etc/dnsmasq.d/netflix
echo "address=/cbp.nccp.netflix.com/$CBP" >> /etc/dnsmasq.d/netflix
echo "address=/customerevents.netflix.com/$CUST_EVENTS" >> /etc/dnsmasq.d/netflix
echo "address=/api-global.netflix.com/$API_GLOBAL" >> /etc/dnsmasq.d/netflix
echo "address=/netflix.com/$NETFLIX" >> /etc/dnsmasq.d/netflix
echo "address=/signup.netflix.com/$SIGNUP" >> /etc/dnsmasq.d/netflix
echo "address=/www.netflix.com/$WWW_NETFLIX" >> /etc/dnsmasq.d/netflix
echo "netflix_front_hosts = \"{ $API_NET, $MOVIES, $PRESENT_TRACK, $CBP_US, $CBP, $CUST_EVENTS, $API_GLOBAL, $NETFLIX, $SIGNUP, $WWW_NETFLIX}\"" > /etc/pf.netflix.conf
/etc/dnsmasq.conf
Just add this line at the end so dnsmasq loads additional configuration from /etc/dnsmasq.d/*, such as /etc/dnsmasq.d/netflix created on reboot by netflix.sh
conf-dir=/etc/dnsmasq.d
/etc/usvpn/dnsmasq.conf
This minimal dnsmasq configuration provides DHCP and DNS resolution on the 'MURICA VLAN. This dnsmasq server is started from /etc/rc.local, and is run in the 'MURICA rdomain, so any requests it makes to its upstream (Google Public DNS) will always run over the VPN tunnel.
server=8.8.8.8
listen-address=192.168.21.1
dhcp-range=192.168.21.10,192.168.21.50,48h

Results

Here are some example traceroutes showing where the traffic is routed on both the default (taken from a Windows 8.1 machine) and 'MURICA VLAN (taken from an OS X machine).
Site Default VLAN 'MURICA VLAN
Routing table
IPv4 Route Table
===========================================================================
Active Routes:
Network Destination        Netmask          Gateway       Interface  Metric
          0.0.0.0          0.0.0.0      192.168.8.1     192.168.8.98     10
		
netstat -rn
Destination        Gateway            Flags        Refs      Use   Netif Expire
default            192.168.21.1       UGSc            9      370     en0
		
whirlpool.net.au
Tracing route to whirlpool.net.au [117.53.166.22]
over a maximum of 30 hops:

  1    <1 ms    <1 ms    <1 ms  192.168.8.1
  2     1 ms     1 ms     1 ms  lns20.mel4.on.ii.net [150.101.212.44]
  3     2 ms     1 ms    <1 ms  xe-0-3-2.cr1.mel4.on.ii.net [150.101.208.65]
  4    12 ms    13 ms    13 ms  ae2.br1.syd7.on.ii.net [150.101.33.28]
  5    41 ms    15 ms    37 ms  ae0.br1.syd4.on.ii.net [150.101.33.14]
  6    12 ms    13 ms    12 ms  4826.syd.equinix.com [202.167.228.74]
  7    14 ms    12 ms    13 ms  ten-0-3-0-0.cor03.syd03.nsw.VOCUS.net.au [175.45
.72.117]
  8    13 ms    12 ms    13 ms  ten-1-0-0.bdr03.syd04.nsw.VOCUS.net.au [175.45.7
2.73]
  9    13 ms    13 ms    13 ms  as17732.cust.bdr03.syd04.nsw.VOCUS.net.au [119.1
61.90.162]
 10    13 ms    13 ms    13 ms  vl8-0.ds03.syd07.aunsw.bltprf.net [117.53.160.3]

 11    13 ms    13 ms    13 ms  22-166-53-117.rev.bulletproof.net [117.53.166.22
]
traceroute to whirlpool.net.au (117.53.166.22), 64 hops max, 72 byte packets
 1  192.168.21.1 (192.168.21.1)  0.499 ms  0.363 ms  0.283 ms
 2  10.8.0.1 (10.8.0.1)  201.921 ms  201.352 ms  202.074 ms
 3  205.185.112.XXX (205.185.112.XXX)  201.911 ms  201.302 ms  201.929 ms
 4  10.1.1.5 (10.1.1.5)  203.514 ms  210.273 ms  202.454 ms
 5  vocus.com.au.any2ix.coresite.com (206.223.143.136)  217.492 ms  217.665 ms  218.000 ms
 6  ten-0-0-2-2.cor02.sjc01.ca.vocus.net (114.31.199.244)  374.069 ms  374.060 ms  374.188 ms
 7  ten-0-2-0-2.cor01.syd04.nsw.vocus.net.au (114.31.199.45)  373.805 ms  373.459 ms  374.350 ms
 8  ten-2-0-0.bdr03.syd04.nsw.vocus.net.au (175.45.72.77)  372.761 ms  372.672 ms  373.195 ms
 9  as17732.cust.bdr03.syd04.nsw.vocus.net.au (119.161.90.162)  381.952 ms  382.470 ms  381.809 ms
10  vl8-0.ds03.syd07.aunsw.bltprf.net (117.53.160.3)  381.986 ms  382.529 ms  382.469 ms
11  22-166-53-117.rev.bulletproof.net (117.53.166.22)  382.982 ms  359.895 ms  360.057 ms
		
netflix.com
Tracing route to netflix.com [69.53.236.17]
over a maximum of 30 hops:

  1    <1 ms    <1 ms    <1 ms  10.8.0.2
  2   202 ms   201 ms   201 ms  10.8.0.1
  3   201 ms   201 ms   200 ms  205.185.112.XXX
  4   201 ms   212 ms   202 ms  10.1.1.5
  5   210 ms   209 ms   209 ms  xe-0-1-0-5.r04.lsanca03.us.bb.gin.ntt.net [129.2
50.202.37]
  6   210 ms   209 ms   212 ms  206.111.11.64.ptr.us.xo.net [206.111.11.64]
  7   226 ms   226 ms   227 ms  207.88.14.209.ptr.us.xo.net [207.88.14.209]
  8   220 ms   217 ms   218 ms  207.88.14.226.ptr.us.xo.net [207.88.14.226]
  9   218 ms   218 ms   261 ms  216.156.84.6.ptr.us.xo.net [216.156.84.6]
 10   219 ms   219 ms   218 ms  xe-2-2-0-955.jnrt-edge02.prod1.netflix.com [69.5
3.225.30]
 11   218 ms   218 ms   218 ms  te1-8.csrt-agg02.prod1.netflix.com [69.53.225.10
]
12   218 ms   219 ms   219 ms  netflixfreetrial.com [69.53.236.17] 
	
traceroute netflix.com
traceroute to netflix.com (69.53.236.17), 64 hops max, 52 byte packets
 1  192.168.21.1 (192.168.21.1)  0.559 ms  0.366 ms  0.286 ms
 2  10.8.0.1 (10.8.0.1)  201.513 ms  200.959 ms  201.137 ms
 3  205.185.112.XXX (205.185.112.XXX)  201.673 ms  201.814 ms  201.684 ms
 4  10.1.1.5 (10.1.1.5)  213.096 ms  201.999 ms  202.177 ms
 5  xe-0-1-0-5.r04.lsanca03.us.bb.gin.ntt.net (129.250.202.37)  209.727 ms  209.247 ms  210.273 ms
 6  206.111.11.64.ptr.us.xo.net (206.111.11.64)  209.588 ms  209.565 ms  209.907 ms
 7  207.88.14.209.ptr.us.xo.net (207.88.14.209)  226.017 ms  227.645 ms  223.384 ms
 8  207.88.14.226.ptr.us.xo.net (207.88.14.226)  218.534 ms  218.444 ms  218.890 ms
 9  216.156.84.6.ptr.us.xo.net (216.156.84.6)  218.930 ms  218.659 ms  218.901 ms
10  xe-2-2-0-955.jnrt-edge02.prod1.netflix.com (69.53.225.30)  219.956 ms  219.420 ms  219.958 ms
11  te1-8.csrt-agg02.prod1.netflix.com (69.53.225.10)  219.297 ms  218.571 ms  218.889 ms
12  netflixfreetrial.com (69.53.236.17)  219.146 ms  219.286 ms  219.332 ms
Netflix CDN (LA)
Tracing route to ipv4_1.lagg0.c057.lax001.ix.nflxvideo.net [108.175.46.102]
over a maximum of 30 hops:

  1    <1 ms    <1 ms    <1 ms  192.168.8.1
  2     1 ms     1 ms     1 ms  lns20.mel4.on.ii.net [150.101.212.44]
  3     1 ms     1 ms     1 ms  xe-0-3-2.cr1.mel4.on.ii.net [150.101.208.65]
  4   159 ms   160 ms   159 ms  ae2.br1.syd7.on.ii.net [150.101.33.28]
  5    13 ms    36 ms    12 ms  ae0.br1.syd4.on.ii.net [150.101.33.14]
  6   160 ms   159 ms   159 ms  te0-1-1-3.br2.lax1.on.ii.net [150.101.33.195]
  7   161 ms   159 ms   159 ms  any2ix.coresite.com [206.223.143.215]
  8   188 ms   159 ms   159 ms  ipv4_1.lagg0.c057.lax001.ix.nflxvideo.net [108.1
75.46.102]
traceroute to 108.175.46.102 (108.175.46.102), 64 hops max, 72 byte packets
 1  192.168.8.1 (192.168.8.1)  0.647 ms  0.293 ms  0.274 ms
 2  lns20.mel4.on.ii.net (150.101.212.44)  1.454 ms  1.619 ms  2.018 ms
 3  xe-0-3-2.cr1.mel4.on.ii.net (150.101.208.65)  2.145 ms  1.688 ms  2.008 ms
 4  ae2.br1.syd7.on.ii.net (150.101.33.28)  159.859 ms  192.705 ms  179.317 ms
 5  ae0.br1.syd4.on.ii.net (150.101.33.14)  54.368 ms  44.557 ms  29.814 ms
 6  te0-1-1-3.br2.lax1.on.ii.net (150.101.33.195)  160.081 ms  159.610 ms  160.065 ms
 7  any2ix.coresite.com (206.223.143.215)  160.722 ms  160.224 ms  159.970 ms
 8  ipv4_1.lagg0.c057.lax001.ix.nflxvideo.net (108.175.46.102)  159.210 ms  188.856 ms  159.284 ms

Performance

TL;DR: Better than Comcast
My Internet connection is a 100Mbps Fibre to the Home (NBN) connection with Internode. Keep in mind, over such a long distance it takes a while for the TCP Window size to ramp up, so getting to the max SuperHD bitrate takes a while.

Ramp up performance

Steady-state performance

OpEx comparison

Here is a comparison based on suggestions I've seen from the Whirlpool forums.

My methodUnblock-UsUnoTelly
$15USD/yr$60USD/yr$59.40/yr
Keep in mind, this doesn't take into account the (educational and fun) time I spent researching this. I would estimate that adding a 'new' content source would take one hour of 'researching' with Wireshark, with a subscription service, there are people who have already done this for you.


Your email address will not be published

Please retry reCAPTCHA

Welcome to my site

Mathew McBride, telecoms hardware access engineer, programmer, gamer and all round nerd

Warning: contents of blog may not make any sense whatsoever.

ipv6 ready

You are accessing this page over IPv6!

(C) Mathew McBride, 2006-2017
Creative Commons License
Unless specified, the content on this website is licensed under a Creative Commons Attribution-ShareAlike 3.0 Australia License.