def check_ssl_cert(domain, env):
    # Check that SSL certificate is signed.

    # Skip the check if the A record is not pointed here.
    if query_dns(domain, "A", None) not in (env['PUBLIC_IP'], None): return

    # Where is the SSL stored?
    ssl_key, ssl_certificate, ssl_csr_path = get_domain_ssl_files(domain, env)

    if not os.path.exists(ssl_certificate):
        env['out'].print_error(
            "The SSL certificate file for this domain is missing.")
        return

    # Check that the certificate is good.

    cert_status = check_certificate(domain, ssl_certificate, ssl_key)

    if cert_status == "SELF-SIGNED":
        fingerprint = shell('check_output', [
            "openssl", "x509", "-in", ssl_certificate, "-noout", "-fingerprint"
        ])
        fingerprint = re.sub(".*Fingerprint=", "", fingerprint).strip()

        if domain == env['PRIMARY_HOSTNAME']:
            env['out'].print_error(
                """The SSL certificate for this domain is currently self-signed. You will get a security
			warning when you check or send email and when visiting this domain in a web browser (for webmail or
			static site hosting). You may choose to confirm the security exception, but check that the certificate
			fingerprint matches the following:""")
            env['out'].print_line("")
            env['out'].print_line("   " + fingerprint, monospace=True)
        else:
            env['out'].print_error(
                """The SSL certificate for this domain is currently self-signed. Visitors to a website on
			this domain will get a security warning. If you are not serving a website on this domain, then it is
			safe to leave the self-signed certificate in place.""")
        env['out'].print_line("")
        env['out'].print_line(
            """You can purchase a signed certificate from many places. You will need to provide this Certificate Signing Request (CSR)
			to whoever you purchase the SSL certificate from:""")
        env['out'].print_line("")
        env['out'].print_line(open(ssl_csr_path).read().strip(),
                              monospace=True)
        env['out'].print_line("")
        env['out'].print_line(
            """When you purchase an SSL certificate you will receive a certificate in PEM format and possibly a file containing intermediate certificates in PEM format.
			If you receive intermediate certificates, use a text editor and paste your certificate on top and then the intermediate certificates
			below it. Save the file and place it onto this machine at %s. Then run "service nginx restart"."""
            % ssl_certificate)

    elif cert_status == "OK":
        env['out'].print_ok("SSL certificate is signed & valid.")

    else:
        env['out'].print_error("The SSL certificate has a problem:")
        env['out'].print_line("")
        env['out'].print_line(cert_status)
        env['out'].print_line("")
def check_ssl_cert(domain, env):
	# Check that SSL certificate is signed.

	# Skip the check if the A record is not pointed here.
	if query_dns(domain, "A") != env['PUBLIC_IP']: return

	# Where is the SSL stored?
	ssl_key, ssl_certificate, ssl_csr_path = get_domain_ssl_files(domain, env)

	if not os.path.exists(ssl_certificate):
		print_error("The SSL certificate file for this domain is missing.")
		return

	# Check that the certificate is good.

	cert_status = check_certificate(domain, ssl_certificate, ssl_key)

	if cert_status == "SELF-SIGNED":
		fingerprint = shell('check_output', [
			"openssl",
			"x509",
			"-in", ssl_certificate,
			"-noout",
			"-fingerprint"
			])
		fingerprint = re.sub(".*Fingerprint=", "", fingerprint).strip()

		if domain == env['PRIMARY_HOSTNAME']:
			print_error("""The SSL certificate for this domain is currently self-signed. You will get a security
			warning when you check or send email and when visiting this domain in a web browser (for webmail or
			static site hosting). You may choose to confirm the security exception, but check that the certificate
			fingerprint matches the following:""")
			print()
			print("   " + fingerprint)
		else:
			print_error("""The SSL certificate for this domain is currently self-signed. Visitors to a website on
			this domain will get a security warning. If you are not serving a website on this domain, then it is
			safe to leave the self-signed certificate in place.""")
		print()
		print_block("""You can purchase a signed certificate from many places. You will need to provide this Certificate Signing Request (CSR)
			to whoever you purchase the SSL certificate from:""")
		print()
		print(open(ssl_csr_path).read().strip())
		print()
		print_block("""When you purchase an SSL certificate you will receive a certificate in PEM format and possibly a file containing intermediate certificates in PEM format.
			If you receive intermediate certificates, use a text editor and paste your certificate on top and then the intermediate certificates
			below it. Save the file and place it onto this machine at %s. Then run "service nginx restart".""" % ssl_certificate)

	elif cert_status == "OK":
		print_ok("SSL certificate is signed & valid.")

	else:
		print_error("The SSL certificate has a problem:")
		print("")
		print(cert_status)
		print("")
Beispiel #3
0
def check_ssl_cert(domain, env):
    # Check that SSL certificate is signed.

    # Skip the check if the A record is not pointed here.
    if query_dns(domain, "A", None) not in (env['PUBLIC_IP'], None): return

    # Where is the SSL stored?
    ssl_key, ssl_certificate, ssl_csr_path = get_domain_ssl_files(domain, env)

    if not os.path.exists(ssl_certificate):
        env['out'].print_error(
            "The SSL certificate file for this domain is missing.")
        return

    # Check that the certificate is good.

    cert_status, cert_status_details = check_certificate(
        domain, ssl_certificate, ssl_key)

    if cert_status == "OK":
        # The certificate is ok. The details has expiry info.
        env['out'].print_ok("SSL certificate is signed & valid. " +
                            cert_status_details)

    elif cert_status == "SELF-SIGNED":
        # Offer instructions for purchasing a signed certificate.

        fingerprint = shell('check_output', [
            "openssl", "x509", "-in", ssl_certificate, "-noout", "-fingerprint"
        ])
        fingerprint = re.sub(".*Fingerprint=", "", fingerprint).strip()

        if domain == env['PRIMARY_HOSTNAME']:
            env['out'].print_error(
                """The SSL certificate for this domain is currently self-signed. You will get a security
			warning when you check or send email and when visiting this domain in a web browser (for webmail or
			static site hosting). Use the SSL Certificates page in this control panel to install a signed SSL certificate.
			You may choose to leave the self-signed certificate in place and confirm the security exception, but check that
			the certificate fingerprint matches the following:""")
            env['out'].print_line("")
            env['out'].print_line("   " + fingerprint, monospace=True)
        else:
            env['out'].print_warning(
                """The SSL certificate for this domain is currently self-signed. Visitors to a website on
			this domain will get a security warning. If you are not serving a website on this domain, then it is
			safe to leave the self-signed certificate in place. Use the SSL Certificates page in this control panel to
			install a signed SSL certificate.""")

    else:
        env['out'].print_error("The SSL certificate has a problem: " +
                               cert_status)
        if cert_status_details:
            env['out'].print_line("")
            env['out'].print_line(cert_status_details)
            env['out'].print_line("")
Beispiel #4
0
def check_ssl_cert(domain, rounded_time, ssl_certificates, env, output):
	# Check that SSL certificate is signed.

	# Skip the check if the A record is not pointed here.
	if query_dns(domain, "A", None) not in (env['PUBLIC_IP'], None): return

	# Where is the SSL stored?
	x = get_domain_ssl_files(domain, ssl_certificates, env, allow_missing_cert=True)

	if x is None:
		output.print_warning("""No SSL certificate is installed for this domain. Visitors to a website on
			this domain will get a security warning. If you are not serving a website on this domain, you do
			not need to take any action. Use the SSL Certificates page in the control panel to install a
			SSL certificate.""")
		return

	ssl_key, ssl_certificate, ssl_via = x

	# Check that the certificate is good.

	cert_status, cert_status_details = check_certificate(domain, ssl_certificate, ssl_key, rounded_time=rounded_time)

	if cert_status == "OK":
		# The certificate is ok. The details has expiry info.
		output.print_ok("SSL certificate is signed & valid. %s %s" % (ssl_via if ssl_via else "", cert_status_details))

	elif cert_status == "SELF-SIGNED":
		# Offer instructions for purchasing a signed certificate.

		fingerprint = shell('check_output', [
			"openssl",
			"x509",
			"-in", ssl_certificate,
			"-noout",
			"-fingerprint"
			])
		fingerprint = re.sub(".*Fingerprint=", "", fingerprint).strip()

		if domain == env['PRIMARY_HOSTNAME']:
			output.print_error("""The SSL certificate for this domain is currently self-signed. You will get a security
			warning when you check or send email and when visiting this domain in a web browser (for webmail or
			static site hosting). Use the SSL Certificates page in the control panel to install a signed SSL certificate.
			You may choose to leave the self-signed certificate in place and confirm the security exception, but check that
			the certificate fingerprint matches the following:""")
			output.print_line("")
			output.print_line("   " + fingerprint, monospace=True)
		else:
			output.print_error("""The SSL certificate for this domain is self-signed.""")

	else:
		output.print_error("The SSL certificate has a problem: " + cert_status)
		if cert_status_details:
			output.print_line("")
			output.print_line(cert_status_details)
			output.print_line("")
Beispiel #5
0
def check_ssl_cert(domain, env):
	# Check that SSL certificate is signed.

	# Skip the check if the A record is not pointed here.
	if query_dns(domain, "A") != env['PUBLIC_IP']: return

	# Where is the SSL stored?
	ssl_key, ssl_certificate, ssl_csr_path = get_domain_ssl_files(domain, env)

	if not os.path.exists(ssl_certificate):
		print_error("The SSL certificate file for this domain is missing.")
		return

	# Check that the certificate is good.

	cert_status = check_certificate(ssl_certificate)

	if cert_status == "SELF-SIGNED":
		fingerprint = shell('check_output', [
			"openssl",
			"x509",
			"-in", ssl_certificate,
			"-noout",
			"-fingerprint"
			])
		fingerprint = re.sub(".*Fingerprint=", "", fingerprint).strip()

		print_error("""The SSL certificate for this domain is currently self-signed. That's OK if you are willing to confirm security
			exceptions when you check your mail (either via IMAP or webmail), but if you are serving a website on this domain then users
			will not be able to access the site. When confirming security exceptions, check that the certificate fingerprint matches:""")
		print()
		print("   " + fingerprint)
		print()
		print_block("""You can purchase a signed certificate from many places. You will need to provide this Certificate Signing Request (CSR)
			to whoever you purchase the SSL certificate from:""")
		print()
		print(open(ssl_csr_path).read().strip())
		print()
		print_block("""When you purchase an SSL certificate you will receive a certificate in PEM format and possibly a file containing intermediate certificates in PEM format.
			If you receive intermediate certificates, use a text editor and paste your certificate on top and then the intermediate certificates
			below it. Save the file and place it onto this machine at %s.""" % ssl_certificate)

	elif cert_status == "OK":
		print_ok("SSL certificate is signed.")

	else:
		print_error("The SSL certificate has a problem:")
		print("")
		print(cert_status)
		print("")
Beispiel #6
0
def ssl_get_csr(domain):
    from web_update import get_domain_ssl_files, create_csr
    ssl_key, ssl_certificate, csr_path = get_domain_ssl_files(domain, env)
    return create_csr(domain, ssl_key, env)
def ssl_get_csr(domain):
	from web_update import get_domain_ssl_files, create_csr
	ssl_key, ssl_certificate, csr_path = get_domain_ssl_files(domain, env)
	return create_csr(domain, ssl_key, env)
                linelen = 0
            if linelen == 0 and w.strip() == "": continue
            print(w, end="")
            linelen += len(w)
        print()

    def print_line(self, message, monospace=False):
        for line in message.split("\n"):
            self.print_block(line)


if __name__ == "__main__":
    import sys
    from utils import load_environment
    env = load_environment()
    if len(sys.argv) == 1:
        run_checks(env, ConsoleOutput())
    elif sys.argv[1] == "--check-primary-hostname":
        # See if the primary hostname appears resolvable and has a signed certificate.
        domain = env['PRIMARY_HOSTNAME']
        if query_dns(domain, "A") != env['PUBLIC_IP']:
            sys.exit(1)
        ssl_key, ssl_certificate, ssl_csr_path = get_domain_ssl_files(
            domain, env)
        if not os.path.exists(ssl_certificate):
            sys.exit(1)
        cert_status = check_certificate(domain, ssl_certificate, ssl_key)
        if cert_status != "OK":
            sys.exit(1)
        sys.exit(0)
Beispiel #9
0
			getattr(output, attr)(*args, **kwargs)


if __name__ == "__main__":
	from utils import load_environment

	env = load_environment()
	pool = multiprocessing.pool.Pool(processes=10)

	if len(sys.argv) == 1:
		run_checks(False, env, ConsoleOutput(), pool)

	elif sys.argv[1] == "--show-changes":
		run_and_output_changes(env, pool, sys.argv[-1] == "--smtp")

	elif sys.argv[1] == "--check-primary-hostname":
		# See if the primary hostname appears resolvable and has a signed certificate.
		domain = env['PRIMARY_HOSTNAME']
		if query_dns(domain, "A") != env['PUBLIC_IP']:
			sys.exit(1)
		ssl_key, ssl_certificate, ssl_via = get_domain_ssl_files(domain, env)
		if not os.path.exists(ssl_certificate):
			sys.exit(1)
		cert_status, cert_status_details = check_certificate(domain, ssl_certificate, ssl_key, warn_if_expiring_soon=False)
		if cert_status != "OK":
			sys.exit(1)
		sys.exit(0)

	elif sys.argv[1] == "--version":
		print(what_version_is_this(env))
Beispiel #10
0
		return w
	def playback(self, output):
		for attr, args, kwargs in self.buf:
			getattr(output, attr)(*args, **kwargs)


if __name__ == "__main__":
	from utils import load_environment

	env = load_environment()
	pool = multiprocessing.pool.Pool(processes=10)

	if len(sys.argv) == 1:
		run_checks(False, env, ConsoleOutput(), pool)

	elif sys.argv[1] == "--show-changes":
		run_and_output_changes(env, pool, sys.argv[-1] == "--smtp")

	elif sys.argv[1] == "--check-primary-hostname":
		# See if the primary hostname appears resolvable and has a signed certificate.
		domain = env['PRIMARY_HOSTNAME']
		if query_dns(domain, "A") != env['PUBLIC_IP']:
			sys.exit(1)
		ssl_key, ssl_certificate, ssl_via = get_domain_ssl_files(domain, env)
		if not os.path.exists(ssl_certificate):
			sys.exit(1)
		cert_status, cert_status_details = check_certificate(domain, ssl_certificate, ssl_key)
		if cert_status != "OK":
			sys.exit(1)
		sys.exit(0)
Beispiel #11
0
				print()
				print("   ", end="")
				linelen = 0
			if linelen == 0 and w.strip() == "": continue
			print(w, end="")
			linelen += len(w)
		print()

	def print_line(self, message, monospace=False):
		for line in message.split("\n"):
			self.print_block(line)

if __name__ == "__main__":
	import sys
	from utils import load_environment
	env = load_environment()
	if len(sys.argv) == 1:
		run_checks(env, ConsoleOutput())
	elif sys.argv[1] == "--check-primary-hostname":
		# See if the primary hostname appears resolvable and has a signed certificate.
		domain = env['PRIMARY_HOSTNAME']
		if query_dns(domain, "A") != env['PUBLIC_IP']:
			sys.exit(1)
		ssl_key, ssl_certificate, ssl_csr_path = get_domain_ssl_files(domain, env)
		if not os.path.exists(ssl_certificate):
			sys.exit(1)
		cert_status, cert_status_details = check_certificate(domain, ssl_certificate, ssl_key)
		if cert_status != "OK":
			sys.exit(1)
		sys.exit(0)
Beispiel #12
0
def buy_ssl_certificate(api_key, domain, command, env):
    if domain != env['PRIMARY_HOSTNAME'] \
     and domain not in get_web_domains(env):
        raise ValueError(
            "Domain is not %s or a domain we're serving a website for." %
            env['PRIMARY_HOSTNAME'])

    # Initialize.

    gandi = xmlrpc.client.ServerProxy('https://rpc.gandi.net/xmlrpc/')

    try:
        existing_certs = gandi.cert.list(api_key)
    except Exception as e:
        if "Invalid API key" in str(e):
            print(
                "Invalid API key. Check that you copied the API Key correctly from https://www.gandi.net/admin/api_key."
            )
            sys.exit(1)
        else:
            raise

    # Where is the SSL cert stored?

    ssl_key, ssl_certificate, ssl_csr_path = get_domain_ssl_files(domain, env)

    # Have we already created a cert for this domain?

    for cert in existing_certs:
        if cert['cn'] == domain:
            break
    else:
        # No existing cert found. Purchase one.
        if command != 'purchase':
            print(
                "No certificate or order found yet. If you haven't yet purchased a certificate, run ths script again with the 'purchase' command. Otherwise wait a moment and try again."
            )
            sys.exit(1)
        else:
            # Start an order for a single standard SSL certificate.
            # Use DNS validation. Web-based validation won't work because they
            # require a file on HTTP but not HTTPS w/o redirects and we don't
            # serve anything plainly over HTTP. Email might be another way but
            # DNS is easier to automate.
            op = gandi.cert.create(
                api_key,
                {
                    "csr": open(ssl_csr_path).read(),
                    "dcv_method": "dns",
                    "duration": 1,  # year?
                    "package": "cert_std_1_0_0",
                })
            print("An SSL certificate has been ordered.")
            print()
            print(op)
            print()
            print(
                "In a moment please run this script again with the 'setup' command."
            )

    if cert['status'] == 'pending':
        # Get the information we need to update our DNS with a code so that
        # Gandi can verify that we own the domain.

        dcv = gandi.cert.get_dcv_params(
            api_key,
            {
                "csr": open(ssl_csr_path).read(),
                "cert_id": cert['id'],
                "dcv_method": "dns",
                "duration": 1,  # year?
                "package": "cert_std_1_0_0",
            })
        if dcv["dcv_method"] != "dns":
            raise Exception(
                "Certificate ordered with an unknown validation method.")

        # Update our DNS data.

        dns_config = env['STORAGE_ROOT'] + '/dns/custom.yaml'
        if os.path.exists(dns_config):
            dns_records = rtyaml.load(open(dns_config))
        else:
            dns_records = {}

        qname = dcv['md5'] + '.' + domain
        value = dcv['sha1'] + '.comodoca.com.'
        dns_records[qname] = {"CNAME": value}

        with open(dns_config, 'w') as f:
            f.write(rtyaml.dump(dns_records))

        shell('check_call', ['tools/dns_update'])

        # Okay, done with this step.

        print("DNS has been updated. Gandi will check within 60 minutes.")
        print()
        print(
            "See https://www.gandi.net/admin/ssl/%d/details for the status of this order."
            % cert['id'])

    elif cert['status'] == 'valid':
        # The certificate is ready.

        # Check before we overwrite something we shouldn't.
        if os.path.exists(ssl_certificate):
            cert_status = check_certificate(None, ssl_certificate, None)
            if cert_status != "SELF-SIGNED":
                print(
                    "Please back up and delete the file %s so I can save your new certificate."
                    % ssl_certificate)
                sys.exit(1)

        # Form the certificate.

        # The certificate comes as a long base64-encoded string. Break in
        # into lines in the usual way.
        pem = "-----BEGIN CERTIFICATE-----\n"
        pem += "\n".join(chunk for chunk in re.split(r"(.{64})", cert['cert'])
                         if chunk != "")
        pem += "\n-----END CERTIFICATE-----\n\n"

        # Append intermediary certificates.
        pem += urllib.request.urlopen(
            "https://www.gandi.net/static/CAs/GandiStandardSSLCA.pem").read(
            ).decode("ascii")

        # Write out.

        with open(ssl_certificate, "w") as f:
            f.write(pem)

        print(
            "The certificate has been installed in %s. Restarting services..."
            % ssl_certificate)

        # Restart dovecot and if this is for PRIMARY_HOSTNAME.

        if domain == env['PRIMARY_HOSTNAME']:
            shell('check_call', ["/usr/sbin/service", "dovecot", "restart"])
            shell('check_call', ["/usr/sbin/service", "postfix", "restart"])

        # Restart nginx in all cases.

        shell('check_call', ["/usr/sbin/service", "nginx", "restart"])

    else:
        print(
            "The certificate has an unknown status. Please check https://www.gandi.net/admin/ssl/%d/details for the status of this order."
            % cert['id'])
Beispiel #13
0
def buy_ssl_certificate(api_key, domain, command, env):
	if domain != env['PRIMARY_HOSTNAME'] \
		and domain not in get_web_domains(env):
		raise ValueError("Domain is not %s or a domain we're serving a website for." % env['PRIMARY_HOSTNAME'])

	# Initialize.

	gandi = xmlrpc.client.ServerProxy('https://rpc.gandi.net/xmlrpc/')

	try:
		existing_certs = gandi.cert.list(api_key)
	except Exception as e:
		if "Invalid API key" in str(e):
			print("Invalid API key. Check that you copied the API Key correctly from https://www.gandi.net/admin/api_key.")
			sys.exit(1)
		else:
			raise

	# Where is the SSL cert stored?

	ssl_key, ssl_certificate, ssl_csr_path = get_domain_ssl_files(domain, env)	

	# Have we already created a cert for this domain?

	for cert in existing_certs:
		if cert['cn'] == domain:
			break
	else:
		# No existing cert found. Purchase one.
		if command != 'purchase':
			print("No certificate or order found yet. If you haven't yet purchased a certificate, run ths script again with the 'purchase' command. Otherwise wait a moment and try again.")
			sys.exit(1)
		else:
			# Start an order for a single standard SSL certificate.
			# Use DNS validation. Web-based validation won't work because they
			# require a file on HTTP but not HTTPS w/o redirects and we don't
			# serve anything plainly over HTTP. Email might be another way but
			# DNS is easier to automate.
			op = gandi.cert.create(api_key, {
				"csr": open(ssl_csr_path).read(),
				"dcv_method": "dns",
				"duration": 1, # year?
				"package": "cert_std_1_0_0",
				})
			print("An SSL certificate has been ordered.")
			print()
			print(op)
			print()
			print("In a moment please run this script again with the 'setup' command.")

	if cert['status'] == 'pending':
		# Get the information we need to update our DNS with a code so that
		# Gandi can verify that we own the domain.

		dcv = gandi.cert.get_dcv_params(api_key, {
				"csr": open(ssl_csr_path).read(),
				"cert_id": cert['id'],
				"dcv_method": "dns",
				"duration": 1, # year?
				"package": "cert_std_1_0_0",
				})
		if dcv["dcv_method"] != "dns":
			raise Exception("Certificate ordered with an unknown validation method.")

		# Update our DNS data.

		dns_config = env['STORAGE_ROOT'] + '/dns/custom.yaml'
		if os.path.exists(dns_config):
			dns_records = rtyaml.load(open(dns_config))
		else:
			dns_records = { }

		qname = dcv['md5'] + '.' + domain
		value = dcv['sha1'] + '.comodoca.com.'
		dns_records[qname] = { "CNAME": value }

		with open(dns_config, 'w') as f:
			f.write(rtyaml.dump(dns_records))

		shell('check_call', ['tools/dns_update'])

		# Okay, done with this step.

		print("DNS has been updated. Gandi will check within 60 minutes.")
		print()
		print("See https://www.gandi.net/admin/ssl/%d/details for the status of this order." % cert['id'])

	elif cert['status'] == 'valid':
		# The certificate is ready.

		# Check before we overwrite something we shouldn't.
		if os.path.exists(ssl_certificate):
			cert_status, cert_status_details = check_certificate(None, ssl_certificate, None)
			if cert_status != "SELF-SIGNED":
				print("Please back up and delete the file %s so I can save your new certificate." % ssl_certificate)
				sys.exit(1)

		# Form the certificate.

		# The certificate comes as a long base64-encoded string. Break in
		# into lines in the usual way.
		pem = "-----BEGIN CERTIFICATE-----\n"
		pem += "\n".join(chunk for chunk in re.split(r"(.{64})", cert['cert']) if chunk != "")
		pem += "\n-----END CERTIFICATE-----\n\n"

		# Append intermediary certificates.
		pem += urllib.request.urlopen("https://www.gandi.net/static/CAs/GandiStandardSSLCA.pem").read().decode("ascii")

		# Write out.

		with open(ssl_certificate, "w") as f:
			f.write(pem)

		print("The certificate has been installed in %s. Restarting services..." % ssl_certificate)

		# Restart dovecot and if this is for PRIMARY_HOSTNAME.

		if domain == env['PRIMARY_HOSTNAME']:
			shell('check_call', ["/usr/sbin/service", "dovecot", "restart"])
			shell('check_call', ["/usr/sbin/service", "postfix", "restart"])

		# Restart nginx in all cases.

		shell('check_call', ["/usr/sbin/service", "nginx", "restart"])

	else:
		print("The certificate has an unknown status. Please check https://www.gandi.net/admin/ssl/%d/details for the status of this order." % cert['id'])