Com bastante frequência, precisamos trabalhar com certificados SSL. Vamos recordar o processo de criação e instalação de um certificado (de forma geral para a maioria).
- Encontrar um provedor (um site onde podemos comprar SSL).
- Gerar CSR.
- Enviar para o provedor.
- Confirmar a posse do domínio.
- Receber o certificado.
- Converter o certificado para o formato necessário (opcional). Por exemplo, de pem para PKCS #12.
- Instalar o certificado no servidor web.
Relativamente rápido, não é difícil e é compreensível. Essa opção é adequada se tivermos no máximo uma dezena de projetos. E se forem mais, com pelo menos três ambientes cada? Clássico dev — staging — production. Nesse caso, vale a pena considerar a automação desse processo. Proponho aprofundar um pouco no problema e encontrar uma solução que minimize, no futuro, o tempo gasto na criação e manutenção de certificados. O artigo incluirá uma análise do problema e um pequeno guia para repetição.
Apenas para esclarecer: a especialização principal da nossa empresa é .net, e consequentemente, IIS e outras questões relacionadas ao Windows. Portanto, o cliente ACME e todas as ações para ele também serão descritas do ponto de vista do uso do Windows.
Para quem isso é relevante e alguns dados iniciais
A empresa K, representada pelo autor. URL (a título de exemplo): company.tld
O projeto X — um dos nossos projetos, que me levou à conclusão de que devemos avançar em direção à máxima economia de tempo ao trabalhar com certificados. Este projeto possui quatro ambientes: dev, test, staging e production. Dev e test estão do nosso lado, staging e production no lado do cliente.
Uma característica do projeto é que ele possui um grande número de módulos disponíveis como subdomínios.
Ou seja, temos o seguinte cenário:
Dev
Test
Staging
Produção
projectX.dev.company.tld
projectX.test.company.tld
staging.projectX.tld
projectX.tld
module1.projectX.dev.company.tld
module1.projectX.test.company.tld
module1.staging.projectX.tld
module1.projectX.tld
module2.projectX.dev.company.tld
module2.projectX.test.company.tld
module2.staging.projectX.tld
module2.projectX.tld
…
…
…
…
moduleN.projectX.dev.company.tld
moduleN.projectX.test.company.tld
moduleN.staging.projectX.tld
moduleN.projectX.tld
Para produção, é utilizado um certificado wildcard adquirido, aqui não há dúvidas. Mas ele cobre apenas o primeiro nível do subdomínio. Portanto, se houver um certificado para *.projectX.tld — ele funcionará para staging.projectX.tld, mas não para module1.staging.projectX.tld. E comprar um separado não parece atraente.
E isso é apenas um exemplo de um projeto de uma única empresa. E o projeto, naturalmente, não é único.
As razões gerais para se começar a solucionar essa questão se apresentam da seguinte maneira:
- Relativamente recente O Google propôs reduzir o prazo máximo de validade dos certificados SSL. Com todas as implicações.
- Facilitar o processo de emissão e manutenção SSL para as necessidades internas dos projetos e da empresa como um todo.
- Armazenamento centralizado de registros sobre os certificados, que parcialmente resolve o problema da validação de domínio via DNS e a posterior atualização automática, além de abordar a questão da confiança do cliente. Afinal, causa mais confiança um CNAME em um servidor da empresa do parceiro/executor, do que em um recurso externo.
- E, por fim, neste caso, a frase "é melhor ter do que não ter" se aplica perfeitamente.
Escolha do provedor SSL e etapas preparatórias
Das opções disponíveis de certificados SSL gratuitos, foram considerados cloudflare e letsencrypt. O DNS para isso (e alguns outros projetos) está localizado no cloudflare, mas não sou a favor do uso de seus certificados. Portanto, foi decidido usar o letsencrypt.
Para criar wildcard SSL o certificado precisa validar a posse do domínio. Este procedimento implica a criação de um registro DNS (TXT ou CNAME), que será posteriormente verificado durante a emissão do certificado. No Linux, existe uma ferramenta — certbot, que permite automatizar parcialmente (ou totalmente para alguns provedores de DNS) esse processo. Para Windows, entre as opções encontradas e testadas de clientes ACME, optei por WinACME.
Um registro para o domínio foi criado, agora vamos criar o certificado:

Estamos interessados na última saída, especificamente — as opções disponíveis de validação da posse do domínio para a emissão de um certificado wildcard:
- Criação de registros DNS manualmente (atualização automática não suportada)
- Criação de registros DNS usando o servidor acme-dns (pode ler mais detalhadamente aqui.
- Criação de registros DNS usando um script próprio (análogo ao plugin cloudflare para certbot).
À primeira vista, o terceiro ponto parece ser adequado, mas e se o provedor DNS não suportar essa funcionalidade? Precisamos de um caso geral. E o caso geral são os registros CNAME, que são suportados por todos. Portanto, ficamos com o ponto 2 e vamos configurar nosso servidor ACME-DNS.
Configuração do servidor ACME-DNS e processo de emissão de certificado
Como exemplo, criei o domínio 2nd.pp.ua e o usarei a seguir.
Uma exigência obrigatória para o funcionamento correto do servidor é a criação de registros NS e A para seu domínio. E o primeiro ponto desagradável com o qual me deparei foi que o Cloudflare (pelo menos na versão gratuita) não permite criar simultaneamente um registro NS e um registro A para o mesmo host. Não que isso seja um problema, mas no bind isso é possível. O suporte respondeu que o painel deles não permite isso. Sem problemas, criaremos dois registros:
acmens.2nd.pp.ua. IN A 35.237.128.147
acme.2nd.pp.ua. IN NS acmens.2nd.pp.ua.
Neste estágio, nosso host deve resolver acmens.2nd.pp.ua.
$ ping acmens.2nd.pp.ua
PING acmens.2nd.pp.ua (35.237.128.147) 56(84) bytes de dados
Aqui está acme.2nd.pp.ua não será resolvido, pois o servidor DNS que o atende ainda não foi iniciado.
Os registros foram criados, vamos para a configuração e inicialização do servidor ACME-DNS. Ele estará rodando em meu servidor ubuntu dentro de docker um contêiner, mas pode ser iniciado em qualquer lugar onde haja golang. O Windows também serve, mas eu ainda prefiro um servidor Linux.
Criamos os diretórios e arquivos necessários:
$ mkdir config
$ mkdir data
$ touch config/config.cfg
Usaremos o vim, seu editor de texto favorito, e vamos colar no config.cfg um exemplo configuração.
Para um funcionamento bem-sucedido, basta ajustar as seções general e api:
[general]
listen = "0.0.0.0:53"
protocol = "both"
domain = "acme.2nd.pp.ua"
nsname = "acmens.2nd.pp.ua"
nsadmin = "admin.2nd.pp.ua"
records =
"acme.2nd.pp.ua. A 35.237.128.147",
"acme.2nd.pp.ua. NS acmens.2nd.pp.ua.", ]
...
[api]
...
tls = "letsencrypt"
…
Além disso, se desejar, criaremos um arquivo docker-compose no diretório principal do serviço:
version: '3.7'
services:
acmedns:
image: joohoi/acme-dns:latest
ports:
- "443:443"
- "53:53"
- "53:53/udp"
- "80:80"
volumes:
- ./config:/etc/acme-dns:ro
- ./data:/var/lib/acme-dns
Pronto. Agora pode ser iniciado.
$ docker-compose up -d
Neste estágio, o host deve começar a resolver acme.2nd.pp.ua, e deve aparecer 404 em https://acme.2nd.pp.ua
$ ping acme.2nd.pp.ua
PING acme.2nd.pp.ua (35.237.128.147) 56(84) bytes de dados.
$ curl https://acme.2nd.pp.ua
404 página não encontrada
Se isso não aparecer — docker logs -f será útil, felizmente, os logs são bem legíveis.
Podemos começar a criar o certificado. Abra o PowerShell como administrador e inicie o winacme. Estamos interessados nas opções:
- M: Criar novo certificado (opções completas)
- 2: Inserção manual
- 2: [dns-01] Criar registros de verificação com acme-dns (https://github.com/joohoi/acme-dns)
- Na pergunta sobre o link para o servidor ACME-DNS, insira a URL do servidor criado (https). URL do servidor acme-dns: https://acme.2nd.pp.ua
O cliente nota um registro que deve ser adicionado ao servidor DNS existente (o procedimento é único):
[INFO] Criando novo registro acme-dns para o domínio 1nd.pp.ua
Domínio: 1nd.pp.ua
Registro: _acme-challenge.1nd.pp.ua
Tipo: CNAME
Conteúdo: c82a88a5-499f-464f-96e4-be7f606a3b47.acme.2nd.pp.ua.
Nota: Alguns painéis de controle DNS adicionam automaticamente o ponto final.
Apenas um é necessário.

Criamos o registro necessário e verificamos se foi criado corretamente:
![]()
$ dig CNAME _acme-challenge.1nd.pp.ua +short
c82a88a5-499f-464f-96e4-be7f606a3b47.acme.2nd.pp.ua.
Confirmamos que criamos o registro necessário no winacme e continuamos o processo de criação do certificado:

Como usar o certbot como cliente é descrito aqui.
Com isso, o processo de criação do certificado está concluído; agora podemos instalá-lo no servidor web e utilizá-lo. Se, ao criar o certificado, também for criada uma tarefa no agendador, o processo de atualização do certificado ocorrerá automaticamente.
Fonte: habr.com
