acme: Servindo automaticamente certificados Let's Encrypt e implementação Lua do protocolo ACMEv2
Instalação
Se você ainda não configurou a assinatura do repositório RPM, inscreva-se. Em seguida, você pode prosseguir com os seguintes passos.
CentOS/RHEL 7 ou 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 com NGINX, certifique-se de que o nginx-module-lua está instalado.
Este documento descreve lua-resty-acme v0.16.0 lançado em 01 de setembro de 2025.
Serviço automático de certificados Let's Encrypt (RSA + ECC) e implementação pura em Lua do protocolo ACMEv2.
Desafios http-01 e tls-alpn-01 são suportados.
Descrição
Esta biblioteca consiste em duas partes:
resty.acme.autossl: gerenciamento automático do ciclo de vida dos certificados Let's Encryptresty.acme.client: implementação Lua do protocolo ACME v2
Instale usando opm:
opm install fffonion/lua-resty-acme
Alternativamente, para instalar usando luarocks:
luarocks install lua-resty-acme
## instale manualmente um luafilesystem
luarocks install luafilesystem
Observe que você precisará instalar manualmente luafilesystem ao usar LuaRocks. Isso é feito para manter a compatibilidade retroativa.
Esta biblioteca usa um backend openssl baseado em FFI, que atualmente suporta as séries OpenSSL 1.1.1, 1.1.0 e 1.0.2.
Sinopse
Crie a chave privada da conta e certificados de fallback:
## crie a chave da conta
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:4096 -out /etc/openresty/account.key
## crie o certificado e a chave de fallback
openssl req -newkey rsa:2048 -nodes -keyout /etc/openresty/default.key -x509 -days 365 -out /etc/openresty/default.pem
Use a seguinte configuração de exemplo:
events {}
http {
resolver 8.8.8.8 ipv6=off;
lua_shared_dict acme 16m;
# necessário para verificar a API 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({
-- definir o seguinte como verdadeiro
-- implica que você leu e aceitou https://letsencrypt.org/repository/
tos_accepted = true,
-- descomente o seguinte para configuração inicial
-- staging = true,
-- descomente o seguinte para habilitar certificado duplo RSA + ECC
-- domain_key_types = { 'rsa', 'ecc' },
-- descomente o seguinte para habilitar o desafio 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 fallback, certifique-se de criá-los previamente
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()
}
}
}
}
Ao testar a implantação, é recomendado descomentar o staging = true para permitir um teste de ponta a ponta do seu ambiente. Isso pode evitar que falhas de configuração resultem em muitas solicitações que atingem limites de taxa na API Let's Encrypt.
Por padrão, autossl cria apenas certificados RSA. Para usar certificados ECC ou ambos, descomente domain_key_types = { 'rsa', 'ecc' }. Observe que múltiplas cadeias de certificados são suportadas apenas pelo NGINX 1.11.0 ou posterior.
Um certificado será enfileirado para criação após o Nginx ter visto uma solicitação com tal SNI, o que pode levar dezenas de segundos para ser concluído. Durante esse tempo, solicitações com tal SNI são respondidas com o certificado de fallback.
Observe que domain_whitelist ou domain_whitelist_callback devem ser definidos para incluir seu domínio que você deseja servir autossl, para evitar possíveis abusos usando SNI falso na negociação SSL.
domain_whitelist define uma tabela que inclui todos os domínios que devem ser incluídos e o CN a ser usado para criar o certificado. Apenas um único * é permitido como um curinga.
domain_whitelist = { "domain1.com", "domain2.com", "domain3.com", "*.domain4.com" },
Certificados curinga
Para habilitar esta biblioteca a criar certificados curinga, os seguintes requisitos devem ser atendidos:
- O domínio curinga aparece exatamente como
*.somedomain.comemdomain_whitelist. - O desafio
dns-01está habilitado e um provedor DNS que possuidomainscorrespondendo ao domínio está configurado.
Caso contrário, um certificado não curinga será criado como fallback.
Por padrão, o domínio curinga *.example.com aparecerá no Nome Comum. Quando wildcard_domain_in_san é definido como true, no entanto, um certificado com Nome Comum example.com e Nome Alternativo do Sujeito *.example.com será criado. Observe que tanto *.example.com quanto example.com devem aparecer em dns_provider_accounts.
Uso Avançado
Usar uma função para incluir domínios
domain_whitelist_callback define uma função que aceita o domínio como parâmetro e retorna um booleano para indicar se deve ser incluído.
Para corresponder a um padrão no seu nome de domínio, por exemplo, todos os subdomínios sob example.com, use:
domain_whitelist_callback = function(domain, is_new_cert_needed)
return ngx.re.match(domain, [[\.example\.com$]], "jo")
end
Além disso, como a verificação da lista de domínios está sendo executada na fase do certificado, é possível usar a API de cosocket aqui. Observe que isso aumentará a latência da negociação SSL.
domain_whitelist_callback = function(domain, is_new_cert_needed)
-- enviar solicitação HTTP
local http = require("resty.http")
local res, err = httpc:request_uri("http://example.com")
-- acessar o armazenamento
local acme = require("resty.acme.autossl")
local value, err = acme.storage:get("key")
-- obter certificado do cache LRU do resty
-- cached = { pkey, cert } ou nil se o certificado não estiver no cache
local cached, staled, flags = acme.get_cert_from_cache(domain, "rsa")
-- fazer algo para verificar o domínio
-- retornar is_domain_included
end
A função domain_whitelist_callback é fornecida com um segundo argumento, que indica se o certificado está prestes a ser servido em uma solicitação HTTP recebida (falso) ou se um novo certificado está prestes a ser solicitado (verdadeiro). Isso permite usar valores em cache no caminho quente (servindo solicitações) enquanto busca dados frescos do armazenamento para novos certificados. Também é possível implementar uma lógica diferente, por exemplo, fazer verificações extras antes de solicitar um novo certificado.
Definir período de resfriamento em caso de falha
Em caso de falha na solicitação do certificado, pode-se querer evitar que o cliente ACME solicite outro certificado imediatamente. Por padrão, o período de resfriamento é definido como 300 segundos (5 minutos). Pode ser personalizado com failure_cooloff ou com a função failure_cooloff_callback, por exemplo, para implementar backoff 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
Desafio tls-alpn-01
O desafio tls-alpn-01 é atualmente suportado no Openresty 1.15.8.x, 1.17.8.x e 1.19.3.x.
Clique para expandir a configuração de exemplo
events {}
http {
resolver 8.8.8.8 ipv6=off;
lua_shared_dict acme 16m;
# necessário para verificar a API 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({
-- definir o seguinte como verdadeiro
-- implica que você leu e aceitou https://letsencrypt.org/repository/
tos_accepted = true,
-- descomente o seguinte para configuração inicial
-- staging = true,
-- descomente o seguinte para habilitar certificado duplo RSA + ECC
-- domain_key_types = { 'rsa', 'ecc' },
-- descomente o seguinte para habilitar o desafio 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 fallback, certifique-se de criá-los previamente
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({
-- definir o seguinte como verdadeiro
-- implica que você leu e aceitou https://letsencrypt.org/repository/
tos_accepted = true,
-- descomente o seguinte para configuração inicial
-- staging = true,
-- descomente o seguinte para habilitar certificado duplo RSA + ECC
-- domain_key_types = { 'rsa', 'ecc' },
-- descomente o seguinte para habilitar o desafio 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;
# requer --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)
}
}
}
Na configuração de exemplo acima, configuramos um servidor http e dois servidores de stream.
O servidor de stream na frente escuta na porta 443 e roteia para diferentes upstreams com base no ALPN do cliente. O respondedor tls-alpn-01 escuta em unix:/tmp/nginx-tls-alpn.sock. Todo o tráfego https normal escuta em unix:/tmp/nginx-default.sock.
[stream server unix:/tmp/nginx-tls-alpn.sock ssl]
Y /
[stream server 443] --- ALPN é acme-tls ?
N \
[http server unix:/tmp/nginx-default.sock ssl]
- A configuração passada para
require("resty.acme.autossl").initem ambos os subsistemas deve ser mantida o mais semelhante possível. - O manipulador de desafio
tls-alpn-01não precisa de nenhuma dependência de terceiros. - Você pode habilitar os manipuladores de desafio
http-01etls-alpn-01ao mesmo tempo. - Os subsistemas
httpestreamnão compartilham shm, portanto, considere usar um armazenamento diferente deshm. Se você precisar usarshm, precisará aplicar este patch.
Desafio dns-01
O desafio DNS-01 é suportado no lua-resty-acme > 0.13.0. Atualmente, os seguintes provedores DNS são suportados:
cloudflare: Cloudflaredynv6: Dynv6dnspod-intl: Dnspod Internacional (apenas o token Dnspod é suportado e useid,tokenno campo secreto)
Para saber como estender um novo provedor DNS para trabalhar com o desafio dns-01, veja Provedor DNS.
Uma configuração de exemplo para usar o desafio dns-01 seria:
require("resty.acme.autossl").init({
-- definir o seguinte como verdadeiro
-- implica que você leu e aceitou https://letsencrypt.org/repository/
tos_accepted = true,
-- descomente o seguinte para configuração inicial
-- staging = true,
-- descomente o seguinte para habilitar certificado duplo RSA + ECC
-- domain_key_types = { 'rsa', 'ecc' },
-- não defina `http-01` ou `tls-alpn-01` se você apenas planeja 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 of cloudflare",
domains = { "example.com" },
},
{
name = "dynv6_staging",
provider = "dynv6",
secret = "apikey of dynv6",
domains = { "*.anotherdomain.com" },
},
},
-- descomente o seguinte para criar anotherdomain.com em CN e *.anotherdomain.com em SAN
-- wildcard_domain_in_san = true,
})
Por padrão, esta biblioteca tenta até 5 minutos para a propagação DNS. Se o TTL padrão para o provedor DNS for maior que isso, o usuário pode querer ajustar manualmente challenge_start_delay para esperar mais.
resty.acme.autossl
Uma tabela de configuração pode ser passada para resty.acme.autossl.init(), os valores padrão são:
default_config = {
-- aceitar termos de serviço https://letsencrypt.org/repository/
tos_accepted = false,
-- se usar a API de staging do Let's Encrypt
staging = false,
-- o caminho para a chave privada da conta em formato PEM
account_key_path = nil,
-- o e-mail da conta para registro
account_email = nil,
-- número de cache de certificados, por tipo
cache_size = 100,
domain_key_paths = {
-- a chave privada RSA global do domínio
rsa = nil,
-- a chave privada ECC global do domínio
ecc = nil,
},
-- o algoritmo de chave privada a ser usado, pode ser um ou ambos de
-- 'rsa' e 'ecc'
domain_key_types = { 'rsa' },
-- restringir o registro de novos certificados apenas aos domínios definidos nesta tabela
domain_whitelist = nil,
-- restringir o registro de novos certificados apenas aos domínios verificados por esta função
domain_whitelist_callback = nil,
-- intervalo a esperar antes de tentar novamente após falha na solicitação do certificado
failure_cooloff = 300,
-- função que retorna o intervalo a esperar antes de tentar novamente após falha na solicitação do certificado
failure_cooloff_callback = nil,
-- o limite para renovar um certificado antes de expirar, em segundos
renew_threshold = 7 * 86400,
-- intervalo para verificar a renovação do certificado, em segundos
renew_check_interval = 6 * 3600,
-- o adaptador de armazenamento de certificados
storage_adapter = "shm",
-- a configuração de armazenamento passada para o adaptador de armazenamento
storage_config = {
shm_name = 'acme',
},
-- os tipos de desafios habilitados
enabled_challenge_handlers = { 'http-01' },
-- tempo a esperar antes de sinalizar o servidor ACME para validar em segundos
challenge_start_delay = 0,
-- se verdadeiro, a solicitação para o nginx espera até que o certificado tenha sido gerado e é usado imediatamente
blocking = false,
-- se verdadeiro, o certificado para domínio não na lista de permissões será excluído do armazenamento
enabled_delete_not_whitelisted_domain = false,
-- o dicionário de provedores DNS, cada provedor deve ter a seguinte estrutura:
-- {
-- name = "prod_account",
-- provider = "provider_name", -- "cloudflare" ou "dynv6"
-- secret = "the api key or token",
-- domains = { "example.com", "*.example.com" }, -- a lista de domínios que podem ser usados com este provedor
-- }
dns_provider_accounts = {},
-- se habilitado, domínios curinga como *.example.com serão criados como SAN e CN será example.com
wildcard_domain_in_san = false,
}
Se account_key_path não for especificado, uma nova chave de conta será criada toda vez que o Nginx recarregar a configuração. Observe que isso pode acionar Limite de Taxa de Nova Conta rate limiting na API Let's Encrypt.
Se domain_key_paths não for especificado, uma nova chave privada será gerada para cada certificado (RSA de 4096 bits e ECC de 256 bits prime256v1). Observe que gerar tal chave bloqueará o trabalhador e será especialmente notável em VMs onde a entropia é baixa.
Passe a tabela de configuração diretamente para o cliente ACME como segundo parâmetro. O seguinte exemplo demonstra como usar um provedor CA diferente do Let's Encrypt e também definir a cadeia 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",
}
)
Veja também Adaptadores de Armazenamento abaixo.
Ao usar tipos de armazenamento distribuídos, é útil aumentar challenge_start_delay para permitir que as mudanças no armazenamento se propaguem. Quando challenge_start_delay é definido como 0, nenhuma espera será realizada antes de começar a validar desafios.
autossl.get_certkey
sintaxe: certkey, err = autossl.get_certkey(domain, type?)
Retorna o certificado codificado em PEM e a chave privada para domain do armazenamento. Opcionalmente aceita um parâmetro type que pode ser "rsa" ou "ecc"; se omitido, type será padrão para "rsa".
resty.acme.client
client.new
sintaxe: c, err = client.new(config)
Cria um cliente ACMEv2.
Os valores padrão para config são:
default_config = {
-- o endpoint da API ACME v2 a ser usado
api_uri = "https://acme-v02.api.letsencrypt.org/directory",
-- o e-mail da conta para registro
account_email = nil,
-- a chave da conta em texto no formato PEM
account_key = nil,
-- o kid da conta (como uma URL)
account_kid = nil,
-- id da chave de vinculação de conta externa
eab_kid = nil,
-- chave hmac de vinculação de conta externa, codificada em base64url
eab_hmac_key = nil,
-- manipulador de registro de conta externa
eab_handler = nil,
-- armazenamento para desafio
storage_adapter = "shm",
-- a configuração de armazenamento passada para o adaptador de armazenamento
storage_config = {
shm_name = "acme"
},
-- os tipos de desafios habilitados, seleção de `http-01` e `tls-alpn-01`
enabled_challenge_handlers = {"http-01"},
-- selecione o Nome Comum do emissor CA raiz preferido, se aplicável
preferred_chain = nil,
-- função de callback que permite esperar antes de sinalizar o servidor ACME para validar
challenge_start_callback = nil,
-- o dicionário de provedores DNS, cada provedor deve ter a seguinte estrutura:
dns_provider_accounts = {},
}
Se account_kid for omitido, o usuário deve chamar client:new_account() para registrar uma nova conta. Observe que ao usar a mesma account_key, client:new_account() retornará o mesmo kid que foi registrado anteriormente.
Se a CA exigir Vinculação de Conta Externa, o usuário pode definir eab_kid e eab_hmac_key para carregar uma conta existente ou definir account_email e eab_handler para registrar uma nova conta. eab_hmac_key deve ser codificado em base64 url. Neste último caso, o usuário deve chamar client:new_account() para registrar uma nova conta. eab_handler deve ser uma função que aceita account_email como parâmetro e retorna eab_kid, eab_hmac_key e erro, se houver.
eab_handler = function(account_email)
-- faça algo para registrar uma conta com account_email
-- se err então
-- return nil, nil, err
-- end
return eab_kid, eab_hmac_key
end
O manipulador EAB do seguinte provedor CA é suportado pelo lua-resty-acme e o usuário não precisa implementar seu próprio eab_handler:
preferred_chain é usado para selecionar uma cadeia com Nome Comum correspondente em sua CA raiz. Por exemplo, o usuário pode usar "ISRG Root X1" para forçar o uso da nova cadeia padrão no Let's Encrypt. Quando nenhum valor é configurado ou o nome configurado não é encontrado em nenhuma cadeia, a cadeia padrão será usada.
challenge_start_callback é uma função de callback para permitir que o cliente espere antes de sinalizar o servidor ACME para começar a validar o desafio. É útil em uma configuração distribuída onde os desafios levam tempo para se propagar. challenge_start_callback aceita challenge_type e challenge_token. O cliente chama essa função a cada segundo até que ela retorne true, indicando que o desafio deve começar; se esse challenge_start_callback não estiver definido, nenhuma espera será realizada.
challenge_start_callback = function(challenge_type, challenge_token)
-- faça algo aqui
-- se estivermos bem
return true
end
Veja também Adaptadores de Armazenamento abaixo.
client:init
sintaxe: err = client:init()
Inicializa o cliente, requer disponibilidade da API de cosocket. Esta função fará login ou registrará uma conta.
client:order_certificate
sintaxe: err = client:order_certificate(domain,...)
Cria um certificado com um ou mais domínios. Observe que domínios curinga não são suportados, pois só podem ser verificados pelo desafio dns-01.
client:serve_http_challenge
sintaxe: client:serve_http_challenge()
Serve o desafio http-01. Um caso de uso comum será colocá-lo como um bloco content_by_* para o caminho /.well-known.
client:serve_tls_alpn_challenge
sintaxe: client:serve_tls_alpn_challenge()
Serve o desafio tls-alpn-01. Veja esta seção sobre como usar este manipulador.
Adaptadores de Armazenamento
Os adaptadores de armazenamento são usados em autossl ou no cliente acme para armazenar dados temporários ou persistentes. Dependendo do ambiente de implantação, atualmente existem cinco adaptadores de armazenamento disponíveis para seleção. Para implementar um adaptador de armazenamento personalizado, consulte este documento.
file
Armazenamento baseado em sistema de arquivos. Configuração de exemplo:
storage_config = {
dir = '/etc/openresty/storage',
}
dir for omitido, o diretório temporário do SO será usado.
luafilesystem ou luafilesystem-ffi é necessário ao usar o armazenamento file para renovação.
shm
Armazenamento baseado em dicionário compartilhado Lua. Observe que este armazenamento é volátil entre reinicializações do Nginx (não recarregamentos). Configuração de exemplo:
storage_config = {
shm_name = 'dict_name',
}
redis
Armazenamento baseado em Redis. A configuração padrão é:
storage_config = {
host = '127.0.0.1',
port = 6379,
database = 0,
-- chave de autenticação do Redis
auth = nil,
ssl = false,
ssl_verify = false,
ssl_server_name = nil,
-- namespace como um prefixo da chave
namespace = "",
}
Redis >= 2.6.12 é necessário, pois este armazenamento requer SET EX.
vault
Armazenamento baseado em Hashicorp Vault. Apenas o backend KV V2 é suportado. A configuração padrão é:
storage_config = {
host = '127.0.0.1',
port = 8200,
-- caminho do prefixo de segredos kv
kv_path = "acme",
-- timeout em ms
timeout = 2000,
-- usar HTTPS
https = false,
-- ativar verificação tls
tls_verify = true,
-- SNI usado na solicitação, padrão para host se omitido
tls_server_name = nil,
-- Método de Autenticação, padrão para token, pode ser "token" ou "kubernetes"
auth_method = "token",
-- Token do Vault
token = nil,
-- Caminho de autenticação do Vault a ser usado
auth_path = "kubernetes",
-- O papel a tentar atribuir
auth_role = nil,
-- O caminho para o JWT
jwt_path = "/var/run/secrets/kubernetes.io/serviceaccount/token",
-- Namespace do Vault
namespace = nil,
}
Suporte para diferentes métodos de autenticação
- Token: Este é o padrão e permite passar um "token" literal na configuração.
- Kubernetes: Por meio deste método, pode-se utilizar o método de autenticação interno do vault para kubernetes. Basicamente, isso pega o token da conta de serviço e valida que foi assinado pela CA do Kubernetes. O principal benefício aqui é que os arquivos de configuração não expõem mais seu token.
As seguintes configurações se aplicam aqui:
lua
-- Caminho de autenticação do Vault a ser usado
auth_path = "kubernetes",
-- O papel a tentar atribuir
auth_role = nil,
-- O caminho para o JWT
jwt_path = "/var/run/secrets/kubernetes.io/serviceaccount/token",
consul
Armazenamento baseado em Hashicorp Consul. A configuração padrão é:
storage_config = {
host = '127.0.0.1',
port = 8500,
-- caminho do prefixo kv
kv_path = "acme",
-- token ACL do Consul
token = nil,
-- timeout em ms
timeout = 2000,
}
etcd
Armazenamento baseado em etcd. Atualmente, apenas o protocolo v3 é suportado, e a versão do servidor etcd deve ser >= v3.4.0.
A configuração padrão é:
storage_config = {
http_host = 'http://127.0.0.1:4001',
key_prefix = '',
timeout = 60,
ssl_verify = false,
}
O armazenamento etcd requer a biblioteca lua-resty-etcd instalada.
Pode ser instalada manualmente com opm install api7/lua-resty-etcd ou luarocks install lua-resty-etcd.
Provedores DNS
Para criar um provedor DNS personalizado, siga estas etapas:
- Crie um arquivo como
route53.luaemlib/resty/acme/dns_provider - Implemente a seguinte assinatura de função
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
Onde token é a chave da API, fqdn é o nome do registro DNS a ser definido, e content é o valor do registro.
Testes
Configure o ambiente de teste e2e executando bash t/fixtures/prepare_env.sh.
Em seguida, execute cpanm install Test::Nginx::Socket e depois prove -r t.
Veja Também
- Ambiente de Gerenciamento Automático de Certificados (ACME)
- haproxytech/haproxy-lua-acme A implementação ACME em Lua usada no HAProxy.
- GUI/lua-resty-auto-ssl
- lua-resty-openssl
- Limites de taxa da API Let's Encrypt
GitHub
Você pode encontrar dicas adicionais de configuração e documentação para este módulo no repositório GitHub do nginx-module-acme.