Modo Acme.sh + Ansible + Alias: Automatizamos la recepción y distribución de certificados TLS

Acme.sh es un script que te permite cifrar certificados de formas muy diferentes sin ningún problema. En este artículo analizaré cómo obtener certificados a través de la api de DNS, pero esto no sorprenderá a nadie, por lo que les contaré sobre el método de alias de DNS, es fresco (solo 3 años ) e interesante. Y también sobre la automatización en Ansible y un poco sobre la supervisión de certificados.





Versión de video





Modos acme.sh de obtener certificados directamente en el servidor de destino





  • Webroot





  • Nginx \ Apache





  • Stanalone





Los modos son buenos y convenientes cuando tiene uno o dos servidores y simplemente puede instalar acme.sh en cada uno. Cuando la cantidad de servidores que necesitan TLS excede la docena, es más conveniente comenzar a usar certificados wilcard y asignar un servidor separado para recibir y distribuir los certificados. Puede obtener un certificado comodín solo si confirma la propiedad de la zona DNS. Hay varios modos de DNS:





  • Manual de DNS





  • API de DNS





  • Alias ​​de DNS





Todos los ejemplos se mostrarán en mi dominio personal y en acme.sh instalado localmente.





Modo manual de DNS

El modo manual funciona muy fácilmente. Ejecute acme.sh con la bandera --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



- solicitud de recibir





--dns



sin argumento - modo DNS manual





--yes-I-know-dns-manual-mode-enough-go-ahead-please



- una solución interesante al problema cuando la gente no entiende qué es el modo manual





Emite un registro TXT que debemos agregar a nuestro hosting dns, en este caso es _acme-challenge.itdog.info TXT QXRgFOfVOZGOBC1qxAToMNOf7Xsv9gjM8hYG6akRoJ8







, .





Animación en modo manual
manual mode

- , , --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 .





Animación en modo API
API mode

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.





Animación en modo alias
alias mode

. 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 . .





Sí, idealmente ansible debería comprobar antes de copiar que el certificado sea válido y no esté caducado. Y el sistema de seguimiento comprueba, además de caducar, la validez de los certificados.








All Articles