Acme.sh est un script qui vous permet d'obtenir des certificats Let's Encrypt de différentes manières sans aucun problème. Dans cet article, j'analyserai comment obtenir des certificats via l'api DNS, mais cela ne surprendra personne, je vais donc vous parler de la méthode des alias DNS, elle est fraîche (seulement 3 ans ) et intéressante. Et aussi sur l'automatisation sur Ansible et un peu sur la surveillance des certificats.
Version vidéo
acme.sh
Webroot
Nginx\Apache
Stanalone
, - acme.sh. , TLS, , wilcard \. wildcard DNS . DNS :
DNS manual
DNS API
DNS alias
acme.sh.
DNS manual mode
Manual . acme.sh --dns
acme.sh --issue --dns -d *.itdog.info --yes-I-know-dns-manual-mode-enough-go-ahead-please
koala@x220:~$ acme.sh --issue --dns -d *.itdog.info --yes-I-know-dns-manual-mode-enough-go-ahead-please
[ 5 14:52:29 MSK 2021] Using CA: https://acme-v02.api.letsencrypt.org/directory
[ 5 14:52:29 MSK 2021] Creating domain key
[ 5 14:52:29 MSK 2021] The domain key is here: /home/koala/.acme.sh/*.itdog.info/*.itdog.info.key
[ 5 14:52:29 MSK 2021] Single domain='*.itdog.info'
[ 5 14:52:29 MSK 2021] Getting domain auth token for each domain
[ 5 14:52:32 MSK 2021] Getting webroot for domain='*.itdog.info'
[ 5 14:52:32 MSK 2021] Add the following TXT record:
[ 5 14:52:32 MSK 2021] Domain: '_acme-challenge.itdog.info'
[ 5 14:52:32 MSK 2021] TXT value: 'QXRgFOfVOZGOBC1qxAToMNOf7Xsv9gjM8hYG6akRoJ8'
[ 5 14:52:32 MSK 2021] Please be aware that you prepend _acme-challenge. before your domain
[ 5 14:52:32 MSK 2021] so the resulting subdomain will be: _acme-challenge.itdog.info
[ 5 14:52:32 MSK 2021] Please add the TXT records to the domains, and re-run with --renew.
[ 5 14:52:32 MSK 2021] Please add '--debug' or '--log' to check more details.
[ 5 14:52:32 MSK 2021] See: https://github.com/acmesh-official/acme.sh/wiki/How-to-debug-acme.sh
--issue
-
--dns
- DNS
--yes-I-know-dns-manual-mode-enough-go-ahead-please
- ,
TXT , dns , _acme-challenge.itdog.info TXT QXRgFOfVOZGOBC1qxAToMNOf7Xsv9gjM8hYG6akRoJ8
, .

- , , --renew
dns
koala@x220:~$ dig -t txt _acme-challenge.itdog.info @8.8.8.8
; <<>> DiG 9.11.3-1ubuntu1.15-Ubuntu <<>> -t txt _acme-challenge.itdog.info @8.8.8.8
;; ANSWER SECTION:
_acme-challenge.itdog.info. 1798 IN TXT "QXRgFOfVOZGOBC1qxAToMNOf7Xsv9gjM8hYG6akRoJ8"
,
koala@x220:~$ acme.sh --renew --dns -d *.itdog.info --yes-I-know-dns-manual-mode-enough-go-ahead-please
[ 5 14:58:08 MSK 2021] Renew: '*.itdog.info'
[ 5 14:58:09 MSK 2021] Using CA: https://acme-v02.api.letsencrypt.org/directory
[ 5 14:58:09 MSK 2021] Single domain='*.itdog.info'
[ 5 14:58:09 MSK 2021] Getting domain auth token for each domain
[ 5 14:58:09 MSK 2021] Verifying: *.itdog.info
[ 5 14:58:13 MSK 2021] Success
[ 5 14:58:13 MSK 2021] Verify finished, start to sign.
[ 5 14:58:13 MSK 2021] Lets finalize the order.
[ 5 14:58:13 MSK 2021] Le_OrderFinalize='https://acme-v02.api.letsencrypt.org/acme/finalize/121...'
[ 5 14:58:15 MSK 2021] Downloading cert.
[ 5 14:58:15 MSK 2021] Le_LinkCert='https://acme-v02.api.letsencrypt.org/acme/cert/042...'
[ 5 14:58:16 MSK 2021] Cert success.
-----BEGIN CERTIFICATE-----
certificate
-----END CERTIFICATE-----
[ 5 14:58:16 MSK 2021] Your cert is in /home/koala/.acme.sh/*.itdog.info/*.itdog.info.cer
[ 5 14:58:16 MSK 2021] Your cert key is in /home/koala/.acme.sh/*.itdog.info/*.itdog.info.key
[ 5 14:58:16 MSK 2021] The intermediate CA cert is in /home/koala/.acme.sh/*.itdog.info/ca.cer
[ 5 14:58:16 MSK 2021] And the full chain certs is there: /home/koala/.acme.sh/*.itdog.info/fullchain.cer
TXT .
, 3 . 2 , let's enctypt - , .
, , , . , *.example.com.key
# ls -l --time-style=+%Y-%m-%d \*.example.com/
total 28
-rw-r--r-- 1 root root 1587 2021-04-15 ca.cer
-rw-r--r-- 1 root root 3433 2021-04-15 fullchain.cer
-rw-r--r-- 1 root root 1846 2021-04-15 *.example.com.cer
-rw-r--r-- 1 root root 719 2021-04-15 *.example.com.conf
-rw-r--r-- 1 root root 980 2021-04-15 *.example.com.csr
-rw-r--r-- 1 root root 211 2021-04-15 *.example.com.csr.conf
-rw-r--r-- 1 root root 1675 2019-04-10 *.example.com.key
, 2 TXT , .
DNS API mode
? manual, acme.sh TXT API dns .

DNS DNS , DNS . DNS , , (namecheap, beget ) (Amazon Route 53, ClouDNS ), BIND, PowerDNS .
DNS API acme.sh . https://github.com/acmesh-official/acme.sh/wiki/dnsapi
. , , vim, .
DNS namecheap.
DNS , - API , - , namecheap IP allow list. API token, IP .

API
export NAMECHEAP_USERNAME="USERNAME"
export NAMECHEAP_API_KEY="TOKEN"
export NAMECHEAP_SOURCEIP="MY-IP"
force test. -f (--force), , .. acme.sh .
rm -rf ~/.acme.sh/domain/
. --test, let's encrypt. , manual .
[ 5 16:39:31 MSK 2021] *.itdog.info is already verified, skip dns-01.
API
acme.sh --issue --dns dns_namecheap -d *.itdog.info --test
--dns .
acme.sh
koala@x220:~$ acme.sh --issue --dns dns_namecheap -d *.itdog.info --test
[ 5 16:48:05 MSK 2021] Using ACME_DIRECTORY: https://acme-staging-v02.api.letsencrypt.org/directory
[ 5 16:48:06 MSK 2021] Using CA: https://acme-staging-v02.api.letsencrypt.org/directory
[ 5 16:48:06 MSK 2021] Creating domain key
[ 5 16:48:07 MSK 2021] The domain key is here: /home/koala/.acme.sh/*.itdog.info/*.itdog.info.key
[ 5 16:48:07 MSK 2021] Single domain='*.itdog.info'
[ 5 16:48:07 MSK 2021] Getting domain auth token for each domain
[ 5 16:48:09 MSK 2021] Getting webroot for domain='*.itdog.info'
[ 5 16:48:10 MSK 2021] Adding txt value: nCH4tBWCkSVn76301f2SdJqCAzmtXvzQAB_Ag8hURLo for domain: _acme-challenge.itdog.info
[ 5 16:48:15 MSK 2021] The txt record is added: Success.
[ 5 16:48:15 MSK 2021] Let's check each DNS record now. Sleep 20 seconds first.
[ 5 16:48:36 MSK 2021] You can use '--dnssleep' to disable public dns checks.
[ 5 16:48:36 MSK 2021] See: https://github.com/acmesh-official/acme.sh/wiki/dnscheck
[ 5 16:48:36 MSK 2021] Checking itdog.info for _acme-challenge.itdog.info
[ 5 16:48:37 MSK 2021] Domain itdog.info '_acme-challenge.itdog.info' success.
[ 5 16:48:37 MSK 2021] All success, let's return
[ 5 16:48:37 MSK 2021] Verifying: *.itdog.info
[ 5 16:48:41 MSK 2021] Success
[ 5 16:48:41 MSK 2021] Removing DNS records.
[ 5 16:48:41 MSK 2021] Removing txt: nCH4tBWCkSVn76301f2SdJqCAzmtXvzQAB_Ag8hURLo for domain: _acme-challenge.itdog.info
[ 5 16:48:46 MSK 2021] Removed: Success
[ 5 16:48:46 MSK 2021] Verify finished, start to sign.
[ 5 16:48:46 MSK 2021] Lets finalize the order.
[ 5 16:48:46 MSK 2021] Le_OrderFinalize='https://acme-staging-v02.api.letsencrypt.org/acme/finalize/193...'
[ 5 16:48:48 MSK 2021] Downloading cert.
[ 5 16:48:48 MSK 2021] Le_LinkCert='https://acme-staging-v02.api.letsencrypt.org/acme/cert/fa62...'
[ 5 16:48:49 MSK 2021] Cert success.
-----BEGIN CERTIFICATE-----
certificate
-----END CERTIFICATE-----
[ 5 16:48:49 MSK 2021] Your cert is in /home/koala/.acme.sh/*.itdog.info/*.itdog.info.cer
[ 5 16:48:49 MSK 2021] Your cert key is in /home/koala/.acme.sh/*.itdog.info/*.itdog.info.key
[ 5 16:48:49 MSK 2021] The intermediate CA cert is in /home/koala/.acme.sh/*.itdog.info/ca.cer
[ 5 16:48:49 MSK 2021] And the full chain certs is there: /home/koala/.acme.sh/*.itdog.info/fullchain.cer
, acme.sh TXT , , DNS , .
API, acme.sh env c API ~/.acme.sh/account.conf .
, , . :
\, ,
API?
. "" , - , . API, \ txt _acme-challenge. ? , - AWS . API,
(). API acme.sh , . API
- , DNS - - \
DNS aliase mode
DNS API.
: , TXT . .. acme.sh CNAME , "" TXT . DNS API.

. tech-domain.club, . itdog.info namecheap, tech-domain.club Hetzner DNS, API Hetzner'a.
CNAME ,
_acme-challenge CNAME _acme-challenge.tech-domain.club
API.
Hetzner export HETZNER_Token="TOKEN"
(-f --test )
acme.sh --issue -d *.itdog.info --challenge-alias tech-domain.club --dns dns_hetzner -f --test
koala@x220:~$ acme.sh --issue -d *.itdog.info -d itdog.info --challenge-alias tech-domain.club --dns dns_hetzner -f --test
[ 7 13:40:11 MSK 2021] Domains have changed.
[ 7 13:40:11 MSK 2021] Using CA: https://acme-v02.api.letsencrypt.org/directory
[ 7 13:40:11 MSK 2021] Multi domain='DNS:*.itdog.info,DNS:itdog.info'
[ 7 13:40:11 MSK 2021] Getting domain auth token for each domain
[ 7 13:40:15 MSK 2021] Getting webroot for domain='*.itdog.info'
[ 7 13:40:15 MSK 2021] Getting webroot for domain='itdog.info'
[ 7 13:40:15 MSK 2021] Adding txt value: Zlrij9n4y5QXfH6yx_PBn45bgmIcT70-JuW2rIUa6lc for domain: _acme-challenge.tech-domain.club
[ 7 13:40:16 MSK 2021] Adding record
[ 7 13:40:17 MSK 2021] Record added, OK
[ 7 13:40:20 MSK 2021] The txt record is added: Success.
[ 7 13:40:20 MSK 2021] Let's check each DNS record now. Sleep 20 seconds first.
[ 7 13:40:41 MSK 2021] You can use '--dnssleep' to disable public dns checks.
[ 7 13:40:41 MSK 2021] See: https://github.com/acmesh-official/acme.sh/wiki/dnscheck
[ 7 13:40:41 MSK 2021] Checking itdog.info for _acme-challenge.tech-domain.club
[ 7 13:40:42 MSK 2021] Domain itdog.info '_acme-challenge.tech-domain.club' success.
[ 7 13:40:42 MSK 2021] All success, let's return
[ 7 13:40:42 MSK 2021] *.itdog.info is already verified, skip dns-01.
[ 7 13:40:42 MSK 2021] Verifying: itdog.info
[ 7 13:40:46 MSK 2021] Success
[ 7 13:40:46 MSK 2021] Removing DNS records.
[ 7 13:40:46 MSK 2021] Removing txt: Zlrij9n4y5QXfH6yx_PBn45bgmIcT70-JuW2rIUa6lc for domain: _acme-challenge.tech-domain.club
[ 7 13:40:50 MSK 2021] Record deleted
[ 7 13:40:50 MSK 2021] Removed: Success
[ 7 13:40:50 MSK 2021] Verify finished, start to sign.
[ 7 13:40:50 MSK 2021] Lets finalize the order.
[ 7 13:40:50 MSK 2021] Le_OrderFinalize='https://acme-v02.api.letsencrypt.org/acme/finalize/121...'
[ 7 13:40:52 MSK 2021] Downloading cert.
[ 7 13:40:52 MSK 2021] Le_LinkCert='https://acme-v02.api.letsencrypt.org/acme/cert/04e...'
[ 7 13:40:53 MSK 2021] Cert success.
-----BEGIN CERTIFICATE-----
certificate
-----END CERTIFICATE-----
[ 7 13:40:53 MSK 2021] Your cert is in /home/koala/.acme.sh/*.itdog.info/*.itdog.info.cer
[ 7 13:40:53 MSK 2021] Your cert key is in /home/koala/.acme.sh/*.itdog.info/*.itdog.info.key
[ 7 13:40:53 MSK 2021] The intermediate CA cert is in /home/koala/.acme.sh/*.itdog.info/ca.cer
[ 7 13:40:53 MSK 2021] And the full chain certs is there: /home/koala/.acme.sh/*.itdog.info/fullchain.cer
CNAME , . , CNAME .
, , itdog.info wildcard *.itdog.info, -d,
acme.sh --issue --challenge-alias tech-domain.club --dns hetzner -d *.itdog.info -d itdog.info
.
, :
API , , , acme.sh
API, . , token , , acme.sh, - . , ,
, , CNAME
domain-alias, _acme-challenge , ,
, ~/.acme.sh . - . , ansible. Ansible \ . , . Playbooks, hosts github.
ansible, , acme.sh , . , acme.sh crontab, .
Playbook
vars , . API vars , git. Task "Date and time" , - . shell, . , wildcard , loop.
, , wildcard taks, loop. wilcard *.*.itdog.info
, -d subkey item. ignore_errors , exit code 0
6 , , , ansible .
? acme.sh !
, , TLS, , - acme.sh. , , , vars_files, \, loop. , ~/.acme.sh, vars_files git.
Playbook
, , .
:
tls-hosts - nginx
tls-hosts-docker - nginx, docker
tls-hosts-docker-rename - , ( Harbor, Zabbix)
, nginx . , nginx -s reload
- , docker exec project-nginx -s reolad
, .. handler.
handler , , , , .
, , , . . , hosts .
nginx.itdog.info tls_path=/etc/letsencrypt/*.itdog.info/ DOMAIN=*.itdog.info
, , ansible_host (, , ).
nginx.example.com-1 ansible_host=nginx.example.com tls_path=/etc/letsencrypt/*.example.com/ DOMAIN=example.com
nginx.example.com-2 ansible_host=nginx.example.com tls_path=/etc/letsencrypt/*.example.org/ DOMAIN=example.org
hosts. tasks. tls-hosts-docker nginx. tls-hosts-docker-rename , .
docker-zabbix.itdog.info tls_path=/root/docker-zabbix/zbx_env/etc/ssl/nginx/ DOMAIN=*.itdog.info CONTAINER=docker-zabbix_zabbix-web-nginx-pgsql_1 cert_name=ssl.crt key_name=ssl.key
nginx fullchain domain.key - . , handler nginx -s reload
. , nginx, . , acme.sh, . traefik 1.7 acme.json , . . , , python-pyOpenSSL.
Crontab
23 3 * * * /usr/bin/ansible-playbook /etc/ansible/playbook-get-tls.yml -v >> /var/log/get-tls.log
23 4 * * * /usr/bin/ansible-playbook /etc/ansible/playbook-copy-tls.yml -v >> /var/log/copy-tls.log
, let's encrypt , . , .
, . , - - warning . , , traefik, .
zabbix @selivanov_pavel
koala@x220 ~/t/acme.sh-test> ./ssl_cert_check.sh expire itdog.info 443
41
41 itdog.info . let's encrypt 30 . , , 10 , - .
item trigger. github
ssl_cert_check.sh["expire","{HOST.NAME}","{$TLS_PORT}"]

item , HOST.NAME , . $TLS_PORT 443, , macros.
{Check tls expire:ssl_cert_check.sh["expire","{HOST.NAME}","{$TLS_PORT}"].last()}<=10

10 - . , 10 .
?
, acme.sh + DNS API + ansible . acme.sh + DNS Alias + ansible . , crontab staging . .
Oui, idéalement, ansible devrait vérifier avant de copier que le certificat est valide et n'a pas expiré. Et le système de surveillance vérifie, en plus d'expirer, la validité des certificats.