def post_install_func(env, is_tlsa_update_required=False): ret = [] # Get the certificate to use for PRIMARY_HOSTNAME. ssl_certificates = get_ssl_certificates(env) cert = get_domain_ssl_files(env['PRIMARY_HOSTNAME'], ssl_certificates, env, use_main_cert=False) if not cert: # Ruh-row, we don't have any certificate usable # for the primary hostname. ret.append("there is no valid certificate for " + env['PRIMARY_HOSTNAME']) # Symlink the best cert for PRIMARY_HOSTNAME to the system # certificate path, which is hard-coded for various purposes, and then # restart postfix and dovecot. system_ssl_certificate = os.path.join( os.path.join(env["STORAGE_ROOT"], 'ssl', 'ssl_certificate.pem')) if cert and os.readlink(system_ssl_certificate) != cert['certificate']: # Update symlink. ret.append("updating primary certificate") ssl_certificate = cert['certificate'] os.unlink(system_ssl_certificate) os.symlink(ssl_certificate, system_ssl_certificate) # Restart postfix and dovecot so they pick up the new file. shell('check_call', ["/usr/sbin/service", "postfix", "restart"]) shell('check_call', ["/usr/sbin/service", "dovecot", "restart"]) ret.append("mail services restarted") # The DANE TLSA record will remain valid so long as the private key # hasn't changed. We don't ever change the private key automatically. # If the user does it, they must manually update DNS. if is_tlsa_update_required: from dns_update import do_dns_update, set_custom_dns_record, build_tlsa_record subprocess.check_output([ "mv", env["STORAGE_ROOT"] + "/ssl/next_ssl_private_key.pem", env["STORAGE_ROOT"] + "/ssl/ssl_private_key.pem" ]) subprocess.check_output([ "openssl", "genrsa", "-out", env["STORAGE_ROOT"] + "/ssl/next_ssl_private_key.pem", "2048" ]) qname1 = "_25._tcp." + env['PRIMARY_HOSTNAME'] qname2 = "_443._tcp." + env['PRIMARY_HOSTNAME'] rtype = "TLSA" value = build_tlsa_record(env, from_cert=False) action = "add" if set_custom_dns_record(qname1, rtype, value, action, env): set_custom_dns_record(qname2, rtype, value, action, env) ret.append(do_dns_update(env)) # Update the web configuration so nginx picks up the new certificate file. from web_update import do_web_update ret.append(do_web_update(env)) return ret
def check_primary_hostname_dns(domain, env, dns_domains, dns_zonefiles): # If a DS record is set on the zone containing this domain, check DNSSEC now. for zone in dns_domains: if zone == domain or domain.endswith("." + zone): if query_dns(zone, "DS", nxdomain=None) is not None: check_dnssec(zone, env, dns_zonefiles, is_checking_primary=True) # Check that the ns1/ns2 hostnames resolve to A records. This information probably # comes from the TLD since the information is set at the registrar as glue records. # We're probably not actually checking that here but instead checking that we, as # the nameserver, are reporting the right info --- but if the glue is incorrect this # will probably fail. ip = query_dns("ns1." + domain, "A") + '/' + query_dns("ns2." + domain, "A") if ip == env['PUBLIC_IP'] + '/' + env['PUBLIC_IP']: env['out'].print_ok("Nameserver glue records are correct at registrar. [ns1/ns2.%s => %s]" % (env['PRIMARY_HOSTNAME'], env['PUBLIC_IP'])) else: env['out'].print_error("""Nameserver glue records are incorrect. The ns1.%s and ns2.%s nameservers must be configured at your domain name registrar as having the IP address %s. They currently report addresses of %s. It may take several hours for public DNS to update after a change.""" % (env['PRIMARY_HOSTNAME'], env['PRIMARY_HOSTNAME'], env['PUBLIC_IP'], ip)) # Check that PRIMARY_HOSTNAME resolves to PUBLIC_IP in public DNS. ip = query_dns(domain, "A") if ip == env['PUBLIC_IP']: env['out'].print_ok("Domain resolves to box's IP address. [%s => %s]" % (env['PRIMARY_HOSTNAME'], env['PUBLIC_IP'])) else: env['out'].print_error("""This domain must resolve to your box's IP address (%s) in public DNS but it currently resolves to %s. 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)) # Check reverse DNS on the PRIMARY_HOSTNAME. Note that it might not be # a DNS zone if it is a subdomain of another domain we have a zone for. ipaddr_rev = dns.reversename.from_address(env['PUBLIC_IP']) existing_rdns = query_dns(ipaddr_rev, "PTR") if existing_rdns == domain: env['out'].print_ok("Reverse DNS is set correctly at ISP. [%s => %s]" % (env['PUBLIC_IP'], env['PRIMARY_HOSTNAME'])) else: env['out'].print_error("""Your box's reverse DNS is currently %s, but it should be %s. Your ISP or cloud provider will have instructions on setting up reverse DNS for your box at %s.""" % (existing_rdns, domain, env['PUBLIC_IP']) ) # Check the TLSA record. tlsa_qname = "_25._tcp." + domain tlsa25 = query_dns(tlsa_qname, "TLSA", nxdomain=None) tlsa25_expected = build_tlsa_record(env) if tlsa25 == tlsa25_expected: env['out'].print_ok("""The DANE TLSA record for incoming mail is correct (%s).""" % tlsa_qname,) elif tlsa25 is None: env['out'].print_error("""The DANE TLSA record for incoming mail is not set. This is optional.""") else: env['out'].print_error("""The DANE TLSA record for incoming mail (%s) is not correct. It is '%s' but it should be '%s'. Try running tools/dns_update to regenerate the record. It may take several hours for public DNS to update after a change.""" % (tlsa_qname, tlsa25, tlsa25_expected)) # Check that the hostmaster@ email address exists. check_alias_exists("hostmaster@" + domain, env)
def check_primary_hostname_dns(domain, env, dns_domains, dns_zonefiles): # If a DS record is set on the zone containing this domain, check DNSSEC now. for zone in dns_domains: if zone == domain or domain.endswith("." + zone): if query_dns(zone, "DS", nxdomain=None) is not None: check_dnssec(zone, env, dns_zonefiles, is_checking_primary=True) # Check that the ns1/ns2 hostnames resolve to A records. This information probably # comes from the TLD since the information is set at the registrar as glue records. # We're probably not actually checking that here but instead checking that we, as # the nameserver, are reporting the right info --- but if the glue is incorrect this # will probably fail. ip = query_dns("ns1." + domain, "A") + '/' + query_dns("ns2." + domain, "A") if ip == env['PUBLIC_IP'] + '/' + env['PUBLIC_IP']: env['out'].print_ok("Nameserver glue records are correct at registrar. [ns1/ns2.%s => %s]" % (env['PRIMARY_HOSTNAME'], env['PUBLIC_IP'])) else: env['out'].print_error("""Nameserver glue records are incorrect. The ns1.%s and ns2.%s nameservers must be configured at your domain name registrar as having the IP address %s. They currently report addresses of %s. It may take several hours for public DNS to update after a change.""" % (env['PRIMARY_HOSTNAME'], env['PRIMARY_HOSTNAME'], env['PUBLIC_IP'], ip)) # Check that PRIMARY_HOSTNAME resolves to PUBLIC_IP in public DNS. ip = query_dns(domain, "A") if ip == env['PUBLIC_IP']: env['out'].print_ok("Domain resolves to box's IP address. [%s => %s]" % (env['PRIMARY_HOSTNAME'], env['PUBLIC_IP'])) else: env['out'].print_error("""This domain must resolve to your box's IP address (%s) in public DNS but it currently resolves to %s. 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)) # Check reverse DNS on the PRIMARY_HOSTNAME. Note that it might not be # a DNS zone if it is a subdomain of another domain we have a zone for. ipaddr_rev = dns.reversename.from_address(env['PUBLIC_IP']) existing_rdns = query_dns(ipaddr_rev, "PTR") if existing_rdns == domain: env['out'].print_ok("Reverse DNS is set correctly at ISP. [%s => %s]" % (env['PUBLIC_IP'], env['PRIMARY_HOSTNAME'])) else: env['out'].print_error("""Your box's reverse DNS is currently %s, but it should be %s. Your ISP or cloud provider will have instructions on setting up reverse DNS for your box at %s.""" % (existing_rdns, domain, env['PUBLIC_IP']) ) # Check the TLSA record. tlsa_qname = "_25._tcp." + domain tlsa25 = query_dns(tlsa_qname, "TLSA", nxdomain=None) tlsa25_expected = build_tlsa_record(env) if tlsa25 == tlsa25_expected: env['out'].print_ok("""The DANE TLSA record for incoming mail is correct (%s).""" % tlsa_qname,) elif tlsa25 is None: env['out'].print_error("""The DANE TLSA record for incoming mail is not set. This is optional.""") else: env['out'].print_error("""The DANE TLSA record for incoming mail (%s) is not correct. It is '%s' but it should be '%s'. It may take several hours for public DNS to update after a change.""" % (tlsa_qname, tlsa25, tlsa25_expected)) # Check that the hostmaster@ email address exists. check_alias_exists("hostmaster@" + domain, env)
def check_primary_hostname_dns(domain, env, output, dns_domains, dns_zonefiles): # If a DS record is set on the zone containing this domain, check DNSSEC now. has_dnssec = False for zone in dns_domains: if zone == domain or domain.endswith("." + zone): if query_dns(zone, "DS", nxdomain=None) is not None: has_dnssec = True check_dnssec(zone, env, output, dns_zonefiles, is_checking_primary=True) ip = query_dns(domain, "A") my_ips = env['PUBLIC_IP'] + ((" / "+env['PUBLIC_IPV6']) if env.get("PUBLIC_IPV6") else "") # Check that PRIMARY_HOSTNAME resolves to PUBLIC_IP[V6] in public DNS. ipv6 = query_dns(domain, "AAAA") if env.get("PUBLIC_IPV6") else None if ip == env['PUBLIC_IP'] and not (ipv6 and env['PUBLIC_IPV6'] and ipv6 != normalize_ip(env['PUBLIC_IPV6'])): output.print_ok("Domain resolves to box's IP address. [%s ↦ %s]" % (env['PRIMARY_HOSTNAME'], my_ips)) else: output.print_error("""This domain must resolve to your box's IP address (%s) in public DNS but it currently resolves to %s. It may take several hours for public DNS to update after a change. This problem may result from other issues listed above.""" % (my_ips, ip + ((" / " + ipv6) if ipv6 is not None else ""))) # Check reverse DNS matches the PRIMARY_HOSTNAME. Note that it might not be # a DNS zone if it is a subdomain of another domain we have a zone for. existing_rdns_v4 = query_dns(dns.reversename.from_address(env['PUBLIC_IP']), "PTR") existing_rdns_v6 = query_dns(dns.reversename.from_address(env['PUBLIC_IPV6']), "PTR") if env.get("PUBLIC_IPV6") else None if existing_rdns_v4 == domain and existing_rdns_v6 in (None, domain): output.print_ok("Reverse DNS is set correctly at ISP. [%s ↦ %s]" % (my_ips, env['PRIMARY_HOSTNAME'])) elif existing_rdns_v4 == existing_rdns_v6 or existing_rdns_v6 is None: output.print_error("""Your box's reverse DNS is currently %s, but it should be %s. Your ISP or cloud provider will have instructions on setting up reverse DNS for your box.""" % (existing_rdns_v4, domain) ) else: output.print_error("""Your box's reverse DNS is currently %s (IPv4) and %s (IPv6), but it should be %s. Your ISP or cloud provider will have instructions on setting up reverse DNS for your box.""" % (existing_rdns_v4, existing_rdns_v6, domain) ) # Check the TLSA record. tlsa_qname = "_25._tcp." + domain tlsa25 = query_dns(tlsa_qname, "TLSA", nxdomain=None) tlsa25_expected = build_tlsa_record(env) if tlsa25 == tlsa25_expected: output.print_ok("""The DANE TLSA record for incoming mail is correct (%s).""" % tlsa_qname,) elif tlsa25 is None: if has_dnssec: # Omit a warning about it not being set if DNSSEC isn't enabled, # since TLSA shouldn't be used without DNSSEC. output.print_warning("""The DANE TLSA record for incoming mail is not set. This is optional.""") else: output.print_error("""The DANE TLSA record for incoming mail (%s) is not correct. It is '%s' but it should be '%s'. It may take several hours for public DNS to update after a change.""" % (tlsa_qname, tlsa25, tlsa25_expected)) # Check that the hostmaster@ email address exists. check_alias_exists("Hostmaster contact address", "hostmaster@" + domain, env, output)
def check_primary_hostname_dns(domain, env, output, dns_domains, dns_zonefiles): # If a DS record is set on the zone containing this domain, check DNSSEC now. has_dnssec = False for zone in dns_domains: if zone == domain or domain.endswith("." + zone): if query_dns(zone, "DS", nxdomain=None) is not None: has_dnssec = True check_dnssec(zone, env, output, dns_zonefiles, is_checking_primary=True) ip = query_dns(domain, "A") ns_ips = query_dns("ns1." + domain, "A") + '/' + query_dns("ns2." + domain, "A") my_ips = env['PUBLIC_IP'] + ((" / "+env['PUBLIC_IPV6']) if env.get("PUBLIC_IPV6") else "") # Check that the ns1/ns2 hostnames resolve to A records. This information probably # comes from the TLD since the information is set at the registrar as glue records. # We're probably not actually checking that here but instead checking that we, as # the nameserver, are reporting the right info --- but if the glue is incorrect this # will probably fail. if ns_ips == env['PUBLIC_IP'] + '/' + env['PUBLIC_IP']: output.print_ok("Nameserver glue records are correct at registrar. [ns1/ns2.%s ↦ %s]" % (env['PRIMARY_HOSTNAME'], env['PUBLIC_IP'])) elif ip == env['PUBLIC_IP']: # The NS records are not what we expect, but the domain resolves correctly, so # the user may have set up external DNS. List this discrepancy as a warning. output.print_warning("""Nameserver glue records (ns1.%s and ns2.%s) should be configured at your domain name registrar as having the IP address of this box (%s). They currently report addresses of %s. If you have set up External DNS, this may be OK.""" % (env['PRIMARY_HOSTNAME'], env['PRIMARY_HOSTNAME'], env['PUBLIC_IP'], ns_ips)) else: output.print_error("""Nameserver glue records are incorrect. The ns1.%s and ns2.%s nameservers must be configured at your domain name registrar as having the IP address %s. They currently report addresses of %s. It may take several hours for public DNS to update after a change.""" % (env['PRIMARY_HOSTNAME'], env['PRIMARY_HOSTNAME'], env['PUBLIC_IP'], ns_ips)) # Check that PRIMARY_HOSTNAME resolves to PUBLIC_IP[V6] in public DNS. ipv6 = query_dns(domain, "AAAA") if env.get("PUBLIC_IPV6") else None if ip == env['PUBLIC_IP'] and ipv6 in (None, env['PUBLIC_IPV6']): output.print_ok("Domain resolves to box's IP address. [%s ↦ %s]" % (env['PRIMARY_HOSTNAME'], my_ips)) else: output.print_error("""This domain must resolve to your box's IP address (%s) in public DNS but it currently resolves to %s. It may take several hours for public DNS to update after a change. This problem may result from other issues listed above.""" % (my_ips, ip + ((" / " + ipv6) if ipv6 is not None else ""))) # Check reverse DNS matches the PRIMARY_HOSTNAME. Note that it might not be # a DNS zone if it is a subdomain of another domain we have a zone for. existing_rdns_v4 = query_dns(dns.reversename.from_address(env['PUBLIC_IP']), "PTR") existing_rdns_v6 = query_dns(dns.reversename.from_address(env['PUBLIC_IPV6']), "PTR") if env.get("PUBLIC_IPV6") else None if existing_rdns_v4 == domain and existing_rdns_v6 in (None, domain): output.print_ok("Reverse DNS is set correctly at ISP. [%s ↦ %s]" % (my_ips, env['PRIMARY_HOSTNAME'])) elif existing_rdns_v4 == existing_rdns_v6 or existing_rdns_v6 is None: output.print_error("""Your box's reverse DNS is currently %s, but it should be %s. Your ISP or cloud provider will have instructions on setting up reverse DNS for your box.""" % (existing_rdns_v4, domain) ) else: output.print_error("""Your box's reverse DNS is currently %s (IPv4) and %s (IPv6), but it should be %s. Your ISP or cloud provider will have instructions on setting up reverse DNS for your box.""" % (existing_rdns_v4, existing_rdns_v6, domain) ) # Check the TLSA record. tlsa_qname = "_25._tcp." + domain tlsa25 = query_dns(tlsa_qname, "TLSA", nxdomain=None) tlsa25_expected = build_tlsa_record(env) if tlsa25 == tlsa25_expected: output.print_ok("""The DANE TLSA record for incoming mail is correct (%s).""" % tlsa_qname,) elif tlsa25 is None: if has_dnssec: # Omit a warning about it not being set if DNSSEC isn't enabled, # since TLSA shouldn't be used without DNSSEC. output.print_warning("""The DANE TLSA record for incoming mail is not set. This is optional.""") else: output.print_error("""The DANE TLSA record for incoming mail (%s) is not correct. It is '%s' but it should be '%s'. It may take several hours for public DNS to update after a change.""" % (tlsa_qname, tlsa25, tlsa25_expected)) # Check that the hostmaster@ email address exists. check_alias_exists("Hostmaster contact address", "hostmaster@" + domain, env, output)
def check_primary_hostname_dns(domain, env, output, dns_domains, dns_zonefiles): # If a DS record is set on the zone containing this domain, check DNSSEC now. has_dnssec = False for zone in dns_domains: if zone == domain or domain.endswith("." + zone): if query_dns(zone, "DS", nxdomain=None) is not None: has_dnssec = True check_dnssec(zone, env, output, dns_zonefiles, is_checking_primary=True) ip = query_dns(domain, "A") ns_ips = query_dns("ns1." + domain, "A") + '/' + query_dns("ns2." + domain, "A") my_ips = env['PUBLIC_IP'] + ((" / "+env['PUBLIC_IPV6']) if env.get("PUBLIC_IPV6") else "") # Check that the ns1/ns2 hostnames resolve to A records. This information probably # comes from the TLD since the information is set at the registrar as glue records. # We're probably not actually checking that here but instead checking that we, as # the nameserver, are reporting the right info --- but if the glue is incorrect this # will probably fail. if ns_ips == env['PUBLIC_IP'] + '/' + env['PUBLIC_IP']: output.print_ok("Nameserver glue records are correct at registrar. [ns1/ns2.%s ↦ %s]" % (env['PRIMARY_HOSTNAME'], env['PUBLIC_IP'])) elif ip == env['PUBLIC_IP']: # The NS records are not what we expect, but the domain resolves correctly, so # the user may have set up external DNS. List this discrepancy as a warning. output.print_warning("""Nameserver glue records (ns1.%s and ns2.%s) should be configured at your domain name registrar as having the IP address of this box (%s). They currently report addresses of %s. If you have set up External DNS, this may be OK.""" % (env['PRIMARY_HOSTNAME'], env['PRIMARY_HOSTNAME'], env['PUBLIC_IP'], ns_ips)) else: output.print_error("""Nameserver glue records are incorrect. The ns1.%s and ns2.%s nameservers must be configured at your domain name registrar as having the IP address %s. They currently report addresses of %s. It may take several hours for public DNS to update after a change.""" % (env['PRIMARY_HOSTNAME'], env['PRIMARY_HOSTNAME'], env['PUBLIC_IP'], ns_ips)) # Check that PRIMARY_HOSTNAME resolves to PUBLIC_IP[V6] in public DNS. ipv6 = query_dns(domain, "AAAA") if env.get("PUBLIC_IPV6") else None if ip == env['PUBLIC_IP'] and not (ipv6 and env['PUBLIC_IPV6'] and normalize_ip(ipv6) != normalize_ip(env['PUBLIC_IPV6'])): output.print_ok("Domain resolves to box's IP address. [%s ↦ %s]" % (env['PRIMARY_HOSTNAME'], my_ips)) else: output.print_error("""This domain must resolve to your box's IP address (%s) in public DNS but it currently resolves to %s. It may take several hours for public DNS to update after a change. This problem may result from other issues listed above.""" % (my_ips, ip + ((" / " + ipv6) if ipv6 is not None else ""))) # Check reverse DNS matches the PRIMARY_HOSTNAME. Note that it might not be # a DNS zone if it is a subdomain of another domain we have a zone for. existing_rdns_v4 = query_dns(dns.reversename.from_address(env['PUBLIC_IP']), "PTR") existing_rdns_v6 = query_dns(dns.reversename.from_address(env['PUBLIC_IPV6']), "PTR") if env.get("PUBLIC_IPV6") else None if existing_rdns_v4 == domain and existing_rdns_v6 in (None, domain): output.print_ok("Reverse DNS is set correctly at ISP. [%s ↦ %s]" % (my_ips, env['PRIMARY_HOSTNAME'])) elif existing_rdns_v4 == existing_rdns_v6 or existing_rdns_v6 is None: output.print_error("""Your box's reverse DNS is currently %s, but it should be %s. Your ISP or cloud provider will have instructions on setting up reverse DNS for your box.""" % (existing_rdns_v4, domain) ) else: output.print_error("""Your box's reverse DNS is currently %s (IPv4) and %s (IPv6), but it should be %s. Your ISP or cloud provider will have instructions on setting up reverse DNS for your box.""" % (existing_rdns_v4, existing_rdns_v6, domain) ) # Check the TLSA record. tlsa_qname = "_25._tcp." + domain tlsa25 = query_dns(tlsa_qname, "TLSA", nxdomain=None) tlsa25_expected = build_tlsa_record(env) if tlsa25 == tlsa25_expected: output.print_ok("""The DANE TLSA record for incoming mail is correct (%s).""" % tlsa_qname,) elif tlsa25 is None: if has_dnssec: # Omit a warning about it not being set if DNSSEC isn't enabled, # since TLSA shouldn't be used without DNSSEC. output.print_warning("""The DANE TLSA record for incoming mail is not set. This is optional.""") else: output.print_error("""The DANE TLSA record for incoming mail (%s) is not correct. It is '%s' but it should be '%s'. It may take several hours for public DNS to update after a change.""" % (tlsa_qname, tlsa25, tlsa25_expected)) # Check that the hostmaster@ email address exists. check_alias_exists("Hostmaster contact address", "hostmaster@" + domain, env, output)
def check_primary_hostname_dns(domain, env): # Check that the ns1/ns2 hostnames resolve to A records. This information probably # comes from the TLD since the information is set at the registrar. ip = query_dns("ns1." + domain, "A") + '/' + query_dns( "ns2." + domain, "A") if ip == env['PUBLIC_IP'] + '/' + env['PUBLIC_IP']: print_ok( "Nameserver IPs are correct at registrar. [ns1/ns2.%s => %s]" % (env['PRIMARY_HOSTNAME'], env['PUBLIC_IP'])) else: print_error( """Nameserver IP addresses are incorrect. The ns1.%s and ns2.%s nameservers must be configured at your domain name registrar as having the IP address %s. They currently report addresses of %s. It may take several hours for public DNS to update after a change.""" % (env['PRIMARY_HOSTNAME'], env['PRIMARY_HOSTNAME'], env['PUBLIC_IP'], ip)) # Check that PRIMARY_HOSTNAME resolves to PUBLIC_IP in public DNS. ip = query_dns(domain, "A") if ip == env['PUBLIC_IP']: print_ok("Domain resolves to box's IP address. [%s => %s]" % (env['PRIMARY_HOSTNAME'], env['PUBLIC_IP'])) else: print_error( """This domain must resolve to your box's IP address (%s) in public DNS but it currently resolves to %s. 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)) # Check reverse DNS on the PRIMARY_HOSTNAME. Note that it might not be # a DNS zone if it is a subdomain of another domain we have a zone for. ipaddr_rev = dns.reversename.from_address(env['PUBLIC_IP']) existing_rdns = query_dns(ipaddr_rev, "PTR") if existing_rdns == domain: print_ok("Reverse DNS is set correctly at ISP. [%s => %s]" % (env['PUBLIC_IP'], env['PRIMARY_HOSTNAME'])) else: print_error( """Your box's reverse DNS is currently %s, but it should be %s. Your ISP or cloud provider will have instructions on setting up reverse DNS for your box at %s.""" % (existing_rdns, domain, env['PUBLIC_IP'])) # Check the TLSA record. tlsa_qname = "_25._tcp." + domain tlsa25 = query_dns(tlsa_qname, "TLSA", nxdomain=None) tlsa25_expected = build_tlsa_record(env) if tlsa25 == tlsa25_expected: print_ok( """The DANE TLSA record for incoming mail is correct (%s).""" % tlsa_qname, ) elif tlsa25 is None: print_error( """The DANE TLSA record for incoming mail is not set. This is optional.""" ) else: print_error( """The DANE TLSA record for incoming mail (%s) is not correct. It is '%s' but it should be '%s'. Try running tools/dns_update to regenerate the record. It may take several hours for public DNS to update after a change.""" % (tlsa_qname, tlsa25, tlsa25_expected)) # Check that the hostmaster@ email address exists. check_alias_exists("hostmaster@" + domain, env)