March 10, 2009

Who wants Hulu?

Filed under: Technical — Tags: , , , — delx @ 12:15 am

This guide is out of date! Please see the new guide here:
Hulu and Pandora outside USA

Hulu is a website that offers commercial-supported streaming video of TV shows and movies from NBC, Fox and many other networks and studios. Currently Hulu is only available from within the United States of America.

If you want to be notified of updates to this post, subscribe to the comments feed.

This is kind of lame. One of the fundamental principles of the internet is global access. That’s why we have the world wide web, not the America-web.

So, in that spirit, here’s how to make Hulu fully functional on your local network and accessible from any ordinary web browser.

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

For my friends

You can skip the USA proxy configuration and just use 72.232.203.84 everywhere you would put that server’s IP.
Make sure you email me and I’ll add your local IP address to the allow list for the RTMP proxy.

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, hulu_proxy.ini with these contents:
    [proxy]
    mode = proxy
    listen_port = 9997
    
    [allowed]
    host1 = YOUR_LOCAL_IP_OR_DOMAIN
    
  • Download proxy.py and run this command to start forwarding requests on port 9997 from the allowed hosts.
    proxy.py -d hulu_proxy.ini
  • Create an HTTP virtual server for these domains: releasegeo.hulu.com
  • Download proxy.rb and path.cgi to these virtual hosts.
  • Edit path.cgi to end with
    proxyTo "http://" + ENV["HTTP_HOST"], False
  • Now set up a rewrite rule to forward / to /path.cgi for each of these virtual hosts.

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.
Follow these steps on your LAN’s router or your on any Linux computer:

  • Add this to your /etc/hosts file (these addresses may be out of date, see the last section in this blog):
    XXX.YYY.ZZZ.AAA releasegeo.hulu.com
    205.241.224.55 cp41752.edgefcs.net # HULU
    205.241.224.45 cp39465.edgefcs.net # HULU
    205.241.224.158 cp51756.edgefcs.net # HULU
    205.241.224.37 cp47346.edgefcs.net # HULU
    

    where XXX.YYY.ZZZ.AAA is the IP address of your US server.

  • 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.
  • Add this to your firewall config for Linux:
    grep 'HULU$' /etc/hosts | awk '{print $1;}' | while read huluip; do
        iptables -t nat -A PREROUTING -i eth0 -p tcp \
            --destination "$huluip"  --dport 1935 -j REDIRECT --to-ports 9997
        iptables -t nat -A OUTPUT -p tcp \
            --destination "$huluip" --dport 1935 -j REDIRECT --to-ports 9997
    done
    
  • Add this to your firewall config for OSX:
    grep 'HULU$' /etc/hosts | awk '{print $1;}' | while read huluip; do
        ipfw add 50000 fwd 127.0.0.1,9997 \
            tcp from any to "$huluip" dst-port 1935
    done
    
  • Create a file, hulu_interceptor.ini with these contents:
    [proxy]
    mode = interceptor
    listen_port = 9997
    host = XXX.YYY.ZZZ.XXX
    port = 9997
    
  • Download proxy.py and run this command to start capturing and forwarding the Flash RTMP port to your US server.
    proxy.py -d hulu_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 Flash RTMP 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 some videos may not work and the hosts file will need updating.

If you are having difficulty viewing videos and you suspect that this is the issue, try running this tcpdump command to see whether your connections are being sent to a server within your ISPs address range:

# tcpdump -i INTERFACE port 1935

You’ll then need to find the corresponding domain name and the ‘correct’ IP to add 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: http://delx.net.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 http://delx.net.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

27 Comments »

  1. Brilliant.

    Also, I see you have been productive ^^

    Comment by Greg Darke — March 10, 2009 @ 1:13 am

  2. Awesome! :) Now i just have to figure out how to get firefox to let me full-screen it. :/

    Comment by Katie — March 29, 2009 @ 3:21 pm

  3. Looks like Hulu doesn’t support full screen concurrently with other apps at the moment. I’m annoyed by this too.
    See http://www.hulu.com/support/technical_faq#dual

    Comment by delx — March 29, 2009 @ 10:20 pm

  4. Hi!, this still working?
    Looks like a crossdomain.xml file is requested now to releasegeo.hulu.com instead of /

    Comment by Ivan — June 3, 2009 @ 8:35 am

  5. Should do, that’s what the cgiproxy stuff is for.

    Comment by delx — June 3, 2009 @ 9:32 am

  6. Yeah, but when my proxyed version of releasegeo.hulu.com receives an http GET of /crossdomain.xml it doesn’t know what to do with it, or I’m missing sthing in your sentence “create a rewrite rule to forward / to /path.cgi. I just wrote RewriteRule ^/$ /usr/lib/cgi-bin/path.cgi [T=application/x-httpd-cgi] and all I get is File does not exist: /var/www/releasegeo/crossdomain.xml (my firefox hulu “client” requests that xml, of course)…

    Comment by Ivan — June 3, 2009 @ 9:42 am

  7. You need something like this:
    RewriteRule ^(.*) /a/b/c/path.cgi/$1
    Edited

    Comment by delx — June 3, 2009 @ 12:22 pm

  8. Ok, did it, but what I notice first is that I get caught as being outside US before I see any packet leaving my machine through port 1935 (or its redirected version to port 9997). My guess is they’re checking Geo outside the flash streaming. I redirected all 1935 traffic (not only for the hulu IP addresses) but always get the “US only” screen…

    Comment by Ivan — June 4, 2009 @ 9:14 am

  9. I happen to have access to an SSH server that provides only -L and -R support, not -D. to make a long story short, I able to build the same configuration only using tarted localport forwards (-L), including for the 1935 ports. I then setup ipfw rules for each 1935 forward and Foxyproxy rules for each 80/HTTP forward. Yet still, I get past the first GeoCheck but still get the message “Sorry, we are unable to stream this video. Please check your Internet connection and try again.”

    Troubleshooting:
    * I made sure all URL’s being accessed return 200. Verified with Proxy log that nothing was slipping through without being proxied over SSH.
    * I routinely updated my ipfw rules after each attempt as sometimes they add a new FCS/1935 server. Here is what they look like currently:
    50000 0 0 fwd 127.0.0.1,4000 tcp from any to 74.125.45.100 dst-port 1935
    50000 0 0 fwd 127.0.0.1,4001 tcp from any to 209.107.215.165 dst-port 1935
    50000 0 0 fwd 127.0.0.1,4002 tcp from any to 209.107.215.167 dst-port 1935
    50000 0 0 fwd 127.0.0.1,4003 tcp from any to 209.107.215.180 dst-port 1935
    50000 0 0 fwd 127.0.0.1,4004 tcp from any to 209.107.215.183 dst-port 1935

    Please, any suggestions? Currently I have scripts that update foxyproxy, ipfw and my ssh tunnel, if that helps anyone

    Comment by cyphunk — August 26, 2009 @ 8:40 am

  10. Looks pretty good. I’d double check that it is actually passing the geocheck. Make sure that pulling this URL looks ok: http://releasegeo.hulu.com/geoCheck. Also make sure that you have the edgefcs.net servers in your hosts file.

    Comment by delx — August 26, 2009 @ 10:16 am

  11. Updated the /etc/hosts list

    Comment by delx — September 5, 2009 @ 4:10 pm

  12. Another /etc/hosts update.

    Comment by delx — September 14, 2009 @ 9:58 pm

  13. oh man, been trying all day to get this working. Nothing seems to do it. Im not sure what im doing wrong but ive checked everything and it seems to run as it should. I might be skrewing up the htaccess file. Ive added /cgi-bin as an alias to my vhost and im doing RewriteRule $/ /cgi-bin/path.cgi$1 [L] in my htaccess – still nothing seems to work right. Any tips?

    Comment by christian — October 30, 2009 @ 9:59 am

  14. Try running this command:
    $ curl http://releasegeo.hulu.com/geoCheck

    If you have set up the rewrite rules correctly then you should get:

    <?xml version="1.0" encoding="UTF-8"?>
    <geocheck>
      <status>valid</status>
    </geocheck>
    <proxycheck>
      <status>false</status>
    </proxycheck>
    

    Comment by delx — November 1, 2009 @ 10:35 am

  15. Hi

    Wondering if you can help. On my US server:

    /usr/lib/cgi-bin/path.cgi
    /var/www/relasegeo/proxy.rb

    in my apache file:

    RewriteEngine On
    RewriteRule $/ /usr/lib/cgi-bin/path.cgi$1

    When I go to http://releasegeo.hulu.com/ I just get a directory listing with the proxy.rb file
    When I go to http://releasegeo.hulu.com/geoCheck I get a 404

    When I executive /usr/lib/cgi-bin/path.cgi from CLI I get:

    /usr/lib/cgi-bin/path.cgi:4:in `+’: can’t convert nil into String (TypeError)
    from /usr/lib/cgi-bin/path.cgi:4

    Any ideas??

    Comment by IF — December 3, 2009 @ 3:58 am

  16. The path.cgi script is not meant to be executed from the command line. Try using something like:
    RewriteRule ^(.*) /a/b/c/path.cgi/$1

    Comment by delx — December 3, 2009 @ 7:00 pm

  17. Thanks for the reply.

    If I use your rewrite I rule I get a 404 on both http://releasegeo.hulu.com/ and http://releasegeo.hulu.com/geoCheck

    If I take the /$1 off the end, I get a printout of the path.cgi, without it being parsed or executed.

    Here’s my complete VirtualHost

    DocumentRoot /root/releasegeo/apache
    ServerName releasegeo.hulu.com

    # Other directives here
    RewriteEngine On
    RewriteRule ^(.*) /usr/lib/cgi-bin/path.cgi/$1

    Comment by IF — December 6, 2009 @ 1:17 pm

  18. Does this still work for others?

    I’m server geoCheck and crossdomain correctly (and a result pass the geocheck on the support page), but still get blocked with a non-us/proxy notice.

    Comment by james — December 12, 2009 @ 6:19 pm

  19. Updated /etc/hosts again

    Comment by delx — January 28, 2010 @ 12:24 am

  20. Hi

    Just wanted to thank you for this list, I ended up routing it over a VPN but I still need your /etc/hosts file to know what to route and what to leave on my normal connection. Much appreciated. Also, I recently stopped being able to get on and found that the IP address 205.241.224.46 on hulu’s end was being accessed on the flash streaming port. It wasn’t one I had previously been routing over the VPN. Maybe useful for someone else.

    Comment by IF — February 2, 2010 @ 6:45 am

  21. Automatic updates to /etc/hosts for those who want it

    Comment by delx — February 14, 2010 @ 5:53 pm

  22. thanks for posting all this

    fwiw it appears that ipfw forwarding is broken on mac os x 10.6.x – so if you run into trouble with this & are using snow leopard – there’s the problem :P

    Comment by pwl — February 18, 2010 @ 2:29 am

  23. I’m trying to do this with iptables, and a Squid proxy in the US. I’d like to only forward certain urls to the US proxy (hulu , pandora…) I can get pandora to work but not hulu. Any ideas?

    iptables -t nat -A PREROUTING -i $interface -p tcp -d http://www.pandora.com –dport 80 -j DNAT –to 321.321.321.321:3128
    iptables -t nat -A PREROUTING -i $interface -p tcp -d releasegeo.hulu.com –dport 80 -j DNAT –to 321.321.321.321:3128
    iptables -t nat -A PREROUTING -i $interface -p tcp -d 205.241.224.0/24 –dport 80 -j DNAT –to 321.321.321.321:3128

    iptables -t nat -A PREROUTING -i $interface -p tcp –dport 80 -j REDIRECT –to-ports $HTTP_PROXY_PORT

    Thanks

    Comment by mlr — April 2, 2010 @ 10:24 am

  24. You need to read the instructions more carefully. In particular, to the best of my knowledge you cannot use an HTTP proxy (I’m assuming it’s Squid or similar) to proxy the Flash streams. You must use the script I wrote, or a SOCKS proxy.

    Comment by delx — April 6, 2010 @ 8:27 pm

  25. I made a new huluhosts.txt it contains several IPs like 20 plus cause I found that It often stops working so i used the tcpdump command you mentioned to keep watch and added them one by one
    as necessary here is my list http://www.insidiousramblings.com/huluhosts.txt hope it helps someone

    Comment by oobe — April 11, 2010 @ 3:58 pm

  26. Amazing, 5 days trying to get Huludesktop working with dante socks, 5 minutes and huludesktop is up and running using this solution. Many thanks

    Comment by Bob — February 13, 2011 @ 6:48 am

  27. This guide is out of date, please see the new guide here: http://delx.net.au/blog/2011/12/hulu-and-pandora-outside-usa/

    Comment by delx — December 11, 2011 @ 5:17 pm

RSS feed for comments on this post. TrackBack URL

Leave a comment