Skip to content
Snippets Groups Projects
0_setup.py 3.54 KiB
Newer Older
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
import re

import utils


def setup(interactive=True):
    # Check if a custom SSL certificate is used
    ssl_conf = '/etc/nginx/conf.d/ssl.conf'
    if not os.path.exists(ssl_conf):
        utils.log('The SSL configuration file "%s" does not exist, letsencrypt will not be used.' % ssl_conf)
        return
    default_cert = '/etc/ssl/certs/ssl-cert-snakeoil.pem'
    ssl_cert = utils.get_conf('SSL_CERTIFICATE') or default_cert
    if ssl_cert != default_cert:
        utils.log('The configuration does not use the default certificate, letsencrypt will not be used.')
        return
    # Install certbot
    cmds = [
        'apt-get update',
        'apt-get install -y software-properties-common',
        'add-apt-repository ppa:certbot/certbot -y',
        'apt-get update',
        'apt-get install -y certbot',
    ]
    utils.run_commands(cmds)
    # Get system domains
    domains = list()
    nginx_dir = '/etc/nginx/sites-enabled'
    names = os.listdir(nginx_dir)
    names.sort()
    for name in names:
        path = os.path.join(nginx_dir, name)
        with open(path, 'r') as fo:
            vhost = fo.read()
        vhost = re.sub(r'\s+', ' ', vhost)
        matching = re.findall(r'[^#][ ]*server_name ([0-9a-zA-Z\.\-\_\ ]+);', vhost)
        if not matching:
            print('The server_name was not found in: "%s".' % path)
            continue
        matching = ' '.join(matching)
        for domain in matching.strip().split(' '):
            if domain and domain != 'localhost' and '.' in domain and domain not in domains:
                domains.append(domain)
    # Get certificates
    cmds = [
        'mkdir -p /tmp/letsencrypt',
        'chmod 755 /tmp/letsencrypt',
Hugo Mangeart's avatar
Hugo Mangeart committed
        'certbot certonly --agree-tos --no-eff-email --rsa-key-size 4096 --webroot --webroot-path /tmp/letsencrypt --domains "%s" --email sysadmin@ubicast.eu' % (','.join(domains)),
    ]
    utils.run_commands(cmds)
    # Update Nginx configuration in ssl.conf
    ssl_cert = '/etc/letsencrypt/live/%s/fullchain.pem' % domains[0]
    ssl_key = '/etc/letsencrypt/live/%s/privkey.pem' % domains[0]
    if not os.path.exists(ssl_cert):
        raise Exception('The certificate file "%s" does not exist. Was it correclty created by the certbot command ? Has it been moved ? Take a look in "/etc/letsencrypt/live/" to see if it is in it.' % ssl_cert)
    if not os.path.exists(ssl_key):
        raise Exception('The key file "%s" does not exist. Was it correclty created by the certbot command ? Has it been moved ? Take a look in "/etc/letsencrypt/live/" to see if it is in it.' % ssl_key)
    with open(ssl_conf, 'r') as fo:
        content = fo.read()
    new_content = content
    new_content = re.sub(r'ssl_certificate\s+([\w/\-\_\.]+);', 'ssl_certificate %s;' % ssl_cert, new_content)
    new_content = re.sub(r'ssl_certificate_key\s+([\w/\-\_\.]+);', 'ssl_certificate_key %s;' % ssl_key, new_content)
    if new_content != content:
        with open(ssl_conf, 'w') as fo:
            fo.write(new_content)
        utils.log('SSL configuration file "%s" updated.' % ssl_conf)
    else:
        utils.log('SSL configuration file "%s" already up to date.' % ssl_conf)
    utils.run_commands(['nginx -t', 'systemctl restart nginx'])
    # add pre and post certbot hooks
    dir_path = utils.get_dir(__file__)
    cmds = [
        'cp %s/hook_mkdir.sh /etc/letsencrypt/renewal-hooks/pre/mkdir.sh' % dir_path,
        'cp %s/hook_reload.sh /etc/letsencrypt/renewal-hooks/post/reload.sh' % dir_path,
    ]
    utils.run_commands(cmds)