Instantly share code, notes, and snippets.

Embed
What would you like to do?
Prevent proxy/VPN streaming error messages from Netflix when using an IPv6 tunnel

Netflix AAAA DNS Workaround (IPv6 Tunnels)

This gist was essentially created out of my own rant about Netflix being hostile to IPv6 tunnel services since June 2016. You are welcome to read my opinion on the matter, this is the more technical side to the issue and how to combat it within your own network.

The problem

Netflix now treats IPv6 tunnel brokers (such as Hurricane Electric) as proxy servers. It became apparent to users and Netflix that somewhat by accident, IPv6 tunnel users were being served content outside of their geolocation because of the way Netflix was identifying the tunnel services and their geographical origin. The problem was further compounded by certain opportunstic indiviuals deciding to create a business model out of providing the Netflix US (and others) content library via networks like Hurricane Electric and ruined it for everyone. Netflix and friends got all stressy about it and now all IPv6 tunnel users are considered naughty proxy pirates. Also because big media is stuck in the 1990s, they think this block is actually effective, when in fact it just inconveniences most legitimate users, that simply want IPv6 connectivity, beacause their ISP is stuck in 1995.

https://help.netflix.com/en/node/277

In order to maintain keeping your IPv6 tunnel active while browsing Netflix, you must force Netflix to always use IPv4 (which is likely to be using your ISP WAN gateway as normal). Despite Netflix support stating you should simply "disable" your IPv6 tunnel, this is impossible when you have a IPv6 tunnel deployed across a LAN at the router level and have servers and services running over v6 using the address space.

To implement such a workaround you'll need to have a DNS setup that can allow you to conditionally forward specific Netflix domain lookups to a special DNS resolver that can strip AAAA (IPv6 addresses) records from the DNS request, essentially forcing IPv4 connections.

This guide focuses on a couple of common DNS resolver setups. The concept however is pretty standard and can be applied other DNS resolver setups not covered here e.g. Unbound.

Netflix domains that need be specifically treated

These are the key Netflix domains that need to be handled in a specific way. Mainly, have any IPv6 record returned in a DNS query removed before the request happens.

  • netflix.com
  • netflix.net
  • nflxvideo.net
  • nflximg.net
  • nflxext.com
  • nflxso.net

Some of these domains may not have AAAA records currently, but its possible this might change in the future, so they are covered off to be future proofed.

dnsmasq

With dnsmasq, you have two options:

  1. Directly prevent AAAA lookups on specific domains with config magic
  2. Conditionally forward such domains to another DNS resolver that strips AAAA records from lookups.

Method #1:

This config hack, basically prevents AAAA from being returned by dnsmasq, set it, apply it. Job done. The only downside to this method is you have to generate a matching server and address for each domain. Your dnsmasq.conf could get quite long very quickly. If you have a bulk load of domains you could write a script to output the server and address lines with the domain being a variable, fed by a file or another source.

# Restrict these domains to v4 only
server=/netflix.com/#
address=/netflix.com/::
server=/netflix.net/#
address=/netflix.net/::
server=/nflxext.com/#
address=/nflxext.com/::
server=/nflximg.net/#
address=/nflximg.net/::
server=/nflxvideo.net/#
address=/nflxvideo.net/::
server=/nflxso.net/#
address=/nflxso.net/::

Method #2

Conditionally forwarding DNS requests for these domains to another DNS resolver. In this example, there is another DNS resolver running on localhost (likely a router or DNS server) on the non standard port udp 2053. The port number can be anything you'd like, providing no firewall is blocking it. The reason why a non standard port number is used, is to avoid a port collision. For examaple, you may be running DNS on the same box.

# Remove AAAA responses from Netflix DNS requests
server=/netflix.com/127.0.0.1#2053
server=/netflix.net/127.0.0.1#2053
server=/nflxext.com/127.0.0.1#2053
server=/nflximg.com/127.0.0.1#2053
server=/nflxvideo.net/127.0.0.1#2053
server=/nflxso.net/127.0.0.1#2053

You can host the additional DNS server anywhere you like, you can also run multiple servers if you like redundancy. Personally, I host my additional DNS resolver on my router (DD-WRT), its always on, it makes sense. You can of course also use the standard DNS port if your setup allows for it, which in this case you can simply remove the #2053 part from each line, or choose a random port higher than 1024 for DNS traffic to go through.

Creating a BIND DNS resolver that removes AAAA records from lookups

I chose bind as it has a specific parameter filter-aaaa-on-v4. The example below is a very minimal configuration for bind. Its one purpose is basically to strip AAAA records from DNS lookups. It has the advantage of being domain agnostic, meaning it will strip any AAAA records from any domain passed to it. This is useful if other services other than Netflix start blocking IPv6 tunnels in a similar fashion.

You can use any forwarders you like, the example below uses OpenDNS. If you are running this on an external IP address, you should be careful and make sure you only allow recursion on specific requests and ACL accordingly. Not doing so will make you an open DNS resolver, it won't take long for someone to start abusing your server and generating a high rate of traffic.

options {
	directory "/tmp";
  
 	forwarders {
		208.67.222.222;
		208.67.220.220;
  	};
  
  	forward only;

  	dnssec-enable no;

  	auth-nxdomain no;
  	listen-on port 2053 { 127.0.0.1; };
  	// listen-on-v6 port 2053 { ::1; };
  	filter-aaaa-on-v4 yes;
};

The --enable-filter-aaaa option must be enabled at compile time in order for this config to work, see this page for more information:

https://kb.isc.org/article/AA-00576/0/Filter-AAAA-option-in-BIND-9-.html

If you want to run BIND like this on OpenWRT/DD-WRT you may have to compile the bind package yourself with this specific compile flag set, depending on your setup.

As of 08/01/2017, OpenWRT updated the bind package to have this enabled by default. Entware-ng will also inherit this change on their next sync with OpenWRT sources.

If you need to compile bind from source, see this excellent guide below:

https://www.ploek.org/post/netflix_openwrt/

Note: DD-WRT is also mostly compatible with nearly all Entware-ng packages.

Confirming AAAA records are removed from DNS lookups

Once everything is setup, you can query any of the following Netflix domains listed above against a public DNS resolver and compare the output to a query made to the special DNS resolver you've setup.

An AAAA DNS request made via Google Public DNS

Google's public DNS servers will always return AAAA records, this is what a request to netflix.com will mostly look like:

dig @8.8.8.8 netflix.com AAAA
 
; <<>> DiG 9.9.5-3ubuntu0.8-Ubuntu <<>> @8.8.8.8 netflix.com AAAA
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 21293
;; flags: qr rd ra; QUERY: 1, ANSWER: 8, AUTHORITY: 0, ADDITIONAL: 1
 
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;netflix.com.                   IN      AAAA
 
;; ANSWER SECTION:
netflix.com.            59      IN      AAAA    2620:108:700f::36d6:fc9
netflix.com.            59      IN      AAAA    2620:108:700f::36d6:177c
netflix.com.            59      IN      AAAA    2620:108:700f::36d6:fed
netflix.com.            59      IN      AAAA    2620:108:700f::36d6:25bf
netflix.com.            59      IN      AAAA    2620:108:700f::36d6:d62
netflix.com.            59      IN      AAAA    2620:108:700f::36d6:1cd2
netflix.com.            59      IN      AAAA    2620:108:700f::36d6:22b2
netflix.com.            59      IN      AAAA    2620:108:700f::36d6:1699
 
;; Query time: 36 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Fri Nov 25 12:51:43 GMT 2016
;; MSG SIZE  rcvd: 264

An AAAA DNS request made via the BIND DNS server we setup

Making the same request to our primary DNS resolver that has been configured to treat Netflix domains differently, we should get no AAAA records returned, even if we explicitly request them.

dig @127.0.0.1 netflix.com AAAA
 
; <<>> DiG 9.9.9-P3 <<>> @127.0.0.1 netflix.com AAAA
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 36923
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
 
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;netflix.com.                   IN      AAAA
 
;; Query time: 130 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Fri Nov 25 12:51:43 GMT 2016
;; MSG SIZE  rcvd: 40

If you get no AAAA records returned on your DNS resolver with Netflix queries, your in business. Future Netflix connections should now only use IPv4. You may want to reboot your router or device supplying DNS in order to clear existing/cached lookups. If you performed a DNS lookup for a Netflix domain with AAAA records recently prior to implementing this workaround, it may still be cached and can take a bit of time for changes to be reflected on client machines on the network.

If you get issues like timeouts, check to make sure the DNS server is actually running and your firewall is permitting the DNS traffic, especially if using a non-standard port for DNS traffic.

Streaming issues with Google Chromecast/Android devices

Devices like Google Chromecast don't allow direct control of the DNS servers used and always try to use Google's Public DNS resolvers of 8.8.8.8 and 8.8.4.4, these of course will return AAAA records and cause issues when streaming Netflix (even if you have implemented this workaround on the network the stream activity is running on). You can however leverage a fallback option built into Chromecast devices (and possibly other Google devices), where by if you block access to the Google Public DNS resolvers, it forces the Chromecast device to use the DHCP supplied DNS information and hence the DNS workaround will work.

An example of doing this with iptables:

iptables -I FORWARD --destination 8.8.8.8 -j REJECT
iptables -I FORWARD --destination 8.8.4.4 -j REJECT

In addition, some Google devices may also make v6 DNS lookup requests to Google's public DNS servers, you may have to also block this traffic as well:

ip6tables -I FORWARD --destination 2001:4860:4860::8844 -j REJECT
ip6tables -I FORWARD --destination 2001:4860:4860::8888 -j REJECT

REJECT is a bit more friendly than DROP in this case, as the "fail" response will be quicker. You want the request to fail quickly in this case. You'd use DROP if someone was port knocking and want to slow down their efforts of obtaining open ports.

If you happen to use Google's DNS resolvers at the network level for general DNS queries you can limit this block to the IP address of your Chromecast device with the -s option, allowing you to use Google's DNS resolvers for other devices still. This would require you to use static DHCP in order to create a fixed LAN IP address for any Chromecast devices you have, so you know where they are on the network.

Intercepting Google DNS traffic, rather than blocking

There are several reports that some Google based devices like Android tablets don't seem to like having the Google public DNS resolvers sinkholed. If you experience problems streaming with devices like Chromecasts, Google tablets etc. after blocking Google DNS requests, you might want to instead intercept the requests rather than block them. This can also be achieved via iptables:

iptables -t nat -A PREROUTING -s 192.168.x.x/24 -d 8.8.8.8 -p udp --dport 53 -j DNAT --to 192.168.x.x
iptables -t nat -A PREROUTING -s 192.168.x.x/24 -d 8.8.4.4 -p udp --dport 53 -j DNAT --to 192.168.x.x
  • 192.168.x.x/24 - Range of your LAN, example: 192.168.1.0/24
  • 192.168.x.x - The device that is running DNS i.e. router 192.168.1.1

This method essentially allows DNS requests to 8.8.8.8 or 8.8.4.4, but the request itself will be intercepted and actually resolved by a DNS server of the users choosing, alebit transparently. You can run the Google DNS test example if you apply this method and confirm that no AAAA records are returned, because the DNS server used was actually something else.

DNS traffic is typically UDP based, but there are circumstances where TCP is used as well, however, it is unlikely any Google DNS request will be using TCP, hence why the rules above only target UDP and should be fine for this purpose.

Thanks @seiferma for the report and testing this scenario! Additionally, vertified and tested by myself. (25/06/2017)

Enjoy your Netflix again!

Extra Q&A bit

In case you have any questions about the purpose/reasons for this workaround, here's some answers to potential questions you might have.

Q. Will I be able to stop using this workaround at some point?

A. Once your ISP provides a native IPv6 subnet to you, you can disable your IPv6 tunnel and use the IPv6 subnet delegated to you by your ISP (likely a /56 or something similar).

To clarify, Netflix is only blocking IPv6 tunnels because it cannot fully confirm your exact country of origin and sees any usage of a IPv6 tunnel as a way of circumventing geo-restrcitions on content that is licensed to specific countries, despite this being the intention or not. In the case of Hurricane Electric, while it operates tunnels in loads of different countries, the IPv6 address space they have ultimately identifies as US to a lot of geo based systems concerning IPv6. This problem however is now redundant as Netflix has now straight blocked the IPv6 ranges of various IPv6 tunnel services.

Q. Will Netflix block my actual ISP?

A. No. When you use your ISPs connection, the IP address you connect from will essentially be on whitelist as Netflix won't block the IPv4/IPv6 space of a registered residental/business ISP as its server locations will be fixed and registered. The exception to this is known VPN/proxy services, these are being added to Netflix's blocklists and it gets updated regularly.

Q. How does this workaround work?

A. Essentially when a request is sent to Netflix, a IPv6 connectivity test is done to confirm if you can use their IPv6 network. Remeber, the default protocol behaviour is to try IPv6 first (happy eyeballs). We are essentially fooling Netflix into making all requests use their IPv4 network, because we stripped any AAAA records from such requests, making it look like we only have IPv4 connectivity. Sneaky, yet effective. Netflix traffic goes over IPv4, while you get to keep your IPv6 connectivity for everything else and be part of the slowly rising IPv6 traffic level of the world. Bonus!

Q. Will this workaround stop working in the future?

A. It should be pretty robust, but if Netflix introduce a new domain not covered in the list above that has some form of IPv6 connectivity, which then determines proxy/VPN usage, it may have to be expanded, I have personally used this workaround since June 2016 and it hasn't let me down yet. To be fair this block has been implemented for sometime now, which should satisfy big media, if Netflix further tinker with it, it's just going to become a game of cat and mouse.

Q. Does this workaround allow me to bypass geo-restrictions?

A. No. It is simply designed to allow connectivity to Netflix, while having an IPv6 tunnel active. This does not allow you to obtain access to library content outside your region. This is basically the reason why this workaround has to be implemented in the first place for us legit IPv6 tunnel users. This is why we can't have nice things!

Q. Will Netflix unblock IPv6 tunnels in the future?

A. Probably not, they were likely pressured into it in the first place by media companies and license holders. Netflix probably don't care that much either, as long as your paying your monthly subscription. Big media didn't like it though! Hence the ban hammer. Its also worth noting that IPv6 tunnel services are transitional mechanisms and shouldn't be a permanent solution for IPv6. Hassle your ISP to sort out their IPv6 (or lack of!).

Q. Do any proxy/VPN services still work with Netflix?

A. There are likely some services that might still work, but they are likely operating on borrowed time, as Netflix will be monitoring and updating their blocklists regularly. Most of the well known proxy/VPN services will be blocked for sure.

Q. Can I forward other non-Netflix domains using this method?

A. Yes. The way the bind9 config is setup is basically to strip any AAAA records from domains passed to it. It is not limited to Netflix domains. You just need to let your primary DNS server/resolver (in this example, Dnsmasq) know to forward it to somewhere else. This is the main reason why I'd recommend going the slightly more technical route for more benefits with bind9. Its an even better solution if you already run a bind9 DNS server and simply can create conditional forwarders directly on your primary bind9 servers, but that's not an essential requirement, as explained above.

For a real non-Netflix example, mega.co.nz or mega.nz will not work over v6 via Hurricane Electric because MEGA uses Cogent to carry their IPv6 traffic, which lacks any route to the Hurricane Electric network. See this thread on the HE forums: https://forums.he.net/index.php?topic=3530.0 about the whole HE vs Cogent saga. Using this workaround for MEGA domains will allow you to access the service, because IPv4 will essentially be forced.

Q. I'm not able to run bind9, are there any alternatives?

A. Yes. There is a excellent lightweight DNS proxy specifically for Netflix IPv6 tunnel purposes. Written in Python, it should work on most Unix/Linux systems with little setup required.

https://github.com/cdhowie/netflix-no-ipv6-dns-proxy

The same concept applies, you need to have your primary DNS server/resolver forward requests to this proxy, be aware this DNS proxy is specifically for Netflix domain usage and won't strip the AAAA records of other domains if sent to it. You can edit the source code to expand it if you wanted to though.

Q. Who is "big media"?

A. My pet name for the media rights corporations who are stuck in the past and don't know jack shit about technology. Much like the government of the United Kingdom (example: Investigatory Powers Act 2016). True story.

@seiferma

This comment has been minimized.

seiferma commented Jun 18, 2017

Thanks for your extensive manual. I was able to watch Netflix again.

However, I experienced problems with hard coded DNS servers with my tablet as well, which might be caused by an old version of the Netflix app. I could not watch videos when blocking the Google DNS servers. Instead, I redirected the requests with destination NAT as follows:
iptables -t nat -A PREROUTING -s 192.168.0.0/24 -d 8.8.8.8 -p udp --dport 53 -j DNAT --to 192.168.0.1

You might want to include this solution in your manual.

@jamesmacwhite

This comment has been minimized.

Owner

jamesmacwhite commented Jun 25, 2017

@seiferma Thanks for your response! Sadly Github didn't notify me of the comment on this gist. I will update the information sure, thanks for report!

@almaslegacy

This comment has been minimized.

almaslegacy commented Sep 20, 2017

My kingdom for simple detailed plain english instructions here.

@iphoting

This comment has been minimized.

iphoting commented Dec 24, 2017

Consider the following configuration for dnsmasq:

server=/netflix.com/#
address=/netflix.com/::
server=/netflix.net/#
address=/netflix.net/::
server=/nflxext.com/#
address=/nflxext.com/::
server=/nflximg.net/#
address=/nflximg.net/::
server=/nflxvideo.net/#
address=/nflxvideo.net/::
server=/nflxso.net/#
address=/nflxso.net/::

Adapted from: https://forums.he.net/index.php?topic=3564.msg20916#msg20916

@CraigHumphrey

This comment has been minimized.

CraigHumphrey commented Dec 26, 2017

Windows users can also use the following "fix" from Microsoft, to prefer IPv4 addresses over IPv6.

Article HERE

Use the download that says "Prefer IPv4 over IPv6 in prefix policies"

@seiferma

This comment has been minimized.

seiferma commented Jan 6, 2018

I had to block the IPv6 addresses of the google dns servers in order to watch Netflix on my chromecast device today. They might have hard coded these addresses as well. The fallback to IPv4 dns servers (which are covered in your manual) works.

I added the following lines to my firewall configuration

ip6tables -I FORWARD --destination 2001:4860:4860::8844 -j REJECT
ip6tables -I FORWARD --destination 2001:4860:4860::8888 -j REJECT
@jamesmacwhite

This comment has been minimized.

Owner

jamesmacwhite commented Jan 23, 2018

@iphoting This seems like a more simpler solution for dnsmasq resolvers. I'll check it out.

@CraigHumphrey I'd discourage that approach, because IPv6 is meant to be tried first. There's also no guarantee that the policy will be honoured. I believe I tested it a Windows box once and I still had issues. I think DNS is the "better" way to fix it (its a hack either way without native IPv6), but it is more complicated and in some cases you won't have the level of control over the network to do it.

@seiferma Thanks for letting me know. I know the Google DNS servers have been available over v6 for sometime. Perhaps only certain Chromecast apps are doing v6 DNS lookups to the Google resolvers more recently.

@csdexter

This comment has been minimized.

csdexter commented Apr 6, 2018

Thanks for taking the time to write this and a heartfelt booo to Netflix for handling the issue caveman style. I would like to add to your text that you don't need to reboot machines after making the change: any BIND instance can be told to forget its cache via rndc flush, any dnsmasq instance can do the same via a service dnsmasq restart and any (poor) Windows client can use ipconfig /flushdns. See, no need to reboot the whole machine :-D

@jamesmacwhite

This comment has been minimized.

Owner

jamesmacwhite commented Apr 30, 2018

@csdexter Thanks for your recommendation! It is indeed somewhat overkill to reboot, but sometimes its just easier, given the varying commands to flush the DNS cache. Lazy I know, but I tried to be as generic as possible with examples, so the generic concept can be applied to different DNS resolvers, setups etc.

@puggan

This comment has been minimized.

puggan commented Jun 21, 2018

Blocking the netflix-ipv6 adresses worked for me.

ip6tables -A OUTPUT -d 2a01:578:3::/64 -j REJECT
ip6tables -A FORWARD -d 2a01:578:3::/64 -j REJECT
@imbaczek

This comment has been minimized.

imbaczek commented Aug 14, 2018

dnsmasq #1 worked great for me on tomato (freshtomato-arm https://openlinksys.info/forum/viewthread.php?thread_id=21651).

@souravndp

This comment has been minimized.

souravndp commented Oct 30, 2018

Thank you for such a great article. I was a little bit confused about the dnsmasq Method#1 configurations. At first, I only added address=/netflix.com/:: in the configuration file, but the DNS query didn't return any ipv4 A records. Then, I added server=/netflix.com/# and the ipv4 records were returned.

From the manual:

The special server address '#' means, "use the standard servers", so --server=/google.com/1.2.3.4 --server=/www.google.com/# will send queries for *.google.com to 1.2.3.4, except *www.google.com which will be forwarded as usual.

Then after some trial, I understood that:
If we specify ipv4 or ipv6 address and omit the server # line, then only that specified ipv4/ipv6/both will be returned. No query will be sent to the upstream DNS server, but if we specify ipv6 address and the server #, then dnsmasq will query the upstream DNS server for ipv4 records and return those with our specified ipv6 IP. Similarly, if we specify ipv4 address and server #, then dnsmasq will query the upstream DNS server for ipv6 records and return those with our specified ipv4 IP.

My config:

...
server=/jio.com/#
address=/jio.com/::
log-queries

nslookup

C:\WINDOWS\system32> nslookup sngprcdnems01.cdnsrv.jio.com
Server: GL-AR150.lan
Address: fd49:6a12:b99a::1
Non-authoritative answer:
Name: sngprcdnems01.cdnsrv.jio.com
Addresses: ::
49.44.53.234

From my log:

Tue Oct 30 13:17:18 2018 daemon.info dnsmasq[9372]: started, version 2.78 cachesize 150
...
Tue Oct 30 13:17:18 2018 daemon.info dnsmasq[9372]: using nameserver 8.8.8.8#53
Tue Oct 30 13:17:18 2018 daemon.info dnsmasq[9372]: using standard nameservers for domain jio.com
...
Tue Oct 30 13:21:12 2018 daemon.info dnsmasq[9372]: query[A] sngprcdnems01.cdnsrv.jio.com from fd49:6a12:b99a::a1c8:fda4:3434:b54d
Tue Oct 30 13:21:12 2018 daemon.info dnsmasq[9372]: forwarded sngprcdnems01.cdnsrv.jio.com to 8.8.8.8
Tue Oct 30 13:21:12 2018 daemon.info dnsmasq[9372]: reply sngprcdnems01.cdnsrv.jio.com is 49.44.53.234
Tue Oct 30 13:21:12 2018 daemon.info dnsmasq[9372]: query[AAAA] sngprcdnems01.cdnsrv.jio.com from fd49:6a12:b99a::a1c8:fda4:3434:b54d
Tue Oct 30 13:21:12 2018 daemon.info dnsmasq[9372]: config sngprcdnems01.cdnsrv.jio.com is ::

You wrote that

This config hack, basically prevents AAAA from being returned by dnsmasq

The above is not true. Dnsmasq returns AAAA but it is :: which is a NULL address. From the manual:

Note that NULL addresses normally work in the same way as localhost, so beware that clients looking up these names are likely to end up talking to themselves.

However, most probably the client OS just ignore these addresses and uses the ipv4 IP.

@GTAdoum

This comment has been minimized.

GTAdoum commented Dec 9, 2018

Blocking the netflix-ipv6 adresses worked for me.

ip6tables -A OUTPUT -d 2a01:578:3::/64 -j REJECT
ip6tables -A FORWARD -d 2a01:578:3::/64 -j REJECT

I live in Canada with an HE IPv6 tunnel on an OpenWRT router, this command worked in my case :
ip6tables -I FORWARD -d 2406:da00:ff00:0::/64 -j REJECT

-I instead of -A, to have the rule at beginning of the chain, otherwise it was not working.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment