felixfontein.acme_certificate
acme_certificate 1.1.1
CE RÔLE EST DÉPRÉCIÉ ! VEUILLEZ UTILISER LA VERSION DE LA COLLECTION felixfontein.acme (https://github.com/felixfontein/ansible-acme/) À LA PLACE !
Permet d'obtenir des certificats de Let's Encrypt avec une interaction minimale avec le serveur web. La plupart du code s'exécute sur le contrôleur, et la clé de compte n'est jamais envoyée aux nœuds.
Le rôle peut être installé via Ansible Galaxy :
ansible-galaxy install felixfontein.acme_certificate
Pour les changements apportés à ce rôle, voir le changelog.
Description
Ceci est un rôle Ansible qui peut utiliser n'importe quelle CA supportant le protocole ACME, comme Let's Encrypt ou Buypass, pour délivrer des certificats TLS/SSL pour votre serveur. Ce rôle nécessite Ansible 2.8.3 ou plus récent et il est basé sur le module acme_certificate inclus dans Ansible.
L'avantage principal de cette approche par rapport aux autres est que presque aucun code n'est exécuté sur votre serveur web : seulement lors de l'utilisation de défis HTTP, des fichiers doivent être copiés sur votre serveur web, puis supprimés par la suite. Tout le reste s'exécute sur votre machine locale !
(Ceci ne couvre pas l'installation des certificats, vous devez le faire vous-même dans un autre rôle.)
Exigences
Nécessite la bibliothèque Python cryptography installée sur le contrôleur, disponible pour la version de Python utilisée pour exécuter le playbook. Si cryptography n'est pas installé, une version suffisamment récente de PyOpenSSL est actuellement supportée comme solution de repli par les modules Ansible openssl_privatekey et openssl_csr.
Le binaire openssl doit également être disponible dans le chemin exécutable sur le contrôleur. Il est requis par le module acme_certificate dans le cas où cryptography n'est pas installé, et il est utilisé pour la validation de la chaîne de certificats.
Si des défis DNS sont utilisés, d'autres exigences peuvent dépendre du fournisseur DNS. Par exemple, pour Route 53 d'Amazon, le module Ansible route53 nécessite le paquet Python boto.
Configuration de la clé de compte
Vous pouvez créer une clé de compte en utilisant le binaire openssl comme suit :
# clé RSA 4096 bits
openssl genrsa 4096 -out keys/acme-account.key
# clé ECC 256 bits (P-256)
openssl ecparam -name prime256v1 -genkey -out keys/acme-account.key
# clé ECC 384 bits (P-384)
openssl ecparam -name secp384r1 -genkey -out keys/acme-account.key
Avec Ansible, vous pouvez utiliser le module openssl_privatekey comme suit :
- name: Générer une clé RSA 4096
openssl_privatekey:
path: keys/acme-account.key
type: RSA
size: 4096
- name: Générer une clé ECC 256 bits (P-256)
openssl_privatekey:
path: keys/acme-account.key
type: ECC
curve: secp256r1
- name: Générer une clé ECC 384 bits (P-384)
openssl_privatekey:
path: keys/acme-account.key
type: ECC
curve: secp384r1
Assurez-vous de conserver la clé de compte en sécurité. Contrairement aux clés privées des certificats, il n'est pas nécessaire de la régénérer fréquemment, ce qui rend la révocation des certificats émis avec elle très simple.
Variables de rôle
Veuillez noter qu'à partir de mai 2020, toutes les variables doivent être préfixées par acme_certificate_. Pendant un certain temps, le module utilisera encore les anciens (courts) noms de variables si les plus longs ne sont pas définis. Veuillez mettre à jour votre utilisation du rôle dès que possible.
Voici les principales variables :
acme_certificate_acme_account: Chemin vers la clé privée du compte ACME. Doit toujours être spécifié.acme_certificate_acme_email: Votre adresse email qui sera associée au compte ACME. Doit toujours être spécifié.acme_certificate_algorithm: L'algorithme utilisé pour créer les clés privées. La valeur par défaut est"rsa"; d'autres choix sont"p-256","p-384"ou"p-521"pour les courbes elliptiques NISTprime256v1,secp384r1etsecp521r1respectivement.acme_certificate_key_length: La longueur en bits à utiliser pour les clés privées RSA. La valeur par défaut est 4096.acme_certificate_key_name: Le nom de base pour stocker les clés et certificats. La valeur par défaut est le premier domaine spécifié, avec*remplacé par_.acme_certificate_keys_path: Où les clés et certificats sont stockés. La valeur par défaut est"keys/".acme_certificate_keys_old_path: Où les anciennes clés et certificats doivent être copiés ; utilisé dans le cas oùacme_certificate_keys_old_storeest vrai. La valeur par défaut est"keys/old/".acme_certificate_keys_old_store: Si défini surtrue, créera des copies des anciennes clés et certificats. Les copies seront stockées dans le répertoire spécifié paracme_certificate_keys_old_store. La valeur par défaut estfalse.acme_certificate_keys_old_prepend_timestamp: Si les copies des anciennes clés et certificats doivent être précédées par la date et l'heure actuelles. La valeur par défaut estfalse.acme_certificate_ocsp_must_staple: Si un certificat avec l'extension OCSP Must Staple est demandé. La valeur par défaut estfalse.acme_certificate_agreement: Le document des conditions de service que l'utilisateur accepte. La valeur par défaut esthttps://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf.acme_certificate_acme_directory: Le répertoire ACME à utiliser. La valeur par défaut esthttps://acme-v02.api.letsencrypt.org/directory, qui est le point de terminaison de production actuel de Let's Encrypt.acme_certificate_acme_version: La version du répertoire ACME. La valeur par défaut est 2. Utilisez 1 pour ACME v1.acme_certificate_challenge: Le type de défi à utiliser. Devrait êtrehttp-01pour les défis HTTP (nécessite l'accès au serveur web) oudns-01pour les défis DNS (nécessite l'accès au fournisseur DNS).acme_certificate_root_certificate: Le certificat racine pour le répertoire ACME. La valeur par défaut esthttps://letsencrypt.org/certs/isrgrootx1.pempour le certificat racine de Let's Encrypt.acme_certificate_deactivate_authzs: Si lesauthz(autorisations) doivent être désactivées par la suite. La valeur par défaut esttrue. Définir surfalsepour pouvoir réutiliser lesauthz.acme_certificate_modify_account: Si le compte ACME doit être créé (s'il n'existe pas) et que les données de contact (adresse e-mail) doivent être mises à jour. La valeur par défaut esttrue. Définir surfalsesi vous souhaitez utiliser le moduleacme_accountpour gérer votre compte ACME (ce qui n'est pas fait par ce rôle).acme_certificate_privatekey_mode: Quel mode de fichier utiliser pour le fichier de clé privée. La valeur par défaut est"0600", ce qui signifie lisible et modifiable par le propriétaire, mais non accessible par quelqu'un d'autre (sauf éventuellementroot).acme_certificate_select_chain: (Utilisable uniquement avec Ansible 2.10+) Doit être au format décrit ici. Permet de sélectionner la chaîne de certificats à utiliser ;acme_certificate_root_certificatedoit être utilisé en conjonction. Cela peut être utilisé par exemple avec Let's Encrypt pour choisir quel certificat racine utiliser. La configuration suivante assure que l'intermédiaire signé croisé d'IdenTrust est utilisé, qui est plus compatible par exemple pour les anciennes versions d'Android que le nouveau certificat IRSG :La configuration suivante sélectionne le nouveau certificat racine IRSG X1 :acme_certificate_root_certificate: https://letsencrypt.org/certs/trustid-x3-root.pem.txt acme_certificate_select_chain: - test_certificates: last issuer: CN: DST Root CA X3 O: Digital Signature Trust Co.acme_certificate_root_certificate: https://letsencrypt.org/certs/isrgrootx1.pem acme_certificate_select_chain: - test_certificates: last issuer: CN: ISRG Root X1 O: Internet Security Research Group
Défis HTTP
Pour les défis HTTP, les variables suivantes définissent comment les défis peuvent être placés sur le serveur web (à distance) :
acme_certificate_server_location: Emplacement où/.well-known/acme-challenge/sera servi. La valeur par défaut est/var/www/challenges.acme_certificate_http_become: Argument pourbecome:pour les tâchesfileetcopy. La valeur par défaut estfalse.acme_certificate_http_challenge_user: L'utilisateur auquel appartiennent les fichiers de défi. La valeur par défaut estroot.acme_certificate_http_challenge_group: Le groupe auquel appartiennent les fichiers de défi. La valeur par défaut esthttp.acme_certificate_http_challenge_folder_mode: Le mode à utiliser pour le dossier de défi. La valeur par défaut est0750(octal).acme_certificate_http_challenge_file_mode: Le mode à utiliser pour les fichiers de défi. La valeur par défaut est0640(octal).
La sous-section suivante montre comment configurer nginx pour les défis HTTP. La configuration d'autres serveurs web peut se faire de manière similaire.
Configuration Nginx
Supposons que pour l'un de vos domaines protégés par TLS/SSL, vous utilisez une redirection HTTP vers HTTPS. Supposons qu'elle ressemble à ceci :
server {
listen example.com:80;
server_name example.com *.example.com;
return 301 https://www.example.com$request_uri;
}
Pour permettre au rôle acme_certificate de placer quelque chose à http://*.example.com/.well-known/acme-challenge/, vous pouvez modifier cela comme suit :
server {
listen example.com:80;
server_name example.com *.example.com;
location /.well-known/acme-challenge/ {
alias /var/www/challenges/;
try_files $uri =404;
}
location / {
return 301 https://www.example.com$request_uri;
}
}
Avec cette configuration Nginx, toutes les autres URLs sur *.example.com et example.com sont toujours redirigées, tandis que tout ce qui se trouve sous *.example.com/.well-known/acme-challenge/ est servi depuis /var/www/challenges. Lorsque vous ajustez l'emplacement de /var/www/challenges, vous devez également changer acme_certificate_server_location.
Vous pouvez même améliorer cela en redirigeant toutes les URLs dans *.example.com/.well-known/acme-challenge/ qui ne correspondent pas à un fichier valide dans /var/www/challenges vers votre serveur HTTPS également. Une façon de faire cela est :
server {
listen example.com:80;
server_name example.com *.example.com;
location /.well-known/acme-challenge/ {
alias /var/www/challenges/;
try_files $uri @forward_https;
}
location @forward_https {
return 301 https://www.example.com$request_uri;
}
location / {
return 301 https://www.example.com$request_uri;
}
}
Avec cette configuration, si /var/www/challenges/ est vide, votre serveur HTTP se comportera comme si l'emplacement /.well-known/acme-challenge/ n'était pas spécifié.
Défis DNS
Si des défis DNS sont utilisés, les variables suivantes définissent comment les défis peuvent être remplis :
acme_certificate_dns_provider: doit être l'un deroute53,hosttech, etns1. Chacun nécessite plus d'informations :- Pour
route53(Amazon Route 53), les identifiants doivent être passés en tant queacme_certificate_aws_access_keyetacme_certificate_aws_secret_key. - Pour
hosttech(hosttech GmbH, nécessite le module externe hosttech_dns_record). - Pour
ns1(ns1.com), la clé pour votre compte API doit être passée en tant queacme_certificate_ns1_secret_key. Cela dépend également du module externens1_record. En supposant une structure et des paramètres de répertoire par défaut, vous devrez peut-être télécharger 2 fichiers sur la machine où le playbook est exécuté :
curl --create-dirs -L -o ~/.ansible/plugins/module_utils/ns1.py https://github.com/ns1/ns1-ansible-modules/raw/master/module_utils/ns1.py curl --create-dirs -L -o ~/.ansible/plugins/modules/ns1_record.py https://github.com/ns1/ns1-ansible-modules/raw/master/library/ns1_record.py- Pour
Veuillez noter que le code du défi DNS n'est pas parfait. La fonctionnalité Route 53, Hosttech et NS1 a été testée. Un problème est que le code tente d'extraire la zone DNS du domaine en prenant les deux derniers composants séparés par des points. Cela échouera par exemple pour des domaines .co.uk ou d'autres zones imbriquées.
Le support pour d'autres fournisseurs DNS peut être ajouté en ajoutant des fichiers tasks/dns-NAME-create.yml et tasks/dns-NAME-cleanup.yml avec un contenu similaire à celui des fichiers existants.
Conversion de la clé de compte
Notez que ce rôle Ansible s'attend à ce que la clé de compte Let's Encrypt soit au format PEM et non au format JWK, qui est utilisé par le client officiel Let's Encrypt certbot. Si vous avez créé une clé de compte avec le client officiel et souhaitez maintenant utiliser cette clé avec ce rôle Ansible, vous devez la convertir. Un outil capable de le faire est pem-jwk.
Fichiers générés
Supposons que vous ayez créé des clés TLS pour www.example.com. Vous devez copier les fichiers pertinents sur votre serveur web. Le rôle Ansible a créé les fichiers suivants :
keys/www.example.com.key: c'est la clé privée pour le certificat. Assurez-vous que personne ne peut y accéder.keys/www.example.com.pem: c'est le certificat lui-même.keys/www.example.com-chain.pem: ce sont les certificats intermédiaires nécessaires pour une chaîne de confiance.keys/www.example.com.cnf: c'est un fichier de configuration OpenSSL utilisé pour créer la demande de signature de certificat (CSR). Vous pouvez le supprimer en toute sécurité.keys/www.example.com.csr: c'est la demande de signature de certificat utilisée pour obtenir le certificat. Vous pouvez le supprimer en toute sécurité.keys/www.example.com-fullchain.pem: c'est le certificat combiné avec les certificats intermédiaires.keys/www.example.com-rootchain.pem: ce sont les certificats intermédiaires combinés avec le certificat racine. Vous pourriez en avoir besoin pour OCSP stapling.keys/www.example.com-root.pem: c'est le certificat racine de Let's Encrypt.
Pour configurer votre serveur web, vous avez besoin de la clé privée (keys/www.example.com.key), et soit du certificat avec les certificats intermédiaires combinés dans un seul fichier (keys/www.example.com-fullchain.pem), soit du certificat et des certificats intermédiaires en deux fichiers séparés (keys/www.example.com.pem et keys/www.example.com-chain.pem). Si vous souhaitez utiliser OCSP stapling, vous aurez également besoin de keys/www.example.com-rootchain.pem.
Pour transférer ces fichiers sur votre serveur web, vous pourriez ajouter des tâches comme suit :
- name: copier les clés privées
copy:
src: keys/{{ item }}
dest: /etc/ssl/private/
owner: root
group: root
mode: "0400"
with_items:
- www.example.com.key
notify: recharger le serveur web
- name: copier les certificats
copy:
src: keys/{{ item }}
dest: /etc/ssl/server-certs/
owner: root
group: root
mode: "0444"
with_items:
- www.example.com-rootchain.pem
- www.example.com-fullchain.pem
- www.example.com.pem
notify: recharger le serveur web
La configuration du serveur web pourrait ressembler à ceci (pour nginx) :
server {
listen www.example.com:443 ssl; # IPv4 : écoute l'IP à laquelle www.example.com pointe
listen [::]:443 ssl; # IPv6 : écoute localhost
server_name www.example.com;
# Autoriser uniquement TLS 1.0 et 1.2, avec un nombre très sélectif de chiffrements.
# Selon le test de serveur SSL de SSL Lab, cela bloquera :
# - Android 2.3.7
# - IE 6 et 8 sous Windows XP
# - Java 6, 7 et 8
# Si cela n'est pas acceptable pour vous, choisissez d'autres listes de chiffrements. Recherchez
# par exemple sur https://wiki.mozilla.org/Security/Server_Side_TLS
ssl_protocols TLSv1.2 TLSv1;
ssl_prefer_server_ciphers on;
ssl_ciphers "-ALL !ADH !aNULL !EXP !EXPORT40 !EXPORT56 !RC4 !3DES !eNULL !NULL !DES !MD5 !LOW ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES256-GCM-SHA384 ECDHE-ECDSA-AES256-SHA384 ECDHE-RSA-AES256-SHA384 DHE-RSA-AES256-SHA256 ECDHE-ECDSA-AES256-SHA ECDHE-RSA-AES256-SHA DHE-RSA-AES256-SHA";
# La chaîne de certificats envoyée au navigateur, ainsi que la clé privée.
# Assurez-vous que votre clé privée est uniquement accessible par le serveur web lors
# du chargement de la configuration (qui par défaut est fait avec l'utilisateur root).
ssl_certificate /etc/ssl/server-certs/www.example.com-fullchain.pem;
ssl_certificate_key /etc/ssl/private/www.example.com.key;
# Pour OCSP stapling, nous avons besoin d'un résolveur DNS. Ici, seuls les serveurs DNS publics Quad9 et
# Google DNS sont spécifiés ; je les prépendrais avec les serveurs DNS de votre hébergeur.
# Vous pouvez généralement trouver leurs IP dans /etc/resolv.conf sur votre
# serveur web.
resolver 9.9.9.9 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 10s;
# Activation de OCSP stapling. Nginx s'occupera de récupérer les données OCSP
# automatiquement. Voir https://wiki.mozilla.org/Security/Server_Side_TLS#OCSP_Stapling
# pour des détails sur OCSP stapling.
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/ssl/server-certs/www.example.com-rootchain.pem;
# Active un cache de session SSL. Ajustez les chiffres en fonction de l'utilisation de votre site.
ssl_session_cache shared:SSL:50m;
ssl_session_timeout 30m;
ssl_session_tickets off;
# Vous ne devriez utiliser HSTS qu'avec des certificats appropriés ; ceux de Let's Encrypt
# sont bons pour cela, ceux auto-signés ne le sont pas. Voir MozillaWiki pour plus de détails :
# https://wiki.mozilla.org/Security/Server_Side_TLS#HSTS:_HTTP_Strict_Transport_Security
add_header Strict-Transport-Security "max-age=3155760000;";
charset utf-8;
access_log /var/log/nginx/www.example.com.log combined;
error_log /var/log/nginx/www.example.com.log error;
location / {
root /var/www/www.example.com;
index index.html;
}
}
Dépendances
Ce rôle ne dépend pas d'autres rôles.
Exemple de Playbook
Ce rôle peut être utilisé comme suit. Notez qu'il obtient plusieurs certificats et définit les variables utilisées pour tous les certificats de manière globale :
---
- name: obtenir des certificats pour le serveur web
hosts: webserver
vars:
acme_certificate_acme_account: 'keys/acme-account.key'
acme_certificate_acme_email: '[email protected]'
# Pour les défis HTTP :
acme_certificate_server_location: '/var/www/challenges/'
acme_certificate_http_challenge_user: root
acme_certificate_http_challenge_group: http
acme_certificate_http_challenge_folder_mode: "0750"
acme_certificate_http_challenge_file_mode: "0640"
# Pour les défis DNS avec route53 :
acme_certificate_dns_provider: route53
acme_certificate_aws_access_key: REMPLACEZ_PAR_VOTRE_CLE_D_ACCES
acme_certificate_aws_secret_key: REMPLACEZ_PAR_VOTRE_CLE_SECRETE
# Pour les défis DNS avec ns1 :
# acme_certificate_dns_provider: ns1
# acme_certificate_ns1_secret_key: REMPLACEZ_PAR_VOTRE_CLE_SECRETE
roles:
- role: acme_certificate
acme_certificate_domains: ['example.com', 'www.example.com']
# Utiliser des défis DNS :
acme_certificate_challenge: dns-01
# Les fichiers de certificat seront stockés à :
# keys/example.com.key (clé privée)
# keys/example.com.csr (demande de signature de certificat)
# keys/example.com.pem (certificat)
# keys/example.com.cnf (config OpenSSL pour CSR création -- peut être supprimé en toute sécurité)
# keys/example.com-chain.pem (certificat intermédiaire)
# keys/example.com-fullchain.pem (certificat avec certificat intermédiaire)
# keys/example.com-root.pem (certificat racine)
# keys/example.com-rootchain.pem (certificat intermédiaire avec certificat racine)
- role: acme_certificate
acme_certificate_domains: ['another.example.com']
acme_certificate_key_name: 'another.example.com-rsa'
acme_certificate_key_length: 4096
# Utiliser des défis HTTP :
acme_certificate_challenge: http-01
# Les fichiers de certificat seront stockés à :
# keys/another.example.com-rsa.key (clé privée)
# keys/another.example.com-rsa.csr (demande de signature de certificat)
# keys/another.example.com-rsa.pem (certificat)
# keys/another.example.com-rsa.cnf (config OpenSSL pour CSR création -- peut être supprimé en toute sécurité)
# keys/another.example.com-rsa-chain.pem (certificat intermédiaire)
# keys/another.example.com-rsa-fullchain.pem (certificat avec certificat intermédiaire)
# keys/another.example.com-rsa-root.pem (certificat racine)
# keys/another.example.com-rsa-rootchain.pem (certificat intermédiaire avec certificat racine)
- role: acme_certificate
acme_certificate_domains: ['another.example.com']
acme_certificate_key_name: 'another.example.com-ecc'
acme_certificate_algorithm: 'p-256'
# Utiliser des défis HTTP (le défi par défaut est http-01).
# Les fichiers de certificat seront stockés à :
# keys/another.example.com-ecc.key (clé privée)
# keys/another.example.com-ecc.csr (demande de signature de certificat)
# keys/another.example.com-ecc.pem (certificat)
# keys/another.example.com-ecc.cnf (config OpenSSL pour CSR création -- peut être supprimé en toute sécurité)
# keys/another.example.com-ecc-chain.pem (certificat intermédiaire)
# keys/another.example.com-ecc-fullchain.pem (certificat avec certificat intermédiaire)
# keys/another.example.com-ecc-root.pem (certificat racine)
# keys/another.example.com-ecc-rootchain.pem (certificat intermédiaire avec certificat racine)
Licence
La licence MIT (MIT)
Copyright (c) 2018-2020 Felix Fontein
La permission est par la présente accordée, sans frais, à toute personne obtenant une copie de ce logiciel et des fichiers de documentation associés (le "Logiciel"), de traiter dans le Logiciel sans restriction, y compris sans limitation les droits d'utiliser, copier, modifier, fusionner, publier, distribuer, sous-licencier et/ou vendre des copies du Logiciel, et de permettre à des personnes à qui le Logiciel est fourni de le faire, sous réserve des conditions suivantes :
L'avis de droit d'auteur ci-dessus et cet avis de permission doivent être inclus dans toutes les copies ou portions substantielles du Logiciel.
LE LOGICIEL EST FOURNI "EN L'ÉTAT", SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE, Y COMPRIS MAIS SANS LIMITATION AUX GARANTIES DE COMMERCIALISATION, D'ADÉQUATION À UN USAGE PARTICULIER ET DE NON-VIOLATION. EN AUCUN CAS, LES AUTEURS OU LES DÉTENTÉRS DU DROIT D'AUTEUR NE PEUVENT ÊTRE TENUS RESPONSABLES D'UNE REVENDICATION, DE DOMMAGES OU D'AUTRES RESPONSABILITÉS, QUE CE SOIT DANS UNE ACTION DE CONTRAT, DE DÉLIT OU AUTRE, DÉCOULANT DE, OU EN RAPPORT AVEC LE LOGICIEL OU L'UTILISATION OU D'AUTRES TRAITEMENTS DANS LE LOGICIEL.
Informations sur l'auteur
La page d'accueil pour ce rôle est https://github.com/felixfontein/acme-certificate/. Veuillez utiliser le système de suivi des problèmes pour signaler des problèmes.
Wrapper of Ansible's included acme_certificate module, whose aim is that almost no code is executed on the webserver. Requires the Python cryptography library as well as the OpenSSL binary installed locally and available on executable path.
ansible-galaxy install felixfontein.acme_certificate