def get_certificates_to_provision(env, limit_domains=None, show_valid_certs=True): # Get a set of domain names that we can provision certificates for # using certbot. We start with domains that the box is serving web # for and subtract: # * domains not in limit_domains if limit_domains is not empty # * domains with custom "A" records, i.e. they are hosted elsewhere # * domains with actual "A" records that point elsewhere (misconfiguration) # * domains that already have certificates that will be valid for a while from web_update import get_web_domains from status_checks import query_dns, normalize_ip existing_certs = get_ssl_certificates(env) plausible_web_domains = get_web_domains(env, exclude_dns_elsewhere=False) actual_web_domains = get_web_domains(env) domains_to_provision = set() domains_cant_provision = {} for domain in plausible_web_domains: # Skip domains that the user doesn't want to provision now. if limit_domains and domain not in limit_domains: continue # Check that there isn't an explicit A/AAAA record. if domain not in actual_web_domains: domains_cant_provision[ domain] = "The domain has a custom DNS A/AAAA record that points the domain elsewhere, so there is no point to installing a TLS certificate here and we could not automatically provision one anyway because provisioning requires access to the website (which isn't here)." # Check that the DNS resolves to here. else: # Does the domain resolve to this machine in public DNS? If not, # we can't do domain control validation. For IPv6 is configured, # make sure both IPv4 and IPv6 are correct because we don't know # how Let's Encrypt will connect. bad_dns = [] for rtype, value in [("A", env["PUBLIC_IP"]), ("AAAA", env.get("PUBLIC_IPV6"))]: if not value: continue # IPv6 is not configured response = query_dns(domain, rtype) if response != normalize_ip(value): bad_dns.append("%s (%s)" % (response, rtype)) if bad_dns: domains_cant_provision[domain] = "The domain name does not resolve to this machine: " \ + (", ".join(bad_dns)) \ + "." else: # DNS is all good. # Check for a good existing cert. existing_cert = get_domain_ssl_files(domain, existing_certs, env, use_main_cert=False, allow_missing_cert=True) if existing_cert: existing_cert_check = check_certificate( domain, existing_cert['certificate'], existing_cert['private-key'], warn_if_expiring_soon=14) if existing_cert_check[0] == "OK": if show_valid_certs: domains_cant_provision[ domain] = "The domain has a valid certificate already. ({} Certificate: {}, private key {})".format( existing_cert_check[1], existing_cert['certificate'], existing_cert['private-key']) continue domains_to_provision.add(domain) return (domains_to_provision, domains_cant_provision)
def get_certificates_to_provision(env, limit_domains=None, show_valid_certs=True): # Get a set of domain names that we can provision certificates for # using certbot. We start with domains that the box is serving web # for and subtract: # * domains not in limit_domains if limit_domains is not empty # * domains with custom "A" records, i.e. they are hosted elsewhere # * domains with actual "A" records that point elsewhere # * domains that already have certificates that will be valid for a while from web_update import get_web_domains from status_checks import query_dns, normalize_ip existing_certs = get_ssl_certificates(env) plausible_web_domains = get_web_domains(env, exclude_dns_elsewhere=False) actual_web_domains = get_web_domains(env) domains_to_provision = set() domains_cant_provision = { } for domain in plausible_web_domains: # Skip domains that the user doesn't want to provision now. if limit_domains and domain not in limit_domains: continue # Check that there isn't an explicit A/AAAA record. if domain not in actual_web_domains: domains_cant_provision[domain] = "The domain has a custom DNS A/AAAA record that points the domain elsewhere, so there is no point to installing a TLS certificate here and we could not automatically provision one anyway because provisioning requires access to the website (which isn't here)." # Check that the DNS resolves to here. else: # Does the domain resolve to this machine in public DNS? If not, # we can't do domain control validation. For IPv6 is configured, # make sure both IPv4 and IPv6 are correct because we don't know # how Let's Encrypt will connect. bad_dns = [] for rtype, value in [("A", env["PUBLIC_IP"]), ("AAAA", env.get("PUBLIC_IPV6"))]: if not value: continue # IPv6 is not configured response = query_dns(domain, rtype) if response != normalize_ip(value): bad_dns.append("%s (%s)" % (response, rtype)) if bad_dns: domains_cant_provision[domain] = "The domain name does not resolve to this machine: " \ + (", ".join(bad_dns)) \ + "." else: # DNS is all good. # Check for a good existing cert. existing_cert = get_domain_ssl_files(domain, existing_certs, env, use_main_cert=False, allow_missing_cert=True) if existing_cert: existing_cert_check = check_certificate(domain, existing_cert['certificate'], existing_cert['private-key'], warn_if_expiring_soon=14) if existing_cert_check[0] == "OK": if show_valid_certs: domains_cant_provision[domain] = "The domain has a valid certificate already. ({} Certificate: {}, private key {})".format( existing_cert_check[1], existing_cert['certificate'], existing_cert['private-key']) continue domains_to_provision.add(domain) return (domains_to_provision, domains_cant_provision)