acme: Servicio automático de certificados Let's Encrypt e implementación en Lua del protocolo ACMEv2
Instalación
Si no has configurado la suscripción al repositorio RPM, regístrate. Luego puedes proceder con los siguientes pasos.
CentOS/RHEL 7 o Amazon Linux 2
yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install lua-resty-acme
CentOS/RHEL 8+, Fedora Linux, Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install lua5.1-resty-acme
Para usar esta biblioteca Lua con NGINX, asegúrate de que nginx-module-lua esté instalado.
Este documento describe lua-resty-acme v0.16.0 lanzado el 01 de septiembre de 2025.
Servicio automático de certificados Let's Encrypt (RSA + ECC) e implementación pura en Lua del protocolo ACMEv2.
Se admiten los desafíos http-01 y tls-alpn-01.
Descripción
Esta biblioteca consta de dos partes:
resty.acme.autossl: gestión automática del ciclo de vida de los certificados Let's Encryptresty.acme.client: implementación en Lua del protocolo ACME v2
Instala usando opm:
opm install fffonion/lua-resty-acme
Alternativamente, para instalar usando luarocks:
luarocks install lua-resty-acme
## instalar manualmente un luafilesystem
luarocks install luafilesystem
Ten en cuenta que necesitarás instalar manualmente luafilesystem al usar LuaRocks. Esto se hace para mantener la compatibilidad hacia atrás.
Esta biblioteca utiliza un backend de openssl basado en FFI, que actualmente soporta las series OpenSSL 1.1.1, 1.1.0 y 1.0.2.
Sinopsis
Crea la clave privada de la cuenta y los certificados de respaldo:
## crear clave de cuenta
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:4096 -out /etc/openresty/account.key
## crear certificado y clave de respaldo
openssl req -newkey rsa:2048 -nodes -keyout /etc/openresty/default.key -x509 -days 365 -out /etc/openresty/default.pem
Usa la siguiente configuración de ejemplo:
events {}
http {
resolver 8.8.8.8 ipv6=off;
lua_shared_dict acme 16m;
# requerido para verificar la API de Let's Encrypt
lua_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt;
lua_ssl_verify_depth 2;
init_by_lua_block {
require("resty.acme.autossl").init({
-- establecer lo siguiente en verdadero
-- implica que has leído y aceptado https://letsencrypt.org/repository/
tos_accepted = true,
-- descomentar lo siguiente para la configuración inicial
-- staging = true,
-- descomentar lo siguiente para habilitar certificado doble RSA + ECC
-- domain_key_types = { 'rsa', 'ecc' },
-- descomentar lo siguiente para habilitar el desafío tls-alpn-01
-- enabled_challenge_handlers = { 'http-01', 'tls-alpn-01' },
account_key_path = "/etc/openresty/account.key",
account_email = "[email protected]",
domain_whitelist = { "example.com" },
})
}
init_worker_by_lua_block {
require("resty.acme.autossl").init_worker()
}
server {
listen 80;
listen 443 ssl;
server_name example.com;
# certificados de respaldo, asegúrate de crearlos de antemano
ssl_certificate /etc/openresty/default.pem;
ssl_certificate_key /etc/openresty/default.key;
ssl_certificate_by_lua_block {
require("resty.acme.autossl").ssl_certificate()
}
location /.well-known {
content_by_lua_block {
require("resty.acme.autossl").serve_http_challenge()
}
}
}
}
Al probar la implementación, se recomienda descomentar staging = true para permitir una prueba de extremo a extremo de tu entorno. Esto puede evitar que un fallo de configuración resulte en demasiadas solicitudes que golpeen la limitación de tasa en la API de Let's Encrypt.
Por defecto, autossl solo crea certificados RSA. Para usar certificados ECC o ambos, descomenta domain_key_types = { 'rsa', 'ecc' }. Ten en cuenta que la cadena de múltiples certificados solo es compatible con NGINX 1.11.0 o posterior.
Un certificado será enviado a la cola para crear después de que Nginx haya visto una solicitud con tal SNI, lo que puede tardar decenas de segundos en completarse. Mientras tanto, las solicitudes con tal SNI se responden con el certificado de respaldo.
Ten en cuenta que domain_whitelist o domain_whitelist_callback deben configurarse para incluir tu dominio que deseas servir con autossl, para prevenir posibles abusos usando SNI falso en el apretón de manos SSL.
domain_whitelist define una tabla que incluye todos los dominios que deben incluirse y el CN que se utilizará para crear el certificado. Solo se permite un único * como comodín.
domain_whitelist = { "domain1.com", "domain2.com", "domain3.com", "*.domain4.com" },
Certificados comodín
Para habilitar que esta biblioteca cree certificados comodín, se deben cumplir los siguientes requisitos:
- El dominio comodín debe aparecer exactamente como
*.somedomain.comendomain_whitelist. - El desafío
dns-01debe estar habilitado y se debe configurar un proveedor de DNS que tengadomainsque coincidan con el dominio.
De lo contrario, se creará un certificado no comodín como respaldo.
Por defecto, el dominio comodín *.example.com aparecerá en el Nombre Común. Sin embargo, cuando wildcard_domain_in_san se establece en true, se creará un certificado con Nombre Común example.com y Nombre Alternativo de Sujeto *.example.com. Ten en cuenta que tanto *.example.com como example.com deben aparecer en dns_provider_accounts.
Uso Avanzado
Usar una función para incluir dominios
domain_whitelist_callback define una función que acepta el dominio como parámetro y devuelve un booleano para indicar si debe incluirse.
Para hacer coincidir un patrón en tu nombre de dominio, por ejemplo, todos los subdominios bajo example.com, usa:
domain_whitelist_callback = function(domain, is_new_cert_needed)
return ngx.re.match(domain, [[\.example\.com$]], "jo")
end
Además, dado que la verificación de la lista blanca de dominios se ejecuta en la fase de certificado, es posible utilizar la API de cosocket aquí. Ten en cuenta que esto aumentará la latencia del apretón de manos SSL.
domain_whitelist_callback = function(domain, is_new_cert_needed)
-- enviar solicitud HTTP
local http = require("resty.http")
local res, err = httpc:request_uri("http://example.com")
-- acceder al almacenamiento
local acme = require("resty.acme.autossl")
local value, err = acme.storage:get("key")
-- obtener certificado de la caché LRU de resty
-- cached = { pkey, cert } o nil si el cert no está en caché
local cached, staled, flags = acme.get_cert_from_cache(domain, "rsa")
-- hacer algo para verificar el dominio
-- devolver is_domain_included
end
La función domain_whitelist_callback se proporciona con un segundo argumento, que indica si el certificado está a punto de ser servido en una solicitud HTTP entrante (falso) o si se está a punto de solicitar un nuevo certificado (verdadero). Esto permite usar valores en caché en la ruta caliente (sirviendo solicitudes) mientras se obtienen datos frescos del almacenamiento para nuevos certificados. También se puede implementar una lógica diferente, por ejemplo, realizar verificaciones adicionales antes de solicitar un nuevo certificado.
Definir un período de enfriamiento por fallos
En caso de fallo en la solicitud de certificado, es posible que desees evitar que el cliente ACME solicite otro certificado inmediatamente. Por defecto, el período de enfriamiento se establece en 300 segundos (5 minutos). Puede personalizarse con failure_cooloff o con la función failure_cooloff_callback, por ejemplo, para implementar un retroceso exponencial.
failure_cooloff_callback = function(domain, count)
if count == 1 then
return 600 -- 10 minutos
elseif count == 2 then
return 1800 -- 30 minutos
elseif count == 3 then
return 3600 -- 1 hora
elseif count == 4 then
return 43200 -- 12 horas
elseif count == 5 then
return 43200 -- 12 horas
else
return 86400 -- 24 horas
end
end
Desafío tls-alpn-01
El desafío tls-alpn-01 es actualmente compatible con Openresty 1.15.8.x, 1.17.8.x y 1.19.3.x.
Haz clic para expandir la configuración de ejemplo
events {}
http {
resolver 8.8.8.8 ipv6=off;
lua_shared_dict acme 16m;
# requerido para verificar la API de Let's Encrypt
lua_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt;
lua_ssl_verify_depth 2;
init_by_lua_block {
require("resty.acme.autossl").init({
-- establecer lo siguiente en verdadero
-- implica que has leído y aceptado https://letsencrypt.org/repository/
tos_accepted = true,
-- descomentar lo siguiente para la configuración inicial
-- staging = true,
-- descomentar lo siguiente para habilitar certificado doble RSA + ECC
-- domain_key_types = { 'rsa', 'ecc' },
-- descomentar lo siguiente para habilitar el desafío tls-alpn-01
enabled_challenge_handlers = { 'http-01', 'tls-alpn-01' },
account_key_path = "/etc/openresty/account.key",
account_email = "[email protected]",
domain_whitelist = { "example.com" },
storage_adapter = "file",
})
}
init_worker_by_lua_block {
require("resty.acme.autossl").init_worker()
}
server {
listen 80;
listen unix:/tmp/nginx-default.sock ssl;
# listen unix:/tmp/nginx-default.sock ssl proxy_protocol;
server_name example.com;
# set_real_ip_from unix:;
# real_ip_header proxy_protocol;
# certificados de respaldo, asegúrate de crearlos de antemano
ssl_certificate /etc/openresty/default.pem;
ssl_certificate_key /etc/openresty/default.key;
ssl_certificate_by_lua_block {
require("resty.acme.autossl").ssl_certificate()
}
location /.well-known {
content_by_lua_block {
require("resty.acme.autossl").serve_http_challenge()
}
}
}
}
stream {
init_worker_by_lua_block {
require("resty.acme.autossl").init({
-- establecer lo siguiente en verdadero
-- implica que has leído y aceptado https://letsencrypt.org/repository/
tos_accepted = true,
-- descomentar lo siguiente para la configuración inicial
-- staging = true,
-- descomentar lo siguiente para habilitar certificado doble RSA + ECC
-- domain_key_types = { 'rsa', 'ecc' },
-- descomentar lo siguiente para habilitar el desafío tls-alpn-01
enabled_challenge_handlers = { 'http-01', 'tls-alpn-01' },
account_key_path = "/etc/openresty/account.key",
account_email = "[email protected]",
domain_whitelist = { "example.com" },
storage_adapter = "file"
})
require("resty.acme.autossl").init_worker()
}
map $ssl_preread_alpn_protocols $backend {
~\bacme-tls/1\b unix:/tmp/nginx-tls-alpn.sock;
default unix:/tmp/nginx-default.sock;
}
server {
listen 443;
listen [::]:443;
ssl_preread on;
proxy_pass $backend;
# proxy_protocol on;
}
server {
listen unix:/tmp/nginx-tls-alpn.sock ssl;
# listen unix:/tmp/nginx-tls-alpn.sock ssl proxy_protocol;
ssl_certificate certs/default.pem;
ssl_certificate_key certs/default.key;
# requiere --with-stream_realip_module
# set_real_ip_from unix:;
ssl_certificate_by_lua_block {
require("resty.acme.autossl").serve_tls_alpn_challenge()
}
content_by_lua_block {
ngx.exit(0)
}
}
}
En la configuración de ejemplo anterior, configuramos un servidor http y dos servidores de stream.
El servidor de stream frontal escucha el puerto 443 y enruta a diferentes upstream según el ALPN del cliente. El respondedor tls-alpn-01 escucha en unix:/tmp/nginx-tls-alpn.sock. Todo el tráfico https normal escucha en unix:/tmp/nginx-default.sock.
[servidor de stream unix:/tmp/nginx-tls-alpn.sock ssl]
Y /
[servidor de stream 443] --- ¿ALPN es acme-tls?
N \
[servidor http unix:/tmp/nginx-default.sock ssl]
- La configuración pasada a
require("resty.acme.autossl").initen ambos subsistemas debe mantenerse lo más igual posible. - El controlador de desafío
tls-alpn-01no necesita ninguna dependencia de terceros. - Puedes habilitar los controladores de desafío
http-01ytls-alpn-01al mismo tiempo. - Los subsistemas
httpystreamno comparten shm, por lo que se considera usar un almacenamiento diferente ashm. Si debes usarshm, necesitarás aplicar este parche.
Desafío dns-01
El desafío DNS-01 es compatible con lua-resty-acme > 0.13.0. Actualmente, se admiten los siguientes proveedores de DNS:
cloudflare: Cloudflaredynv6: Dynv6dnspod-intl: Dnspod Internacional (solo se admite el token de Dnspod y se usaid,tokenen el campo secreto)
Para leer cómo extender un nuevo proveedor de DNS para trabajar con el desafío dns-01, consulta Proveedores de DNS.
Una configuración de ejemplo para usar el desafío dns-01 sería:
require("resty.acme.autossl").init({
-- establecer lo siguiente en verdadero
-- implica que has leído y aceptado https://letsencrypt.org/repository/
tos_accepted = true,
-- descomentar lo siguiente para la configuración inicial
-- staging = true,
-- descomentar lo siguiente para habilitar certificado doble RSA + ECC
-- domain_key_types = { 'rsa', 'ecc' },
-- no establecer `http-01` o `tls-alpn-01` si solo planeas usar dns-01.
enabled_challenge_handlers = { 'dns-01' },
account_key_path = "/etc/openresty/account.key",
account_email = "[email protected]",
domain_whitelist = { "example.com", "subdomain.anotherdomain.com" },
dns_provider_accounts = {
{
name = "cloudflare_prod",
provider = "cloudflare",
secret = "apikey de cloudflare",
domains = { "example.com" },
},
{
name = "dynv6_staging",
provider = "dynv6",
secret = "apikey de dynv6",
domains = { "*.anotherdomain.com" },
},
},
-- descomentar lo siguiente para crear anotherdomain.com en CN y *.anotherdomain.com en SAN
-- wildcard_domain_in_san = true,
})
Por defecto, esta biblioteca intenta hasta 5 minutos para la propagación DNS. Si el TTL predeterminado para el proveedor de DNS es más largo que eso, el usuario puede querer ajustar manualmente challenge_start_delay para esperar más tiempo.
resty.acme.autossl
Se puede pasar una tabla de configuración a resty.acme.autossl.init(), los valores predeterminados son:
default_config = {
-- aceptar términos de servicio https://letsencrypt.org/repository/
tos_accepted = false,
-- si se utiliza la API de staging de Let's Encrypt
staging = false,
-- la ruta a la clave privada de la cuenta en formato PEM
account_key_path = nil,
-- el correo electrónico de la cuenta para registrarse
account_email = nil,
-- número de caché de certificados, por tipo
cache_size = 100,
domain_key_paths = {
-- la clave privada RSA global del dominio
rsa = nil,
-- la clave privada ECC global del dominio
ecc = nil,
},
-- el algoritmo de clave privada a utilizar, puede ser uno o ambos de
-- 'rsa' y 'ecc'
domain_key_types = { 'rsa' },
-- restringir el registro de nuevos certificados solo con dominios definidos en esta tabla
domain_whitelist = nil,
-- restringir el registro de nuevos certificados solo con dominios verificados por esta función
domain_whitelist_callback = nil,
-- intervalo a esperar antes de reintentar después de una solicitud de certificado fallida
failure_cooloff = 300,
-- función que devuelve el intervalo a esperar antes de reintentar después de una solicitud de certificado fallida
failure_cooloff_callback = nil,
-- el umbral para renovar un certificado antes de que expire, en segundos
renew_threshold = 7 * 86400,
-- intervalo para verificar la renovación del certificado, en segundos
renew_check_interval = 6 * 3600,
-- el almacenamiento de certificados
storage_adapter = "shm",
-- la configuración de almacenamiento pasada al adaptador de almacenamiento
storage_config = {
shm_name = 'acme',
},
-- los tipos de desafío habilitados
enabled_challenge_handlers = { 'http-01' },
-- tiempo a esperar antes de señalar al servidor ACME para validar en segundos
challenge_start_delay = 0,
-- si es verdadero, la solicitud a nginx espera hasta que el certificado ha sido generado y se utiliza de inmediato
blocking = false,
-- si es verdadero, el certificado para dominios no en la lista blanca será eliminado del almacenamiento
enabled_delete_not_whitelisted_domain = false,
-- el diccionario de proveedores de DNS, cada proveedor debe tener la siguiente estructura:
-- {
-- name = "prod_account",
-- provider = "provider_name", -- "cloudflare" o "dynv6"
-- secret = "la clave API o token",
-- domains = { "example.com", "*.example.com" }, -- la lista de dominios que se pueden usar con este proveedor
-- }
dns_provider_accounts = {},
-- si está habilitado, los dominios comodín como *.example.com se crearán como SAN y CN será example.com
wildcard_domain_in_san = false,
}
Si account_key_path no se especifica, se creará una nueva clave de cuenta cada vez que Nginx recargue la configuración. Ten en cuenta que esto puede activar la limitación de tasa de Nueva Cuenta en la API de Let's Encrypt.
Si domain_key_paths no se especifica, se generará una nueva clave privada para cada certificado (RSA de 4096 bits y ECC de 256 bits prime256v1). Ten en cuenta que generar tal clave bloqueará el trabajador y será especialmente notable en VMs donde la entropía es baja.
Pasa la tabla de configuración directamente al cliente ACME como segundo parámetro. El siguiente ejemplo demuestra cómo usar un proveedor de CA diferente a Let's Encrypt y también establecer la cadena preferida.
resty.acme.autossl.init({
tos_accepted = true,
account_email = "[email protected]",
}, {
api_uri = "https://acme.otherca.com/directory",
preferred_chain = "OtherCA PKI Root CA",
}
)
Consulta también Adaptadores de Almacenamiento a continuación.
Al usar tipos de almacenamiento distribuidos, es útil aumentar challenge_start_delay para permitir que los cambios en el almacenamiento se propaguen. Cuando challenge_start_delay se establece en 0, no se realizará ninguna espera antes de comenzar a validar desafíos.
autossl.get_certkey
sintaxis: certkey, err = autossl.get_certkey(domain, type?)
Devuelve el certificado y la clave privada codificados en PEM para domain desde el almacenamiento. Opcionalmente acepta un parámetro type que puede ser "rsa" o "ecc"; si se omite, type se establecerá de forma predeterminada en "rsa".
resty.acme.client
client.new
sintaxis: c, err = client.new(config)
Crea un cliente ACMEv2.
Los valores predeterminados para config son:
default_config = {
-- el punto final de la API ACME v2 a utilizar
api_uri = "https://acme-v02.api.letsencrypt.org/directory",
-- el correo electrónico de la cuenta para registrarse
account_email = nil,
-- la clave de la cuenta en texto de formato PEM
account_key = nil,
-- el kid de la cuenta (como una URL)
account_kid = nil,
-- id de clave de enlace de cuenta externa
eab_kid = nil,
-- clave hmac de enlace de cuenta externa, codificada en base64url
eab_hmac_key = nil,
-- controlador de registro de cuenta externa
eab_handler = nil,
-- almacenamiento para el desafío
storage_adapter = "shm",
-- la configuración de almacenamiento pasada al adaptador de almacenamiento
storage_config = {
shm_name = "acme"
},
-- los tipos de desafío habilitados, selección de `http-01` y `tls-alpn-01`
enabled_challenge_handlers = {"http-01"},
-- seleccionar el nombre común del emisor de CA raíz preferido si es aplicable
preferred_chain = nil,
-- función de callback que permite esperar antes de señalar al servidor ACME para validar
challenge_start_callback = nil,
-- el diccionario de proveedores de DNS, cada proveedor debe tener la siguiente estructura:
dns_provider_accounts = {},
}
Si se omite account_kid, el usuario debe llamar a client:new_account() para registrar una nueva cuenta. Ten en cuenta que al usar la misma account_key, client:new_account() devolverá el mismo kid que se registró previamente.
Si la CA requiere Vinculación de Cuenta Externa, el usuario puede establecer eab_kid y eab_hmac_key para cargar una cuenta existente, o establecer account_email y eab_handler para registrar una nueva cuenta. eab_hmac_key debe estar codificado en base64 url. En este último caso, el usuario debe llamar a client:new_account() para registrar una nueva cuenta. eab_handler debe ser una función que acepte account_email como parámetro y devuelva eab_kid, eab_hmac_key y error si lo hay.
eab_handler = function(account_email)
-- hacer algo para registrar una cuenta con account_email
-- si err entonces
-- return nil, nil, err
-- end
return eab_kid, eab_hmac_key
end
El siguiente controlador EAB de proveedor de CA es compatible con lua-resty-acme y el usuario no necesita implementar su propio eab_handler:
preferred_chain se utiliza para seleccionar una cadena con un Nombre Común coincidente en su CA raíz. Por ejemplo, el usuario puede usar "ISRG Root X1" para forzar el uso de la nueva cadena predeterminada en Let's Encrypt. Cuando no se configura ningún valor o el nombre configurado no se encuentra en ninguna cadena, se utilizará la cadena predeterminada.
challenge_start_callback es una función de callback que permite al cliente esperar antes de señalar al servidor ACME para comenzar a validar el desafío. Es útil en una configuración distribuida donde los desafíos tardan en propagarse. challenge_start_callback acepta challenge_type y challenge_token. El cliente llama a esta función cada segundo hasta que devuelve true, indicando que el desafío debe comenzar; si este challenge_start_callback no está configurado, no se realizará ninguna espera.
challenge_start_callback = function(challenge_type, challenge_token)
-- hacer algo aquí
-- si estamos bien
return true
end
Consulta también Adaptadores de Almacenamiento a continuación.
client:init
sintaxis: err = client:init()
Inicializa el cliente, requiere disponibilidad de la API de cosocket. Esta función iniciará sesión o registrará una cuenta.
client:order_certificate
sintaxis: err = client:order_certificate(domain,...)
Crea un certificado con uno o más dominios. Ten en cuenta que los dominios comodín no son compatibles, ya que solo se pueden verificar mediante el desafío dns-01.
client:serve_http_challenge
sintaxis: client:serve_http_challenge()
Sirve el desafío http-01. Un caso de uso común será poner esto como un bloque content_by_* para la ruta /.well-known.
client:serve_tls_alpn_challenge
sintaxis: client:serve_tls_alpn_challenge()
Sirve el desafío tls-alpn-01. Consulta esta sección sobre cómo usar este controlador.
Adaptadores de Almacenamiento
Los adaptadores de almacenamiento se utilizan en autossl o en el cliente acme para almacenar datos temporales o persistentes. Dependiendo del entorno de implementación, actualmente hay cinco adaptadores de almacenamiento disponibles para seleccionar. Para implementar un adaptador de almacenamiento personalizado, consulta este documento.
file
Almacenamiento basado en el sistema de archivos. Configuración de muestra:
storage_config = {
dir = '/etc/openresty/storage',
}
dir, se utilizará el directorio temporal del sistema operativo.
Se necesita luafilesystem o luafilesystem-ffi al usar el almacenamiento file para la renovación.
shm
Almacenamiento basado en el diccionario compartido de Lua. Ten en cuenta que este almacenamiento es volátil entre reinicios de Nginx (no recargas). Configuración de muestra:
storage_config = {
shm_name = 'dict_name',
}
redis
Almacenamiento basado en Redis. La configuración predeterminada es:
storage_config = {
host = '127.0.0.1',
port = 6379,
database = 0,
-- Clave de autenticación de Redis
auth = nil,
ssl = false,
ssl_verify = false,
ssl_server_name = nil,
-- espacio de nombres como prefijo de clave
namespace = "",
}
Se requiere Redis >= 2.6.12 ya que este almacenamiento requiere SET EX.
vault
Almacenamiento basado en Hashicorp Vault. Solo se admite el backend KV V2. La configuración predeterminada es:
storage_config = {
host = '127.0.0.1',
port = 8200,
-- ruta de prefijo de secretos kv
kv_path = "acme",
-- tiempo de espera en ms
timeout = 2000,
-- usar HTTPS
https = false,
-- activar la verificación tls
tls_verify = true,
-- SNI utilizado en la solicitud, predeterminado al host si se omite
tls_server_name = nil,
-- Método de Autenticación, predeterminado a token, puede ser "token" o "kubernetes"
auth_method = "token",
-- Token de Vault
token = nil,
-- Ruta de autenticación de Vault a utilizar
auth_path = "kubernetes",
-- El rol a intentar asignar
auth_role = nil,
-- La ruta al JWT
jwt_path = "/var/run/secrets/kubernetes.io/serviceaccount/token",
-- Espacio de nombres de Vault
namespace = nil,
}
Soporte para diferentes métodos de autenticación
- Token: Este es el predeterminado y permite pasar un "token" literal en la configuración.
- Kubernetes: A través de este método, se puede utilizar el método de autenticación integrado de vault para kubernetes. Básicamente, esto toma el token de la cuenta de servicio y valida que ha sido firmado por la CA de Kubernetes. El principal beneficio aquí es que los archivos de configuración ya no exponen tu token.
Las siguientes configuraciones se aplican aquí:
lua
-- Ruta de autenticación de Vault a utilizar
auth_path = "kubernetes",
-- El rol a intentar asignar
auth_role = nil,
-- La ruta al JWT
jwt_path = "/var/run/secrets/kubernetes.io/serviceaccount/token",
consul
Almacenamiento basado en Hashicorp Consul. La configuración predeterminada es:
storage_config = {
host = '127.0.0.1',
port = 8500,
-- ruta de prefijo kv
kv_path = "acme",
-- token ACL de Consul
token = nil,
-- tiempo de espera en ms
timeout = 2000,
}
etcd
Almacenamiento basado en etcd. En este momento solo se admite el protocolo v3, y la versión del servidor etcd debe ser >= v3.4.0.
La configuración predeterminada es:
storage_config = {
http_host = 'http://127.0.0.1:4001',
key_prefix = '',
timeout = 60,
ssl_verify = false,
}
El almacenamiento de etcd requiere que se instale la biblioteca lua-resty-etcd.
Se puede instalar manualmente con opm install api7/lua-resty-etcd o luarocks install lua-resty-etcd.
Proveedores de DNS
Para crear un proveedor de DNS personalizado, sigue estos pasos:
- Crea un archivo como
route53.luaenlib/resty/acme/dns_provider. - Implementa la siguiente firma de función
function _M.new(token)
-- ...
return self
end
function _M:post_txt_record(fqdn, content)
return ok, err
end
function _M:delete_txt_record(fqdn)
return ok, err
end
Donde token es la clave API, fqdn es el nombre del registro DNS para establecer el registro, y content es el valor del registro.
Pruebas
Configura el entorno de prueba e2e ejecutando bash t/fixtures/prepare_env.sh.
Luego ejecuta cpanm install Test::Nginx::Socket y luego prove -r t.
Ver También
- Entorno de Gestión Automática de Certificados (ACME)
- haproxytech/haproxy-lua-acme La implementación de ACME en Lua utilizada en HAProxy.
- GUI/lua-resty-auto-ssl
- lua-resty-openssl
- Límites de tasa de la API de Let's Encrypt
GitHub
Puedes encontrar consejos de configuración adicionales y documentación para este módulo en el repositorio de GitHub para nginx-module-acme.