SSLmentor

Certificados TLS/SSL de qualidade para sites e projetos de internet.

Lego

Lego

Cliente ACME Lego

O cliente ACME Lego é um projeto independente, gratuito e de código aberto escrito na linguagem Go. É ideal para integração personalizada e scripting e beneficia de amplo suporte por parte dos registadores de domínios e fornecedores de DNS. O Lego é um cliente ACME flexível que pode ser facilmente integrado em sistemas e scripts personalizados. Além da validação HTTP-01, oferece validação DNS através de muitos fornecedores de DNS (lista de fornecedores de DNS suportados) para obter certificados SSL WildCard.
O guia utiliza sintaxe verificada na versão Lego 5.*.* e destina-se a Debian/Ubuntu com Apache 2 e o cliente ACME Lego.

Conceitos básicos

  • ACME – protocolo para emissão e renovação automatizadas de certificados SSL/TLS.
  • HTTP-01 – método de validação ACME que verifica a propriedade do domínio utilizando um ficheiro temporário acessível através de HTTP.
  • DNS-01 – método de validação através do registo DNS TXT _acme-challenge.
  • EAB kid + hmac – detalhes External Account Binding (EAB) da autoridade de certificação. Ligam o Certbot a uma conta ou produto.
  • Systemd service - um ficheiro de configuração que indica ao sistema Linux como iniciar uma aplicação e mantê-la em execução mesmo após um reinício do servidor.

Se o domínio example.com aparecer nos exemplos, substitua-o sempre pelo seu próprio domínio.

Instalação do Lego

apt update
apt install -y curl tar

cd /tmp
LEGO_URL=$(curl -s https://api.github.com/repos/go-acme/lego/releases/latest | sed -n 's/.*"browser_download_url": "\(.*linux_amd64.tar.gz\)".*/\1/p' | head -n1)
echo "$LEGO_URL"
curl -L -o lego.tar.gz "$LEGO_URL"
tar -xzf lego.tar.gz
install -m 0755 lego /usr/local/bin/lego
lego --version

Após uma instalação bem-sucedida, recomendamos remover os ficheiros temporários.

rm -f /tmp/lego /tmp/lego.tar.gz /tmp/LICENSE /tmp/CHANGELOG.md
Comando / valor O que faz / o que substituir
apt update Atualiza a lista de pacotes.
apt install -y curl tar Instala as ferramentas para descarregar e extrair o Lego.
LEGO_URL=... Encontra o URL do pacote de versão Linux amd64 mais recente.
curl -L -o lego.tar.gz Descarrega o arquivo do Lego.
tar -xzf lego.tar.gz Extrai o arquivo.
install -m 0755 lego /usr/local/bin/lego Instala o Lego como um comando de sistema executável.
lego --version Verifica a versão instalada do Lego.

Apache, webroot

Este procedimento cria uma configuração básica de VirtualHost para o domínio na porta 80. Define o DocumentRoot, as permissões do diretório web, cria os logs do Apache, ativa a configuração utilizando o a2ensite, verifica a sua correção (apache2ctl configtest) e recarrega as alterações. Por fim, verifica a disponibilidade do website utilizando um pedido HTTP curl.

›› Mostrar/Ocultar secção

Antes de executar, substitua o valor example.com na linha DOMAIN="example.com" pelo seu próprio domínio. A variável $DOMAIN é depois utilizada nos comandos seguintes para os caminhos, o vhost do Apache e a página de teste.

cd /var/www
apt update
apt install -y apache2
systemctl enable --now apache2
a2enmod rewrite headers ssl
systemctl reload apache2

# or just updates
apt update
apt install --only-upgrade apache2
systemctl reload apache2
DOMAIN="example.com"
mkdir -p /var/www/$DOMAIN/public
chown -R www-data:www-data /var/www/$DOMAIN
chmod -R 755 /var/www/$DOMAIN
echo "OK $DOMAIN" > /var/www/$DOMAIN/public/index.html
Comando / valor O que faz / o que substituir
cd /var/www Muda para o diretório onde os ficheiros web são normalmente armazenados.
apt update Atualiza a lista de pacotes.
apt install -y apache2 Instala o Apache; o -y confirma automaticamente a instalação.
systemctl enable --now apache2 Ativa o Apache no arranque do servidor e inicia-o ao mesmo tempo.
a2enmod rewrite headers ssl Ativa os módulos para redirecionamentos, cabeçalhos e HTTPS.
DOMAIN="example.com" Define a variável do domínio. Substitua example.com pelo seu próprio domínio.
mkdir/chown/chmod/echo Cria o webroot, define as permissões para o Apache e guarda uma página de teste simples.

Vhost HTTP tanto para o apex como para o subdomínio:


cat > /etc/apache2/sites-available/$DOMAIN.conf <<EOF
<VirtualHost *:80>
    ServerName $DOMAIN
    ServerAlias www.$DOMAIN

    DocumentRoot /var/www/$DOMAIN/public
    <Directory /var/www/$DOMAIN/public>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog \${APACHE_LOG_DIR}/${DOMAIN}_error.log
    CustomLog \${APACHE_LOG_DIR}/${DOMAIN}_access.log combined
</VirtualHost>
EOF

a2ensite "$DOMAIN.conf"
apache2ctl configtest
systemctl reload apache2
curl -I "http://$DOMAIN"
curl -I "http://www.$DOMAIN"

Resultado: Após abrir http://example.com, a página de teste deve aparecer.

Comando / valor O que faz / o que substituir
cat > ... <<EOF Escreve um novo vhost HTTP do Apache num ficheiro em sites-available.
ServerName $DOMAIN O domínio principal do virtual host.
ServerAlias www.$DOMAIN Cria o tratamento do subdomínio de primeiro nível.
DocumentRoot O diretório a partir do qual o Apache serve o conteúdo.
a2ensite "$DOMAIN.conf" Ativa o vhost.
apache2ctl configtest Verifica a sintaxe da configuração do Apache.
curl -I http://$DOMAIN Verifica a resposta HTTP do domínio.

Ficheiros de configuração do Lego

A abordagem recomendada para o Lego v5 é armazenar as definições num ficheiro de configuração. O systemd service não precisa então de conter um comando longo com domínios e hooks.

Ficheiro de configuração lego.yml

O ficheiro .yml é um ficheiro de configuração de texto em formato YAML, utilizado para uma notação clara de definições, parâmetros e dados estruturados. Antes de guardar a configuração YAML, substitua example.com pelo seu próprio domínio, vas@email.cz pelo seu e-mail de contacto e os valores KID / HMAC pelos detalhes da sua encomenda de certificado ACME.

mkdir /etc/lego/$DOMAIN
nano /etc/lego/$DOMAIN/lego.yml
storage: /etc/lego/example.com

accounts:
  certum-account:
    server: certum
    email: your@email.com   # your email address for CA Certum
    acceptsTermsOfService: true
    eab:
      kid: KID
      hmacKey: HMAC

servers:
  certum:
    url: https://acme.certum.pl/directory

challenges:
  http-chal:
    http:
      # Path to your website's document root.
      # Lego will temporarily write a file to this directory .well-known/acme-challenge/
      webroot: /var/www/example.com/public

certificates:
  example-com:
    account: certum-account
    challenge: http-chal
    domains:
      - example.com
      - www.example.com
    renew:
      days: 30

hooks:
  deploy:
    command: systemctl reload apache2

Dica! Pode gerar um conteúdo YML quase completo diretamente no servidor e depois basta preencher o e-mail, o kid e o hmacKey corretos. Basta executar o comando abaixo e copiar o conteúdo da página index.html para o ficheiro lego.yml.
›› Mostrar/Ocultar o YML preparado.

cat > "/var/www/$DOMAIN/public/index.html" <<EOF
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>${DOMAIN}</title>
<style>
body { font-family: sans-serif; max-width: 900px; margin: 40px auto; }
pre { background:#f4f4f4; padding:1em; overflow:auto; }
</style>
</head>
<body>

<h1>OK – ${DOMAIN}</h1>
<p>Apache is working correctly.</p>
<h2>lego.yml</h2>
<pre><code>storage: /etc/lego/${DOMAIN}

accounts:
  certum-account:
    server: certum
    email: YOUR_EMAIL
    acceptsTermsOfService: true
    eab:
      kid: YOUR_KID
      hmacKey: YOUR_HMAC_KEY

servers:
  certum:
    url: https://acme.certum.pl/directory

challenges:
  http-chal:
    http:
      webroot: /var/www/${DOMAIN}/public

certificates:
  ${DOMAIN//./-}:
    account: certum-account
    challenge: http-chal
    domains:
      - ${DOMAIN}
      - www.${DOMAIN}
    renew:
      days: 30

hooks:
  deploy:
    command: systemctl reload apache2
</code></pre>

</body>
</html>
EOF

O ficheiro lego.yml contém o EAB HMAC, pelo que tem de ter permissões restritas. Na documentação, utilize apenas marcadores de posição.

chmod 600 /etc/lego/$DOMAIN/lego.yml

Verificar as permissões e o proprietário do ficheiro:

stat -c "%a %U:%G %n" /etc/lego/$DOMAIN/lego.yml
Comando / valor O que faz / o que substituir
storage Diretório para a conta do Lego, os certificados e os metadados.
accounts Definição da conta ACME, incluindo o e-mail e os detalhes EAB.
servers.certum.url O endpoint ACME da Certum.
challenges.http-chal Validação através de http.
certificates Lista de certificados que o Lego deve gerir.
domains O domínio apex e o domínio wildcard no certificado.
renew.days Quantos dias antes da expiração o Lego deve renovar.
hooks.deploy.command Comando após uma emissão ou renovação bem-sucedida, aqui o recarregamento do Apache.

Emissão do certificado SSL/TLS

Antes de executar, verifique echo ${DOMAIN} ou defina a variável DOMAIN para o nome do seu domínio DOMAIN="example.com". A ferramenta Lego realiza a validação HTTP-01 utilizando um ficheiro armazenado temporariamente no webroot, verifica a propriedade do domínio e depois cria um certificado SSL/TLS. O certificado, a chave privada e o certificado do emissor (intermédio) serão armazenados no diretório /etc/lego/${DOMAIN}/certificates/.

lego --config /etc/lego/$DOMAIN/lego.yml

Durante a geração, o cliente ACME Lego imprime informações sobre o pedido:

root@vmiXXXXXXXX:~# echo ${DOMAIN}
example.com

root@:~# lego --config /etc/lego/$DOMAIN/lego.yml

INFO  Archive account scope=accountID filepath=/etc/lego/example.com/accounts/acme.certum.pl/certum-acme/
      archives=/etc/lego/example.com/archives/accounts/acme.certum.pl_certum-acme_1785270773.zip
INFO  Private key saved. filepath=/etc/lego/example.com/accounts/acme.certum.pl/certum-account/certum-account.key
INFO  Registering the account (EAB). email=your@email.com
WARN  !!!! HEADS UP !!!!

Your account credentials have been saved in your
configuration directory at "/etc/lego/example.com/accounts".

You should make a secure backup of this folder now. This
configuration directory will also contain private keys
generated by lego and certificates obtained from the ACME
server. Making regular backups of this folder is ideal.

INFO  Obtaining bundled SAN certificate. domains="example.com, www.example.com"
INFO  Use solver. domain=www.example.com type=http-01
INFO  Use solver. domain=example.com type=http-01
INFO  http01: Trying to solve HTTP-01. domain=www.example.com
INFO  The server validated our request. domain=www.example.com
INFO  http01: Trying to solve HTTP-01. domain=example.com
INFO  The server validated our request. domain=example.com
INFO  Validations succeeded; requesting certificates. domains="example.com, www.example.com"
INFO  Waiting for certificates. timeout=30s interval=500ms domains="example.com, www.example.com"
INFO  Server responded with a certificate. domains="example.com, www.example.com"
INFO  Writing file. filepath=/etc/lego/example.com/certificates/acmeapi-online.crt
INFO  Writing file. filepath=/etc/lego/example.com/certificates/acmeapi-online.issuer.crt
INFO  Writing file. filepath=/etc/lego/example.com/certificates/acmeapi-online.key
INFO  Writing file. filepath=/etc/lego/example.com/certificates/acmeapi-online.pem
INFO  Writing file. filepath=/etc/lego/example.com/certificates/acmeapi-online.json

Verificar os ficheiros do certificado SSL gerado

Mostra o conteúdo do diretório de certificados criado pelo serviço Lego, incluindo o certificado, a chave privada e o certificado do emissor para o domínio selecionado.

ls -la /etc/lego/$DOMAIN/certificates/

O diretório certificates/ contém o .crt emitido, o .key, os certificados intermédios da autoridade de certificação e os metadados.

Implementar o certificado no Apache

Este exemplo utiliza a variável ${DOMAIN}, que já deverá ter definido desde o início do guia. Antes de executar os comandos, pode certificar-se de que a variável está definida corretamente, por exemplo: echo ${DOMAIN}
A variável ${DOMAIN} é utilizada no nome do ficheiro de configuração, nos valores ServerName e ServerAlias e no caminho para o webroot.
Aviso! - os caminhos para o certificado SSL e a chave privada utilizam o domínio na forma example-com. Os caminhos têm de corresponder ao domínio utilizado na configuração do Lego.


cat > /etc/apache2/sites-available/${DOMAIN}-le-ssl.conf <<EOF
<IfModule mod_ssl.c>
<VirtualHost *:443>
    ServerName ${DOMAIN}
    ServerAlias www.${DOMAIN}

    DocumentRoot /var/www/${DOMAIN}/public
    <Directory /var/www/${DOMAIN}/public>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    SSLEngine on
    SSLCertificateFile /etc/lego/${DOMAIN}/certificates/${DOMAIN//./-}.crt
    SSLCertificateKeyFile /etc/lego/${DOMAIN}/certificates/${DOMAIN//./-}.key

    ErrorLog ${APACHE_LOG_DIR}/${DOMAIN}_ssl_error.log
    CustomLog ${APACHE_LOG_DIR}/${DOMAIN}_ssl_access.log combined
</VirtualHost>
</IfModule>
EOF
a2ensite ${DOMAIN}-le-ssl.conf
apache2ctl configtest
systemctl reload apache2

curl -I https://${DOMAIN}
curl -I https://www.${DOMAIN}

Resultado: HTTPS funcional.

Comando / valor O que faz / o que substituir
cat > ...-le-ssl.conf Cria o vhost HTTPS do Apache.
ServerName / ServerAlias Especifica o domínio apex e o subdomínio.
SSLCertificateFile Caminho para o certificado.
SSLCertificateKeyFile Caminho para a chave privada.
a2ensite Ativa o vhost HTTPS.
systemctl reload apache2 Recarrega a nova configuração do Apache.
curl -I https://... Verifica a resposta HTTPS.

Renovação automática

O Lego pode renovar o certificado automaticamente, mas após a instalação não cria por si próprio as systemd units para a execução regular. É por isso necessário criar duas units para a renovação automática:

  • lego-example-com-renew.service – executa a verificação e, se necessário, a renovação do certificado.
  • lego-example-com-renew.timer – assegura que o serviço é executado diariamente a uma hora definida.

Antes de inserir, substitua example-com no nome do service/timer pelo seu próprio nome, se necessário, e substitua example.com no caminho da configuração pelo seu próprio domínio.


cat > /etc/systemd/system/lego-${DOMAIN//./-}-renew.service <<EOF
[Unit]
Description=Renew ACME Certum SSL for example.com using Lego HTTP-01
Wants=network-online.target
After=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/lego --config /etc/lego/${DOMAIN}/lego.yml
EOF

cat > /etc/systemd/system/lego-${DOMAIN//./-}-renew.timer <<EOF
[Unit]
Description=Daily Lego renewal check for ${DOMAIN}

[Timer]
OnCalendar=*-*-* 03:20:00
RandomizedDelaySec=1800
Persistent=true

[Install]
WantedBy=timers.target
EOF

Após criar as units, verifique o seu conteúdo:

cat /etc/systemd/system/lego-example-com-renew.service
echo "----------------"
cat /etc/systemd/system/lego-example-com-renew.timer

Recarregue as novas units, ative o timer e verifique se está em execução:

systemctl daemon-reload
systemctl enable --now lego-${DOMAIN//./-}-renew.timer
systemctl list-timers | grep lego

Resultado: O timer está ativo e o systemd agendou a sua próxima execução.

Comando / valor O que faz / o que substituir
lego-example-com-renew.service Systemd service para uma execução única do Lego renew/run.
Type=oneshot O serviço inicia, executa a sua tarefa e termina.
ExecStart Executa o Lego de acordo com o lego.yml.
lego-example-com-renew.timer Systemd timer que executa o serviço regularmente.
OnCalendar Hora da verificação diária.
RandomizedDelaySec Atraso aleatório para que os pedidos não comecem todos exatamente ao mesmo tempo.
Persistent=true Executa uma execução perdida após o arranque do servidor.
systemctl enable --now Ativa o timer e ativa-o imediatamente.

Teste seguro do serviço:

systemctl start lego-${DOMAIN//./-}-renew.service
systemctl status lego-${DOMAIN//./-}-renew.service --no-pager
journalctl -u lego-${DOMAIN//./-}-renew.service -n 100 --no-pager

Resultado: Se o certificado não estiver perto de expirar, o Lego pode indicar que a renovação não é necessária. Este é o comportamento correto.

Comando / valor O que faz / o que substituir
systemctl start ...service Executa manualmente o serviço de renovação para um teste.
systemctl status ... Mostra se o serviço terminou com sucesso
journalctl -u ... Mostra os logs mais recentes do serviço.

Lista das units do Lego disponíveis:

ls -l /etc/systemd/system/lego*

systemctl list-timers | grep lego

Resultado: Ambas as variantes mostram todos os serviços e timers relacionados com o cliente ACME Lego.

Voltar para Ajuda
Encontrou um erro ou não entendeu algo? Escreva para nós!

CA Sectigo
CA RapidSSL
CA Thawte
CA GeoTrust
CA DigiCert
CA Certum