forked from cdhowie/netflix-no-ipv6-dns-proxy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
server.py
executable file
·87 lines (70 loc) · 3.1 KB
/
server.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#!/usr/bin/env python
OPTIONS = {
# Port to bind to.
'listen-port': 53,
# Address to bind to. '::' will bind IPv6; make sure bindv6only is 0 in
# your sysctl configuration for this binding to service IPv4 clients, too.
# ("cat /proc/sys/net/ipv6/bindv6only" to verify.)
'listen-address': '::',
# Here is where you configure what DNS server to proxy to. You must
# specify exactly one of the following options; comment out the other.
# Specify one or more servers to proxy to. Note that Twisted may not be
# happy if you use an IPv6 address.
# 'upstream-dns': [('127.0.0.1', 10053)],
# Specify a resolv.conf file from which to read upstream nameservers. As
# noted above, if you have any upstream IPv6 servers, Twisted may not be
# happy about that.
# 'resolv-conf': '/etc/resolv.conf',
# Set this to an IPv6 address and all blocked queries will return this
# address instead of an empty result set. The Android Netflix client has
# (for me) started getting testy when AAAA queries return nothing. Set
# this to an address in an unreachable route to resolve that issue. I
# suggest b'100::1' as this is within the RFC6666-specified discard prefix.
#
# Run this command on your Linux router to add an unreachable route for the
# entire discard prefix (100::/64). Add it to the "up" script for your lo
# interface if you want it preserved on reboots.
#
# # ip route add unreachable 0100::/64
'blackhole': None, # b'100::1',
}
from twisted.internet import reactor, defer
from twisted.names import client, dns, error, server
class BlockNetflixAAAAResolver(object):
def __shouldBlock(self, query):
parts = query.name.name.split(b'.')
if len(parts) < 2:
return False
penultimateDomainPart = parts[-2]
return query.type == dns.AAAA and penultimateDomainPart in (b'netflix', b'nflximg', b'nflxext', b'nflxvideo', b'nflxso')
def query(self, query, timeout=None):
if self.__shouldBlock(query):
results = []
blackhole = OPTIONS.get('blackhole', None)
if blackhole is not None:
results.append(
dns.RRHeader(
name=query.name.name,
type=dns.AAAA,
payload=dns.Record_AAAA(address=blackhole)
)
)
return defer.succeed((results, [], []))
else:
return defer.fail(error.DomainError())
def main():
factory = server.DNSServerFactory(
clients=[
BlockNetflixAAAAResolver(),
client.Resolver(
servers=OPTIONS.get('upstream-dns', None),
resolv=OPTIONS.get('resolv-conf', None)
)
]
)
protocol = dns.DNSDatagramProtocol(controller=factory)
reactor.listenUDP(OPTIONS['listen-port'], protocol, interface=OPTIONS['listen-address'])
reactor.listenTCP(OPTIONS['listen-port'], factory, interface=OPTIONS['listen-address'])
reactor.run()
if __name__ == '__main__':
raise SystemExit(main())