run management/dns_update.py from the console to dump the DNS records, with explanations, in case the user wants to host DNS off of the box
This commit is contained in:
parent
7803ac9ca4
commit
d7a9e7cc17
|
@ -1,3 +1,5 @@
|
||||||
|
#!/usr/bin/python3
|
||||||
|
|
||||||
# Creates DNS zone files for all of the domains of all of the mail users
|
# Creates DNS zone files for all of the domains of all of the mail users
|
||||||
# and mail aliases and restarts nsd.
|
# and mail aliases and restarts nsd.
|
||||||
########################################################################
|
########################################################################
|
||||||
|
@ -63,8 +65,7 @@ def do_dns_update(env):
|
||||||
updated_domains = []
|
updated_domains = []
|
||||||
for i, (domain, zonefile) in enumerate(zonefiles):
|
for i, (domain, zonefile) in enumerate(zonefiles):
|
||||||
# Build the records to put in the zone.
|
# Build the records to put in the zone.
|
||||||
subdomains = [d for d in domains if d.endswith("." + domain)]
|
records = build_zone(domain, domains, additional_records, env)
|
||||||
records = build_zone(domain, subdomains, additional_records, env)
|
|
||||||
|
|
||||||
# See if the zone has changed, and if so update the serial number
|
# See if the zone has changed, and if so update the serial number
|
||||||
# and write the zone file.
|
# and write the zone file.
|
||||||
|
@ -125,7 +126,7 @@ def do_dns_update(env):
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
|
|
||||||
def build_zone(domain, subdomains, additional_records, env, with_ns=True):
|
def build_zone(domain, all_domains, additional_records, env, with_ns=True):
|
||||||
records = []
|
records = []
|
||||||
|
|
||||||
# For top-level zones, define ourselves as the authoritative name server.
|
# For top-level zones, define ourselves as the authoritative name server.
|
||||||
|
@ -135,6 +136,22 @@ def build_zone(domain, subdomains, additional_records, env, with_ns=True):
|
||||||
records.append((None, "NS", "ns1.%s." % env["PRIMARY_HOSTNAME"], False))
|
records.append((None, "NS", "ns1.%s." % env["PRIMARY_HOSTNAME"], False))
|
||||||
records.append((None, "NS", "ns2.%s." % env["PRIMARY_HOSTNAME"], False))
|
records.append((None, "NS", "ns2.%s." % env["PRIMARY_HOSTNAME"], False))
|
||||||
|
|
||||||
|
# In PRIMARY_HOSTNAME...
|
||||||
|
if domain == env["PRIMARY_HOSTNAME"]:
|
||||||
|
# Define ns1 and ns2.
|
||||||
|
# 'False' in the tuple indicates these records would not be used if the zone
|
||||||
|
# is managed outside of the box.
|
||||||
|
records.append(("ns1", "A", env["PUBLIC_IP"], False))
|
||||||
|
records.append(("ns2", "A", env["PUBLIC_IP"], False))
|
||||||
|
|
||||||
|
# Set the A/AAAA records. Do this early for the PRIMARY_HOSTNAME so that the user cannot override them
|
||||||
|
# and we can provide different explanatory text.
|
||||||
|
records.append((None, "A", env["PUBLIC_IP"], "Required. Sets the IP address of the box."))
|
||||||
|
if env.get("PUBLIC_IPV6"): records.append((None, "AAAA", env["PUBLIC_IPV6"], "Required. Sets the IPv6 address of the box."))
|
||||||
|
|
||||||
|
# Add a DANE TLSA record for SMTP.
|
||||||
|
records.append(("_25._tcp", "TLSA", build_tlsa_record(env), "Recommended when DNSSEC is enabled. Advertises to mail servers connecting to the box that mandatory encryption should be used."))
|
||||||
|
|
||||||
# The MX record says where email for the domain should be delivered: Here!
|
# The MX record says where email for the domain should be delivered: Here!
|
||||||
records.append((None, "MX", "10 %s." % env["PRIMARY_HOSTNAME"], "Required. Specifies the hostname of the machine that handles @%s mail." % domain))
|
records.append((None, "MX", "10 %s." % env["PRIMARY_HOSTNAME"], "Required. Specifies the hostname of the machine that handles @%s mail." % domain))
|
||||||
|
|
||||||
|
@ -142,8 +159,9 @@ def build_zone(domain, subdomains, additional_records, env, with_ns=True):
|
||||||
# the domain, and no one else.
|
# the domain, and no one else.
|
||||||
records.append((None, "TXT", '"v=spf1 mx -all"', "Recomended. Specifies that only the box is permitted to send @%s mail." % domain))
|
records.append((None, "TXT", '"v=spf1 mx -all"', "Recomended. Specifies that only the box is permitted to send @%s mail." % domain))
|
||||||
|
|
||||||
# If we need to define DNS for any subdomains of this domain, include it
|
# Add DNS records for any subdomains of this domain. We should not have a zone for
|
||||||
# in the zone.
|
# both a domain and one of its subdomains.
|
||||||
|
subdomains = [d for d in all_domains if d.endswith("." + domain)]
|
||||||
for subdomain in subdomains:
|
for subdomain in subdomains:
|
||||||
subdomain_qname = subdomain[0:-len("." + domain)]
|
subdomain_qname = subdomain[0:-len("." + domain)]
|
||||||
subzone = build_zone(subdomain, [], {}, env, with_ns=False)
|
subzone = build_zone(subdomain, [], {}, env, with_ns=False)
|
||||||
|
@ -154,17 +172,6 @@ def build_zone(domain, subdomains, additional_records, env, with_ns=True):
|
||||||
child_qname += "." + subdomain_qname
|
child_qname += "." + subdomain_qname
|
||||||
records.append((child_qname, child_rtype, child_value, child_explanation))
|
records.append((child_qname, child_rtype, child_value, child_explanation))
|
||||||
|
|
||||||
# In PRIMARY_HOSTNAME...
|
|
||||||
if domain == env["PRIMARY_HOSTNAME"]:
|
|
||||||
# Define ns1 and ns2.
|
|
||||||
# 'False' in the tuple indicates these records would not be used if the zone
|
|
||||||
# is managed outside of the box.
|
|
||||||
records.append(("ns1", "A", env["PUBLIC_IP"], False))
|
|
||||||
records.append(("ns2", "A", env["PUBLIC_IP"], False))
|
|
||||||
|
|
||||||
# Add a DANE TLSA record for SMTP.
|
|
||||||
records.append(("_25._tcp", "TLSA", build_tlsa_record(env), "Recommended when DNSSEC is enabled. Advertises to mail servers connecting to the box that mandatory encryption should be used."))
|
|
||||||
|
|
||||||
def has_rec(qname, rtype):
|
def has_rec(qname, rtype):
|
||||||
for rec in records:
|
for rec in records:
|
||||||
if rec[0] == qname and rec[1] == rtype:
|
if rec[0] == qname and rec[1] == rtype:
|
||||||
|
@ -531,3 +538,29 @@ def justtestingdotemail(domain, records):
|
||||||
"--data", "record=%s" % urllib.parse.quote(value),
|
"--data", "record=%s" % urllib.parse.quote(value),
|
||||||
]).decode("utf8"))
|
]).decode("utf8"))
|
||||||
print("\t...", resp.get("message", "?"))
|
print("\t...", resp.get("message", "?"))
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
from utils import load_environment
|
||||||
|
env = load_environment()
|
||||||
|
domains = get_dns_domains(env)
|
||||||
|
zonefiles = get_dns_zones(env)
|
||||||
|
for domain, zonefile in zonefiles:
|
||||||
|
records = build_zone(domain, domains, {}, env)
|
||||||
|
|
||||||
|
# remove records that we don't dislay
|
||||||
|
records = [r for r in records if r[3] is not False]
|
||||||
|
|
||||||
|
# put Required at the top
|
||||||
|
records.sort(key = lambda r : 0 if r[3].startswith("Required.") else (1 if r[3].startswith("Recommended.") else 2))
|
||||||
|
|
||||||
|
# print
|
||||||
|
for qname, rtype, value, explanation in records:
|
||||||
|
print("; " + explanation)
|
||||||
|
if qname == None:
|
||||||
|
qname = domain
|
||||||
|
else:
|
||||||
|
qname = qname + "." + domain
|
||||||
|
print(qname, rtype, value)
|
||||||
|
print()
|
||||||
|
|
Loading…
Reference in New Issue