Netflix - Using a VPN for just one application
(note: if you're on Windows, you could take a look at this blogpost, or install Ubuntu first)
Some companies have not really yet grasped the concept of a global Internet, and like to restrict things to the public of just one country. In this case, the movie industry comes to mind, which allows Netflix to only air certain movies and tv shows in certain countries. Although I am located in The Netherlands, and Netflix recently opened their doors there as well, I'm still affected by geo-restrictions. In The Netherlands I'm served Dutch subs, and some tv shows are not available. Others, are available on DVD only in the US, whereas I can simply stream them in The Netherlands.
There's a simple solution of course, a VPN service. With most VPN services, you simply download a small application, and click & run. The VPN application will direct all your traffic to a host in a location of your choosing, and for the outside world it will look as if you were located at that location.
However, even though that works, I don't want to route all of my traffic through a US host (for you know, there's the NSA, MPAA, they got it all). So I needed a way to route all of the Netflix traffic through the VPN, while leaving the rest of my traffic unaffected.
My first attempt did not succeed. Most routing is based on destination IP, but Netflix uses Amazon and other generic CDNs for content distribution. This brings along two problems; The ip-adresses used are constantly changed, so it's near-impossible to track specific IP-addresses. Especially not, because Amazon hosts more than one website, which I'd like to access via my regular IP. The first attempt therefore used a hosts file that mapped the Amazon hostnames to alternative IP's, and based on those IP's I then did some destination based routing. The problem is that netflix uses many hostnames, therewith not really maintainable (I stopped collecting them after two-dozen). I didn't try configuring an HTTP proxy in Firefox, because I figured it wouldn't work in Silverlight. My first attempt can be found here.
We begin by installing netflix-desktop and setting up the Netflix-user:
Then when you have this file, you can grant the Netflix user access:
Now you should be able to run Netflix with the following command. That is, you get a nice window, telling you that you do not have access from your country/ip.
Linux supports multiple routing tables. When you show the contents of the routing table ('ip route show'), it shows the contents of the default routing table. Just compare the output of the following two commands:
So after you've set up the VPN service, and you know there is more than one routing table you can use, all you need to do is configure a new routing table that sends all traffic through the VPN, and tell Linux to use that routing table for all traffic originating from the Netflix user:
Now you should be good to go, and all should be running.
I myself proxy all my traffic via my own VPS (located in the EU as well), and from there I route my traffic via the appropriate VPN service. But because the Netflix application runs locally, I cannot make a distinction based on GID on my VPS. In a next blog I'll show how you can still get that done. EDIT: New blogpost: Netflix - Application based routing over another VPN
Edit September 24, 2013: I did some more digging. It turns out the rp_filtering will by defintion have to be disabled. Therefore, the section 'RP_Filter' has been added.
Edit September 26, 2013: Added the keep-alive statement to the OpenVPN config so there are less timeouts and your routes etc should be more stable due to less changing IP's.
Some companies have not really yet grasped the concept of a global Internet, and like to restrict things to the public of just one country. In this case, the movie industry comes to mind, which allows Netflix to only air certain movies and tv shows in certain countries. Although I am located in The Netherlands, and Netflix recently opened their doors there as well, I'm still affected by geo-restrictions. In The Netherlands I'm served Dutch subs, and some tv shows are not available. Others, are available on DVD only in the US, whereas I can simply stream them in The Netherlands.
There's a simple solution of course, a VPN service. With most VPN services, you simply download a small application, and click & run. The VPN application will direct all your traffic to a host in a location of your choosing, and for the outside world it will look as if you were located at that location.
However, even though that works, I don't want to route all of my traffic through a US host (for you know, there's the NSA, MPAA, they got it all). So I needed a way to route all of the Netflix traffic through the VPN, while leaving the rest of my traffic unaffected.
My first attempt did not succeed. Most routing is based on destination IP, but Netflix uses Amazon and other generic CDNs for content distribution. This brings along two problems; The ip-adresses used are constantly changed, so it's near-impossible to track specific IP-addresses. Especially not, because Amazon hosts more than one website, which I'd like to access via my regular IP. The first attempt therefore used a hosts file that mapped the Amazon hostnames to alternative IP's, and based on those IP's I then did some destination based routing. The problem is that netflix uses many hostnames, therewith not really maintainable (I stopped collecting them after two-dozen). I didn't try configuring an HTTP proxy in Firefox, because I figured it wouldn't work in Silverlight. My first attempt can be found here.
Setting it up
So given that using destination IP's wasn't really an option to make any distinction on, I opted to do it based on UID. IPtables has the ability to have a firewall rule match on the user that initiated the traffic, so running netflix as its own user enables one to use a whole set of firewall rules dedicated to just Netflix.We begin by installing netflix-desktop and setting up the Netflix-user:
code:
1
2
3
4
| apt-add-repository ppa:ehoover/compholio apt-get update apt-get install netflix-desktop useradd -m netflix |
Allow a sudo'ed application to use X
Netflix will not start though. It requires access to X, and we haven't done anything with the network yet either. To allow Netflix to use X, it needs access to your 'xauthority' file. You can find the location of this file by running the following command in Bash.code:
1
2
| export | grep xauthority -i declare -x XAUTHORITY="/run/gdm/auth-for-dolf-7osFEz/database" |
Then when you have this file, you can grant the Netflix user access:
code:
1
2
| chmod 640 /run/gdm/auth-for-dolf-7osFEz/database chown dolf:netflix /run/gdm/auth-for-dolf-7osFEz/database |
Now you should be able to run Netflix with the following command. That is, you get a nice window, telling you that you do not have access from your country/ip.
code:
1
| DISPLAY=":0" XAUTHORITY="/run/gdm/auth-for-dolf-7osFEz/database" sudo -u netflix -H netflix-desktop |
Networking
Next up is the networking. First you'll need a VPN service. I went with Private Internet Access (PIA) because it works with Netflix, is cheap, and offers an OpenVPN service (some are stuck in the PPTP era). To ensure not all your traffic is automatically redirected to the VPN, and to not have to type your password everytime, you do have to modify the default config files PIA provides. E.g.:code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| client dev tunUS # renamed the interface name for brevity. proto udp remote us-california.privateinternetaccess.com 1194 resolv-retry infinite nobind persist-key persist-tun ca ca.crt tls-client remote-cert-tls server auth-user-pass comp-lzo verb 1 reneg-sec 0 ca /etc/openvpn/privateinternetaccess/ca.crt # Add these lines: auth-user-pass /etc/openvpn/privateinternetaccess/passwd route-nopull keepalive 1 30 |
Linux supports multiple routing tables. When you show the contents of the routing table ('ip route show'), it shows the contents of the default routing table. Just compare the output of the following two commands:
code:
1
2
3
4
| > ip route show default via 192.168.1.1 dev eth0 proto static > ip route show table 254 default via 192.168.1.1 dev eth0 proto static |
So after you've set up the VPN service, and you know there is more than one routing table you can use, all you need to do is configure a new routing table that sends all traffic through the VPN, and tell Linux to use that routing table for all traffic originating from the Netflix user:
code:
1
2
3
| ip route add default dev tunUS table 2 iptables -t mangle -A OUTPUT -m owner --gid-owner netflix -j MARK --set-mark 2 ip rule add fwmark 2 table 2 |
RP_Filter
Linux has a feature called reverse-path filtering. This feature drops traffic from any ip it has no route for on that interface. Because it does not keep into account the use of multiple routing tables, we'll need to disable it:code:
1
2
3
| for f in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 0 > $f done |
Audio through PulseAudio
If you start Netflix as netflix user, you should get a nice GUI, and no more errors about being in the wrong country. However, once you start to play a movie or an episode of a tv serie, you'll have no sound yet. Assuming a default Ubuntu installation, Pulseaudio is used to manage all audio, and by default it doesn't support multiple users. Now you can try to get that right the right way, or you can go the quick-and-dirty way (my favorite). The only disadvantage is that if Netflix is playing, no other applications can use the sound system.code:
1
2
3
4
| sudo usermod -a -G audio netflix sudo ln -s /home/dolf/.pulse-cookie /home/netflix/.pulse-cookie sudo chown dolf:audio .pulse-cookie sudo chmod 640 .pulse-cookie |
Now you should be good to go, and all should be running.
I myself proxy all my traffic via my own VPS (located in the EU as well), and from there I route my traffic via the appropriate VPN service. But because the Netflix application runs locally, I cannot make a distinction based on GID on my VPS. In a next blog I'll show how you can still get that done. EDIT: New blogpost: Netflix - Application based routing over another VPN
Edit September 24, 2013: I did some more digging. It turns out the rp_filtering will by defintion have to be disabled. Therefore, the section 'RP_Filter' has been added.
Edit September 26, 2013: Added the keep-alive statement to the OpenVPN config so there are less timeouts and your routes etc should be more stable due to less changing IP's.
09-'13 Netflix - Application based routing over another VPN
08-'13 OpenVPN, IPv6 with ULA and NAT
Comments
Nice blog, thanks for sharing!
This can also be useful for other sites/services using the same 'stupid' ip-localisation.
If you're not using gdm as displaymanager but lightdm or kdm, you have to change the path a bit though.
Looking forward to your next blog.

This can also be useful for other sites/services using the same 'stupid' ip-localisation.
If you're not using gdm as displaymanager but lightdm or kdm, you have to change the path a bit though.
Looking forward to your next blog.
Great guide. This was one of my rejections as well: I don't want all my traffic to go through US servers. This solves the problem with an elegant solution.
Is gewoon een kwestie van rechten. De publicatierechten kunnen bijvoorbeeld in verschillende regios bij verschillende bedrijven liggen die er een ander beleid op nahouden. In geval van TV series zal men ook eerst proberen van de serie op de lokale markt verkocht te krijgen ipv deze onmiddelijk online te gooien. Als amerikaanse series hier per direct beschikbaar komen zou dat voor een hoop commerciële omroepen het einde betekenen.Some companies have not really yet grasped the concept of a global Internet, and like to restrict things to the public of just one country. In this case, the movie industry comes to mind, which allows Netflix to only air certain movies and tv shows in certain countries.
En in plaats van VPN bestaan er eenvoudigere oplossingen. Zet simpelweg een proxy op en je kan elke proxy aware applicatie instellen om gebruik te maken van die proxy.
Nice blog, but the code for the firewall and pulse audio is a bit obscure. Is there a way to do this via a GUI?
I'm aware of that. But that was a model inspired by a system where you still had to distribute movies in physical form. The primary reasons for doing it like that up to today, are to maximize profits, not to serve customers in an optimal way (I think).Is gewoon een kwestie van rechten. De publicatierechten kunnen bijvoorbeeld in verschillende regios bij verschillende bedrijven liggen die er een ander beleid op nahouden.
Not that I'm aware of, but you could always create a gui for itDreeke fixed wrote on Thursday 12 September 2013 @ 14:48:
Nice blog, but the code for the firewall and pulse audio is a bit obscure. Is there a way to do this via a GUI?

Does netflix give a nicer user experience as the combination of sickbeard, an usenet account and an upnp streamer to the tv screen?
Too much effort for my tastes. Why go through all this hazzle when you can just browse to a URL that serves as a proxy to the Pirate Bay and start downloading within seconds? It's perfectly legal as long as you're a gigantic dick like myself who sets his upload speed to 0. It is more convenient and you get access to more content. I read somewhere that the TV series Arrow will get added to Netflix next month. I can already watch it at my own leisure. I like convenience, and Netflix doesn't really offer that, so I'll create my own convenience.
I don't know. I've never used usenet, and I don't watch on a tv sceen. Netflix did recently open their doors in The Netherlands. You could just give it a shot and see for yourself if it's to your likings? (first month is free)green944 wrote on Thursday 12 September 2013 @ 16:21:
Does netflix give a nicer user experience as the combination of sickbeard, an usenet account and an upnp streamer to the tv screen?
For the stuff that's not yet available I'll continue to use Torrents without a doubt. The hassle I described here is a one-time thing, I find that once set up, it's easier to play a movie using Netflix than using Torrents (you just click and play, there's no waiting involved).Amanoo wrote on Thursday 12 September 2013 @ 16:27:
Too much effort for my tastes. Why go through all this hazzle when you can just browse to a URL that serves as a proxy to the Pirate Bay and start downloading within seconds? It's perfectly legal as long as you're a gigantic dick like myself who sets his upload speed to 0. It is more convenient and you get access to more content. I read somewhere that the TV series Arrow will get added to Netflix next month. I can already watch it at my own leisure. I like convenience, and Netflix doesn't really offer that, so I'll create my own convenience.
it does not , specially if you combine an xbmc / autosub / couchpotato along side it.green944 wrote on Thursday 12 September 2013 @ 16:21:
Does netflix give a nicer user experience as the combination of sickbeard, an usenet account and an upnp streamer to the tv screen?
Netflix IS estimated to be 10.000x easier to setup though.Aionicus wrote on Thursday 12 September 2013 @ 23:41:
[...]
it does not , specially if you combine an xbmc / autosub / couchpotato along side it.
Is er ook een ondertitel voor de blog post? 

Feel free to imagine there is

I've just published the second part of the blog, it can be found here.
I really thank you for the toff article you have made. I am having the same issue like this article, but I am with another app. I tried your solution but I got stuck in some points. could you please help me to just make it go for my app?
Thank you very much at advacne
Thank you very much at advacne
I tried the mentioned solution here, for the routing based on GID, but while my openVPN indeed connects ok, and my normal user has no issues connecting to the non-vpn, my designated user just gets a hang when pinging anything.
I don't really know what I can do to fix this. Any tips?
I don't really know what I can do to fix this. Any tips?
You, sir, are a genius. Thank you!
I couldn't get this to work either, in the same manner as peter (just get a hang while pinging).
I however get these similar instructions to work... not sure which step is causing the difference.
https://www.niftiestsoftw...ecific-network-interface/
I however get these similar instructions to work... not sure which step is causing the difference.
https://www.niftiestsoftw...ecific-network-interface/
Comments are closed