systemli.letsencrypt
Rola Ansible do uzyskiwania certyfikatów SSL Let's Encrypt
Ta rola ma na celu żądanie certyfikatów SSL od Let's Encrypt, używając wyzwania HTTP lub DNS dla ich interfejsu API ACME.
Funkcje:
- Instaluje i konfiguruje certbot oraz skrypt pomocniczy do wyzwania DNS
- Obsługuje zarówno wyzwanie HTTP, jak i DNS
- Dla wyzwania HTTP, obsługiwane są wtyczki uwierzytelniające
apache
,nginx
,standalone
orazwebroot
- Dla wyzwania HTTP, obsługiwane są wtyczki uwierzytelniające
- Wyzwanie DNS używa dedykowanej strefy tylko dla tokenów wyzwania AMCE, co zmniejsza ryzyko związane z dynamicznymi aktualizacjami. Koncept jest wyjaśniony tutaj
- Restart usług przy odnawianiu certyfikatu z użyciem post-hooków lub własnego polecenia post-hook
- Kontrola dostępu do certyfikatów z użyciem dedykowanej grupy systemowej
Obsługiwane dystrybucje:
- Debian 11 (Bullseye)
- Debian 12 (Bookworm)
Testowane na:
- Debian 11 (Bullseye)
- Debian 12 (Bookworm)
- CentOS7
- Ubuntu 2204 (Jammy Jellyfish)
Co robi:
Gdy letsencrypt_setup jest True (domyślnie), ta rola wykonuje:
- Instaluje certbot
- Rejestruje konto w Let's Encrypt
- Instaluje wymagane pliki/klucze do wyzwania DNS
- Tworzy grupę systemową 'letsencrypt'
Gdy wywołana jest z wypełnioną zmienną 'letsencrypt_cert':
- Żąda certyfikatu SSL za pośrednictwem interfejsu API ACME Let's Encrypt, używając wyzwania HTTP lub DNS
- Opcjonalnie ustawia post-hook dla odnawiania certyfikatów (aby uruchomić wymagane usługi po tym)
- Opcjonalnie dodaje użytkowników systemowych do grupy 'letsencrypt', aby przyznać im dostęp do certyfikatów SSL i ich kluczy prywatnych
Jak to działa (przykłady)
- Instalacja certbota
ansible-playbook site.yml -l localhost -t letsencrypt
- Tworzenie certyfikatu za pomocą wyzwania HTTP i uwierzytelniającego
webroot
(restartowanie usługi 'apache2' przy odnawianiu):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"]}}'
- Tworzenie certyfikatu za pomocą wyzwania DNS (przyznawanie dostępu do
certyfikatów dla użytkownika 'Debian-exim', restartowanie usług 'exim4' i 'dovecot`
przy odnawianiu):
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"]}}'
- Tworzenie certyfikatu za pomocą wyzwania HTTP i uwierzytelniającego
standalone
(ponowne użycie tego samego klucza prywatnego przy odnawianiu i uruchomienie własnego skryptu post-hook przy odnawianiu):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"}}'
Oczekiwana struktura zmiennej letsencrypt_cert
Zmienna letsencrypt_cert
powinna być słownikiem:
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
lub:
letsencrypt_cert:
name: sub2
domains:
- sub2.example.org
- sub2.another.example.org
challenge: dns
services:
- dovecot
- exim4
users:
- Debian-exim
lub:
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"
letsencrypt_cert:
name: sub3
domains:
- sub3.example.org
challenge: http
http_auth: standalone
reuse_key: True
deploy_hook: "/usr/local/bin/cert-post-hook.sh"
Słownik obsługuje następujące klucze:
name
: nazwa certyfikatu [opcjonalnie]domains
: lista domen dla certyfikatu [wymagane]challenge
: 'http' lub 'dns' [wymagane]- dla wyzwania 'http':
http_auth
: 'webroot', 'apache' lub 'nginx' [opcjonalnie, domyślnie 'webroot']- dla
http_auth
'webroot':webroot_path
[opcjonalnie, domyślnie '/var/www']
- dla
- dla wyzwania 'http':
services
: lista usług do zrestartowania w post-hook [opcjonalnie]reuse_key
: Ponowne użycie tego samego klucza prywatnego przy odnawianiu certyfikatu. 'True' lub 'False' (domyślnie 'False')post_hook
: Własny post-hook do wykonania po próbie uzyskania/odnowienia certyfikatu [opcjonalnie]deploy_hook
: Własny deploy-hook do wykonania po udanej próbie uzyskania/odnowienia certyfikatu [opcjonalnie]renew_hook
: Własny renew-hook do wykonania raz dla każdego odnowionego certyfikatu po odnawianiu certyfikatu [opcjonalnie]users
: lista użytkowników do dodania do grupy systemowej 'letsencrypt' [opcjonalnie]
Ogólne wstępne informacje
Rola zajmuje się instalacją certbota i żądaniem certyfikatów SSL używając wyzwania HTTP lub DNS. Nie instaluje ani nie konfiguruje wymaganej infrastruktury (tj. serwera Apache czy serwera DNS).
Rola jest testowana tylko z Ansible 2.2. Brak gwarancji, że działa z wcześniejszymi wersjami Ansible.
Wyzwanie HTTP
Wymagania:
- Nazwa domeny (domen), dla której żądany jest certyfikat, musi wskazywać na system
- Dla
http_auth
'apache', Apache2 musi być zainstalowany (i skonfigurowany) na systemie - Dla
http_auth
'nginx', NGINX musi być zainstalowany (i skonfigurowany) na systemie
Wyzwanie DNS
Wymagania:
- Serwer DNS z dedykowaną strefą, używaną tylko dla wyzwania DNS ACME. Ta strefa musi pozwalać na dynamiczne aktualizacje DNS (NSUPDATE).
- Rekordy CNAME dla
_acme-challenge.sub.example.org
dla wszystkich nazw domen żądanych certyfikatów muszą wskazywać nasub.example.org._le.example.org
(w dedykowanej strefie dla wyzwania DNS ACME). - Zawartość klucza aktualizacji DNS i prywatnych kluczy aktualizacji DNS
musi być dostępna w zmiennych Ansible
letsencrypt_ddns_key
iletsencrypt_ddns_privkey
(najlepiej wewnątrz skarbca).
Ta rola instaluje skrypt pomocniczy do wyzwania DNS w
/usr/local/bin/certbot-dns-hook.sh
. Skrypt ten doda token weryfikacyjny
do rekordu TXT w sub.example.org._le.example.org
podczas wyzwania DNS
i usunie go później.
Obsługa wildcard dla wyzwania DNS
Uzyskiwanie certyfikatów wildcard powinno działać od razu przez wyzwanie DNS.
Konfiguracja bind9 dla wyzwania DNS
(Inną opcją byłoby użycie serwera acme-dns dla tego)
Wygeneruj klucz do dynamicznych aktualizacji:
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
Dodaj klucz do konfiguracji bind (np. w /etc/bind/named.conf.options
):
key "_le.example.org_ddns_update" {
algorithm hmac-sha512;
secret "...";
};
Utwórz strefę dla dynamicznych aktualizacji:
$ORIGIN .
$TTL 86400 ; 1 dzień
_le.example.org IN SOA ns1.example.org. postmaster.example.org. (
2017061501 ; serial
86400 ; odświeżanie (1 dzień)
3600 ; ponowna próba (1 godzina)
2419200 ; wygaszenie (4 tygodnie)
86400 ; minimum (1 dzień)
)
NS ns1.example.org.
NS ns2.example.org.
TXT "v=spf1 -all"
i skonfiguruj ją w swoim pliku konfiguracyjnym bind (np. w /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 dla /etc/letsencrypt/keys/ddns_update.key
(z bind)
key "<key>" {
algorithm HMAC-SHA512;
secret "<key>";
};
Format dla /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
Domyślne zmienne Ansible
# Wykonaj krok instalacji; ustaw na false, aby wyłączyć
letsencrypt_setup: True
# Podaj istniejące dane konta do skopiowania
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
# Ustaw adres e-mail związany z kontem Let's Encrypt
letsencrypt_account_email: ""
# Domyślny uwierzytelniacz dla wyzwania HTTP ('webroot' lub 'apache')
letsencrypt_http_auth: webroot
# Domyślna ścieżka do webroot dla uwierzytelniającego 'webroot'
letsencrypt_webroot_path: /var/www
# Zainstaluj skrypt pomocniczy do wyzwania DNS i klucz aktualizacji DNS
letsencrypt_dns_challenge: yes
# Ustawienia dla dynamicznych aktualizacji strefy DNS
# letsencrypt_ddns_server: ""
# letsencrypt_ddns_zone: ""
# letsencrypt_ddns_key: ""
# letsencrypt_ddns_privkey: ""
# Utwórz grupę systemową 'letsencrypt' dla dostępu do certyfikatów
letsencrypt_group: yes
# Ponownie używać klucza prywatnego przy odnawianiu certyfikatu?
letsencrypt_reuse_key: False
# Zezwolić na podzbiór nazw?
letsencrypt_subset_names: True
# Ustaw globalne dodatkowe opcje wiersza poleceń dla certbota
letsencrypt_opts_extra: ""
# Ustaw ścieżkę do katalogu letsencrypt (bez ukośnika na końcu !!)
letsencrypt_directory: /etc/letsencrypt
Testowanie
Do celów testowych, zmienna letsencrypt_test
może być ustawiona. Jeśli ustawiona na
True, rola użyje testowych serwerów Let's Encrypt do tworzenia konta
i uzyskiwania certyfikatu.
Do rozwijania i testowania roli używamy Molecule i Vagrant/Github Actions. W lokalnym środowisku można łatwo przetestować rolę za pomocą
molecule test
Licencja
Ta rola Ansible jest licencjonowana na mocy GNU GPLv3.
Autor
Copyright 2017-2019 systemli.org (https://www.systemli.org/)
ansible-galaxy install systemli.letsencrypt