dont serve web for domains with custom DNS records that point A/AAAA elsewhere, and in whats_next only check that an A record exists on a domain if we are serving web on the domain

This commit is contained in:
Joshua Tauberer 2014-07-20 15:15:33 +00:00
parent 8354d9732a
commit 8042ab66ac
3 changed files with 45 additions and 26 deletions

View File

@ -48,6 +48,11 @@ def get_dns_zones(env):
return zonefiles
def get_custom_dns_config(env):
try:
return rtyaml.load(open(os.path.join(env['STORAGE_ROOT'], 'dns/custom.yaml')))
except:
return { }
def do_dns_update(env):
# What domains (and their zone filenames) should we build?
@ -55,10 +60,7 @@ def do_dns_update(env):
zonefiles = get_dns_zones(env)
# Custom records to add to zones.
try:
additional_records = rtyaml.load(open(os.path.join(env['STORAGE_ROOT'], 'dns/custom.yaml')))
except:
additional_records = { }
additional_records = get_custom_dns_config(env)
# Write zone files.
os.makedirs('/etc/nsd/zones', exist_ok=True)

View File

@ -5,17 +5,32 @@
import os, os.path, re, rtyaml
from mailconfig import get_mail_domains
from dns_update import get_custom_dns_config
from utils import shell, safe_domain_name, sort_domains
def get_web_domains(env):
# What domains should we serve HTTP/HTTPS for?
# What domains should we serve websites for?
domains = set()
# Add all domain names in use by email users and mail aliases.
# At the least it's the PRIMARY_HOSTNAME so we can serve webmail
# as well as Z-Push for Exchange ActiveSync.
domains.add(env['PRIMARY_HOSTNAME'])
# Also serve web for all mail domains so that we might at least
# provide Webfinger and ActiveSync auto-discover of email settings
# (though the latter isn't really working). These will require that
# an SSL cert be installed.
domains |= get_mail_domains(env)
# Ensure the PRIMARY_HOSTNAME is in the list.
domains.add(env['PRIMARY_HOSTNAME'])
# ...Unless the domain has an A/AAAA record that maps it to a different
# IP address than this box. Remove those domains from our list.
dns = get_custom_dns_config(env)
for domain, value in dns.items():
if domain not in domains: continue
if (isinstance(value, str) and (value != "local")) \
or (isinstance(value, dict) and ("A" in value) and (value["A"] != "local")) \
or (isinstance(value, dict) and ("AAAA" in value) and (value["AAAA"] != "local")):
domains.remove(domain)
# Sort the list. Put PRIMARY_HOSTNAME first so it becomes the
# default server (nginx's default_server).
@ -23,7 +38,6 @@ def get_web_domains(env):
return domains
def do_web_update(env):
# Build an nginx configuration file.
nginx_conf = ""

View File

@ -66,11 +66,8 @@ def run_domain_checks(env):
if domain in mail_domains:
check_mail_domain(domain, env)
if domain == env["PRIMARY_HOSTNAME"] or domain in web_domains:
# We need a SSL certificate for PRIMARY_HOSTNAME because that's where the
# user will log in with IMAP or webmail. Any other domain we serve a
# website for also needs a signed certificate.
check_ssl_cert(domain, env)
if domain in web_domains:
check_web_domain(domain, env)
print()
@ -128,18 +125,6 @@ def check_dns_zone(domain, env, dns_zonefiles):
control panel to set the nameservers to %s."""
% (existing_ns, correct_ns) )
# See if the domain's A record resolves to our PUBLIC_IP. This is already checked
# for PRIMARY_HOSTNAME, for which it is required. For other domains it is just nice
# to have if we want web.
if domain != env['PRIMARY_HOSTNAME']:
ip = query_dns(domain, "A")
if ip == env['PUBLIC_IP']:
print_ok("Domain resolves to this box's IP address. [%s => %s]" % (domain, env['PUBLIC_IP']))
else:
print_error("""This domain should resolve to your box's IP address (%s) if you would like the box to serve
webmail or a website on this domain. The domain currently resolves to %s in public DNS. It may take several hours for
public DNS to update after a change. This problem may result from other issues listed here.""" % (env['PUBLIC_IP'], ip))
# See if the domain has a DS record set.
ds = query_dns(domain, "DS", nxdomain=None)
ds_correct = open('/etc/nsd/zones/' + dns_zonefiles[domain] + '.ds').read().strip()
@ -198,6 +183,24 @@ def check_mail_domain(domain, env):
# Check that the postmaster@ email address exists.
check_alias_exists("postmaster@" + domain, env)
def check_web_domain(domain, env):
# See if the domain's A record resolves to our PUBLIC_IP. This is already checked
# for PRIMARY_HOSTNAME, for which it is required for mail specifically. For it and
# other domains, it is required to access its website.
if domain != env['PRIMARY_HOSTNAME']:
ip = query_dns(domain, "A")
if ip == env['PUBLIC_IP']:
print_ok("Domain resolves to this box's IP address. [%s => %s]" % (domain, env['PUBLIC_IP']))
else:
print_error("""This domain should resolve to your box's IP address (%s) if you would like the box to serve
webmail or a website on this domain. The domain currently resolves to %s in public DNS. It may take several hours for
public DNS to update after a change. This problem may result from other issues listed here.""" % (env['PUBLIC_IP'], ip))
# We need a SSL certificate for PRIMARY_HOSTNAME because that's where the
# user will log in with IMAP or webmail. Any other domain we serve a
# website for also needs a signed certificate.
check_ssl_cert(domain, env)
def query_dns(qname, rtype, nxdomain='[Not Set]'):
resolver = dns.resolver.get_default_resolver()
try: