Esempio n. 1
0
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)
Esempio n. 2
0
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)