felixfontein.acme_certificate
acme_certificate 1.1.1
TA ROLE JEST NIESTOSOWANA! PROSIMY UŻYWAĆ ZBIORU WERSJI felixfontein.acme ZAMIENIE!
Umożliwia uzyskanie certyfikatów od Let's Encrypt przy minimalnej interakcji z serwerem WWW. Większość kodu jest wykonywana na kontrolerze, a klucz konta nigdy nie jest przesyłany do węzłów.
Role można zainstalować przez Ansible Galaxy:
ansible-galaxy install felixfontein.acme_certificate
Dla zmian w tej roli zobacz dziennik zmian.
Opis
To jest rola Ansible, która może używać dowolnego CA wspierającego protokół ACME, takiego jak Let's Encrypt lub Buypass, do wydawania certyfikatów TLS/SSL dla twojego serwera. Ta rola wymaga Ansible 2.8.3 lub nowszego i opiera się na module acme_certificate dostarczanym z Ansible.
Główną zaletą tego podejścia w porównaniu do innych jest to, że prawie żaden kod nie jest wykonywany na twoim serwerze WWW: tylko w przypadku używania wyzwań HTTP pliki muszą być kopiowane na serwer WWW, a następnie usuwane. Wszystko inne jest wykonywane na twoim lokalnym komputerze!
(To nie obejmuje instalacji certyfikatów, musisz to zrobić samodzielnie w innej roli.)
Wymagania
Wymagana jest biblioteka Python cryptography zainstalowana na kontrolerze, dostępna dla wersji Pythona używanej do wykonania playbooka. Jeśli cryptography
nie jest zainstalowane, wspierana jest wystarczająco nowa wersja PyOpenSSL jako alternatywa przez moduły Ansible openssl_privatekey
i openssl_csr
.
Binarne narzędzie openssl
również musi być dostępne w ścieżce wykonywalnej na kontrolerze. Jest używane przez moduł acme_certificate
w przypadku, gdy cryptography
nie jest zainstalowane, i jest używane do walidacji łańcucha certyfikatów.
Jeśli stosowane są wyzwania DNS, mogą istnieć inne wymagania w zależności od dostawcy DNS. Na przykład dla Route 53 Amazona, moduł Ansible route53
wymaga pakietu Pythona boto
.
Ustawienie Klucza Konta
Możesz utworzyć klucz konta za pomocą narzędzia openssl
w następujący sposób:
# Klucz RSA 4096 bitowy
openssl genrsa 4096 -out keys/acme-account.key
# Klucz ECC 256 bitowy (P-256)
openssl ecparam -name prime256v1 -genkey -out keys/acme-account.key
# Klucz ECC 384 bitowy (P-384)
openssl ecparam -name secp384r1 -genkey -out keys/acme-account.key
Z Ansible można użyć modułu openssl_privatekey
w następujący sposób:
- name: Generuj klucz RSA 4096
openssl_privatekey:
path: keys/acme-account.key
type: RSA
size: 4096
- name: Generuj klucz ECC 256 bitowy (P-256)
openssl_privatekey:
path: keys/acme-account.key
type: ECC
curve: secp256r1
- name: Generuj klucz ECC 384 bitowy (P-384)
openssl_privatekey:
path: keys/acme-account.key
type: ECC
curve: secp384r1
Upewnij się, że bezpiecznie przechowujesz klucz konta. W przeciwieństwie do prywatnych kluczy certyfikatów, nie ma potrzeby jego częstego regenerowania, a unieważnienie wydanych certyfikatów jest bardzo proste.
Zmienne Roli
Należy pamiętać, że od maja 2020 roku wszystkie zmienne muszą być poprzedzone acme_certificate_
. Przez pewien czas moduł wciąż użyje starych (krótkich) nazw zmiennych, jeśli dłuższe nie zostaną zdefiniowane. Proszę jak najszybciej zaktualizować użycie roli.
Oto główne zmienne:
acme_certificate_acme_account
: Ścieżka do prywatnego klucza konta ACME. Musi być zawsze określona.acme_certificate_acme_email
: Twój adres e-mail, który ma być powiązany z kontem ACME. Musi być zawsze określony.acme_certificate_algorithm
: Algorytm używany do tworzenia prywatnych kluczy. Domyślnie"rsa"
; inne możliwości to"p-256"
,"p-384"
lub"p-521"
dla krzywych eliptycznych NISTprime256v1
,secp384r1
isecp521r1
.acme_certificate_key_length
: Długość klucza do użycia dla prywatnych kluczy RSA. Domyślnie 4096.acme_certificate_key_name
: Podstawowa nazwa dla przechowywania kluczy i certyfikatów. Domyślnie jest to pierwsza domena określona, z*
zastąpionym przez_
.acme_certificate_keys_path
: Gdzie przechowywane są klucze i certyfikaty. Domyślna wartość to"keys/"
.acme_certificate_keys_old_path
: Gdzie stare klucze i certyfikaty powinny zostać skopiowane; używane, jeśliacme_certificate_keys_old_store
jest prawdziwe. Domyślna wartość to"keys/old/"
.acme_certificate_keys_old_store
: Jeśli ustawione natrue
, utworzy kopie starych kluczy i certyfikatów. Kopie będą przechowywane w katalogu określonym przezacme_certificate_keys_old_store
. Domyślna wartość tofalse
.acme_certificate_keys_old_prepend_timestamp
: Czy kopie starych kluczy i certyfikatów powinny być poprzedzone bieżącą datą i czasem. Domyślna wartość tofalse
.acme_certificate_ocsp_must_staple
: Czy żądany jest certyfikat z rozszerzeniem OCSP Must Staple. Domyślna wartość tofalse
.acme_certificate_agreement
: Dokument warunków umowy, z którym użytkownik się zgadza. Domyślna wartość tohttps://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf
.acme_certificate_acme_directory
: Katalog ACME do użycia. Domyślna wartość tohttps://acme-v02.api.letsencrypt.org/directory
, który jest aktualnym produkcyjnym punktem dostępu ACME v2 dla Let's Encrypt.acme_certificate_acme_version
: Wersja katalogu ACME. Domyślna wartość to 2. Użyj 1 dla ACME v1.acme_certificate_challenge
: Typ wyzwania do użycia. Powinno byćhttp-01
dla wyzwań HTTP (wymaga dostępu do serwera WWW) lubdns-01
dla wyzwań DNS (wymaga dostępu do dostawcy DNS).acme_certificate_root_certificate
: Główny certyfikat dla katalogu ACME. Domyślna wartość tohttps://letsencrypt.org/certs/isrgrootx1.pem
dla głównego certyfikatu Let's Encrypt.acme_certificate_deactivate_authzs
: Czyauthz
s (autoryzacje) powinny być następnie dezaktywowane. Domyślna wartość totrue
. Ustaw nafalse
, aby móc ponownie używaćauthz
s.acme_certificate_modify_account
: Czy konto ACME powinno być utworzone (jeśli nie istnieje) i dane kontaktowe (adres e-mail) powinny być zaktualizowane. Domyślna wartość totrue
. Ustaw nafalse
, jeśli chcesz używać modułuacme_account
do zarządzania swoim kontem ACME (nie zarządzane przez tę rolę).acme_certificate_privatekey_mode
: Jaki tryb plików użyć dla pliku klucza prywatnego. Domyślna wartość to"0600"
, co oznacza, że tylko właściciel ma prawo do odczytu i zapisu, ale nikt inny (z wyjątkiem ewentualnieroot
).acme_certificate_select_chain
: (Dostępne tylko w Ansible 2.10+) Musi być w formacie opisanym tutaj. Umożliwia wybór łańcucha certyfikatów do użycia;acme_certificate_root_certificate
musi być używane łącznie. Może to być na przykład używane z Let's Encrypt, aby wybrać, który główny certyfikat użyć.
Wyzwania HTTP
Dla wyzwań HTTP, następujące zmienne definiują, jak wyzwania mogą być umieszczane na (zdalnym) serwerze WWW:
acme_certificate_server_location
: Miejsce, z którego będą serwowane.well-known/acme-challenge/
. Domyślnie/var/www/challenges
.acme_certificate_http_become
: Argument dlabecome:
dla zadańfile
icopy
. Domyślna wartość tofalse
.acme_certificate_http_challenge_user
: Użytkownik, którego pliki wyzwań są własnością. Domyślna wartość toroot
.acme_certificate_http_challenge_group
: Grupa, której pliki wyzwań są własnością. Domyślna wartość tohttp
.acme_certificate_http_challenge_folder_mode
: Tryb do użycia dla folderu wyzwań. Domyślna wartość to0750
(ósemkowy).acme_certificate_http_challenge_file_mode
: Tryb do użycia dla plików wyzwań. Domyślna wartość to0640
(ósemkowy).
Niżej przedstawiono jak skonfigurować nginx dla wyzwań HTTP. Konfiguracja innych serwerów WWW może być zrobiona w podobny sposób.
Konfiguracja nginx
Zakładamy, że dla jednej z domen zabezpieczonych TLS/SSL używasz przekierowania HTTP do HTTPS. Zakładamy, że wygląda to tak:
server {
listen example.com:80;
server_name example.com *.example.com;
return 301 https://www.example.com$request_uri;
}
Aby umożliwić roli acme_certificate
umieszczenie czegokolwiek pod http://*.example.com/.well-known/acme-challenge/
, można to zmienić na:
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;
}
}
Dzięki tej konfiguracji nginx, wszystkie inne adresy URL na *.example.com
i example.com
nadal będą przekierowywane, podczas gdy wszystko w *.example.com/.well-known/acme-challenge/
będzie serwowane z /var/www/challenges
. Przy dostosowywaniu lokalizacji /var/www/challenges
, musisz również zmienić acme_certificate_server_location
.
Możesz nawet poprawić to, przekierowując wszystkie adresy URL w *.example.com/.well-known/acme-challenge/
, które nie wskazują na ważny plik w /var/www/challenges
, do swojego serwera HTTPS. Jednym sposobem, aby to zrobić, jest:
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;
}
}
Z tą konfiguracją, jeśli /var/www/challenges/
jest pusty, twój serwer HTTP będzie działał tak, jakby lokalizacja /.well-known/acme-challenge/
nie była określona.
Wyzwania DNS
Jeśli stosowane są wyzwania DNS, następujące zmienne definiują, jak wyzwania mogą być spełnione:
acme_certificate_dns_provider
: Musi być jednym zroute53
,hosttech
ins1
. Każdy potrzebuje więcej informacji:- Dla
route53
(Amazon Route 53), muszą być przekazane dane uwierzytelniające jakoacme_certificate_aws_access_key
iacme_certificate_aws_secret_key
. - Dla
hosttech
(hosttech GmbH, wymaga zewnętrznego hosttech_dns_record module). - Dla
ns1
(ns1.com) klucz do twojego konta API musi być przekazany jakoacme_certificate_ns1_secret_key
. Również zależy od zewnętrznego modułuns1_record
. Zakładając domyślną strukturę katalogów i ustawienia, możesz potrzebować pobrać 2 pliki na maszynę, na której wykonywany jest playbook:
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
- Dla
Należy pamiętać, że kod wyzwań DNS nie jest doskonały. Funkcjonalność Route 53, Hosttech i NS1 została przetestowana. Jedną rzeczą, która nie jest w pełni rozwiązywana, jest to, że kod próbuje wydobyć strefę DNS z domeny, biorąc ostatnie dwa składniki rozdzielone kropkami. To nie zadziała, na przykład dla domen .co.uk
lub innych zagnieżdżonych stref.
Obsługę większej liczby dostawców DNS można dodać, dodając pliki tasks/dns-NAME-create.yml
i tasks/dns-NAME-cleanup.yml
z podobną zawartością jak w istniejących plikach.
Konwersja klucza konta
Należy pamiętać, że ta rola Ansible oczekuje, że klucz konta Let's Encrypt będzie w formacie PEM, a nie w formacie JWK, który jest używany przez oficjalnego klienta Let's Encrypt certbot. Jeśli utworzyłeś klucz konta za pomocą oficjalnego klienta, a teraz chcesz użyć tego klucza z tą rolą ansible, musisz go przekonwertować. Jednym z narzędzi, które może to zrobić, jest pem-jwk.
Wygenerowane pliki
Załóżmy, że utworzyłeś klucze TLS dla www.example.com
. Musisz skopiować odpowiednie pliki na swój serwer WWW. Rola ansible utworzyła następujące pliki:
keys/www.example.com.key
: to jest prywatny klucz certyfikatu. Upewnij się, że nikt nie ma do niego dostępu.keys/www.example.com.pem
: to jest certyfikat.keys/www.example.com-chain.pem
: to są pośrednie certyfikaty potrzebne do ścieżki zaufania.keys/www.example.com.cnf
: to jest plik konfiguracyjny OpenSSL używany do stworzenia Żądania Podpisania Certyfikatu. Możesz go bezpiecznie usunąć.keys/www.example.com.csr
: to jest Żądanie Podpisania Certyfikatu używane do uzyskania certyfikatu. Możesz je bezpiecznie usunąć.keys/www.example.com-fullchain.pem
: to jest certyfikat połączony z pośrednimi certyfikatami.keys/www.example.com-rootchain.pem
: to są pośrednie certyfikaty połączone z głównym certyfikatem. Możesz tego potrzebować do OCSP stapling.keys/www.example.com-root.pem
: to jest główny certyfikat Let's Encrypt.
Do skonfigurowania serwera WWW potrzebujesz klucza prywatnego (keys/www.example.com.key
) i albo certyfikatu z pośrednimi certyfikatami połączonymi w jeden plik (keys/www.example.com-fullchain.pem
), albo certyfikatu i pośrednich certyfikatów jako dwa oddzielne pliki (keys/www.example.com.pem
i keys/www.example.com-chain.pem
). Jeśli chcesz używać OCSP stapling, będziesz również potrzebować keys/www.example.com-rootchain.pem
.
Aby uzyskać te pliki na swój serwer WWW, możesz dodać zadania w następujący sposób:
- name: kopiuj prywatne klucze
copy:
src: keys/{{ item }}
dest: /etc/ssl/private/
owner: root
group: root
mode: "0400"
with_items:
- www.example.com.key
notify: przeładuj serwer WWW
- name: kopiuj certyfikaty
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: przeładuj serwer WWW
Konfiguracja serwera WWW może wyglądać następująco (dla nginx):
server {
listen www.example.com:443 ssl; # IPv4: nasłuchuj na IP, do którego wskazuje www.example.com
listen [::]:443 ssl; # IPv6: nasłuchuj na localhost
server_name www.example.com;
# Zezwalamy tylko na TLS 1.0 i 1.2, z bardzo selektywną ilością szyfrów.
# Zgodnie z testem serwera SSL Lab, zablokuje to:
# - Android 2.3.7
# - IE 6 i 8 w Windows XP
# - Java 6, 7 i 8
# Jeśli to nie jest dla ciebie akceptowalne, wybierz inne listy szyfrów. Szukaj
# na przykład na 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";
# Łańcuch certyfikatów wysyłany do przeglądarki, a także klucz prywatny.
# Upewnij się, że twój klucz prywatny jest dostępny tylko dla serwera WWW podczas
# ładowania konfiguracji (co jest domyślnie wykonywane przez użytkownika root).
ssl_certificate /etc/ssl/server-certs/www.example.com-fullchain.pem;
ssl_certificate_key /etc/ssl/private/www.example.com.key;
# Do OCSP stapling potrzebujemy resolvera DNS. Tutaj podane są tylko publiczne serwery DNS Quad9 i
# Google; sugerowałbym poprzedzić je serwerami DNS twojego dostawcy. Zwykle możesz znaleźć ich IP w /etc/resolv.conf na
# swoim serwerze WWW.
resolver 9.9.9.9 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 10s;
# Włączanie OCSP stapling. Nginx automatycznie zajmie się pobieraniem danych OCSP.
# Zobacz https://wiki.mozilla.org/Security/Server_Side_TLS#OCSP_Stapling
# w celu uzyskania szczegółowych informacji na temat OCSP stapling.
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/ssl/server-certs/www.example.com-rootchain.pem;
# Włącza pamięć podręczną sesji SSL. Dostosuj liczby w zależności od użycia twojej strony.
ssl_session_cache shared:SSL:50m;
ssl_session_timeout 30m;
ssl_session_tickets off;
# Powinieneś używać HSTS tylko z odpowiednimi certyfikatami; te od Let's Encrypt
# są w porządku, samodzielnie podpisane nie. Zobacz MozillaWiki w celu uzyskania dalszych informacji:
# 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;
}
}
Zależności
Ta rola nie zależy od innych ról.
Przykładowy Playbook
Ta rola może być używana w następujący sposób. Zauważ, że uzyskuje kilka certyfikatów i definiuje zmienne używane dla wszystkich certyfikatów globalnie:
---
- name: uzyskiwanie certyfikatów dla serwera WWW
hosts: webserver
vars:
acme_certificate_acme_account: 'keys/acme-account.key'
acme_certificate_acme_email: '[email protected]'
# Dla wyzwań 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"
# Dla wyzwań DNS z route53:
acme_certificate_dns_provider: route53
acme_certificate_aws_access_key: REPLACE_WITH_YOUR_ACCESS_KEY
acme_certificate_aws_secret_key: REPLACE_WITH_YOUR_SECRET_KEY
# Dla wyzwań DNS z ns1:
# acme_certificate_dns_provider: ns1
# acme_certificate_ns1_secret_key: REPLACE_WITH_YOUR_SECRET_KEY
roles:
- role: acme_certificate
acme_certificate_domains: ['example.com', 'www.example.com']
# Użyj wyzwań DNS:
acme_certificate_challenge: dns-01
# Pliki certyfikatów będą przechowywane w:
# keys/example.com.key (klucz prywatny)
# keys/example.com.csr (żądanie podpisania certyfikatu)
# keys/example.com.pem (certyfikat)
# keys/example.com.cnf (konfiguracja OpenSSL do tworzenia CSR -- można bezpiecznie usunąć)
# keys/example.com-chain.pem (certyfikat pośredni)
# keys/example.com-fullchain.pem (certyfikat z certyfikatem pośrednim)
# keys/example.com-root.pem (główny certyfikat)
# keys/example.com-rootchain.pem (pośredni certyfikat z głównym certyfikatem)
- role: acme_certificate
acme_certificate_domains: ['another.example.com']
acme_certificate_key_name: 'another.example.com-rsa'
acme_certificate_key_length: 4096
# Użyj wyzwań HTTP:
acme_certificate_challenge: http-01
# Pliki certyfikatów będą przechowywane w:
# keys/another.example.com-rsa.key (klucz prywatny)
# keys/another.example.com-rsa.csr (żądanie podpisania certyfikatu)
# keys/another.example.com-rsa.pem (certyfikat)
# keys/another.example.com-rsa.cnf (konfiguracja OpenSSL do tworzenia CSR -- można bezpiecznie usunąć)
# keys/another.example.com-rsa-chain.pem (certyfikat pośredni)
# keys/another.example.com-rsa-fullchain.pem (certyfikat z certyfikatem pośrednim)
# keys/another.example.com-rsa-root.pem (główny certyfikat)
# keys/another.example.com-rsa-rootchain.pem (pośredni certyfikat z głównym certyfikatem)
- role: acme_certificate
acme_certificate_domains: ['another.example.com']
acme_certificate_key_name: 'another.example.com-ecc'
acme_certificate_algorithm: 'p-256'
# Użyj wyzwań HTTP (domyślnym wyzwaniem jest http-01).
# Pliki certyfikatów będą przechowywane w:
# keys/another.example.com-ecc.key (klucz prywatny)
# keys/another.example.com-ecc.csr (żądanie podpisania certyfikatu)
# keys/another.example.com-ecc.pem (certyfikat)
# keys/another.example.com-ecc.cnf (konfiguracja OpenSSL do tworzenia CSR -- można bezpiecznie usunąć)
# keys/another.example.com-ecc-chain.pem (certyfikat pośredni)
# keys/another.example.com-ecc-fullchain.pem (certyfikat z certyfikatem pośrednim)
# keys/another.example.com-ecc-root.pem (główny certyfikat)
# keys/another.example.com-ecc-rootchain.pem (pośredni certyfikat z głównym certyfikatem)
Licencja
Licencja MIT (MIT)
Copyright (c) 2018-2020 Felix Fontein
Zezwolenie udziela się, bezpłatnie, każdej osobie, która uzyskuje kopię tego oprogramowania i powiązanej dokumentacji (zwanych dalej "Oprogramowaniem"), na zajmowanie się Oprogramowaniem bez jakichkolwiek ograniczeń, w tym bez ograniczeń w prawach do używania, kopiowania, modyfikowania, scalania, publikowania, dystrybuowania, sublicencjonowania i/lub sprzedaży kopii Oprogramowania, oraz na zezwolenie osobom, którym Oprogramowanie jest dostarczane, na robienie tego, pod warunkiem spełnienia następujących warunków:
Powyższa notatka o prawach autorskich oraz to pozwolenie muszą być zawarte w każdej kopii lub znaczącej części Oprogramowania.
OPROGRAMOWANIE JEST DOSTARCZANE "TAK JEST", BEZ GWARANCJI JAKIEGOKOLWIEK RODZAJU, WYRAŹNEJ LUB DOSTRZEGAJĄCEJ, W TYM, ALE NIE OGRANICZAJĄCEJ SIĘ DO GWARANCJI ZDATNOŚCI HANDLOWEJ, DOPASOWANIA DO OKREŚLONEGO CELU I NARUSZENIA. W ŻADNYM PRZYPADKU NIE AUTORZY ANI POSIADACZE PRAW AUTORSKICH NIE PONOSZĄ ODPOWIEDZIALNOŚCI ZA WSZELKIE ROSZCZENIA, SZKODY LUB INNE ODPOWIEDZIALNOŚCI, NIEZALEŻNIE OD CZY TO W DZIAŁANIU UMOWY, DELIKTU LUB INNEGO, POWSTAJĄCE Z, NA PODSTAWIE LUB W ZWIĄZKU Z OPROGRAMOWANIEM LUB UŻYCIEM LUB INNYMI TRANSAKCJAMI W OPROGRAMOWANIU.
Informacje o autorze
Strona domowa tej roli to https://github.com/felixfontein/acme-certificate/. Proszę używać systemu śledzenia problemów, aby zgłaszać problemy.
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