nickjj.acme_sh
¿Qué es ansible-acme-sh? 
Es un rol de Ansible para:
- Instalar acme.sh para emitir, renovar o eliminar certificados SSL basados en Let's Encrypt
- Emitir certificados para dominios únicos, múltiples o comodines
- Configurar múltiples dominios a través de 1 certificado o certificados separados
- Emitir desafíos basados en DNS utilizando la función API de DNS automatizada de acme.sh
- Ejecutar comandos personalizados de acme.sh si los ajustes predeterminados no son suficientes para ti
¿Por qué querrías usar este rol?
Este rol utiliza acme.sh, que es un script de Bash autónomo para manejar todas las complejidades de emitir y renovar automáticamente tus certificados SSL.
Los objetivos de este rol son ser altamente configurables pero tener suficientes valores predeterminados sensatos para que puedas comenzar solo proporcionando una lista de nombres de dominio, configurando tu proveedor de DNS y proporcionando la clave de API de tu proveedor de DNS.
Además, es idempotente para cada tarea porque así es como trabajo.
¿Por qué los desafíos basados en DNS son el único método soportado?
Tener los desafíos realizados a través de DNS significa que puedes configurar tus certificados antes de que tu servidor web o proxy esté provisionado. También significa que tu servidor web no necesita saber nada sobre cómo funciona el desafío ACME. Todo lo que tienes que hacer es referenciar los certificados finales que este rol genera.
Otra ventaja es si estás ejecutando un servidor web dentro de Docker, es posible que no lo tengas en funcionamiento hasta que tu servidor haya sido provisionado por Ansible. Por ejemplo, es común configurar despliegues basados en git para iniciar un despliegue de aplicación.
También es conveniente usar desafíos DNS porque son la única manera de emitir certificados comodín usando Let's Encrypt. Focalizar esfuerzos en 1 solución que funcione con todos los tipos de certificados parecía ser la decisión correcta.
Dicho esto, probablemente no voy a soportar otros modos como standalone, webroot, nginx o Apache, pero nada está grabado en piedra.
Plataformas soportadas
- Ubuntu 16.04 LTS (Xenial)
- Ubuntu 18.04 LTS (Bionic)
- Debian 8 (Jessie)
- Debian 9 (Stretch)
Variables del rol
# El usuario en el sistema con el que correrá acme.sh. Ten en cuenta que este usuario
# debe existir previamente, este rol no lo creará.
acme_sh_become_user: "root"
# Dependencias del paquete acme.sh. Los valores predeterminados son para Debian / Ubuntu.
# Para CentOS y Fedora puedes reemplazar "cron" con "crond".
acme_sh_dependencies: ["cron", "git", "wget"]
# La URL del repositorio acme.sh a clonar.
acme_sh_git_url: "https://github.com/acmesh-official/acme.sh"
# La rama, etiqueta o commit que será clonado.
acme_sh_git_version: "master"
# Por defecto, si clonas este repositorio ahora y luego lo clonas de nuevo en 6 meses,
# se mantendrá con la versión vieja del master de hace 6 meses. Si quieres obtener la
# última versión del master en cada ejecución, establece esto en True.
acme_sh_git_update: False
# ¿Dónde se clonará este repositorio?
acme_sh_git_clone_dest: "/usr/local/src/acme.sh"
# Cuando está habilitado, acme.sh se actualizará a la última versión, que es
# independiente de actualizar el repositorio git. Eso se debe a que acme.sh se
# instala mediante un instalador después de clonar el código fuente.
#
# Habilitarlo podría ser bueno para obtener la última versión que puede tener correcciones
# de errores, pero ten en cuenta que si haces esto, podrías obtener resultados diferentes
# en cada ejecución. Recomiendo establecerlo ocasionalmente en True, pero mantenerlo deshabilitado
# generalmente.
acme_sh_upgrade: False
# Cuando está habilitado, el código fuente clonado, la ruta de instalación, archivos de registro y trabajos cron de renovación
# serán eliminados.
#
# Los certificados instalados no serán eliminados. Si quieres eliminar los certificados instalados,
# hay otra opción para eso que cubriremos más adelante.
acme_sh_uninstall: False
# Al crear una cuenta inicial de Let's Encrypt, puedes opcionalmente proporcionar una
# dirección de correo electrónico. Por defecto, esto no está establecido, pero si deseas,
# siéntete libre de agregar tu dirección de correo aquí. Si lo haces, recibirás un correo
# cuando tus certificados estén dentro de 20 días de expirar.
#
# Recomiendo encarecidamente establecer esto porque si todo sale como se planeó, nunca
# recibirás un correo a menos que acme.sh tenga un mal funcionamiento y falle al renovar
# un certificado.
acme_sh_account_email: ""
# Los certificados se renovarán a través de un trabajo cron gestionado por acme.sh. Por defecto
# acme.sh usa 60 días para cada intento de renovación, pero he elegido ir con 30
# por defecto para dar 1 intento extra en caso de que algo inesperado suceda.
#
# Los certificados que no necesitan ser renovados serán saltados por acme.sh, así que
# está todo bien. También vale la pena mencionar que este valor no puede ser > 60 días, que
# es un límite impuesto por acme.sh, este rol no verifica el valor.
acme_sh_renew_time_in_days: 30
# La ruta base donde se copiarán los certificados. Si estás familiarizado con
# acme.sh, esto es para los certificados generados con --install-cert.
#
# Este es el destino final para tus certificados y el usuario que elegiste
# necesitará acceso de escritura a esta ruta. Esta ruta terminará con su
# propietario:grupo establecido al valor de acme_sh_become_user.
acme_sh_copy_certs_to_path: "/etc/ssl/ansible"
# Al final de la ejecución, un mensaje de depuración de Ansible imprimirá una lista de
# dominios que tienen certificados SSL válidos junto con sus fechas de expiración.
# Puedes desactivar esto estableciéndolo en False.
acme_sh_list_domains: True
# Cuando se establece en False, usará los servidores en vivo de Let's Encrypt, así que asegúrate
# de que todo funcione con staging True o podrías encontrarte con limitaciones de tasa.
#
# Vale la pena mencionar que necesitarás forzar la emisión de un nuevo certificado cuando
# cambies entre staging y en vivo o viceversa.
acme_sh_default_staging: True
# Cuando se establece en True, esto generará un nuevo certificado incluso si tu lista de
# dominios no cambió. También se usa para establecer un nuevo proveedor de DNS y claves de API.
#
# Ten cuidado con esto porque podrías verte limitado si estás en el servidor en vivo.
# Solo considera usar esto para actualizar tu proveedor de DNS. Deberías regresar a
# False cuando termines.
acme_sh_default_force_issue: False
# Cuando se establece en True, esto generará un nuevo certificado para una lista existente
# de certificados. Esto no actualizará tu proveedor de DNS ni claves de API.
#
# Esto podría ser útil si tus certificados expiraron. Deberías regresar a
# False cuando termines.
acme_sh_default_force_renew: False
# Cuando se establece en True, esto proporcionará información más detallada a STDOUT. Esto
# podría ser útil si estás probando el rol en modo de staging.
acme_sh_default_debug: False
# ¿Qué proveedor de DNS deberías usar?
# Una lista de proveedores soportados se puede encontrar en:
# https://github.com/acmesh-official/acme.sh/tree/master/dnsapi
# En cuanto a obtener el nombre a usar, puedes encontrarlo en la URL anterior también.
#
# Por defecto es DigitalOcean. Asegúrate de incluir la parte dns_ del nombre,
# pero deja fuera la extensión .sh.
acme_sh_default_dns_provider: "dns_dgon"
# ¿Cuáles son las claves de API de tu proveedor de DNS?
# Los nombres de clave a usar se pueden encontrar en:
# https://github.com/acmesh-official/acme.sh/tree/master/dnsapi
#
# La clave de API se puede crear en el sitio web de tu proveedor de DNS. Algunos proveedores
# requieren 1 clave, mientras que otros requieren 2+. Simplemente agrégalas como pares clave/valor aquí
# sin el "export ".
#
# Por ejemplo, si estás usando DigitalOcean, ingresarías:
# acme_sh_default_dns_provider_api_keys:
# "DO_API_KEY": "EL_TOKEN_SECRETO_DE_API_DEL_DASHBOARD_DE_DO"
acme_sh_default_dns_provider_api_keys: {}
# ¿Cuánto tiempo debería dormir acme.sh después de intentar establecer el registro TXT en tus
# registros DNS? Algunos proveedores de DNS no actualizan tan rápido como otros.
#
# 120 es el valor predeterminado de acme.sh, pero ten en cuenta que si usas
# NameSilo, sus actualizaciones de DNS solo se propagan una vez cada 15 minutos, por lo que necesitarás
# establecer este valor en 900 o corres el riesgo de obtener un error de DNS NXDOMAIN.
#
# Recomiendo mantenerlo establecido en 120 o más si tu proveedor de DNS lo requiere.
#
# Aunque, como un apunte, usé 10 al probar este rol contra DigitalOcean
# y funcionó unas 30 veces seguidas. Aún así, en producción usaría 120
# solo para estar seguro porque esta demora de 2 minutos solo te afectará en la primera
# ejecución de Ansible. Después de eso, se actualizará en segundo plano a través de un trabajo cron.
acme_sh_default_dns_sleep: 120
# Al emitir nuevos certificados, puedes elegir agregar flags adicionales que
# no están presentes aquí por defecto. Proporciónalos tal como lo harías en la línea de comandos,
# como "--help".
acme_sh_default_extra_flags_issue: ""
# Al renovar certificados, puedes elegir agregar flags adicionales que
# no están presentes aquí por defecto. Proporciónalos tal como lo harías en la línea de comandos,
# como "--help".
acme_sh_default_extra_flags_renew: ""
# Al instalar certificados, puedes elegir agregar flags adicionales que
# no están presentes aquí por defecto. Proporciónalos tal como lo harías en la línea de comandos,
# como "--help".
#
# Instalar es diferente de emitir y cubriremos eso más adelante.
acme_sh_default_extra_flags_install_cert: ""
# Cuando se emite o renueva un certificado, acme.sh intentará ejecutar un comando
# de tu elección. Esto podría ser para reiniciar o recargar tu servidor web o proxy.
#
# Ten en cuenta que el usuario que estableciste en acme_sh_become_user necesita derechos de acceso a
# sudo si usas sudo aquí, o si no, necesita derechos de acceso para recargar tu
# servidor web / proxy.
#
# Para un ejemplo de Docker, consulta la sección de ejemplos de este README.
acme_sh_default_install_cert_reloadcmd: "sudo systemctl reload nginx"
# Si necesitas más control detallado que el reloadcmd, puedes conectarte al
# ciclo de vida de emitir o renovar un certificado. Por defecto, las siguientes 3
# opciones no hacen nada a menos que las llenes. No son necesarias para todo
# para funcionar siempre que tu reloadcmd funcione.
#
# Cuando se emite o renueva un certificado, acme.sh intentará ejecutar un comando
# antes de intentar emitir un certificado. Esto solo se puede aplicar al emitir un
# certificado, pero se guardará y usará para la renovación también.
#
# Esto se ejecutará incluso si el certificado no fue emitido / renovado exitosamente.
acme_sh_default_issue_pre_hook: ""
# Cuando se emite o renueva un certificado, acme.sh intentará ejecutar un comando
# después de intentar emitir un certificado. Esto solo se puede aplicar al emitir un
# certificado, pero se guardará y usará para la renovación también.
#
# Esto se ejecutará incluso si el certificado no fue emitido / renovado exitosamente.
acme_sh_default_issue_post_hook: ""
# Cuando se emite o renueva un certificado, acme.sh intentará ejecutar un comando
# después de que un certificado se haya renovado exitosamente. Esto solo se puede aplicar al
# emitir un certificado, pero se guardará y usará para la renovación también.
#
# Esto solo se ejecutará si el certificado fue emitido / renovado exitosamente.
acme_sh_default_issue_renew_hook: ""
# Cuando se establece en True, los certificados serán eliminados y desactivados de ser renovados
# en lugar de ser creados y establecidos para renovación. Esto no desinstalará acme.sh.
acme_sh_default_remove: False
# Esta lista contiene una lista de dominios, junto con pares clave/valor para
# configurar cada conjunto de dominios individualmente.
#
# Aquí hay un ejemplo con cada opción disponible documentada, y un par de ejemplos reales también
# se incluirán en la sección de ejemplos de este README:
acme_sh_domains:
# Una lista de 1 o más dominios, puedes usar ["example.com", "*.example.com"] o
# ["*.example.com", "example.com"] para establecer un certificado comodín junto con
# el certificado de dominio raíz en el mismo archivo. El primer dominio en la lista
# será utilizado como el nombre de archivo base para el nombre del certificado.
#
# Si quieres archivos separados, entonces crea un nuevo ítem "domains:" en la lista.
# - domains: ["example.com", "www.example.com", "admin.example.com"]
# # Opcionalmente, puedes sobrescribir la variable de staging predeterminada. Este patrón general permite
# # que sobrescribas condicionalmente los valores predeterminados mencionados arriba para cada lista de dominios.
# staging: False
# # Opcionalmente, forzar emitir nuevos certificados.
# force_issue: False
# # Opcionalmente, forzar renovación de certificados.
# force_renew: False
# # Opcionalmente, activar modo de depuración.
# debug: True
# # Opcionalmente, sobrescribir el proveedor de DNS predeterminado.
# dns_provider: "dns_namesilo"
# # Opcionalmente, sobrescribir las claves API de DNS predeterminadas.
# dns_provider_api_keys:
# "Namesilo_Key": "EL_TOKEN_SECRETO_DE_API_DEL_DASHBOARD_DE_NAMESILO"
# # Opcionalmente, sobrescribir el tiempo de espera DNS predeterminado.
# dns_sleep: 900
# # Opcionalmente, agrega flags extra a cualquiera de estas 3 acciones:
# extra_flags_issue: ""
# extra_flags_renew: ""
# extra_flags_install_cert: ""
# # Opcionalmente, establece un comando de recarga diferente.
# install_cert_reloadcmd: "whoami"
# # Opcionalmente, ejecuta comandos durante diferentes puntos en el proceso de emisión de certificados:
# extra_issue_pre_hook: ""
# extra_issue_post_hook: ""
# extra_issue_renew_hook: ""
# # Opcionalmente, eliminar y deshabilitar el certificado.
# remove: True
Ejemplo de uso
Para el propósito de este ejemplo, supongamos que tienes un grupo llamado app y
tienes un archivo típico site.yml
.
Para usar este rol, edita tu archivo site.yml
para que luzca algo así:
---
- name: Configurar servidor(es) de aplicación
hosts: "app"
become: True
roles:
- { role: "nickjj.acme_sh", tags: ["acme_sh"] }
Aquí hay algunos ejemplos. Puedes recrear este ejemplo en tu final abriendo o
creando group_vars/app.yml
, que está ubicado relativamente a tu directorio de inventory
y luego haciéndolo lucir así:
---
acme_sh_account_email: "[email protected]"
# Un ejemplo donde un proveedor de DNS tiene 2 claves para acceso a la API:
acme_sh_default_dns_provider: "dns_cf"
acme_sh_default_dns_provider_api_keys:
"CF_Key": "EL_TOKEN_SECRETO_DE_API_DEL_DASHBOARD_DE_CLOUDFLARE"
"CF_Email": "[email protected]"
# Recargando nginx dentro de un contenedor de Docker llamado "nginx".
# Si estás ejecutando nginx en un contenedor de Docker, también necesitarás montar tus certificados,
# ¡pero estoy seguro de que ya sabías eso!
acme_sh_default_install_cert_reloadcmd: "docker exec nginx nginx -s reload"
# --- Aquí hay algunos ejemplos diferentes de acme_sh_domains --------------------------
# Solo necesitarías proporcionar uno de estos basado en lo que quieres hacer.
# ------------------------------------------------------------------------------
# 1 archivo de certificado para todos los dominios.
acme_sh_domains:
- domains: ["example.com", "www.example.com", "admin.example.com"]
# Produce esto en tu servidor:
# /etc/ssl/ansible/example.com.key (la clave privada)
# /etc/ssl/ansible/example.com.pem (el certificado de la cadena completa)
# ------------------------------------------------------------------------------
# 2 archivos de certificado usando los mismos dominios que arriba.
acme_sh_domains:
- domains: ["example.com", "www.example.com"]
- domains: ["admin.example.com"]
# Produce esto en tu servidor:
# /etc/ssl/ansible/example.com.key (la clave privada)
# /etc/ssl/ansible/example.com.pem (el certificado de la cadena completa)
# /etc/ssl/ansible/admin.example.com.key (la clave privada)
# /etc/ssl/ansible/admin.example.com.pem (el certificado de la cadena completa)
# ------------------------------------------------------------------------------
# 2 archivos de certificado usando el mismo ejemplo, pero el certificado de admin será eliminado y deshabilitado.
acme_sh_domains:
- domains: ["example.com", "www.example.com"]
- domains: ["admin.example.com"]
remove: True
# Produce esto en tu servidor:
# /etc/ssl/ansible/example.com.key (la clave privada)
# /etc/ssl/ansible/example.com.pem (el certificado de la cadena completa)
# ------------------------------------------------------------------------------
# 2 archivos de certificado usando el mismo ejemplo pero cambiando de staging a en vivo
# en admin.example.com (pero recuerda eliminar force_issue después de que se ejecute una vez).
acme_sh_domains:
- domains: ["example.com", "www.example.com"]
- domains: ["admin.example.com"]
staging: False
force_issue: True
# ------------------------------------------------------------------------------
# 2 archivos de certificado usando el mismo ejemplo pero forzando una renovación en
# admin.example.com (digamos que ocurrió un error catastrófico y el certificado expiró).
acme_sh_domains:
- domains: ["example.com", "www.example.com"]
- domains: ["admin.example.com"]
force_renew: True
Si estás buscando un rol de Ansible para crear usuarios, consulta mi rol de usuario.
Ahora ejecutarías ansible-playbook -i inventory/hosts site.yml -t acme_sh
.
Instalación
$ ansible-galaxy install nickjj.acme_sh
Ansible Galaxy
Puedes encontrarlo en el oficial Ansible Galaxy si deseas calificarlo.
Licencia
MIT
Install and auto-renew SSL certificates with Let's Encrypt using acme.sh.
ansible-galaxy install nickjj.acme_sh