extract nserver parsing + change to _with_fallback for queries
This commit is contained in:
parent
86c7a00b5b
commit
68bf8a7704
1 changed files with 48 additions and 62 deletions
|
@ -1,5 +1,7 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
REGISTRY_PATH = "../registry"
|
||||||
|
|
||||||
import hashlib
|
import hashlib
|
||||||
import base64
|
import base64
|
||||||
import struct
|
import struct
|
||||||
|
@ -25,7 +27,6 @@ except ImportError:
|
||||||
import dns.exception
|
import dns.exception
|
||||||
import binascii
|
import binascii
|
||||||
|
|
||||||
REGISTRY_PATH = "../registry"
|
|
||||||
|
|
||||||
# step1:
|
# step1:
|
||||||
|
|
||||||
|
@ -42,6 +43,24 @@ def get_domain_by_mntner(mntner):
|
||||||
|
|
||||||
# domains dict containing dns objects and inet(6)nums if they have nserver specified
|
# domains dict containing dns objects and inet(6)nums if they have nserver specified
|
||||||
domains = {}
|
domains = {}
|
||||||
|
|
||||||
|
|
||||||
|
def _parse_nserver(line):
|
||||||
|
nserver = line[20:].split(" ")
|
||||||
|
# handle edge case where
|
||||||
|
if "\t" in nserver[0]:
|
||||||
|
nserver = nserver[0].split("\t")
|
||||||
|
# ignore registry-sync nservers
|
||||||
|
if "registry-sync.dn42" in nserver[0]:
|
||||||
|
return
|
||||||
|
|
||||||
|
# nserver should be defined in an other dns file
|
||||||
|
if len(nserver) == 1:
|
||||||
|
return [nserver[0], None]
|
||||||
|
# nserver is defined in this file
|
||||||
|
elif len(nserver) == 2:
|
||||||
|
return nserver
|
||||||
|
|
||||||
# read dns files
|
# read dns files
|
||||||
for domain in dns_files:
|
for domain in dns_files:
|
||||||
with open(domain) as d:
|
with open(domain) as d:
|
||||||
|
@ -51,24 +70,13 @@ def get_domain_by_mntner(mntner):
|
||||||
for line in d.readlines():
|
for line in d.readlines():
|
||||||
line = line.replace("\n", "")
|
line = line.replace("\n", "")
|
||||||
if line.startswith("nserver"):
|
if line.startswith("nserver"):
|
||||||
nserver = line[20:].split(" ")
|
_tmp = _parse_nserver(line)
|
||||||
# handle edge case where
|
if _tmp == "break": break
|
||||||
if "\t" in nserver[0]:
|
if _tmp[0] in domains[domain_name]["nserver"]:
|
||||||
nserver = nserver[0].split("\t")
|
domains[domain_name]["nserver"][_tmp[0]].append(_tmp[1])
|
||||||
# ignore registry-sync nservers
|
else:
|
||||||
if "registry-sync.dn42" in nserver[0]:
|
domains[domain_name]["nserver"][_tmp[0]
|
||||||
break
|
] = [_tmp[1]]
|
||||||
# nserver should be defined in an other dns file
|
|
||||||
if len(nserver) == 1:
|
|
||||||
domains[domain_name]["nserver"][nserver[0]] = None
|
|
||||||
# nserver is defined in this file
|
|
||||||
elif len(nserver) == 2:
|
|
||||||
if nserver[0] not in domains[domain_name]["nserver"]:
|
|
||||||
domains[domain_name]["nserver"][nserver[0]] = [
|
|
||||||
nserver[1]]
|
|
||||||
else:
|
|
||||||
domains[domain_name]["nserver"][nserver[0]].append(
|
|
||||||
nserver[1])
|
|
||||||
|
|
||||||
elif line.startswith("ds-rdata:"):
|
elif line.startswith("ds-rdata:"):
|
||||||
domains[domain_name]["ds-rdata"].append(line[20:].lower())
|
domains[domain_name]["ds-rdata"].append(line[20:].lower())
|
||||||
|
@ -95,22 +103,12 @@ def get_domain_by_mntner(mntner):
|
||||||
# TODO: implement creation of multiple zones for every /24 within
|
# TODO: implement creation of multiple zones for every /24 within
|
||||||
print(f"WARN: currently only ipv4 subnets with length >=24 or 16 or 8 are possible to be checked: relavent inetnum {line}")
|
print(f"WARN: currently only ipv4 subnets with length >=24 or 16 or 8 are possible to be checked: relavent inetnum {line}")
|
||||||
elif line.startswith("nserver"):
|
elif line.startswith("nserver"):
|
||||||
nserver = line[20:].split(" ")
|
_tmp = _parse_nserver(line)
|
||||||
# handle edge case where
|
if _tmp == "break": break
|
||||||
if "\t" in nserver[0]:
|
if _tmp[0] in _nserver:
|
||||||
nserver = nserver[0].split("\t")
|
_nserver[_tmp[0]].append(_tmp[1])
|
||||||
# ignore registry-sync nservers
|
else:
|
||||||
if "registry-sync.dn42" in nserver[0]:
|
_nserver[_tmp[0]] = _tmp[1]
|
||||||
break
|
|
||||||
# nserver should be defined in an other dns file
|
|
||||||
if len(nserver) == 1:
|
|
||||||
_nserver[nserver[0]] = None
|
|
||||||
# nserver is defined in this file
|
|
||||||
elif len(nserver) == 2:
|
|
||||||
if nserver[0] not in _nserver:
|
|
||||||
_nserver[nserver[0]] = [nserver[1]]
|
|
||||||
else:
|
|
||||||
_nserver[nserver[0]].append(nserver[1])
|
|
||||||
|
|
||||||
elif line.startswith("ds-rdata:"):
|
elif line.startswith("ds-rdata:"):
|
||||||
_ds_rdata.append(line[20:].lower())
|
_ds_rdata.append(line[20:].lower())
|
||||||
|
@ -138,24 +136,12 @@ def get_domain_by_mntner(mntner):
|
||||||
break
|
break
|
||||||
_domain_name = _digit1 + "." + _domain_name
|
_domain_name = _digit1 + "." + _domain_name
|
||||||
elif line.startswith("nserver"):
|
elif line.startswith("nserver"):
|
||||||
nserver = line[20:].split(" ")
|
_tmp = _parse_nserver(line)
|
||||||
|
if _tmp == "break": break
|
||||||
# handle edge case where
|
if _tmp[0] in _nserver:
|
||||||
if "\t" in nserver[0]:
|
_nserver[_tmp[0]].append(_tmp[1])
|
||||||
nserver = nserver[0].split("\t")
|
else:
|
||||||
# ignore registry-sync nservers
|
_nserver[_tmp[0]] = _tmp[1]
|
||||||
if "registry-sync.dn42" in nserver[0]:
|
|
||||||
break
|
|
||||||
|
|
||||||
# nserver should be defined in an other dns file
|
|
||||||
if len(nserver) == 1:
|
|
||||||
_nserver[nserver[0]] = None
|
|
||||||
# nserver is defined in this file
|
|
||||||
elif len(nserver) == 2:
|
|
||||||
if nserver[0] not in _nserver:
|
|
||||||
_nserver[nserver[0]] = [nserver[1]]
|
|
||||||
else:
|
|
||||||
_nserver[nserver[0]].append(nserver[1])
|
|
||||||
|
|
||||||
elif line.startswith("ds-rdata:"):
|
elif line.startswith("ds-rdata:"):
|
||||||
_ds_rdata.append(line[20:].lower())
|
_ds_rdata.append(line[20:].lower())
|
||||||
|
@ -191,19 +177,19 @@ def get_dnskey(domain_name, nserver):
|
||||||
try:
|
try:
|
||||||
request = dns.message.make_query(
|
request = dns.message.make_query(
|
||||||
domain_name, dns.rdatatype.DNSKEY, want_dnssec=False)
|
domain_name, dns.rdatatype.DNSKEY, want_dnssec=False)
|
||||||
response = dns.query.udp(request, nserver, timeout=2)
|
response = dns.query.udp_with_fallback(request, nserver, timeout=2)
|
||||||
except dns.exception.Timeout:
|
except dns.exception.Timeout:
|
||||||
print(f"WARN: querying {nserver} for {domain_name} timed out")
|
print(f"WARN: querying {nserver} for {domain_name} timed out")
|
||||||
return False
|
return False
|
||||||
except dns.query.UnexpectedSource as e:
|
except dns.query.UnexpectedSource as e:
|
||||||
print(f"ERROR: server replied with different different ip than requested: error: {e}")
|
print(f"ERROR: server replied with different different ip than requested: error: {e}")
|
||||||
return False
|
return False
|
||||||
if response.rcode() != 0:
|
if response[0].rcode() != 0:
|
||||||
# HANDLE QUERY FAILED (SERVER ERROR OR NO DNSKEY RECORD)
|
# HANDLE QUERY FAILED (SERVER ERROR OR NO DNSKEY RECORD)
|
||||||
print(
|
print(
|
||||||
f"WARN: query for a DNSKEY on {domain_name} failed on {nserver}, returncode: {response.rcode()}")
|
f"WARN: query for a DNSKEY on {domain_name} failed on {nserver}, returncode: {response[0].rcode()}")
|
||||||
return False
|
return False
|
||||||
return [dnskey.to_text().split("IN DNSKEY ")[1] for dnskey in response.answer]
|
return [dnskey.to_text().split("IN DNSKEY ")[1] for dnskey in response[0].answer]
|
||||||
# if not nserver:
|
# if not nserver:
|
||||||
# # drill: use DNSSEC, fallback to tcp, for $domain
|
# # drill: use DNSSEC, fallback to tcp, for $domain
|
||||||
# drill_cmd = subprocess.Popen(
|
# drill_cmd = subprocess.Popen(
|
||||||
|
@ -335,7 +321,7 @@ def check_dnssec(domain_name, domain_data):
|
||||||
domain_name, dns.rdatatype.SOA, want_dnssec=False)
|
domain_name, dns.rdatatype.SOA, want_dnssec=False)
|
||||||
try:
|
try:
|
||||||
# send the query
|
# send the query
|
||||||
dns.query.udp(request, nsaddr, timeout=2)
|
dns.query.udp_with_fallback(request, nsaddr, timeout=2)
|
||||||
# if it timed out: tell the user
|
# if it timed out: tell the user
|
||||||
except dns.exception.Timeout:
|
except dns.exception.Timeout:
|
||||||
print(
|
print(
|
||||||
|
@ -349,15 +335,15 @@ def check_dnssec(domain_name, domain_data):
|
||||||
# get DNSKEY for zone
|
# get DNSKEY for zone
|
||||||
request = dns.message.make_query(
|
request = dns.message.make_query(
|
||||||
domain_name, dns.rdatatype.DNSKEY, want_dnssec=True)
|
domain_name, dns.rdatatype.DNSKEY, want_dnssec=True)
|
||||||
response = dns.query.udp(request, nsaddr, timeout=2)
|
response = dns.query.udp_with_fallback(request, nsaddr, timeout=2)
|
||||||
|
|
||||||
if response.rcode() != 0:
|
if response[0].rcode() != 0:
|
||||||
# HANDLE QUERY FAILED (SERVER ERROR OR NO DNSKEY RECORD)
|
# HANDLE QUERY FAILED (SERVER ERROR OR NO DNSKEY RECORD)
|
||||||
print(
|
print(
|
||||||
f"WARN: query for a DNSKEY on {domain_name} failed on {nserver} ({nsaddr}), returncode: {response.rcode()}")
|
f"WARN: query for a DNSKEY on {domain_name} failed on {nserver} ({nsaddr}), returncode: {response[0].rcode()}")
|
||||||
continue
|
continue
|
||||||
# answer should contain two RRSET: DNSKEY and RRSIG(DNSKEY)
|
# answer should contain two RRSET: DNSKEY and RRSIG(DNSKEY)
|
||||||
answer = response.answer
|
answer = response[0].answer
|
||||||
if len(answer) != 2:
|
if len(answer) != 2:
|
||||||
# SOMETHING WENT WRONG
|
# SOMETHING WENT WRONG
|
||||||
print(
|
print(
|
||||||
|
|
Loading…
Add table
Reference in a new issue