No, use *my* DNS. (aka Netflix vs tunnelbroker.net)

Google DNS is being hardcoded into a significant number of devices now. Which is nice, because it pretty much always works.

…except when you’re trying to use Netflix and you have a tunnelbroker IPv6 tunnel. Ugh.

So, this is a brief followup to Stupid OpenWRT tricks. Or maybe “Getting Netflix to work when your ISP doesn’t support IPv6 yet” is a better way to put it…

Anyways. In the previous post it I talked about how to use a local instance of bind to strip IPv6 addresses (AAAA records) from responses. (Again, I can’t take credit for that, though I like the way the person who came up with the idea thinks!) That solution works fabulously.

…unless your device decides it’s going to ignore your DNS servers, and go hit up 8.8.8.8 or 8.8.4.4 (or 2001:4860:4860::8888 or 2001:4860:4860::8844) directly. That’s going to fail. Ugh.

DNAT to the rescue! (Some NAT, like some cholesterol, moderate alcohol intake, and not staying up all night too often, is actually incredibly useful to downright fun. Particularly when staying up all night and the moderate alcohol intake are combined with writing ip6tables DNAT rules.)

The problem is that we have clients bypassing our DNS in favor of servers out on the public Internet. Our solution? Find anything that’s headed in through our LAN interface (typically br-lan) and is headed to 53/UDP, and DNAT it so that it’s headed to our router’s LAN IP address. We don’t need to try to capture or reroute DNS traffic to 8.8.8.8 etc, because we don’t really want any of our clients doing direct DNS queries. (At least, I can’t think of a good reason.)

OpenWRT makes this pretty easy. While the Network->Firewall->Traffic Rules page doesn’t support DNAT, it’s easy enough to craft a custom rule and plug it in on the not very deceptively named “Custom Rules” page. OpenWRT also has a rather nice setup of iptables chains, including ones for user-defined rules, so you can add rules without their being trashed every time the firewall is reloaded.

For our purposes, this will do the trick:

1
2
3
iptables -t nat -A prerouting_lan_rule \
  -p udp --dport 53 -j DNAT --to 192.168.1.1 \
  -m comment --comment 'dns capture and redirect DNAT'

Note we’re using the user rule prerouting_lan_rule; this rule already only has packets coming in on br-lan, so we can omit the -i br-lan from our rule we’d otherwise need.

Once you’ve saved this, you either need to reboot or just ssh into your router and run the command directly, and you should be able to watch Netflix again. You can run host netflix.com 8.8.8.8 from a client box to see that no AAAA records are returned.

While we’re here, we should probably do this for IPv6 as well, just in case. First you’re going to need to install a couple additional packages: kmod-ipt-nat6, and if your LAN interface is a bridge you’ll also need kmod-ebtables-ipv6. Then this rule should do it:

1
2
3
4
ip6tables -t nat -A PREROUTING \
    -i br-lan -p udp --dport 53 -j DNAT \
    --to 2001:470:XXXX:XXXX::1 \
    -m comment --comment 'dns capture and redirect DNAT'

Note OpenWRT does not set up any chains in the IPv6 NAT table, because you should never use NAT in IPv6.

Um, aside from this, naturally.

Enjoy!