From 7fa4862f1a125702947ae7ac64efea2946e8ec61 Mon Sep 17 00:00:00 2001 From: Joshua Tauberer Date: Wed, 4 Jun 2014 19:00:31 -0400 Subject: [PATCH] refactor dns_update so that the zone is first generated in a file-format agnostic way --- management/dns_update.py | 72 ++++++++++++++++++++++------------------ 1 file changed, 40 insertions(+), 32 deletions(-) diff --git a/management/dns_update.py b/management/dns_update.py index b7000a5c..63a06f34 100755 --- a/management/dns_update.py +++ b/management/dns_update.py @@ -25,7 +25,8 @@ def do_dns_update(env): os.makedirs('/etc/nsd/zones', exist_ok=True) updated_domains = [] for domain, zonefile in zonefiles: - if write_nsd_zone(domain, "/etc/nsd/zones/" + zonefile, env): + records = build_zone(domain, env) + if write_nsd_zone(domain, "/etc/nsd/zones/" + zonefile, records, env): updated_domains.append(domain) # Write the main nsd.conf file. @@ -45,7 +46,37 @@ def do_dns_update(env): ######################################################################## -def write_nsd_zone(domain, zonefile, env): +def build_zone(domain, env): + records = [] + records.append((None, "NS", "ns1.%s." % env["PUBLIC_HOSTNAME"])) + records.append((None, "NS", "ns2.%s." % env["PUBLIC_HOSTNAME"])) + records.append((None, "A", env["PUBLIC_IP"])) + records.append((None, "MX", "10 %s." % env["PUBLIC_HOSTNAME"])) + records.append((None, "TXT", '"v=spf1 mx -all"')) + records.append(("www", "A", env["PUBLIC_IP"])) + + # In PUBLIC_HOSTNAME, also define ns1 and ns2. + if domain == env["PUBLIC_HOSTNAME"]: + records.append(("ns1", "A", env["PUBLIC_IP"])) + records.append(("ns2", "A", env["PUBLIC_IP"])) + + # If OpenDKIM is in use.. + opendkim_record_file = os.path.join(env['STORAGE_ROOT'], 'mail/dkim/mail.txt') + if os.path.exists(opendkim_record_file): + # Append the DKIM TXT record to the zone as generated by OpenDKIM, after string formatting above. + with open(opendkim_record_file) as orf: + m = re.match(r"(\S+)\s+IN\s+TXT\s+(\(.*\))\s*;", orf.read(), re.S) + records.append((m.group(1), "TXT", m.group(2))) + + # Append ADSP (RFC 5617) and DMARC records. + records.append(("_adsp._domainkey", "TXT", '"dkim=all"')) + records.append(("_dmarc", "TXT", '"v=DMARC1; p=quarantine"')) + + return records + +######################################################################## + +def write_nsd_zone(domain, zonefile, records, env): # We set the administrative email address for every domain to domain_contact@[domain.com]. # You should probably create an alias to your email address. @@ -60,39 +91,17 @@ $TTL 86400 ; default time to live 864000 ; Expire 86400 ; Min TTL ) - - NS ns1.{primary_domain}. - NS ns2.{primary_domain}. - IN A {ip} - MX 10 {primary_domain}. - - 300 TXT "v=spf1 mx -all" - -www IN A {ip} -""" - - # In PUBLIC_HOSTNAME, also define ns1 and ns2. - if domain == env["PUBLIC_HOSTNAME"]: - zone += """ -ns1 IN A {ip} -ns2 IN A {ip} """ # Replace replacement strings. - zone = zone.format(domain=domain, primary_domain=env["PUBLIC_HOSTNAME"], ip=env["PUBLIC_IP"]) + zone = zone.format(domain=domain, primary_domain=env["PUBLIC_HOSTNAME"]) - # If OpenDKIM is in use.. - opendkim_record_file = os.path.join(env['STORAGE_ROOT'], 'mail/dkim/mail.txt') - if os.path.exists(opendkim_record_file): - # Append the DKIM TXT record to the zone as generated by OpenDKIM, after string formatting above. - with open(opendkim_record_file) as orf: - zone += orf.read() - - # Append ADSP (RFC 5617) and DMARC records. - zone += """ -_adsp._domainkey IN TXT "dkim=all" -_dmarc IN TXT "v=DMARC1; p=quarantine" -""" + # Add records. + for subdomain, querytype, value in records: + if subdomain: + zone += subdomain + zone += "\tIN\t" + querytype + "\t" + zone += value + "\n" # Set the serial number. serial = time.strftime("%Y%m%d00") @@ -177,4 +186,3 @@ def write_opendkim_tables(zonefiles, env): for domain, zonefile in zonefiles )) -