From 9f87b36ba182e5ec6e519a4a6c27e9ead8c08469 Mon Sep 17 00:00:00 2001 From: KiekerJan Date: Sun, 22 Dec 2024 13:45:45 +0100 Subject: [PATCH] add check on SOA record to determine up to date synchronization of secondary nameserver (#2429) --- management/status_checks.py | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/management/status_checks.py b/management/status_checks.py index 51f8e631..96d10c95 100755 --- a/management/status_checks.py +++ b/management/status_checks.py @@ -521,6 +521,8 @@ def check_dns_zone(domain, env, output, dns_zonefiles): # Check that each custom secondary nameserver resolves the IP address. if custom_secondary_ns and not probably_external_dns: + SOARecord = query_dns(domain, "SOA", at=env['PUBLIC_IP'])# Explicitly ask the local dns server. + for ns in custom_secondary_ns: # We must first resolve the nameserver to an IP address so we can query it. ns_ips = query_dns(ns, "A") @@ -530,15 +532,36 @@ def check_dns_zone(domain, env, output, dns_zonefiles): # Choose the first IP if nameserver returns multiple ns_ip = ns_ips.split('; ')[0] + checkSOA = True + # Now query it to see what it says about this domain. ip = query_dns(domain, "A", at=ns_ip, nxdomain=None) if ip == correct_ip: - output.print_ok("Secondary nameserver %s resolved the domain correctly." % ns) + output.print_ok(f"Secondary nameserver {ns} resolved the domain correctly.") elif ip is None: - output.print_error("Secondary nameserver %s is not configured to resolve this domain." % ns) + output.print_error(f"Secondary nameserver {ns} is not configured to resolve this domain.") + # No need to check SOA record if not configured as nameserver + checkSOA = False + elif ip == '[timeout]': + output.print_error(f"Secondary nameserver {ns} did not resolve this domain, result: {ip}") + checkSOA = False else: output.print_error(f"Secondary nameserver {ns} is not configured correctly. (It resolved this domain as {ip}. It should be {correct_ip}.)") + if checkSOA: + # Check that secondary DNS server is synchronized with our primary DNS server. Simplified by checking the SOA record which has a version number + SOASecondary = query_dns(domain, "SOA", at=ns_ip) + + if SOARecord == SOASecondary: + output.print_ok(f"Secondary nameserver {ns} has consistent SOA record.") + elif SOARecord == '[Not Set]': + output.print_error(f"Secondary nameserver {ns} has no SOA record configured.") + elif SOARecord == '[timeout]': + output.print_error(f"Secondary nameserver {ns} timed out on checking SOA record.") + else: + output.print_error(f"""Secondary nameserver {ns} has inconsistent SOA record (primary: {SOARecord} versus secondary: {SOASecondary}). + Check that synchronization between secondary and primary DNS servers is properly set-up.""") + def check_dns_zone_suggestions(domain, env, output, dns_zonefiles, domains_with_a_records): # Warn if a custom DNS record is preventing this or the automatic www redirect from # being served.