Roku, Netflix and the Raspberry Pi

I recently bought a Roku 3 media player from Amazon, taking advantage of the latter’s free international shipping offer.

Roku 3

This new Roku, the latest in a line of low-priced devices from the company, is essentially a streaming media device that connects to your TV and allow you to watch content streamed over the network. Featuring a dead-simple interface - be it on-screen or in your hands - the Roku makes browsing for and consuming content in the living room virtually effortless. It’s the promise of ‘Smart TVs’ - actually delivered.

Unfortunately, if you are outside the USA, much of the content that the Roku promises to stream is unavailable – locked away behind geographic restrictions. You can use something like the Plex Media Server to stream your local media to it - and it does an excellent job of that. In fact, you can even treat this tiny device as just the best way to get your Plex content on your living room television.

Aside: My earlier effort at using the Raspberry Pi as a living room media center didn’t quite work out due its inability to output surround sound to my home theater.

There’s a veritable cottage industry of services that have sprung up around mechanisms that let users bypass these content geo-restrictions. One such mechanism utilizes the DNS system to enable access. In this category are services like Unblock-Us and UnoDNS. I’ll just point you to one of these services for an explanation of how this works.

If you read that explanation, you know that it boils down to using these services are your DNS provider. This does come with certain downsides. Specifically:

  1. You must trust these services not to indulge in malicious DNS spoofing.
  2. You must be okay with the results returned by these services for the rest of the Internet’s domain names.

While #1 in the above list may be dismissed as a paranoid concern, the second is a legitimate, everyday concern. As an example, some of these services delegate to Google’s DNS for resolving names that aren’t core to their service (i.e. not netflix.com, hulu.com, etc.). I personally don’t use Google DNS because I’ve had issues with them not resolving my work place’s remote-access domain to the correct load-balanced server.

Simply put, I’d be loath to use one of these services as my primary DNS.

One nice middle ground would be to configure the Roku to use, say, UnoDNS as the DNS provider and continue using my preferred DNS provider for all the other the devices in my network.

Unfortunately, the Roku provides no way to specify the DNS server to use!

If I had a hackable router, there’s some iptables trickery that could be put to use:

iptables -t nat -I PREROUTING -i br0 -s <roku.ip.addr> -p udp --dport 53 -j DNAT --to <dns.ip.addr>
iptables -t nat -I PREROUTING -i br0 -s <roku.ip.addr> -p tcp --dport 53 -j DNAT --to <dns.ip.addr>

The above (disclaimer: untested!) sets up a firewall rule that redirects all requests originating from the Roku device and bound for port 53 (the DNS service port) to a designated DNS server. All other DNS traffic is unaffected.

Alas, I don’t have a router that lets me set such custom firewall rules.

Which brings me to Dnsmasq, the solution I settled on. Dnsmasq is a simple DNS server that’s suitable for small intranets. In essence, you can configure two kinds of mapping rules in Dnsmasq:

The first kind, obviously, sets a static mapping from a hostname to an IP address. This is the basic DNS functionality and you can imagine have ten to fifteen such rules being sufficient for a small intranet with a dozen computers.

The second kind of rule sets a mapping between a hostname and the DNS server to query to get the IP for that hostname. So if I had a rule like so:

server=/netflix.com/69.197.169.9

It means that when there’s a request to fetch the IP address of the domain name netflix.com, forward that request to the DNS server at 69.197.169.9.

That’s all I need! I can configure one of the geo-block-bypassing services as the upstream DNS for a list of domains that host the content I am interested in and then use my regular DNS server for all other domains!

Now comes the question of where to run this dnsmasq server. As I mentioned in the aside above, my Raspberry Pi is no longer serving as a media center so I re-purposed it as a super-silent, power-sipping energy efficient Linux server running just dnsmasq!

Here’s a quick howto:

  1. Install Raspbian on the RPi.
  2. Set it up to use a static IP, say 192.168.0.2
  3. Install dnsmasq: sudo apt-get install dnsmasq
  4. Create a custom mapping rules config file for dnsmasq
  5. Copy the new rules file to /etc/dnsmasq.d/
  6. Setup your main router’s WAN settings to use 192.168.0.2 as the DNS server.

That’s pretty much it. Restart all devices and check if the DNS changes have taken effect. All devices in your intranet should now be using the RPi as a DNS server. To check if dnsmasq is working correctly, browse to a configured domain (say hulu.com) and check whether you get blocked or not. If you aren’t, congratulations!

Because I am still experimenting with the DNS bypass service providers as well as the list of domains that require special handling, I wrote a quick Python script that generates the requisite dnsmasq configuration file. I’ve shared it in my git repository in case anyone finds it useful.

As of this writing, this is the dnsmasq config file that I am using.

Now to figure out what’s the most optimum way to populate my Netflix queue!