From 2f52e4f7f9f3d0f9b6a50bdcc5f81d4ab2b0e608 Mon Sep 17 00:00:00 2001 From: Emmanuel Garette Date: Tue, 15 Mar 2022 12:12:56 +0100 Subject: [PATCH] add let's encrypt support --- .../2022.03.08/base/funcs/funcs.py | 6 +- .../gitea/manual/image/preinstall/gitea.sh | 2 +- .../2022.03.08/letsencrypt/README.md | 34 +++++++++ .../letsencrypt/applicationservice.yml | 4 + .../dictionaries/20-letsencrypt.xml | 25 +++++++ .../letsencrypt/funcs/letsencrypt.py | 75 +++++++++++++++++++ .../postfix-relay/funcs/opendkim.py | 6 +- .../roundcube/dictionaries/31_roundcube.xml | 2 +- 8 files changed, 146 insertions(+), 8 deletions(-) create mode 100644 seed/applicationservice/2022.03.08/letsencrypt/README.md create mode 100644 seed/applicationservice/2022.03.08/letsencrypt/applicationservice.yml create mode 100644 seed/applicationservice/2022.03.08/letsencrypt/dictionaries/20-letsencrypt.xml create mode 100644 seed/applicationservice/2022.03.08/letsencrypt/funcs/letsencrypt.py diff --git a/seed/applicationservice/2022.03.08/base/funcs/funcs.py b/seed/applicationservice/2022.03.08/base/funcs/funcs.py index 6b32c0f0..556642ea 100644 --- a/seed/applicationservice/2022.03.08/base/funcs/funcs.py +++ b/seed/applicationservice/2022.03.08/base/funcs/funcs.py @@ -6,8 +6,8 @@ from os.path import dirname as _dirname, abspath as _abspath, join as _join, isf from os import makedirs as _makedirs -HERE = _dirname(_abspath(__main__.__file__)) -PASSWORD_DIR = _join(HERE, 'password') +_HERE = _dirname(_abspath(__main__.__file__)) +_PASSWORD_DIR = _join(_HERE, 'password') def get_password(server_name: str, @@ -56,7 +56,7 @@ def _set_password(server_name: str, ) -> str: if not server_name or not username: return - dir_name = _join('password', server_name, description) + dir_name = _join(_PASSWORD_DIR, server_name, description) if not _isdir(dir_name): _makedirs(dir_name) file_name = _join(dir_name, username) diff --git a/seed/applicationservice/2022.03.08/gitea/manual/image/preinstall/gitea.sh b/seed/applicationservice/2022.03.08/gitea/manual/image/preinstall/gitea.sh index d71aaf20..dc4db79e 100644 --- a/seed/applicationservice/2022.03.08/gitea/manual/image/preinstall/gitea.sh +++ b/seed/applicationservice/2022.03.08/gitea/manual/image/preinstall/gitea.sh @@ -1 +1 @@ -PKG="$PKG git openssh-server" +PKG="$PKG git" diff --git a/seed/applicationservice/2022.03.08/letsencrypt/README.md b/seed/applicationservice/2022.03.08/letsencrypt/README.md new file mode 100644 index 00000000..cc48ba57 --- /dev/null +++ b/seed/applicationservice/2022.03.08/letsencrypt/README.md @@ -0,0 +1,34 @@ +# Gestion Let's encrypt + +## Fonctionnement du service application + +Ce service gère le téléchargement et la mise à disposition des certificats Let's encrypt. + +Le certificat doit être disponible avant l'installation de la machine de destination. +C'est pourquoi ce le certificat est téléchargement grâce au défi DNS-1. + +Il faut donc installer certbot + python3-certbot-dns-xxx (sur une Fedora), par exemple pour OVH "python3-certbot-dns-ovh". + +Attention, en utilisant ce service vous acceptez les conditions d'utilisation de Let's Encrypt ! + +## Utiliser Let's encrypt dans une machine + +Dans applicationservice.yml ajouter la dépendance "letsencrypt". + +Sur la machine installer Certb + +## Configurer Let's encrypt + +``` +rougail.letsencrypt.domain_names": ["nom de domaine"], +rougail.letsencrypt.authority_cn": {"0": "nom de domaine"}, +rougail.letsencrypt.authority_name": {"0": "NomAutorité"}, +rougail.letsencrypt.plugin_name": {"0": "ovh"}, +rougail.letsencrypt.credential_filename": {"0": "/home/user/ovh.ini"}, +rougail.letsencrypt.email": {"0": "gnunux@gnunux.info"} +``` + +## Exemple avec OVH + +Installation du greffon Certbot : https://certbot-dns-ovh.readthedocs.io/en/stable/ +Création d'une clef d'API : https://eu.api.ovh.com/createToken/ diff --git a/seed/applicationservice/2022.03.08/letsencrypt/applicationservice.yml b/seed/applicationservice/2022.03.08/letsencrypt/applicationservice.yml new file mode 100644 index 00000000..3cd83fac --- /dev/null +++ b/seed/applicationservice/2022.03.08/letsencrypt/applicationservice.yml @@ -0,0 +1,4 @@ +format: '0.1' +description: Let's encrypt +depends: + - base-fedora-35 diff --git a/seed/applicationservice/2022.03.08/letsencrypt/dictionaries/20-letsencrypt.xml b/seed/applicationservice/2022.03.08/letsencrypt/dictionaries/20-letsencrypt.xml new file mode 100644 index 00000000..a9f395ea --- /dev/null +++ b/seed/applicationservice/2022.03.08/letsencrypt/dictionaries/20-letsencrypt.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + authority_cn + authority_name + plugin_name + credential_filename + email + domain_names + + + + + diff --git a/seed/applicationservice/2022.03.08/letsencrypt/funcs/letsencrypt.py b/seed/applicationservice/2022.03.08/letsencrypt/funcs/letsencrypt.py new file mode 100644 index 00000000..2270e43a --- /dev/null +++ b/seed/applicationservice/2022.03.08/letsencrypt/funcs/letsencrypt.py @@ -0,0 +1,75 @@ +import __main__ +from subprocess import run as _run +from os.path import dirname as _dirname, abspath as _abspath, join as _join, isfile as _isfile, isdir as _isdir +from datetime import datetime as _datetime +from shutil import copyfile as _copyfile +from os import makedirs as _makedirs + + + +_HERE = _dirname(_abspath(__main__.__file__)) +_LE_DIR = _join(_HERE, 'pki', 'letsencrypt') +_X509_DIR = _join(_HERE, 'pki', 'x509') + + +def letsencrypt_certif(domain: str, + authority_cn: str, + authority_name: str, + plugin_name: str, + credential_filename: str, + email: str, + ) -> None: + if None in (domain, authority_cn, authority_name, plugin_name, credential_filename, email): + return + date_file = _join(_LE_DIR, f'{domain}.date') + date = _datetime.now() + today = str(date.date()) + if not _isfile(date_file): + letsencrypt_date = '0' + else: + with open(date_file, 'r') as fh: + letsencrypt_date = fh.read().strip() + if letsencrypt_date != today: + print(f"Obtain or renew Let's Encrypt certificate for {domain}...") + cli_args = ['certbot', + 'certonly', + f'--dns-{plugin_name}', + f'--dns-{plugin_name}-credentials', + credential_filename, + '-d', + domain, + '--quiet', + '--config-dir', + f'{_LE_DIR}/{domain}/config', + '--work-dir', + f'{_LE_DIR}/{domain}/work', + '--logs-dir', + f'{_LE_DIR}/{domain}/logs', + '--agree-tos', + '-m', + email, + '--dns-ovh-propagation-seconds', + '360', + ] + ret = _run(cli_args, capture_output=True) + if ret.returncode != 0: + raise ValueError(ret.stderr) + print("Done") + with open(date_file, 'w') as fh: + fh.write(today) + rootdir = _join(_X509_DIR, f'{authority_name}+{authority_cn}') + chaindir = _join(rootdir, 'ca') + certdir = _join(rootdir, 'certificats', domain, 'server') + week_number = date.isocalendar().week + for dirname in (chaindir, certdir): + if not _isdir(dirname): + _makedirs(dirname) + _copyfile(_join(_LE_DIR, domain, 'config/live', domain, 'chain.pem'), + _join(chaindir, f'certificate_{week_number}.crt'), + ) + _copyfile(_join(_LE_DIR, domain, 'config/live', domain, 'privkey.pem'), + _join(certdir, 'private.key'), + ) + _copyfile(_join(_LE_DIR, domain, 'config/live', domain, 'fullchain.pem'), + _join(certdir, f'certificate_{week_number}.crt'), + ) diff --git a/seed/applicationservice/2022.03.08/postfix-relay/funcs/opendkim.py b/seed/applicationservice/2022.03.08/postfix-relay/funcs/opendkim.py index 608947a4..d907bf2b 100644 --- a/seed/applicationservice/2022.03.08/postfix-relay/funcs/opendkim.py +++ b/seed/applicationservice/2022.03.08/postfix-relay/funcs/opendkim.py @@ -10,12 +10,12 @@ def _eprint(*args, **kwargs): _dknewkey.eprint = _eprint -HERE = _dirname(_abspath(__main__.__file__)) -DKIM_DIR = _join(HERE, 'pki/dkim') +_HERE = _dirname(_abspath(__main__.__file__)) +_DKIM_DIR = _join(_HERE, 'pki/dkim') def get_dkim_key(domain_name_eth0, domain): - dkim_dir = _join(DKIM_DIR, domain_name_eth0, domain) + dkim_dir = _join(_DKIM_DIR, domain_name_eth0, domain) dkim_file_src = _join(dkim_dir, f'{domain}') dkim_file_key = _join(dkim_dir, f'{domain}.key') dkim_file = _join(dkim_dir, f'{domain}.dns') diff --git a/seed/applicationservice/2022.03.08/roundcube/dictionaries/31_roundcube.xml b/seed/applicationservice/2022.03.08/roundcube/dictionaries/31_roundcube.xml index 7304b841..be7f801d 100644 --- a/seed/applicationservice/2022.03.08/roundcube/dictionaries/31_roundcube.xml +++ b/seed/applicationservice/2022.03.08/roundcube/dictionaries/31_roundcube.xml @@ -35,7 +35,7 @@ revprox_client_external_domainname revprox_client_location - /index.php/login/oauth + index.php/login/oauth oauth2_client_login