systemli.letsencrypt
Ansible-Rolle zur Beschaffung von Let's Encrypt SSL-Zertifikaten
Diese Rolle ist dazu gedacht, SSL-Zertifikate von Let's Encrypt anzufordern, indem entweder die HTTP- oder die DNS-Herausforderung für die ACME-API verwendet wird.
Funktionen:
- Installiert und konfiguriert certbot und das Hilfsskript für die DNS-Herausforderung
- Unterstützt sowohl die HTTP- als auch die DNS-Herausforderung
- Für die HTTP-Herausforderung werden die Authentifikator-Plugins
apache
,nginx
,standalone
undwebroot
unterstützt
- Für die HTTP-Herausforderung werden die Authentifikator-Plugins
- Die DNS-Herausforderung nutzt eine dedizierte Zone nur für AMCE-Herausforderungstokens, was die Sicherheitsrisiken dynamischer Updates senkt. Das Konzept wird hier erklärt
- Neustart von Diensten bei der Zertifikatsverlängerung mit Post-Hooks oder benutzerdefinierten Post-Hook-Befehlen
- Berechtigungssteuerung zu Zertifikaten durch eine dedizierte Systemgruppe
Unterstützte Distributionen:
- Debian 11 (Bullseye)
- Debian 12 (Bookworm)
Getestet auf:
- Debian 11 (Bullseye)
- Debian 12 (Bookworm)
- CentOS7
- Ubuntu 2204 (Jammy Jellyfish)
Funktionsweise:
Wenn
letsencrypt_setup
auf True (Standard) gesetzt ist, wird diese Rolle:- certbot installieren
- Ein Konto bei Let's Encrypt registrieren
- Die erforderlichen Dateien/Schlüssel für die DNS-Herausforderung installieren
- Die Systemgruppe 'letsencrypt' erstellen
Wenn mit einer ausgefüllten Variable
letsencrypt_cert
aufgerufen:- Ein SSL-Zertifikat über die Let’s Encrypt ACME API anfordern, entweder mit der HTTP- oder DNS-Herausforderung
- Optional den Post-Hook für Zertifikatsverlängerungen festlegen (um erforderliche Dienste danach neu zu starten)
- Optional Systembenutzer zur Gruppe 'letsencrypt' hinzufügen, um ihnen Lesezugriff auf die SSL-Zertifikate und deren private Schlüssel zu gewähren
Beispielhafte Verwendung
- Installation von certbot:
ansible-playbook site.yml -l localhost -t letsencrypt
- Erstellung eines Zertifikats über die HTTP-Herausforderung mit
webroot
-Authentifikator (Neustart des Dienstes 'apache2' bei Verlängerung):ansible-playbook site.yml -l localhost -t letsencrypt -e '{"letsencrypt_cert":{"name":"sub.example.org","domains":["sub.example.org"],"challenge":"http","http_auth":"webroot","webroot_path":"/var/www/sub.example.org","services":["apache2"]}}'
- Erstellung eines Zertifikats über die DNS-Herausforderung (Gewährung von Lesezugriff auf Zertifikate für den Benutzer 'Debian-exim', Neustart der Dienste 'exim4' und 'dovecot' bei Verlängerung):
ansible-playbook site.yml -l localhost -t letsencrypt -e '{"letsencrypt_cert":{"name":"sub2","domains":["sub2.example.org","sub2.another.example.org"],"challenge":"dns","services":["dovecot","exim4"],"users":["Debian-exim"]}}'
- Erstellung eines Zertifikats über die HTTP-Herausforderung mit
standalone
-Authentifikator (Wiederverwendung des gleichen privaten Schlüssels bei Verlängerung oder Ausführung eines benutzerdefinierten Post-Hook-Skripts bei Verlängerung):ansible-playbook site.yml -l localhost -t letsencrypt -e '{"letsencrypt_cert":{"name":"sub3","domains":["sub3.example.org"],"challenge":"http","http_auth":"standalone","reuse_key":True,"post_hook":"/usr/local/bin/cert-post-hook.sh"}}'
Erwartete Struktur der Variable letsencrypt_cert
Die Variable letsencrypt_cert
wird als Wörterbuch erwartet:
letsencrypt_opts_extra: "--register-unsafely-without-email"
letsencrypt_cert:
name: sub.example.org
domains:
- sub.example.org
challenge: http
http_auth: webroot
webroot_path: /var/www/sub.example.org
services:
- apache2
oder:
letsencrypt_cert:
name: sub2
domains:
- sub2.example.org
- sub2.another.example.org
challenge: dns
services:
- dovecot
- exim4
users:
- Debian-exim
oder:
letsencrypt_cert:
name: sub3
domains:
- sub3.example.org
challenge: http
http_auth: standalone
reuse_key: True
post_hook: "/usr/local/bin/cert-post-hook.sh"
Das Wörterbuch unterstützt folgende Schlüssel:
name
: Name des Zertifikats [optional]domains
: Liste der Domains für das Zertifikat [erforderlich]challenge
: 'http' oder 'dns' [erforderlich]- für die Herausforderung 'http':
http_auth
: 'webroot', 'apache' oder 'nginx' [optional, Standard 'webroot']- für
http_auth
: 'webroot':webroot_path
[optional, Standard '/var/www']
- für
- für die Herausforderung 'http':
services
: Liste der Dienste, die im Post-Hook neu gestartet werden sollen [optional]reuse_key
: Den gleichen privaten Schlüssel bei der Zertifikatsverlängerung wiederverwenden. 'True' oder 'False' (Standard 'False')post_hook
: Benutzerdefinierter Post-Hook, der nach dem Versuch, ein Zertifikat zu erhalten/verlängern, ausgeführt wird [optional]deploy_hook
: Benutzerdefinierter Deploy-Hook, der nach einem erfolgreichen Versuch, ein Zertifikat zu erhalten/verlängern, ausgeführt wird [optional]renew_hook
: Benutzerdefinierter Renew-Hook, der einmal für jedes erneuerte Zertifikat nach der Zertifikatsverlängerung ausgeführt wird [optional]users
: Liste der Benutzer, die zur Systemgruppe 'letsencrypt' hinzugefügt werden sollen [optional]
Allgemeine Vorbedingungen
Die Rolle kümmert sich um die Installation von certbot und die Anforderung von SSL-Zertifikaten mithilfe der HTTP- oder DNS-Herausforderung. Es installiert oder konfiguriert nicht die erforderliche Infrastruktur (z. B. den Apache-Webserver oder einen DNS-Server).
Die Rolle wurde nur mit Ansible 2.2 getestet. Es gibt keine Garantien, dass sie mit älteren Versionen von Ansible funktioniert.
Die HTTP-Herausforderung
Anforderungen:
- Die Domainnamen des angeforderten Zertifikats müssen auf das System zeigen
- Für
http_auth
'apache' muss Apache2 auf dem System installiert (und konfiguriert) sein - Für
http_auth
'nginx' muss NGINX auf dem System installiert (und konfiguriert) sein
Die DNS-Herausforderung
Anforderungen:
- Ein DNS-Server mit einer dedizierten Zone, die nur für die ACME-DNS-Herausforderung verwendet wird. Diese Zone muss dynamische DNS-Updates (NSUPDATE) für TXT-Datensätze erlauben.
- CNAME-Einträge für
_acme-challenge.sub.example.org
müssen für alle Domainnamen des angeforderten Zertifikats aufsub.example.org._le.example.org
zeigen (innerhalb der speziellen Zone für die ACME-DNS-Herausforderung). - Der Inhalt des DNS-Update-Schlüssels und der privaten DNS-Update-Schlüssel müssen in den Ansible-Variablen
letsencrypt_ddns_key
undletsencrypt_ddns_privkey
verfügbar sein (vorzugsweise innerhalb eines Vaults).
Diese Rolle installiert ein Hilfsskript für die DNS-Herausforderung in /usr/local/bin/certbot-dns-hook.sh
. Dieses Skript fügt während der DNS-Herausforderung das Validierungstoken zum TXT-Datensatz bei sub.example.org._le.example.org
hinzu und entfernt es anschließend.
Wildcard-Unterstützung mit der DNS-Herausforderung
Die Beschaffung von Wildcard-Zertifikaten sollte ohne Probleme über die DNS-Herausforderung funktionieren.
Konfiguration von bind9 für die DNS-Herausforderung
(Eine andere Option wäre die Verwendung des acme-dns-Servers dafür)
Generieren Sie einen Schlüssel für dynamische Updates:
cd /etc/bind/keys
dnssec-keygen -a HMAC-SHA512 -b 512 -n USER _le.example.org_ddns_update
chown -R bind:bind /etc/bind/keys
Fügen Sie den Schlüssel in Ihre bind-Konfiguration ein (z. B. in /etc/bind/named.conf.options
):
key "_le.example.org_ddns_update" {
algorithm hmac-sha512;
secret "...";
};
Erstellen Sie die Zone für dynamische Updates:
$ORIGIN .
$TTL 86400 ; 1 Tag
_le.example.org IN SOA ns1.example.org. postmaster.example.org. (
2017061501 ; Seriennummer
86400 ; Aktualisierungsintervall (1 Tag)
3600 ; Wiederholungsintervall (1 Stunde)
2419200 ; Ablauffrist (4 Wochen)
86400 ; Minimalzeit (1 Tag)
)
NS ns1.example.org.
NS ns2.example.org.
TXT "v=spf1 -all"
und konfigurieren Sie es in Ihrer bind-Konfiguration (z. B. in /etc/bind/named.conf.local
):
zone "_le.example.org" {
type master;
file "/etc/bind/zones/db._le.example.org";
update-policy { grant _le.example.org_ddns_update wildcard *._le.example.org. TXT; };
};
Format für /etc/letsencrypt/keys/ddns_update.key
(von bind):
key "<key>" {
algorithm HMAC-SHA512;
secret "<key>";
};
Format für /etc/letsencrypt/keys/ddns_update.private
:
Private-key-format: v1.3
Algorithm: 165 (HMAC_SHA512)
Key: <key>
Bits: AAA=
Created: 20181017144534
Publish: 20181017144534
Activate: 20181017144534
Ansible-Standardvariablen
# Einrichtungsprozess durchführen; auf false setzen, um zu deaktivieren
letsencrypt_setup: True
# Vorhandene Kontodaten bereitstellen, die kopiert werden sollen
letsencrypt_account: ""
# letsencrypt_account:
# hash: 1234567890abcdef1234567890abcdef
# id: 123456789
# creation_host: localhost
# creation_dt: 2020-12-13T13:12:00Z
# private_key:
# n: 1234
# e: 5678
# d: 90ab
# p: cdef
# q: 1234
# dp: 5678
# dq: 90ab
# qi: cdef
# kty: RSA
# Die E-Mail-Adresse festlegen, die mit dem Let's Encrypt-Konto verknüpft ist
letsencrypt_account_email: ""
# Standardauthentifikator für die HTTP-Herausforderung ('webroot' oder 'apache')
letsencrypt_http_auth: webroot
# Standard-Webroot-Pfad für den Authentifikator 'webroot'
letsencrypt_webroot_path: /var/www
# Das Hilfsskript für die DNS-Herausforderung und den DNS-Update-Schlüssel installieren
letsencrypt_dns_challenge: ja
# Einstellungen für die dynamischen DNS-Zonenupdates
# letsencrypt_ddns_server: ""
# letsencrypt_ddns_zone: ""
# letsencrypt_ddns_key: ""
# letsencrypt_ddns_privkey: ""
# Erstellen Sie die Systemgruppe 'letsencrypt' für den Zugriff auf Zertifikate
letsencrypt_group: ja
# Den privaten Schlüssel bei der Zertifikatsverlängerung wiederverwenden?
letsencrypt_reuse_key: False
# Erlaubt eine Untermenge von Namen?
letsencrypt_subset_names: True
# Globale zusätzliche Befehlszeilenoptionen für certbot festlegen
letsencrypt_opts_extra: ""
# Pfad für das letsencrypt-Verzeichnis festlegen (kein abschließender "/" !!)
letsencrypt_directory: /etc/letsencrypt
Testen
Zu Testzwecken kann die Variable letsencrypt_test
gesetzt werden. Wenn sie auf True gesetzt ist, verwendet die Rolle die Testserver von Let's Encrypt zur Kontoerstellung und zur Beschaffung des Zertifikats.
Für die Entwicklung und das Testen der Rolle verwenden wir Molecule und Vagrant/Github Actions. In der lokalen Umgebung können Sie die Rolle ganz einfach mit
molecule test
testen.
Lizenz
Diese Ansible-Rolle ist unter der GNU GPLv3 lizenziert.
Autor
Copyright 2017-2019 systemli.org (https://www.systemli.org/)
ansible-galaxy install systemli.letsencrypt