dont create a separate zone for PUBLIC_HOSTNAME if it is a subdomain of another zone (hmm, this is a general principle that could apply to any two domains the box is serving)

This commit is contained in:
Joshua Tauberer 2014-06-17 23:30:00 +00:00
parent 33f06f29c1
commit 14396e58f8
1 changed files with 31 additions and 8 deletions

View File

@ -12,12 +12,21 @@ def get_dns_domains(env):
# What domains should we serve DNS for?
domains = set()
# Ensure the PUBLIC_HOSTNAME is in that list.
domains.add(env['PUBLIC_HOSTNAME'])
# Add all domain names in use by email users and mail aliases.
domains |= get_mail_domains(env)
# Ensure the PUBLIC_HOSTNAME is in that list if it is not a subdomain of
# any other domain we manage. If it's a subdomain, having it be a separate
# zone will confuse DNSSEC because it will be signed without having a DS
# record at the parent.
for d in domains:
if env['PUBLIC_HOSTNAME'].endswith("." + d):
break
else:
# No 'break' was executed, so it is not a subdomain of a domain
# we know about. Thus add it.
domains.add(env['PUBLIC_HOSTNAME'])
# Make a nice and safe filename for each domain.
zonefiles = []
for domain in domains:
@ -92,13 +101,27 @@ def do_dns_update(env):
########################################################################
def build_zone(domain, zonefile, env):
def build_zone(domain, zonefile, env, with_ns=True):
records = []
records.append((None, "NS", "ns1.%s." % env["PUBLIC_HOSTNAME"]))
records.append((None, "NS", "ns2.%s." % env["PUBLIC_HOSTNAME"]))
# For top-level zones, define ourselves as the authoritative name server.
if with_ns:
records.append((None, "NS", "ns1.%s." % env["PUBLIC_HOSTNAME"]))
records.append((None, "NS", "ns2.%s." % env["PUBLIC_HOSTNAME"]))
records.append((None, "MX", "10 %s." % env["PUBLIC_HOSTNAME"]))
records.append((None, "TXT", '"v=spf1 mx -all"'))
# If PUBLIC_HOSTNAME is a subdomain of this domain, define it here.
if env['PUBLIC_HOSTNAME'].endswith("." + domain):
ph = env['PUBLIC_HOSTNAME'][0:-len("." + domain)]
for child_qname, child_rtype, child_value in build_zone(env['PUBLIC_HOSTNAME'], None, env, with_ns=False):
if child_qname == None:
child_qname = ph
else:
child_qname += "." + ph
records.append((child_qname, child_rtype, child_value))
# In PUBLIC_HOSTNAME, also define ns1 and ns2.
if domain == env["PUBLIC_HOSTNAME"]:
records.append(("ns1", "A", env["PUBLIC_IP"]))
@ -111,8 +134,8 @@ def build_zone(domain, zonefile, env):
return False
# The user may set other records that don't conflict with our settings.
custom_zone_file = os.path.join(env['STORAGE_ROOT'], 'dns/custom', zonefile.replace(".txt", ".yaml"))
if os.path.exists(custom_zone_file):
custom_zone_file = os.path.join(env['STORAGE_ROOT'], 'dns/custom', zonefile.replace(".txt", ".yaml")) if zonefile else None
if zonefile and os.path.exists(custom_zone_file):
custom_zone = rtyaml.load(open(custom_zone_file))
for qname, value in custom_zone.items():
if has_rec(qname, value): continue