personal-dns/build_stubs.py
2018-05-09 17:23:04 +02:00

124 lines
3.3 KiB
Python
Executable file

#!/usr/bin/env python
import random
import re
import requests
import jinja2
import dns.resolver
BLACKLIST_FILE = 'https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts'
IANA_TLD_LIST = 'https://data.iana.org/TLD/tlds-alpha-by-domain.txt'
INTERNIC_ROOT_FILE = 'https://www.internic.net/domain/named.root'
OPENNIC_ROOT = '75.127.96.89'
OPENNIC_FILTER = ["..", "opennic.glue."]
IANA_FILTERS = ['arpa.']
roots = None
def get_generic_ip(fqdn):
res = dns.resolver.Resolver()
ans = res.query(fqdn, 'A')
return ans.rrset.items[0].to_text()
def get_iana_tlds():
tlds = requests.get(IANA_TLD_LIST).text.split("\n")
return [t.lower()+'.' for t in tlds if len(t) > 0 and t[0] != "#"]
def get_internic_roots():
global roots
if roots is not None:
return roots
named_file = requests.get(INTERNIC_ROOT_FILE).text
roots = []
for line in named_file.split("\n"):
match = re.search(r"\s+A\s+([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)$", line)
if match is None:
continue
roots.append(match.group(1))
return roots
def get_iana_zone_master(zone):
query = dns.message.make_query(zone, dns.rdatatype.NS)
ans = dns.query.tcp(query, random.choice(get_internic_roots()))
glue = {i.name.__str__(): i.items[0].address
for i in ans.additional
if i.rdtype == dns.rdatatype.A}
auth = [i.to_text() for i in ans.authority[0].items]
return [glue[i] for i in auth if i in glue]
def opennic_ip_from_master(master):
res = dns.resolver.Resolver()
res.nameservers = [OPENNIC_ROOT]
ans = res.query(master, 'A')
return [i.to_text() for i in ans.rrset.items]
def get_opennic_zone_master(zone):
res = dns.resolver.Resolver()
res.nameservers = [OPENNIC_ROOT]
ans = res.query('{}.opennic.glue.'.format(zone.strip('.')), 'CNAME')
masters = [t.strip('"')
for t in ans.rrset.items[0].to_text().split(" ")
if t.startswith('ns')]
masters.append('ns0.opennic.glue.')
master_ips = [opennic_ip_from_master(m) for m in masters]
return [item for sublist in master_ips for item in sublist]
def get_opennic_tlds():
res = dns.resolver.Resolver()
res.nameservers = [OPENNIC_ROOT]
ans = res.query('tlds.opennic.glue.', 'TXT')
return [t.strip('"')+'.' for t in ans.rrset.items[0].to_text().split(" ")]
def main():
entries = {
"opennic.glue.": [OPENNIC_ROOT],
}
iana_tlds = get_iana_tlds()
if len(iana_tlds) == 0:
raise Exception("No IANA TLDs found")
for tld in get_iana_tlds():
if tld in IANA_FILTERS:
continue
print("Working on IANA TLD '{}'...".format(tld))
entries[tld] = get_iana_zone_master(tld)
opennic_tlds = get_opennic_tlds()
if len(opennic_tlds) == 0:
raise Exception("No OpenNIC TLDs found")
for tld in get_opennic_tlds():
if tld in OPENNIC_FILTER:
continue
print("Working on OpenNIC TLD '{}'...".format(tld))
entries[tld] = get_opennic_zone_master(tld)
with open('named.stubs', 'w') as f:
f.write(render_corefile(entries))
def render_corefile(entries):
template = jinja2.Template(open("named.stubs.j2").read())
return template.render(entries=entries)
if __name__ == '__main__':
main()