DNS test: also check a public nameserver to verify that the registrar (or up-host) configuration is correct too
This commit is contained in:
parent
6fd768d6ee
commit
95a17a00c0
1 changed files with 58 additions and 38 deletions
96
tests/dns.py
96
tests/dns.py
|
@ -1,7 +1,11 @@
|
||||||
#!/usr/bin/python3
|
#!/usr/bin/python3
|
||||||
# Test DNS configuration.
|
#
|
||||||
|
# Tests the DNS configuration of a Mail-in-a-Box.
|
||||||
#
|
#
|
||||||
# tests/dns.py ipaddr hostname
|
# tests/dns.py ipaddr hostname
|
||||||
|
#
|
||||||
|
# where ipaddr is the IP address of your Mail-in-a-Box
|
||||||
|
# and hostname is the domain name to check the DNS for.
|
||||||
|
|
||||||
import sys, subprocess, re, difflib
|
import sys, subprocess, re, difflib
|
||||||
|
|
||||||
|
@ -11,48 +15,64 @@ if len(sys.argv) < 3:
|
||||||
|
|
||||||
ipaddr, hostname = sys.argv[1:]
|
ipaddr, hostname = sys.argv[1:]
|
||||||
|
|
||||||
def dig(digargs):
|
|
||||||
# run dig and clean the output
|
|
||||||
response = subprocess.check_output(['dig', '@' + ipaddr] + digargs).decode('utf8')
|
|
||||||
response = re.sub('[\r\n]+', '\n', response) # remove blank lines
|
|
||||||
response = re.sub('\n;.*', '', response) # remove comments
|
|
||||||
response = response.strip() + "\n"
|
|
||||||
return response
|
|
||||||
|
|
||||||
# call dig a few times with different parameters
|
|
||||||
digoutput = \
|
|
||||||
dig([hostname])\
|
|
||||||
+ dig(["www." + hostname, "+noadditional", "+noauthority"]) \
|
|
||||||
+ dig(["mx", hostname, "+noadditional", "+noauthority"]) \
|
|
||||||
+ dig(["txt", hostname, "+noadditional", "+noauthority"]) \
|
|
||||||
+ dig(["txt", "mail._domainkey." + hostname, "+noadditional", "+noauthority"])
|
|
||||||
|
|
||||||
# normalize DKIM key
|
|
||||||
digoutput = re.sub(r"(\"p=).*(\")", r"\1__KEY__\2", digoutput)
|
|
||||||
|
|
||||||
# construct the expected output
|
# construct the expected output
|
||||||
subs = { "ipaddr": ipaddr, "hostname": hostname }
|
subs = { "ipaddr": ipaddr, "hostname": hostname }
|
||||||
expected = """
|
expected = """
|
||||||
{hostname}. 86400 IN A {ipaddr}
|
{hostname}. ##### IN A {ipaddr}
|
||||||
{hostname}. 86400 IN NS ns1.{hostname}.
|
{hostname}. ##### IN NS ns1.{hostname}.
|
||||||
{hostname}. 86400 IN NS ns2.{hostname}.
|
{hostname}. ##### IN NS ns2.{hostname}.
|
||||||
ns1.{hostname}. 86400 IN A {ipaddr}
|
ns1.{hostname}. ##### IN A {ipaddr}
|
||||||
ns2.{hostname}. 86400 IN A {ipaddr}
|
ns2.{hostname}. ##### IN A {ipaddr}
|
||||||
www.{hostname}. 86400 IN A {ipaddr}
|
www.{hostname}. ##### IN A {ipaddr}
|
||||||
{hostname}. 86400 IN MX 10 {hostname}.
|
{hostname}. ##### IN MX 10 {hostname}.
|
||||||
{hostname}. 300 IN TXT "v=spf1 mx -all"
|
{hostname}. ##### IN TXT "v=spf1 mx -all"
|
||||||
mail._domainkey.{hostname}. 86400 IN TXT "v=DKIM1\; k=rsa\; s=email\; " "p=__KEY__"
|
mail._domainkey.{hostname}. ##### IN TXT "v=DKIM1\; k=rsa\; s=email\; " "p=__KEY__"
|
||||||
""".format(**subs).strip() + "\n"
|
""".format(**subs).strip() + "\n"
|
||||||
|
|
||||||
# Show a diff if there are any changes
|
def dig(server, digargs):
|
||||||
has_diff = False
|
# run dig and clean the output
|
||||||
def split(s): return [line+"\n" for line in s.split("\n")]
|
response = subprocess.check_output(['dig', '@' + server, "+noadditional", "+noauthority"] + digargs).decode('utf8')
|
||||||
for line in difflib.unified_diff(split(expected), split(digoutput), fromfile='expected DNS settings', tofile='output from dig'):
|
response = re.sub('[\r\n]+', '\n', response) # remove blank lines
|
||||||
sys.stdout.write(line)
|
response = re.sub('\n;.*', '', response) # remove comments
|
||||||
has_diff = True
|
response = re.sub('(\n\S+\s+)(\d+)', r'\1#####', response) # normalize TTLs
|
||||||
|
response = re.sub(r"(\"p=).*(\")", r"\1__KEY__\2", response) # normalize DKIM key
|
||||||
|
response = response.strip() + "\n"
|
||||||
|
return response
|
||||||
|
|
||||||
if not has_diff:
|
def test(server, description):
|
||||||
print("DNS is OK.")
|
# call dig a few times with different parameters
|
||||||
sys.exit(0)
|
digoutput = \
|
||||||
|
dig(server, [hostname])\
|
||||||
|
+ dig(server, ["ns", hostname]) \
|
||||||
|
+ dig(server, ["ns1." + hostname]) \
|
||||||
|
+ dig(server, ["ns2." + hostname]) \
|
||||||
|
+ dig(server, ["www." + hostname]) \
|
||||||
|
+ dig(server, ["mx", hostname]) \
|
||||||
|
+ dig(server, ["txt", hostname]) \
|
||||||
|
+ dig(server, ["txt", "mail._domainkey." + hostname])
|
||||||
|
|
||||||
|
# Show a diff if there are any changes
|
||||||
|
has_diff = False
|
||||||
|
def split(s): return [line+"\n" for line in s.split("\n")]
|
||||||
|
for line in difflib.unified_diff(split(expected), split(digoutput), fromfile='expected DNS settings', tofile=description):
|
||||||
|
if not has_diff:
|
||||||
|
print("The response from %s (%s) is not correct:" % (description, server))
|
||||||
|
print()
|
||||||
|
has_diff = True
|
||||||
|
|
||||||
|
sys.stdout.write(line)
|
||||||
|
|
||||||
|
return not has_diff
|
||||||
|
|
||||||
|
# Test the response from the machine itself.
|
||||||
|
if test(ipaddr, "Mail-in-a-Box"):
|
||||||
|
# If those settings are OK, also test Google's Public DNS
|
||||||
|
# to see if the machine is hooked up to recursive DNS properly.
|
||||||
|
if test("8.8.8.8", "Google Public DNS"):
|
||||||
|
print ("DNS is OK.")
|
||||||
|
sys.exit(0)
|
||||||
|
else:
|
||||||
|
print ()
|
||||||
|
print ("Check that the nameserver settings for %s are correct at your domain registrar." % hostname)
|
||||||
|
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
Loading…
Reference in a new issue