felixfontein.acme_certificate
acme_certificate 1.1.1
¡ESTE ROLLO ESTÁ OBSOLETO! ¡POR FAVOR UTILIZA LA VERSIÓN DE LA COLECCIÓN felixfontein.acme (https://github.com/felixfontein/ansible-acme/) EN SU LUGAR!
Permite obtener certificados de Let's Encrypt con mínima interacción con el servidor web. La mayoría del código se ejecuta en el controlador y la clave de la cuenta nunca se envía a los nodos.
El rol se puede instalar a través de Ansible Galaxy:
ansible-galaxy install felixfontein.acme_certificate
Para cambios en este rol, consulta el registro de cambios.
Descripción
Este es un rol de Ansible que puede usar cualquier CA que soporte el protocolo ACME, como Let's Encrypt o Buypass, para emitir certificados TLS/SSL para tu servidor. Este rol requiere Ansible 2.8.3 o superior y se basa en el módulo acme_certificate que viene con Ansible.
La principal ventaja de este enfoque sobre otros es que casi no se ejecuta código en tu servidor web: solo cuando usas desafíos HTTP, los archivos necesitan ser copiados a tu servidor web, y luego eliminados de él. ¡Todo lo demás se ejecuta en tu máquina local!
(Esto no cubre la instalación de los certificados, tienes que hacerlo tú mismo en otro rol).
Requisitos
Requiere la biblioteca de Python cryptography instalada en el controlador, disponible para la versión de Python utilizada para ejecutar el libro de jugadas. Si cryptography
no está instalada, una versión suficientemente reciente de PyOpenSSL es actualmente soportada como alternativa por los módulos openssl_privatekey
y openssl_csr
de Ansible.
El binario openssl
también debe estar disponible en la ruta ejecutable del controlador. Es necesario para el módulo acme_certificate
en caso de que cryptography
no esté instalada y se utiliza para la validación de la cadena de certificados.
Si se utilizan desafíos DNS, puede haber otros requisitos dependiendo del proveedor DNS. Por ejemplo, para Route 53 de Amazon, el módulo route53
de Ansible requiere el paquete de Python boto
.
Configuración de la Clave de la Cuenta
Puedes crear una clave de cuenta usando el binario openssl
de la siguiente manera:
# Clave RSA de 4096 bits
openssl genrsa 4096 -out keys/acme-account.key
# Clave ECC de 256 bits (P-256)
openssl ecparam -name prime256v1 -genkey -out keys/acme-account.key
# Clave ECC de 384 bits (P-384)
openssl ecparam -name secp384r1 -genkey -out keys/acme-account.key
Con Ansible, puedes usar el módulo openssl_privatekey
de la siguiente manera:
- name: Generar clave RSA 4096
openssl_privatekey:
path: keys/acme-account.key
type: RSA
size: 4096
- name: Generar clave ECC de 256 bits (P-256)
openssl_privatekey:
path: keys/acme-account.key
type: ECC
curve: secp256r1
- name: Generar clave ECC de 384 bits (P-384)
openssl_privatekey:
path: keys/acme-account.key
type: ECC
curve: secp384r1
Asegúrate de guardar la clave de la cuenta de forma segura. A diferencia de las claves privadas de los certificados, no hay necesidad de regenerarla frecuentemente y facilita la revocación de los certificados emitidos con ella.
Variables del Rol
Ten en cuenta que desde mayo de 2020, todas las variables deben ser precedidas por acme_certificate_
. Durante un tiempo, el módulo seguirá utilizando los nombres de variables antiguos (cortos) si los más largos no están definidos. Por favor, actualiza tu uso del rol lo antes posible.
Estas son las variables principales:
acme_certificate_acme_account
: Ruta a la clave privada de la cuenta ACME. Siempre debe ser especificada.acme_certificate_acme_email
: Tu dirección de correo electrónico que se asociará a la cuenta ACME. Siempre debe ser especificada.acme_certificate_algorithm
: El algoritmo utilizado para crear claves privadas. El valor por defecto es"rsa"
; otras opciones son"p-256"
,"p-384"
o"p-521"
para las curvas elípticas de NISTprime256v1
,secp384r1
ysecp521r1
, respectivamente.acme_certificate_key_length
: La longitud en bits que se usará para las claves privadas RSA. El valor por defecto es 4096.acme_certificate_key_name
: El nombre base para almacenar las claves y certificados. El valor por defecto es el primer dominio especificado, con*
reemplazado por_
.acme_certificate_keys_path
: Dónde se almacenan las claves y certificados. El valor por defecto es"keys/"
.acme_certificate_keys_old_path
: Dónde deben ser copiadas las claves y certificados antiguos; usado en caso de queacme_certificate_keys_old_store
sea verdadero. El valor por defecto es"keys/old/"
.acme_certificate_keys_old_store
: Si se establece entrue
, hará copias de las claves y certificados antiguos. Las copias serán almacenadas en el directorio especificado poracme_certificate_keys_old_store
. El valor por defecto esfalse
.acme_certificate_keys_old_prepend_timestamp
: Si las copias de las claves y certificados antiguos deben ser precedidas por la fecha y hora actuales. El valor por defecto esfalse
.acme_certificate_ocsp_must_staple
: Si se solicita un certificado con la extensión OCSP Must Staple. El valor por defecto esfalse
.acme_certificate_agreement
: El documento de términos de servicio con el que el usuario acepta. El valor por defecto eshttps://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf
.acme_certificate_acme_directory
: El directorio ACME a utilizar. El valor por defecto eshttps://acme-v02.api.letsencrypt.org/directory
, que es el extremo de producción ACME v2 actual de Let's Encrypt.acme_certificate_acme_version
: La versión del directorio ACME. El valor por defecto es 2. Usa 1 para ACME v1.acme_certificate_challenge
: El tipo de desafío a utilizar. Debe serhttp-01
para desafíos HTTP (necesita acceso al servidor web) odns-01
para desafíos DNS (necesita acceso al proveedor DNS).acme_certificate_root_certificate
: El certificado raíz para el directorio ACME. El valor por defecto eshttps://letsencrypt.org/certs/isrgrootx1.pem
para el certificado raíz de Let's Encrypt.acme_certificate_deactivate_authzs
: Si se deben desactivar lasauthz
s (autorizaciones) después. El valor por defecto estrue
. Establecer enfalse
para poder reutilizarauthz
s.acme_certificate_modify_account
: Si se debe crear la cuenta ACME (si no existe) y actualizar los datos de contacto (dirección de correo electrónico). El valor por defecto estrue
. Establecer enfalse
si deseas usar el móduloacme_account
para gestionar tu cuenta ACME (no se realiza con este rol).acme_certificate_privatekey_mode
: Qué modo de archivo usar para el archivo de clave privada. El valor por defecto es"0600"
, que significa que es legible y escribible por el propietario, pero no accesible por nadie más (excepto posiblementeroot
).acme_certificate_select_chain
: (Solo utilizable con Ansible 2.10+) Debe estar en el formato descrito aquí. Permite seleccionar la cadena de certificados a utilizar;acme_certificate_root_certificate
debe usarse en conjunto. Esto se puede usar por ejemplo con Let's Encrypt para seleccionar qué certificado raíz usar.
Desafíos HTTP
Para los desafíos HTTP, las siguientes variables definen cómo los desafíos pueden ser colocados en el servidor web (remoto):
acme_certificate_server_location
: Ubicación donde se servirá.well-known/acme-challenge/
. El valor por defecto es/var/www/challenges
.acme_certificate_http_become
: Argumento parabecome:
para las tareasfile
ycopy
. El valor por defecto esfalse
.acme_certificate_http_challenge_user
: El usuario al que pertenecen los archivos de desafío. El valor por defecto esroot
.acme_certificate_http_challenge_group
: El grupo al que pertenecen los archivos de desafío. El valor por defecto eshttp
.acme_certificate_http_challenge_folder_mode
: El modo a usar para la carpeta de desafío. El valor por defecto es0750
(octal).acme_certificate_http_challenge_file_mode
: El modo a usar para los archivos de desafío. El valor por defecto es0640
(octal).
La siguiente subsección muestra cómo configurar nginx para desafíos HTTP.
Configuración de Nginx
Supongamos que para uno de tus dominios protegidos TLS/SSL, usas una redirección de HTTP a HTTPS. Supongamos que se ve así:
server {
listen example.com:80;
server_name example.com *.example.com;
return 301 https://www.example.com$request_uri;
}
Para permitir que el rol acme_certificate
coloque algo en http://*.example.com/.well-known/acme-challenge/
, puedes cambiar esto a:
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;
}
}
Con esta configuración de nginx, todas las demás URL en *.example.com
y example.com
aún se redirigen, mientras que todo en *.example.com/.well-known/acme-challenge/
se sirve desde /var/www/challenges
. Al ajustar la ubicación de /var/www/challenges
, también debes cambiar acme_certificate_server_location
.
Incluso puedes mejorar esto redirigiendo todas las URL en *.example.com/.well-known/acme-challenge/
que no resuelven a un archivo válido en /var/www/challenges
a tu servidor HTTPS también. Una forma de hacerlo es:
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;
}
}
Con esta configuración, si /var/www/challenges/
está vacío, tu servidor HTTP se comportará como si la ubicación /.well-known/acme-challenge/
no estuviera especificada.
Desafíos DNS
Si se utilizan desafíos DNS, las siguientes variables definen cómo se pueden cumplir los desafíos:
acme_certificate_dns_provider
: debe ser uno deroute53
,hosttech
, yns1
. Cada uno necesita más información:- Para
route53
(Amazon Route 53), las credenciales deben ser pasadas comoacme_certificate_aws_access_key
yacme_certificate_aws_secret_key
. - Para
hosttech
(hosttech GmbH, requiere el módulo externo hosttech_dns_record). - Para
ns1
(ns1.com), la clave para tu cuenta API debe ser pasada comoacme_certificate_ns1_secret_key
. También es necesaria la dependencia del módulo externons1_record
. Suponiendo la estructura y configuraciones predeterminadas, puedes necesitar descargar 2 archivos en la máquina donde se ejecuta el libro de jugadas:
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
- Para
Ten en cuenta que el código del desafío DNS no es perfecto. La funcionalidad de Route 53, Hosttech y NS1 ha sido probada. Una cosa que aún no está completa es que el código intenta extraer la zona DNS del dominio tomando los últimos dos componentes separados por puntos. Esto fallará, por ejemplo, para dominios .co.uk
u otras zonas anidadas.
El soporte para más proveedores DNS puede añadirse al agregar archivos tasks/dns-NAME-create.yml
y tasks/dns-NAME-cleanup.yml
con contenido similar al de los archivos existentes.
Conversión de la clave de cuenta
Nota que este rol de Ansible espera que la clave de cuenta de Let's Encrypt esté en formato PEM y no en formato JWK, que es usado por el cliente oficial Let's Encrypt certbot. Si has creado una clave de cuenta con el cliente oficial y quieres usar esta clave con este rol de ansible, debes convertirla. Una herramienta que puede hacer esto es pem-jwk.
Archivos Generados
Supongamos que creaste claves TLS para www.example.com
. Debes copiar los archivos relevantes a tu servidor web. El rol de ansible creó los siguientes archivos:
keys/www.example.com.key
: esta es la clave privada para el certificado. Asegúrate de que nadie pueda acceder a ella.keys/www.example.com.pem
: este es el certificado en sí.keys/www.example.com-chain.pem
: este es el/los certificado(s) intermedio(s) necesarios para una ruta de confianza.keys/www.example.com.cnf
: este es un archivo de configuración de OpenSSL usado para crear la Solicitud de Firma de Certificado. Puedes eliminarlo de forma segura.keys/www.example.com.csr
: esta es la Solicitud de Firma de Certificado usada para obtener el certificado. Puedes eliminarlo de forma segura.keys/www.example.com-fullchain.pem
: este es el certificado combinado con el/los certificado(s) intermedio(s).keys/www.example.com-rootchain.pem
: este es el/los certificado(s) intermedio(s) combinado(s) con el certificado raíz. Puede que necesites esto para OCSP stapling.keys/www.example.com-root.pem
: este es el certificado raíz de Let's Encrypt.
Para configurar tu servidor web, necesitas la clave privada (keys/www.example.com.key
), y bien el certificado con el/los certificado(s) intermedio(s) combinados en un archivo (keys/www.example.com-fullchain.pem
), o el certificado y el/los certificado(s) intermedio(s) como dos archivos separados (keys/www.example.com.pem
y keys/www.example.com-chain.pem
). Si deseas usar OCSP stapling, también necesitarás keys/www.example.com-rootchain.pem
.
Para mover estos archivos a tu servidor web, puedes agregar tareas como sigue:
- name: copiar claves privadas
copy:
src: keys/{{ item }}
dest: /etc/ssl/private/
owner: root
group: root
mode: "0400"
with_items:
- www.example.com.key
notify: recargar servidor web
- name: copiar certificados
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: recargar servidor web
La configuración del servidor web podría verse así (para nginx):
server {
listen www.example.com:443 ssl; # IPv4: escucha en la IP a la que apunta www.example.com
listen [::]:443 ssl; # IPv6: escucha en localhost
server_name www.example.com;
# Permitirá solo TLS 1.0 y 1.2, con una cantidad muy selectiva de cifrados.
# De acuerdo con la prueba de servidor SSL de SSL Lab, esto bloqueará:
# - Android 2.3.7
# - IE 6 y 8 bajo Windows XP
# - Java 6, 7 y 8
# Si eso no es aceptable para ti, elige otras listas de cifrados. Busca
# por ejemplo en 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";
# La cadena de certificados enviada al navegador, así como la clave privada.
# Asegúrate de que tu clave privada solo sea accesible por el servidor web durante
# la carga de configuración (que por defecto se realiza con el usuario root).
ssl_certificate /etc/ssl/server-certs/www.example.com-fullchain.pem;
ssl_certificate_key /etc/ssl/private/www.example.com.key;
# Para OCSP stapling, necesitamos un resolvedor DNS. Aquí solo se especifican los servidores DNS públicos de Quad9 y Google; yo los precedería por los
# servidores DNS de tu proveedor de hosting. Por lo general, puedes encontrar sus IPs en /etc/resolv.conf en tu
# servidor web.
resolver 9.9.9.9 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 10s;
# Habilitando OCSP stapling. Nginx se encargará de recuperar los datos OCSP
# automáticamente. Consulta https://wiki.mozilla.org/Security/Server_Side_TLS#OCSP_Stapling
# para obtener más detalles sobre OCSP stapling.
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/ssl/server-certs/www.example.com-rootchain.pem;
# Habilita una caché de sesión SSL. Ajusta los números dependiendo del uso de tu sitio.
ssl_session_cache shared:SSL:50m;
ssl_session_timeout 30m;
ssl_session_tickets off;
# Solo deberías usar HSTS con certificados apropiados; los de Let's Encrypt
# son buenos para esto, los auto-firmados no. Consulta MozillaWiki para obtener más detalles:
# 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;
}
}
Dependencias
Este rol no depende de otros roles.
Ejemplo de Libro de Jugadas
Este rol se puede usar de la siguiente manera. Ten en cuenta que obtiene varios certificados y define variables que se utilizan globalmente para todos los certificados:
---
- name: obteniendo certificados para el servidor web
hosts: webserver
vars:
acme_certificate_acme_account: 'keys/acme-account.key'
acme_certificate_acme_email: '[email protected]'
# Para desafíos 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"
# Para desafíos DNS con 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
# Para desafíos DNS con 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']
# Usar desafíos DNS:
acme_certificate_challenge: dns-01
# Los archivos de certificado se almacenarán en:
# keys/example.com.key (clave privada)
# keys/example.com.csr (solicitud de firma de certificado)
# keys/example.com.pem (certificado)
# keys/example.com.cnf (configuración de OpenSSL para la creación de CSR -- se puede eliminar de forma segura)
# keys/example.com-chain.pem (certificado intermedio)
# keys/example.com-fullchain.pem (certificado con certificado intermedio)
# keys/example.com-root.pem (certificado raíz)
# keys/example.com-rootchain.pem (certificado intermedio con certificado raíz)
- role: acme_certificate
acme_certificate_domains: ['another.example.com']
acme_certificate_key_name: 'another.example.com-rsa'
acme_certificate_key_length: 4096
# Usar desafíos HTTP:
acme_certificate_challenge: http-01
# Los archivos de certificado se almacenarán en:
# keys/another.example.com-rsa.key (clave privada)
# keys/another.example.com-rsa.csr (solicitud de firma de certificado)
# keys/another.example.com-rsa.pem (certificado)
# keys/another.example.com-rsa.cnf (configuración de OpenSSL para la creación de CSR -- se puede eliminar de forma segura)
# keys/another.example.com-rsa-chain.pem (certificado intermedio)
# keys/another.example.com-rsa-fullchain.pem (certificado con certificado intermedio)
# keys/another.example.com-rsa-root.pem (certificado raíz)
# keys/another.example.com-rsa-rootchain.pem (certificado intermedio con certificado raíz)
- role: acme_certificate
acme_certificate_domains: ['another.example.com']
acme_certificate_key_name: 'another.example.com-ecc'
acme_certificate_algorithm: 'p-256'
# Usar desafíos HTTP (el desafío predeterminado es http-01).
# Los archivos de certificado se almacenarán en:
# keys/another.example.com-ecc.key (clave privada)
# keys/another.example.com-ecc.csr (solicitud de firma de certificado)
# keys/another.example.com-ecc.pem (certificado)
# keys/another.example.com-ecc.cnf (configuración de OpenSSL para la creación de CSR -- se puede eliminar de forma segura)
# keys/another.example.com-ecc-chain.pem (certificado intermedio)
# keys/another.example.com-ecc-fullchain.pem (certificado con certificado intermedio)
# keys/another.example.com-ecc-root.pem (certificado raíz)
# keys/another.example.com-ecc-rootchain.pem (certificado intermedio con certificado raíz)
Licencia
La Licencia MIT (MIT)
Copyright (c) 2018-2020 Felix Fontein
Se otorga por la presente, sin cargo, a cualquier persona que obtenga una copia de este software y archivos de documentación asociados (el "Software"), para tratar en el Software sin restricción, incluyendo sin limitación los derechos de usar, copiar, modificar, fusionar, publicar, distribuir, sublicenciar y/o vender copias del Software, y permitir a las personas a quienes se les proporciona el Software hacerlo, sujeto a las siguientes condiciones:
El aviso de copyright anterior y este aviso de permiso deberán ser incluidos en todas las copias o porciones sustanciales del Software.
EL SOFTWARE SE PROPORCIONA "TAL CUAL", SIN GARANTÍA DE NINGÚN TIPO, EXPRESA O IMPLÍCITA, INCLUYENDO PERO NO LIMITÁNDOSE A LAS GARANTÍAS DE COMERCIABILIDAD, ADECUACIÓN A UN PROPÓSITO PARTICULAR Y NO INFRACCIÓN. EN NINGÚN CASO LOS AUTORES O TITULARES DE COPYRIGHT SERÁN RESPONSABLES POR NINGUNA RECLAMACIÓN, DAÑO O OTRA RESPONSABILIDAD, YA SEA EN UNA ACCIÓN DE CONTRATO, TORTO O DE OTRA MANERA, QUE SURJA DE, DE O EN CONEXIÓN CON EL SOFTWARE O EL USO O OTRAS NEGOCIACIONES EN EL SOFTWARE.
Información del Autor
La página principal de este rol es https://github.com/felixfontein/acme-certificate/. Por favor, utiliza el rastreador de problemas para reportar problemas.
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