Merge pull request #60 from modoboa/feature/letsencrypt

Feature/letsencrypt
This commit is contained in:
Antoine Nguyen
2016-10-21 17:52:01 +02:00
committed by GitHub
4 changed files with 97 additions and 22 deletions

View File

@@ -11,32 +11,42 @@ class CertificateBackend(object):
def __init__(self, config):
"""Set path to certificates."""
self.config = config
if not config.has_option("general", "tls_key_file"):
for base_dir in ["/etc/pki/tls", "/etc/ssl"]:
if os.path.exists(base_dir):
self.config.set(
"general", "tls_key_file",
"{}/private/%(hostname)s.key".format(base_dir))
self.config.set(
"general", "tls_cert_file",
"{}/certs/%(hostname)s.cert".format(base_dir))
return
raise RuntimeError("Cannot find a directory to store certificate")
else:
return
class SelfSignedCertificate(CertificateBackend):
"""Create a self signed certificate."""
def create(self):
"""Create a certificate."""
def overwrite_existing_certificate(self):
"""Check if certificate already exists."""
if os.path.exists(self.config.get("general", "tls_key_file")):
if not self.config.getboolean("general", "force"):
answer = utils.user_input(
"Overwrite the existing SSL certificate? (y/N) ")
if not answer.lower().startswith("y"):
return
return False
return True
class SelfSignedCertificate(CertificateBackend):
"""Create a self signed certificate."""
def __init__(self, *args, **kwargs):
"""Sanity checks."""
super(SelfSignedCertificate, self).__init__(*args, **kwargs)
if self.config.has_option("general", "tls_key_file"):
# Compatibility
return
for base_dir in ["/etc/pki/tls", "/etc/ssl"]:
if os.path.exists(base_dir):
self.config.set(
"general", "tls_key_file",
"{}/private/%(hostname)s.key".format(base_dir))
self.config.set(
"general", "tls_cert_file",
"{}/certs/%(hostname)s.cert".format(base_dir))
return
raise RuntimeError("Cannot find a directory to store certificate")
def create(self):
"""Create a certificate."""
if not self.overwrite_existing_certificate():
return
utils.printcolor(
"Generating new self-signed certificate", utils.YELLOW)
utils.exec_cmd(
@@ -48,6 +58,37 @@ class SelfSignedCertificate(CertificateBackend):
)
class LetsEncryptCertificate(CertificateBackend):
"""Create a certificate using letsencrypt."""
def create(self):
"""Create a certificate."""
utils.printcolor(
"Generating new certificate using letsencrypt", utils.YELLOW)
hostname = self.config.get("general", "hostname")
utils.exec_cmd(
"wget https://dl.eff.org/certbot-auto; chmod a+x certbot-auto",
cwd="/opt")
utils.exec_cmd(
"/opt/certbot-auto certonly -n --standalone -d {} "
"-m {} --agree-tos".format(
hostname, self.config.get("letsencrypt", "email")))
self.config.set("general", "tls_cert_file", (
"/etc/letsencrypt/live/{}/fullchain.pem".format(hostname)))
self.config.set("general", "tls_key_file", (
"/etc/letsencrypt/live/{}/privkey.pem".format(hostname)))
with open("/etc/cron.d/letsencrypt", "w") as fp:
fp.write("0 */12 * * * root /opt/certbot-auto renew "
"--quiet --no-self-upgrade && "
"service nginx reload && "
"service postfix reload && "
"service dovecot reload")
def get_backend(config):
"""Return the appropriate backend."""
if not config.getboolean("certificate", "generate"):
return None
if config.get("certificate", "type") == "letsencrypt":
return LetsEncryptCertificate(config)
return SelfSignedCertificate(config)