From 95a17a00c030197dd1658af0216968190df01c7d Mon Sep 17 00:00:00 2001 From: Joshua Tauberer Date: Sun, 20 Apr 2014 12:26:35 -0400 Subject: [PATCH] DNS test: also check a public nameserver to verify that the registrar (or up-host) configuration is correct too --- tests/dns.py | 96 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 58 insertions(+), 38 deletions(-) diff --git a/tests/dns.py b/tests/dns.py index 7a9b0b4..524913c 100755 --- a/tests/dns.py +++ b/tests/dns.py @@ -1,7 +1,11 @@ #!/usr/bin/python3 -# Test DNS configuration. +# +# Tests the DNS configuration of a Mail-in-a-Box. # # 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 @@ -11,48 +15,64 @@ if len(sys.argv) < 3: 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 subs = { "ipaddr": ipaddr, "hostname": hostname } expected = """ -{hostname}. 86400 IN A {ipaddr} -{hostname}. 86400 IN NS ns1.{hostname}. -{hostname}. 86400 IN NS ns2.{hostname}. -ns1.{hostname}. 86400 IN A {ipaddr} -ns2.{hostname}. 86400 IN A {ipaddr} -www.{hostname}. 86400 IN A {ipaddr} -{hostname}. 86400 IN MX 10 {hostname}. -{hostname}. 300 IN TXT "v=spf1 mx -all" -mail._domainkey.{hostname}. 86400 IN TXT "v=DKIM1\; k=rsa\; s=email\; " "p=__KEY__" +{hostname}. ##### IN A {ipaddr} +{hostname}. ##### IN NS ns1.{hostname}. +{hostname}. ##### IN NS ns2.{hostname}. +ns1.{hostname}. ##### IN A {ipaddr} +ns2.{hostname}. ##### IN A {ipaddr} +www.{hostname}. ##### IN A {ipaddr} +{hostname}. ##### IN MX 10 {hostname}. +{hostname}. ##### IN TXT "v=spf1 mx -all" +mail._domainkey.{hostname}. ##### IN TXT "v=DKIM1\; k=rsa\; s=email\; " "p=__KEY__" """.format(**subs).strip() + "\n" -# 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='output from dig'): - sys.stdout.write(line) - has_diff = True +def dig(server, digargs): + # run dig and clean the output + response = subprocess.check_output(['dig', '@' + server, "+noadditional", "+noauthority"] + digargs).decode('utf8') + response = re.sub('[\r\n]+', '\n', response) # remove blank lines + response = re.sub('\n;.*', '', response) # remove comments + 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: - print("DNS is OK.") - sys.exit(0) +def test(server, description): + # call dig a few times with different parameters + 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)