December 11, 2011

Hulu and Pandora outside USA

Filed under: Technical — Tags: , , — James Bunton @ 5:15 pm

Back in 2009 I wrote up a short guide to using Hulu outside USA. I stopped using it and the necessary voodoo has changed slightly. Since that post is so old I’ve decided to write a new one with the necessary updates.

My approach is different to what most people do. The goal is to access Hulu and Pandora from outside USA, so obviously we have to use a proxy of some kind. However I don’t want to proxy all my traffic through the USA, as then I would not be able to access Australian specific content. So what I have is a few hacks on my router that tell it to forward only Hulu and Pandora traffic through my USA server.

Update 2014-07-05
Hulu has started blocking access from various data centres in the US. This guide only works if the IP address of your US server is not blocked by Hulu.

Requirements

  • A machine in the US that you can run programs and serve web pages from.
  • A Linux machine at home that shares your net connection

USA Proxy Configuration

First we need to set up your US server to forward some selected HTTP sites as well as the Flash RTMP video streams. Do these steps on the server in the US:

  • Create a file, usa-proxy.ini with these contents:
    [proxy]
    mode = proxy
    listen_port = 9997
    
    [allowed]
    host1 = YOUR_LOCAL_IP_OR_DOMAIN
    
  • Download tcp-proxy and run this command to start forwarding requests on port 9997 from the allowed hosts.
    tcp-proxy -d usa-proxy.ini

Local network

If you have a Linux router you can configure it to forward all packets destined for Hulu from inside your network to your US server. This setup is most convenient as it gives all computers on your LAN access with further configuration, regardless of their operating system. Otherwise you must set this up on each Linux client separately.

Follow these steps on your Linux router or any other Linux computer:

  • Download huluhosts.txt and append it to your /etc/hosts file.
  • If you’re using dnsmasq for your LAN’s DNS server ensure that it reads these addresses from your and resolves them for hosts on your network.
  • For Hulu, add this to your firewall config:
    grep 'HULU$' /etc/hosts | awk '{print $1;}' | while read huluip; do
        iptables -t nat -A PREROUTING -i eth0 -p tcp \
            --destination "$huluip" -j REDIRECT --to-ports 9997
        iptables -t nat -A OUTPUT -p tcp \
            --destination "$huluip" -j REDIRECT --to-ports 9997
    done
    
  • For Pandora, add this to your firewall config:
    iptables -t nat -A PREROUTING -i eth0 -p tcp \
        --destination 208.85.40.0/21 -j REDIRECT --to-ports 9997
    iptables -t nat -A OUTPUT -p tcp \
        --destination 208.85.40.0/21 -j REDIRECT --to-ports 9997
    
  • Depending on your other iptables rules you may need to add this somewhere to make the interceptor port allowed:
    iptables -A INPUT -i eth0 -p tcp --dport 9997 -j ACCEPT
    
  • Create a file, proxy-interceptor.ini with these contents:
    [proxy]
    mode = interceptor
    listen_port = 9997
    host = XXX.YYY.ZZZ.XXX
    port = 9997
    
  • Download tcp-proxy and run this command to start capturing and forwarding the Hulu content through your US server.
    tcp-proxy -d proxy-interceptor.ini

Some ISPs in Australia (Internode, iiNet and others) override the DNS entries for Akamai servers. This is why the modification to /etc/hosts is needed. Note that using the rules above, only traffic to specific Akamai Hulu servers will go through your US server. So unmetered ABC iView content will remain unmetered. However, if Hulu adds new servers to this list, or if I’ve missed some, then things may not work and the hosts file will need updating. See the last section of the blog on how to automate this with a cron job.

If you are having difficulty viewing videos and you suspect that this is the issue, try running your dnsmasq with the log-queries option enabled. Then have a look at /var/log/syslog to see what names are being looked up. Try resolving them from within USA and add the result to /etc/hosts

Automatic /etc/hosts updating

The /etc/hosts file is used to know which IP addresses to route over the tunnel to USA. My USA server resolves the Hulu video hosts that I know about and makes them available at this URL: https://delx.au/files/huluhosts.txt. This is automatically updated every hour.

I use a daily cronjob on my client machines in order to keep their hosts file up to date. Adapt this to your needs.

#!/bin/bash

cp /etc/hosts /etc/hosts.hulubak &&
grep -v HULU /etc/hosts > /etc/_hosts.new &&
curl -s https://delx.au/files/huluhosts.txt >> /etc/_hosts.new &&
chmod 0644 /etc/_hosts.new &&
mv /etc/_hosts.new /etc/hosts &&

# Ensure you clear the previous Hulu firewall rules and restart your
# DNS server (if you use one)
/root/hulutables
/etc/init.d/dnsmasq restart > /dev/null

Here’s the script to generate the huluhosts.txt file. This should be run from a machine in the USA so that you get the correct IP addresses.

#!/bin/bash

HOSTS='
hulu.com
www.hulu.com
secure.hulu.com
releasegeo.hulu.com
urlcheck.hulu.com
p.hulu.com
s.hulu.com
t.hulu.com
t2.hulu.com
assets.hulu.com
static.huluim.com
t.huluim.com
t2.huluim.com
ib1.huluim.com
ib2.huluim.com
ib3.huluim.com
ib4.huluim.com
'
OUTFILE="/var/www/huluhosts.txt"

echo -n > "$OUTFILE"
for host in $HOSTS; do
        echo "$(dig +short $host | tail -n 1) $host # HULU" >> "$OUTFILE"
done

22 comments

James Mills says:

Hey,

Great guide! Seems fairly straight foward.

Q: Will the DNAT / REDIRECT rules work
on the MythTV backend itself? My setup
is a Cisco router.

cheers
James

Dylan says:

Hi,

Nice how-to. I adapted your idea’s to a VPN setup i’m running. I was curious as to how you generate the hosts file though? I’ve been unable to get it to work correctly, although i pass through the initial hulu filter and am able to browse through the videos when i go to play something i get stopped.

Cheers,
Dylan

delx says:

@James Mills
Yes, I’ve clarified the post

@Dylan
I’ve added a section on how to generate the huluhosts.txt file. I’m not
sure what you mean about adapting to a VPN setup, but there are a few
key points to make sure are correct:
* From your LAN you should have hulu.com, etc resolve to the correct USA IP address, from your /etc/hosts file
* iptables on your PC or router should be capturing all traffic on all ports sent to these addresses and redirecting to…
* proxy.py running in interceptor mode forwarding to proxy.py running in proxy mode on your USA host

Ximo says:

Great post, thanks for sharing this!

I’d like to install this on my Tomato firmware flashed Linux router. My only concern is the router’s specifications, with its mere 200 Mhz CPU and 16MB RAM. Do you know how much would be required for the interceptor part to run smoothly?

delx says:

On my Debian server it is using 9556KiB VSZ and 4392KiB RSS. But a more minimally compiled version of Python would certainly use less. If you have another Linux machine in the house I’d suggest using that instead. I have set up a more complicated version of this where the proxy intercept runs on an Ubuntu machine and the OpenWRT router is configured to route the Hulu/Pandora IP addresses to that machine. This also works quite well with only Hulu/Pandora being routed through the Ubuntu box. If you’re interested I can do another blog post about that setup sometime.

NETFLX says:

Any comments if this would work with Netflix or Amazon Instant? Are there any tips you could offer?

Chura says:

Hi,

Great guide, using it for so long :)
Can you help for the same regarding netflix ?
I dont mind using the Script, but what subdomain should I check ?

Thanks!

delx says:

@Chura,@NETFLX
I don’t use Netflix, so I don’t know the specific domain name. But if you are using dnsmasq you can enable the log-queries option. Then have a look at /var/log/syslog to see what domains are being hit.

Ed says:

Hi,

Thanks for sharing this guide. I’ve been using this quite on openwrt while with great success, but just decided to update the huluhosts from cron.

I noticed that your bash script calls /root/hulutables. Can you share the contents of that script? I just substituted it with

/etc/init.d/firewall restart > /dev/null

Cheers

delx says:

@Ed
Rerunning /etc/init.d/firewall is fine provided that it clears the previous Hulu firewall rules and inserts the new ones.

cornasdf says:

To the guy that was asking about netflix above, here is what i have routing over the US vpn, probably overkill as it is basically amazons entire cloud but i am not sure where they will come out. these ips were based on a post on the dd-wrt forums. Upshot is netflix works fine. I am using iptables on dd-wrt as described in a post here: http://cornasdf.blogspot.co.uk/2012/10/dd-wrt-openvpn-and-selectively-routing.html

in my setting, –set-mark 3 means ‘route out a US VPN server’
# amazon ec2 (us)
# https://forums.aws.amazon.com/ann.jspa?annID=1528 & extended via whois
iptables -A PREROUTING -t mangle -p tcp -d 23.20.0.0/255.252.0.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 50.16.0.0/255.252.0.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 50.112.0.0/255.255.0.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 54.224.0.0/255.240.0.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 54.240.0.0/255.240.0.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 67.202.0.0/255.255.192.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 72.44.32.0/255.255.224.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 75.101.128.0/255.255.128.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 107.20.0.0/255.252.0.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 174.129.0.0/255.255.0.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 184.72.0.0/255.254.0.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 184.169.128.0/255.255.128.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 204.236.128.0/255.255.128.0 -j MARK –set-mark 3

# amazon ec2 (eu)
# https://forums.aws.amazon.com/ann.jspa?annID=1528 & extended via whois
iptables -A PREROUTING -t mangle -p tcp -d 46.51.128.0/255.255.192.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 46.51.192.0/255.255.240.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 46.137.0.0/255.255.128.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 46.137.128.0/255.255.192.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 79.125.0.0/255.255.128.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 176.34.64.0/255.255.192.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 176.34.128.0/255.255.128.0 -j MARK –set-mark 3

# netflix
iptables -A PREROUTING -t mangle -p tcp -d 108.175.32.0/255.255.240.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 208.75.76.0/255.255.252.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 64.212.0.0/255.252.0.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 199.92.0.0/255.252.0.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 206.32.0.0/255.252.0.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 209.244.0.0/255.252.0.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 68.142.64.0/255.255.192.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 69.28.128.0/255.255.192.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 69.164.0.0/255.255.192.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 208.111.128.0/255.255.192.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 128.242.0.0/255.255.0.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 204.0.0.0/255.252.0.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 204.141.0.0/255.255.0.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 204.200.0.0/255.252.0.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 208.44.0.0/255.252.0.0 -j MARK –set-mark 3

i also am routing dns requests as follows (you probably need to do something similar for netflix) (dnsmasq config)
server=/hulu.com/8.8.8.8
server=/netflix.com/8.8.8.8
server=/livesport.tv/8.8.8.8
server=/207.net/8.8.8.8
server=/performgroup.com/8.8.8.8

Now, I have tried to do the same for hulu, with less luck. ditto with comedy central/daily show.
I have gathered the following IP ranges based on posts here and other places but I am still missing something. If anybody has ideas, I am all ears..
# hulu
iptables -A PREROUTING -t mangle -p tcp -d 23.32.0.0/255.224.0.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 23.62.0.0/255.255.0.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 23.64.0.0/255.252.0.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 64.221.0.0/255.255.128.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 64.221.128.0/255.255.192.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 64.221.192.0/255.255.224.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 77.109.170.0/255.255.255.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 80.239.221.0/255.255.255.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 92.122.0.0/255.254.0.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 195.27.0.0/255.255.0.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 199.127.192.0/255.255.252.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 208.91.156.0/255.255.252.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 217.156.128.0/255.255.128.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 184.84.252.0/255.255.255.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 23.0.198.0/255.255.255.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 4.23.35.0/255.255.255.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 72.247.242.0/255.255.255.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 87.83.27.0/255.255.255.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 23.0.198.0/255.255.255.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 74.125.45/255.255.255.0 -j MARK –set-mark 3
iptables -A PREROUTING -t mangle -p tcp -d 209.107.215.0/255.255.255.0 -j MARK –set-mark 3

delx says:

@cornasdf, Hulu is served by the Akamai CDN. It uses a relatively small list of fixed hostnames, which resolve to different IP addresses depending on your location and the whims of Akamai. The solution I described in the post uses /etc/hosts to lock down the IP addresses of each Hulu hostname. Then you can add iptables rules for those known IPs. The whole process is repeated daily to keep up with Akamai’s changes.

Jack says:

Hello,

For the one of us who are not very Linux savvy, Could you please share what disti of Linux you are using, and what type of proxy service are you using for the server side? (My guess it’s Apache but I am not %100 sure)

Regards,
Jack

delx says:

@Jack
The proxy server is a custom tool I wrote in python, called proxy.py, see the blog for details. I’m using Debian Linux on the server.

addeswe says:

Hey. Just wanted to know if the host-file still is updated? :-)
Thanks for all the info about hulu. It’s great! :-D

This is fabulous. tvm.

James Mills says:

Hi All, This blog post is possibly one of the most useful on the Internet! I started using this back in 2011 and continue using it today. I may end up rewriting the proxy.py that delx originally wrote using my circuits (1) framework for better reliability and better performance (I’ve found over the years I’ve had to restart either the interceptor or proxy at times). I will also (this weekend) be implementing Netflix rules and signing up for Netflix for the first time ever! Thanks again delx! I may blog about a Hulu + Netflix solution later over at http://shortcircuit.net.au/~prologic/blog/

1. http://circuitsframework.com/

ab1 says:

Great guide! Just for reference, another way of doing this is with BIND and SNI Proxy running on a cheap US VPS. I’ve done it recently and documented it here:
http://blog.belodedenko.me/2014/02/diy-clone-of-netflix-tunlr-vps.html

Perhaps it could be useful to someone.

–ab1

James Mills says:

@ab1; What’s teh advantage of BIND + SNI over the implementation above?

Also has anyone heard of Docker (http://docker.io). It would be really awesome if someone were to create a Docker Image of such a service that one could spin up on a US-based VPS running Docker. This would makes running up such a service such a snap :) (I would do it myself time permitting!)

rostar says:

@delx
I live in the us and I am basically using the router script to send all traffic from certain internal ips to my us based server to get around netflix/verizon bottleneck to get decent stream rates. Now Hulu is blocking most vpn ip address so I can’t access Hulu without turning off OpenVPN router client. I tried using hulu (Akamai)ip ranges like cornasdf above but that is pointless as it changes. The script below creates custom ip tables for my wan and vpn connections. Could your code be incorporated into the script to create another table for Hulu addresses to direct through the wan connection (bypass the vpn)? I could then run a cron job to update the the list of ips to direct. correct? Any help would be appreciated. Thank you

#!/bin/sh

ip route flush table 10
ip route del default table 10
ip rule del fwmark 10 table 10
ip route flush table 12
ip route del default table 12
ip rule del fwmark 12 table 12
ip route flush cache
iptables -t mangle -F PREROUTING

tun_if=”tun11″
tun_ip=$(ifconfig $tun_if | grep ‘inet addr:’| cut -d: -f2 | awk ‘{ print $1}’)

ip route add default via $tun_ip dev $tun_if table 10
ip rule add fwmark 10 table 10
ip route add default via $(nvram get wan_gateway) dev eth0 table 12
ip rule add fwmark 12 table 12

echo 0 > /proc/sys/net/ipv4/conf/$tun_if/rp_filter

iptables -t mangle -A PREROUTING -i br0 -m iprange –src-range 192.168.4.53-192.168.4.66 -j MARK –set-mark 10
iptables -t mangle -A PREROUTING -i br0 -p tcp –dport 563 -j MARK –set-mark 12

exit

delx says:

@rostar
heh, you want to do the exact opposite of me! It should be possible :)

Use the huluhosts.txt file to pin each of the Hulu domains to a specific IP address. Then have a script that loops over each of these IPs and forces them to route without the VPN.

Comments are closed.