mirror of
https://github.com/YunoHost/moulinette.git
synced 2024-09-03 20:06:31 +02:00
Cleaning / reorganizing the way certificates are stored and enabled
This commit is contained in:
parent
80ebaa6895
commit
4e9a2c050d
1 changed files with 46 additions and 45 deletions
|
@ -144,53 +144,48 @@ def certificate_install_selfsigned(domain_list, force=False):
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n('certmanager_attempt_to_replace_valid_cert', domain=domain))
|
raise MoulinetteError(errno.EINVAL, m18n.n('certmanager_attempt_to_replace_valid_cert', domain=domain))
|
||||||
|
|
||||||
|
|
||||||
cert_folder_domain = os.path.join(CERT_FOLDER, domain)
|
date_tag = datetime.now().strftime("%Y%m%d.%H%M%S")
|
||||||
|
new_cert_folder = "%s/%s-history/%s-selfsigned" % (CERT_FOLDER, domain, date_tag)
|
||||||
|
|
||||||
# Backup existing certificate / folder
|
os.makedirs(new_cert_folder)
|
||||||
if os.path.exists(cert_folder_domain) :
|
|
||||||
if not os.path.islink(cert_folder_domain):
|
|
||||||
_backup_current_cert(domain)
|
|
||||||
shutil.rmtree(cert_folder_domain)
|
|
||||||
else :
|
|
||||||
os.remove(cert_folder_domain)
|
|
||||||
|
|
||||||
os.makedirs(cert_folder_domain)
|
|
||||||
|
|
||||||
# Get serial
|
# Get serial
|
||||||
ssl_dir = '/usr/share/yunohost/yunohost-config/ssl/yunoCA'
|
ssl_dir = '/usr/share/yunohost/yunohost-config/ssl/yunoCA'
|
||||||
with open(os.path.join(ssl_dir, 'serial'), 'r') as f:
|
with open(os.path.join(ssl_dir, 'serial'), 'r') as f:
|
||||||
serial = f.readline().rstrip()
|
serial = f.readline().rstrip()
|
||||||
|
|
||||||
shutil.copyfile(os.path.join(ssl_dir, "openssl.cnf"), os.path.join(cert_folder_domain, "openssl.cnf"))
|
shutil.copyfile(os.path.join(ssl_dir, "openssl.cnf"), os.path.join(new_cert_folder, "openssl.cnf"))
|
||||||
|
|
||||||
# FIXME : should refactor this to avoid so many os.system() calls...
|
# FIXME : should refactor this to avoid so many os.system() calls...
|
||||||
# We should be able to do all this using OpenSSL.crypto and os/shutil
|
# We should be able to do all this using OpenSSL.crypto and os/shutil
|
||||||
command_list = [
|
command_list = [
|
||||||
'sed -i "s/yunohost.org/%s/g" %s/openssl.cnf' % (domain, cert_folder_domain),
|
'sed -i "s/yunohost.org/%s/g" %s/openssl.cnf' % (domain, new_cert_folder),
|
||||||
'openssl req -new -config %s/openssl.cnf -days 3650 -out %s/certs/yunohost_csr.pem -keyout %s/certs/yunohost_key.pem -nodes -batch 2>/dev/null'
|
'openssl req -new -config %s/openssl.cnf -days 3650 -out %s/certs/yunohost_csr.pem -keyout %s/certs/yunohost_key.pem -nodes -batch 2>/dev/null'
|
||||||
% (cert_folder_domain, ssl_dir, ssl_dir),
|
% (new_cert_folder, ssl_dir, ssl_dir),
|
||||||
'openssl ca -config %s/openssl.cnf -days 3650 -in %s/certs/yunohost_csr.pem -out %s/certs/yunohost_crt.pem -batch 2>/dev/null'
|
'openssl ca -config %s/openssl.cnf -days 3650 -in %s/certs/yunohost_csr.pem -out %s/certs/yunohost_crt.pem -batch 2>/dev/null'
|
||||||
% (cert_folder_domain, ssl_dir, ssl_dir),
|
% (new_cert_folder, ssl_dir, ssl_dir),
|
||||||
]
|
]
|
||||||
|
|
||||||
for command in command_list:
|
for command in command_list:
|
||||||
if os.system(command) != 0:
|
if os.system(command) != 0:
|
||||||
raise MoulinetteError(errno.EIO, m18n.n('certmanager_domain_cert_gen_failed'))
|
raise MoulinetteError(errno.EIO, m18n.n('certmanager_domain_cert_gen_failed'))
|
||||||
|
|
||||||
os.symlink('/etc/ssl/certs/ca-yunohost_crt.pem', os.path.join(cert_folder_domain, "ca.pem"))
|
os.symlink('/etc/ssl/certs/ca-yunohost_crt.pem', os.path.join(new_cert_folder, "ca.pem"))
|
||||||
shutil.copyfile(os.path.join(ssl_dir, "certs", "yunohost_key.pem"), os.path.join(cert_folder_domain, "key.pem"))
|
shutil.copyfile(os.path.join(ssl_dir, "certs", "yunohost_key.pem"), os.path.join(new_cert_folder, "key.pem"))
|
||||||
shutil.copyfile(os.path.join(ssl_dir, "newcerts", "%s.pem" % serial), os.path.join(cert_folder_domain, "crt.pem"))
|
shutil.copyfile(os.path.join(ssl_dir, "newcerts", "%s.pem" % serial), os.path.join(new_cert_folder, "crt.pem"))
|
||||||
|
|
||||||
# append ca.pem at the end of crt.pem
|
# append ca.pem at the end of crt.pem
|
||||||
with open(os.path.join(cert_folder_domain, "ca.pem"), "r") as ca_pem:
|
with open(os.path.join(new_cert_folder, "ca.pem"), "r") as ca_pem:
|
||||||
with open(os.path.join(cert_folder_domain, "crt.pem"), "a") as crt_pem:
|
with open(os.path.join(new_cert_folder, "crt.pem"), "a") as crt_pem:
|
||||||
crt_pem.write("\n")
|
crt_pem.write("\n")
|
||||||
crt_pem.write(ca_pem.read())
|
crt_pem.write(ca_pem.read())
|
||||||
|
|
||||||
_set_permissions(cert_folder_domain, "root", "root", 0755)
|
_set_permissions(new_cert_folder, "root", "root", 0755)
|
||||||
_set_permissions(os.path.join(cert_folder_domain, "key.pem"), "root", "metronome", 0640)
|
_set_permissions(os.path.join(new_cert_folder, "key.pem"), "root", "metronome", 0640)
|
||||||
_set_permissions(os.path.join(cert_folder_domain, "crt.pem"), "root", "metronome", 0640)
|
_set_permissions(os.path.join(new_cert_folder, "crt.pem"), "root", "metronome", 0640)
|
||||||
_set_permissions(os.path.join(cert_folder_domain, "openssl.cnf"), "root", "root", 0600)
|
_set_permissions(os.path.join(new_cert_folder, "openssl.cnf"), "root", "root", 0600)
|
||||||
|
|
||||||
|
_enable_certificate(domain, new_cert_folder)
|
||||||
|
|
||||||
# Check new status indicate a recently created self-signed certificate,
|
# Check new status indicate a recently created self-signed certificate,
|
||||||
status = _get_status(domain)
|
status = _get_status(domain)
|
||||||
|
@ -239,7 +234,6 @@ def certificate_install_letsencrypt(auth, domain_list, force=False, no_checks=Fa
|
||||||
if not no_checks:
|
if not no_checks:
|
||||||
_check_domain_is_correctly_configured(domain)
|
_check_domain_is_correctly_configured(domain)
|
||||||
|
|
||||||
_backup_current_cert(domain)
|
|
||||||
_configure_for_acme_challenge(auth, domain)
|
_configure_for_acme_challenge(auth, domain)
|
||||||
_fetch_and_enable_new_certificate(domain)
|
_fetch_and_enable_new_certificate(domain)
|
||||||
_install_cron()
|
_install_cron()
|
||||||
|
@ -308,7 +302,6 @@ def certificate_renew(auth, domain_list, force=False, no_checks=False, email=Fal
|
||||||
try:
|
try:
|
||||||
if not no_checks:
|
if not no_checks:
|
||||||
_check_domain_is_correctly_configured(domain)
|
_check_domain_is_correctly_configured(domain)
|
||||||
_backup_current_cert(domain)
|
|
||||||
_fetch_and_enable_new_certificate(domain)
|
_fetch_and_enable_new_certificate(domain)
|
||||||
|
|
||||||
logger.success(m18n.n("certmanager_cert_renew_success", domain=domain))
|
logger.success(m18n.n("certmanager_cert_renew_success", domain=domain))
|
||||||
|
@ -469,7 +462,7 @@ def _fetch_and_enable_new_certificate(domain):
|
||||||
# Create corresponding directory
|
# Create corresponding directory
|
||||||
date_tag = datetime.now().strftime("%Y%m%d.%H%M%S")
|
date_tag = datetime.now().strftime("%Y%m%d.%H%M%S")
|
||||||
|
|
||||||
new_cert_folder = "%s/%s.%s" % (CERT_FOLDER, domain, date_tag)
|
new_cert_folder = "%s/%s-history/%s-letsencrypt" % (CERT_FOLDER, domain, date_tag)
|
||||||
os.makedirs(new_cert_folder)
|
os.makedirs(new_cert_folder)
|
||||||
|
|
||||||
_set_permissions(new_cert_folder, "root", "root", 0655)
|
_set_permissions(new_cert_folder, "root", "root", 0655)
|
||||||
|
@ -486,18 +479,7 @@ def _fetch_and_enable_new_certificate(domain):
|
||||||
|
|
||||||
_set_permissions(domain_cert_file, "root", "metronome", 0640)
|
_set_permissions(domain_cert_file, "root", "metronome", 0640)
|
||||||
|
|
||||||
logger.info("Enabling the new certificate...")
|
_enable_certificate(domain, new_cert_folder)
|
||||||
|
|
||||||
# Replace (if necessary) the link or folder for live cert
|
|
||||||
live_link = os.path.join(CERT_FOLDER, domain)
|
|
||||||
|
|
||||||
if not os.path.islink(live_link):
|
|
||||||
shutil.rmtree(live_link) # Hopefully that's not too dangerous (directory should have been backuped before calling this command)
|
|
||||||
|
|
||||||
elif os.path.lexists(live_link):
|
|
||||||
os.remove(live_link)
|
|
||||||
|
|
||||||
os.symlink(new_cert_folder, live_link)
|
|
||||||
|
|
||||||
# Check the status of the certificate is now good
|
# Check the status of the certificate is now good
|
||||||
status_summary = _get_status(domain)["summary"]
|
status_summary = _get_status(domain)["summary"]
|
||||||
|
@ -505,13 +487,6 @@ def _fetch_and_enable_new_certificate(domain):
|
||||||
if status_summary["code"] != "great":
|
if status_summary["code"] != "great":
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n('certmanager_certificate_fetching_or_enabling_failed', domain=domain))
|
raise MoulinetteError(errno.EINVAL, m18n.n('certmanager_certificate_fetching_or_enabling_failed', domain=domain))
|
||||||
|
|
||||||
logger.info("Restarting services...")
|
|
||||||
|
|
||||||
for service in ("postfix", "dovecot", "metronome"):
|
|
||||||
_run_service_command("restart", service)
|
|
||||||
|
|
||||||
_run_service_command("reload", "nginx")
|
|
||||||
|
|
||||||
|
|
||||||
def _prepare_certificate_signing_request(domain, key_file, output_folder):
|
def _prepare_certificate_signing_request(domain, key_file, output_folder):
|
||||||
# Init a request
|
# Init a request
|
||||||
|
@ -651,6 +626,32 @@ def _set_permissions(path, user, group, permissions):
|
||||||
os.chmod(path, permissions)
|
os.chmod(path, permissions)
|
||||||
|
|
||||||
|
|
||||||
|
def _enable_certificate(domain, new_cert_folder) :
|
||||||
|
logger.info("Enabling the certificate for domain %s ...", domain)
|
||||||
|
|
||||||
|
live_link = os.path.join(CERT_FOLDER, domain)
|
||||||
|
|
||||||
|
# If a live link (or folder) already exists
|
||||||
|
if os.path.exists(live_link) :
|
||||||
|
# If it's not a link ... expect if to be a folder
|
||||||
|
if not os.path.islink(live_link):
|
||||||
|
# Backup it and remove it
|
||||||
|
_backup_current_cert(domain)
|
||||||
|
shutil.rmtree(live_link)
|
||||||
|
# Else if it's a link, simply delete it
|
||||||
|
elif os.path.lexists(live_link):
|
||||||
|
os.remove(live_link)
|
||||||
|
|
||||||
|
os.symlink(new_cert_folder, live_link)
|
||||||
|
|
||||||
|
logger.info("Restarting services...")
|
||||||
|
|
||||||
|
for service in ("postfix", "dovecot", "metronome"):
|
||||||
|
_run_service_command("restart", service)
|
||||||
|
|
||||||
|
_run_service_command("reload", "nginx")
|
||||||
|
|
||||||
|
|
||||||
def _backup_current_cert(domain):
|
def _backup_current_cert(domain):
|
||||||
logger.info("Backuping existing certificate for domain %s", domain)
|
logger.info("Backuping existing certificate for domain %s", domain)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue