Playbook de Ansible para configuração de Certbot
1. Protocolo ACME
O protocolo Automated Certificate Management Environment (ACME) é um protocolo de gestão de certificados SSL desenvolvido para simplificar e automatizar a emissão, renovação e revogação desses certificados. O seu objetivo principal é tornar o processo seguro, eficiente e, acima de tudo, automática. Criado pela Internet Security Research Group (ISRG), o protocolo ACME visa tornar-se numa ferramenta essencial na vida dos administradores de sistemas, garantindo que os certificados SSL estejam sempre atualizados.
1.1. Funcionamento do ACME
O protocolo ACME opera através da troca de um conjunto de mensagens criptográficas entre um cliente ACME e uma Autoridade de Certificação (CA). A CA, por sua vez, é responsável por verificar a identidade do cliente e emitir ou renovar o certificado SSL. As interações entre o servidor e a CA são baseadas em desafios (challenges) criptográficos, garantindo a autenticidade do pedido.
1.1.1. Etapas do ACME
- Pedido de certificado: o cliente ACME envia para a CA o pedido de um certificado.
- Validação da propriedade do domínio (desafios de validação): a CA responde com o envio de um conjunto de desafios (challenges). Para responder aos desafios, o cliente ACME terá de provar que controla cada subject name que pediu no certificado desejado. Os desafios podem ser feitos via DNS ou HTTP.
- Emissão do certificado: Após a validação dos desafios de forma bem sucedida, o cliente ACME envia para a CA um certificate signing request (CSR). A CA verifica se o cliente controla a chave privada associada a esse CSR, e em caso afirmativo emite o certificado para o cliente.
- Domínio já está validado no portal da HARICA e utilização de credenciais EAB: neste caso não são submetidos os desafios mencionados na etapa 2. O domínio pedido do certificado é dado como válido e procede-se imediatamente para a emissão do certificado.
- Domínio não está pré-validado no portal da HARICA: a emissão de certificados SSL segue o protocolo ACME tradicional, sendo necessário validar o controlo de propriedade sobre o Domínio (via DNS ou HTTP). É importante salientar, que mesmo não estando pré-validado, o domínio tem de estar registado no portal da HARICA. Domínios validados durante o processo ACME não passam a estar validados no portal da HARICA.
- nível adicional de segurança, pois reduz a possibilidade de entidades externas com acesso ao URL ACME de uma instituição consigam criar certificados em nome dessa instituição.
- obtenção de certificados mais simples e flexível, pois reduz a necessidade de efetuar a validação com a CA da propriedade do domínio do certificado no momento do seu pedido.
2.2. Vantagens da automação com ACME
-
Eficiência operacional: A automatização elimina a necessidade de intervenção manual repetitiva. Isso não apenas economiza tempo, mas também reduz o risco associado a falhas humanas, garantindo uma gestão eficaz dos certificados SSL.
-
Segurança: A automação proporcionada pelo ACME e pelo cliente ACME reduz significativamente a probabilidade de erro humano. A renovação automática garante que os certificados SSL estejam sempre atualizados, fortalecendo a segurança do tráfego web.
-
Conformidade: A automação facilita a conformidade com prazos de renovação, uma vez que os certificados são renovados automaticamente antes da sua expiração. Isso é crucial para garantir que os sites permaneçam em conformidade com as políticas de segurança e regulamentações.
-
Facilidade de implementação: Os clientes ACME são projetados para serem fáceis de implementar e configurar. Isso torna a adoção do ACME e a automação da gestão de certificados SSL acessíveis a uma ampla gama de utilizadores, desde administradores de sistemas experientes até responsáveis por pequenos websites.
1.2. Desafios da automação com ACME
-
Atualização tecnológica: Para tirar pleno partido do protocolo ACME, os servidores web (ou outras aplicações que requeiram certificados SSL) devem suportar e estar configurados para utilizar este protocolo, nomeadamente através da utilização de clientes ACME. Isso pode exigir atualizações tecnológicas, sendo crucial garantir que os sistemas estejam atualizados.
-
Monitorização contínua: Embora a automação simplifique a gestão de certificados SSL, é essencial implementar uma monitorização contínua para garantir que tudo funcione de acordo com o esperado. Alertas automáticos podem/devem ser configurados para notificar os administradores sobre potenciais problemas.
-
Segurança da chave privada: Uma vez que os clientes ACME lidam com chaves privadas, é crucial implementar práticas de segurança robustas para proteger essas informações sensíveis. Isso inclui a utilização de métodos de armazenamento seguro e a aplicação de políticas de acesso rigorosas. Em infraestruturas que necessitem que os certificados/chaves privadas sejam propagados para servidores diferentes de onde foram gerados, deve também ser garantida a segurança da informação durante o seu trânsito.
2. Clientes ACME
Um cliente ACME corresponde uma implementação específica do protocolo ACME que corre num servidor. Pode ou não correr junto da aplicação que irá servir o certificado SSL (por exemplo, servidor Web). Tal como referido anteriormente, o cliente ACME age como um intermediário entre o servidor e a CA, facilitando a comunicação e automatizando as etapas necessárias para a emissão e renovação de certificados SSL.
2.1 Funcionalidades dos clientes ACME
-
Renovação automática de certificados: Uma das características mais cruciais do clientes ACME é a capacidade de renovar automaticamente os certificados antes destes expirarem. Não requerem intervenção manual, reduzindo os riscos associados a certificados expirados.
-
Verificação de propriedade do domínio: Os clientes ACME executam os desafios criptográficos necessários para provar que o servidor tem controlo sobre o domínio para o qual está a solicitar o certificado. Este processo garante a autenticidade do pedido.
-
Gestão automática de chaves públicas e privadas: Os clientes ACME lidam automaticamente com a geração de chaves públicas e privadas, garantindo que as informações sensíveis permaneçam seguras.
-
Integração com servidores web: Vários clientes ACME (por exemplo, certbot) são projetados para funcionar de maneira integrada com uma variedade de servidores web populares, como Apache e Nginx, entre outros, simplificando a sua implementação e configuração.
2.2. Exemplos de clientes ACME
Existem diversos clientes ACME disponíveis online, muitos dos quais se encontram resumidos nesta lista disponível no Github.
Especificamente, para sistema operativo Linux, os clientes mais frequentemente recomendados são:
Para sistemas Windows, alguns exemplos de clientes:
2.3. Certbot
Tal como referido anteriormente, o certbot é o cliente ACME mais usado para sistemas Linux. É uma ferramenta de linha de comandos, grátis e open-source, e é mantida pela Electronic Frontier Foundation (EFF). As principais características do certbot são:
- Grátis e Open-source
- Fácil de instalar
- Automaticamente renova certificados quando faltarem 30 dias para a sua data de expiração.
Na Secção 3 é fornecido um playbook de Ansible que pode ser usado para instalar a ferramenta certbot.
Uma vez instalado, o certbot pode ser facilmente executado para pedir certificados através da linha de comandos, por exemplo:
shell> sudo certbot certonly -m <contact_email> --server <certificate_acme_directory> --domain <certificate_domains_list> --eab-kid <acme_mac_id> --eab-hmac-key=<acme_mac_key> --standalone
onde devem ser substituídos os seguintes valores:
<contact_email>: email de contacto (e.g., joao.guerreiro@fccn.pt)<certificate_domains_list>: lista separada por vírgulas dos domínios a pedir no certificado (e.g., 'teste1.eduroam.pt, teste2.eduroam.pt')<certificate_acme_directory>: URL da directory ACME da conta fornecido pelo Administrador de Certificados da Instituição.<acme_mac_id>: credencial EAB Key ID fornecida pelo Administrador de Certificados da Instituição.<acme_mac_key>: credencial EAB HMAC Key fornecida pelo Administrador de Certificados da Instituição.
Para mais informações, por favor ver a Documentação Oficial.
3. Pacote de ACME FCCN
Como forma de promover a adopção da utilização do protocolo ACME na comunidade RCTS, a FCCN disponibiliza um pacote de Ansible que permite instalar e configurar um cliente de ACME para servidores Linux, especificamente o cliente certbot. O resto desta Secção encontra-se dividida em 2 sub-secções, consoante os destinatários da mesma, nomeadamente:
- 3.1. Gestão de Contas ACME - Administrador de Certificados da Instituição: relativo às tarefas que têm de ser efetuadas pelo Administrador de Certificados da Instituição, nomeadamente a criação de contas ACME, que é um pré-requisito para que o playbook possa ser utilizado.
- 3.2. Playbook de Ansible - Administrador de Sistemas dos serviços da Instituição: relativo à utilização do pacote de Ansible que permite instalar e configurar um cliente de ACME para servidores Linux.
3.1. Gestão de Contas ACME - Administrador de Certificados da Instituição
Um elemento essencial para a utilização do processo de gestão automática de certificados é a existência de contas ACME, neste caso junto da CA da HARICA. A gestão destas contas, nomeadamente a sua criação, alteração ou remoção é da responsabilidade do Administrador de Certificados da Instituição.
Assim, e para a utilização do procedimento implementado no playbook, é necessário que sejam criadas/configuradas contas ACME no Portal da HARICA.
3.1.1. Criação de conta ACME
Os passos a proceder para a criação de uma conta ACME são os seguintes:
- No menu de Enterprise Admin, carregar na tab de ACME e carregar no botão para criar uma nova Conta.

- Aqui pode-se escolher a Organização sobre a qual se pretende criar a conta ACME. Seleccionar o tipo de validação dos certificados (OV ou DV). É necessário introduzido um nome amigável paraa conta, de preferência algo que permita identificar facilmente a conta ACME que irá ser criada, aceitar os Termos e Condições da HARICA e criar no botão de Criar.

- Depois de criada a conta, ficam disponíveis nesta as credenciais EAB e o URL do endpoint que são necessários configurar nos Clientes ACME.

- Após a sua criação, uma conta ACME ainda não tem nenhum domínio associado. Ao navegar-se para a Tab de Domínios, é possível associar que domínios para os quais essa conta ACME poderá emitir certificados. Apenas podem ser seleccionados domínios já pré-validados no site da HARICA. Existem duas opções: 1) associar todos os domínios da organização, ou 2) associar domínios específicos. É possível adicionar regras de Allow e de Deny, sendo que em caso de conflitos, as regras de Deny explícito tomam precedência.

3.1.2. Passagem das credenciais ao utilizador final
Uma vez criada a conta ACME, as credenciais obtidas podem ser passadas ao utilizador final que as irá utilizar nos seus sistemas.
Por exemplo, pode ser utilizada encriptação dos emails através da utilização de certificados pessoais.
3.2. Playbook de Ansible - Administrador de Sistemas dos serviços da Instituição
3.2.0. Pré-requisitos
As secções seguintes assumem a existência de um ambiente Linux com os seguintes requisitos:
- Ansible instalado.
- Pacote de ACME FCCN (.zip) mais recente já localizado no servidor.
Clique aqui para ver pré-requisitos num servidor Debian (testado em Debian 11 e 12).
shell> sudo apt install -y ansible unzip
shell> wget --no-check-certificate https://certificados.fccn.pt/assets/acme/certbot_playbook_<current_version>.zip
shell> unzip certbot_playbook_<current_version>.zip -d certbot_ansible
shell> cd certbot_ansible
Clique aqui para ver pré-requisitos num servidor CentOS (testado em CentOS Stream 9).
shell> sudo yum install wget unzip
shell> sudo dnf install ansible-core
shell> ansible-galaxy collection install community.general ansible.posix
shell> sudo dnf install epel-release
shell> sudo dnf upgrade
shell> wget --no-check-certificate https://certificados.fccn.pt/assets/acme/certbot_playbook_<current_version>.zip
shell> unzip certbot_playbook_<current_version>.zip -d certbot_ansible
shell> cd certbot_ansible
3.2.1. Inventário - Credenciais ACME
O cliente de ACME (certbot) necessita de credenciais EAB associadas a uma conta ACME (hmac_id e hmac_key) e do endpoint a utilizar (server), pelo que antes da execução do pacote de Ansible devem ser pedidas as credenciais ACME.
Depois de seguido o procedimento detalhado na Secção anterior, as credenciais recebidas devem ser colocadas num ficheiro YAML, por exemplo defaults/credentials.yml, que deve ser construído seguindo a sintaxe exemplificada em defaults/template.yml:
Clique aqui para ver exemplo do ficheiro defaults/template.yml.
contact_email: <contact_fccn> #exemplo: joao.guerreiro@fccn.pt
acme_accounts:
- name: <serviço> #exemplo: "CIENCIA ID"
ca: acme-v02.harica.gr
server: https://acme-v02.harica.gr/acme/<directory_id>/directory
mac_id: <credencial_eab_hmac_id>
mac_key: <credencial_eab_hmac_key>
O pacote permite a existência de diferentes conjuntos de credenciais (por exemplo, associados a diferentes serviços/domínios), podendo ser colocados no ficheiro credentials.yml numa lista.
Cada conjunto de credenciais deve estar associado a um nome (por exemplo, eduroam, rctsaai, etc.) que será fornecido no momento de execução do pacote para escolha das credenciais a utilizar.
Embora opcional, é recomendável que as credenciais ACME sejam encriptadas utilizando o Ansible Vault.
3.2.2. Utilizar o Ansible Vault
Para facilitar a segurança e visibilidade das credenciais ACME, o pacote de Ansible vem com um ficheiro defaults/secrets.yml, que pode ser utilizado de acordo com as recomendações oficiais Ansible.
Nomeadamente:
- Colocar as credenciais encriptadas em variáveis no ficheiro
defaults/secrets.yml. - No ficheiro de credenciais (e.g.,
defaults/credentials.yml) as variáveis com as credenciais que serão usadas pelo playbook deverão apontar para as variáveis encriptadas no ficheirodefaults/secrets.yml.
3.2.2.1. Encriptar as credenciais
Para tal, as credenciais ACME podem ser encriptadas pelo Ansible Vault, através dos seguintes comando:
shell> ansible-vault encrypt_string --ask-vault-pass '<Key ID>' --name 'vault_<service>_mac_id'
shell> ansible-vault encrypt_string --ask-vault-pass '<HMAC Key>' --name 'vault_<service>_mac_key'
onde <Key ID> e <HMAC Key> devem ser substituídos pelas credenciais ACME recebidas, e <service> por um nome que identifique o serviço.
Ao executar cada um destes comandos, vai ser pedida uma password que passará a corresponder à password do Ansible Vault deste inventário.
Para tal, deve ser usada a mesma password em todas as encriptações/desencriptações deste projecto/playbook.
O comando irá fornecer fornecer o bloco de texto que deve ser copiado integralmente para o ficheiro defaults\secrets.yml.
Clique aqui para ver um exemplo do output do commando ansible-vault encrypt.
vault_eduroam_mac_id: !vault |
$ANSIBLE_VAULT;1.1;AES256
62313365396662343061393464336163383764373764613633653634306231386433626436623361
6134333665353966363534333632666535333761666131620a663537646436643839616531643561
63396265333966386166373632626539326166353965363262633030333630313338646335303630
3438626666666137650a353638643435666633633964366338633066623234616432373231333331
6564
Clique aqui para ver um exemplo do ficheiro defaults/secrets.yml preenchido.
---
vault_eduroam_mac_id: !vault |
$ANSIBLE_VAULT;1.1;AES256
39396466383037323236346163383033326236363234613062653862323864383464373165643031
3666653933336134356239356535366530613837363963370a626139306336306435363565613937
66663062303333643363383762373833383632623663313330643435656330326235333731666638
6338643530333832620a653130663762633134386137656236383961666437383534323731316135
34356439353038333737663265633334336265613765316435313237313762306535
vault_eduroam_mac_key: !vault |
$ANSIBLE_VAULT;1.1;AES256
61396563393339636639383362326563396363653438313831653565356635383734633861376534
3661316165643935393338303238643062323366323232380a633164346137303263306566643333
62323834396530663830663635643661636366383965346235363934653266666337393234356632
3034663632393031300a306563333236666439313934663435633766646338306134353035396634
36643839626135646539653333383366306433313265376665653262656135343532366430333164
65663664313032366338343135653137353138323161396666646664306338343364353333616363
62616630633863323038323764393535623938643265326236323933313631333730643131633061
65636332323037323563363464613139396138326339616337343030383736323531623233393530
6262
3.2.2.2. Utilizar as variáveis encriptadas no Inventário
Por fim, é necessário que as variáveis de credenciais utilizadas dentro do playbook de Ansible referenciem as variáveis encriptadas que foram criadas, utilizando sintaxe jinja2.
Para tal, basta alterar o ficheiro de inventário previamente criado com base no defaults/template.yml (por exemplo, defaults/credentials.yml), de acordo com o exemplo seguinte:
---
contact_email: joao.guerreiro@fccn.pt
acme_accounts:
- name: "eduroam"
ca: "acme-v02.harica.gr"
server: "https://acme-v02.harica.gr/acme/XXXXXXXXXXXXX/directory"
mac_id: "{{ vault_eduroam_mac_id }}"
mac_key: "{{ vault_eduroam_mac_key }}"
É importante que o nome das variáveis correspondam exactamente aos que estão definidos no ficheiro defaults/secrets.yml.
Desta forma as variáveis das credenciais vão utilizar os valores encriptados.
3.2.3. Executar o playbook
O pacote fornecido consiste num playbook de Ansible que irá efetuar sempre as seguintes etapas:
- Instalar o certbot (caso não esteja já instalado)
- Registar o certbot como cliente de ACME na entidade certificadora da Sectigo com as credenciais ACME fornecidas (caso não esteja já registado)
- Pedir o(s) certificado(s) desejados
O playbook de Ansible permite que sejam fornecidos 7 argumentos:
option_acme_account_name
- Obrigatório.
- Nome das credenciais ACME a utilizar. Deve corresponder a um valor existente no ficheiro
defaults/credentials.yml. - Exemplo:
option_acme_account_name='eduroam'
option_common_names_list
- Obrigatório.
- lista de common-names, separados por vírgulas. Para cada common-name será gerado um (ou vários, dependendo do valor de
option_multi_domain) certificado(s) SSL do tipo OV. - Exemplo:
option_common_names_list='teste1.eduroam.pt,teste2.eduroam.pt'
option_credentials_file
- Opcional (default:
'defaults/template.yml'). - Caminho para o ficheiro com as credenciais ACME.
- Exemplo:
option_credentials_file='defaults/credentials.yml'
option_multi_domain
- Opcional (default:
'single-domain'). - Valores permitidos:
single-domainmulti-domain
- Permite selecionar se se pretende um certificado single-domain por cada common-name ou um único certificado multi-domain com todos os common-names fornecidos.
- Exemplo:
option_multi_domain='single-domain'
option_post_hook
- Opcional (default:
''). - Permite definir uma ação (comando, script, etc.) a executar sempre que existe uma nova versão de um certificado. Um exemplo pode ser reiniciar o servidor web (e.g., apache, nginx, etc.) após renovação de certificados.
- Exemplo:
option_post_hook='service apache2 reload'
option_webserver
- Opcional (default:
'standalone'). - Permite definir o servidor web a ser usado para comunicar com a CA.
- Exemplo:
option_webserver='standalone'
option_encryption_algorithm
- Opcional (default:
'ecdsa'). - Permite definir o algoritmo de encriptação usado.
- Exemplo:
option_encryption_algorithm='ecdsa'
option_concatenate_certs
- Opcional (default:
'False'). - Permite gerar, para além dos ficheiros habituais, um ficheiro que agrega o certificado gerado e a chave privada. Util para algumas aplicações, como por exemplo Haproxy.
- Exemplo:
option_concatenate_certs='False'
Uma vez clonado o repositório, e devidamente configurado o ficheiro defaults/credentials.yml, o playbook de Ansible pode ser executado de uma de duas formas:
- Localmente.
- Remotamente com inventário de Ansible devidamente configurado.
A execução local pode ser feita com o seguinte comando:
shell> ansible-playbook playbook_acme_ssl.yml --extra-vars "option_acme_account_name='eduroam' option_common_names_list='teste1.eduroam.pt,teste2.eduroam.pt' option_credentials_file='defaults/credentials.yml' option_multi_domain='single-domain' option_post_hook='service apache2 reload'"
--ask-vault-pass.
Em caso de utilização de Ansible Vault, o comando anterior deve ser substituído pelo seguinte comando:
shell> ansible-playbook playbook_acme_ssl.yml --ask-vault-pass --extra-vars "option_acme_account_name='eduroam' option_common_names_list='teste1.eduroam.pt,teste2.eduroam.pt' option_credentials_file='defaults/credentials.yml' option_multi_domain='single-domain' option_post_hook='service apache2 reload'"
3.2.3 Estado Final
Após execução do pacote, deverá ser criada a directoria /etc/letsencrypt/ com a seguinte estrutura:
/etc/letsencrypt/
├── accounts/
│ └── acme-v02.harica.gr/
│ └── acme/
│ └── e2b2669d-33bd-3308-8dc7-c0fba5d5b507/
├── archive/
│ ├── teste1.eduroam.pt/
│ │ ├── cert1.pem*
│ │ ├── chain1.pem*
│ │ ├── fullchain1.pem*
│ │ └── privkey1.pem*
│ └── teste2.eduroam.pt/
│ ├── cert1.pem*
│ ├── chain1.pem*
│ ├── fullchain1.pem*
│ └── privkey1.pem*
├── live/
│ ├── teste1.eduroam.pt/
│ │ ├── cert.pem -> ../../archive/teste1.eduroam.pt/cert1.pem*
│ │ ├── chain.pem -> ../../archive/teste1.eduroam.pt/chain1.pem*
│ │ ├── fullchain.pem -> ../../archive/teste1.eduroam.pt/fullchain1.pem*
│ │ ├── privkey.pem -> ../../archive/teste1.eduroam.pt/privkey1.pem*
│ │ └── README*
│ ├── teste2.eduroam.pt/
│ │ ├── cert.pem -> ../../archive/teste2.eduroam.pt/cert1.pem*
│ │ ├── chain.pem -> ../../archive/teste2.ciencia-id.pt/chain1.pem*
│ │ ├── fullchain.pem -> ../../archive/teste2.ciencia-id.pt/fullchain1.pem*
│ │ ├── privkey.pem -> ../../archive/teste2.ciencia-id.pt/privkey1.pem*
│ │ └── README*
│ └── README*
├── options-ssl-apache.conf*
├── renewal/
│ ├── teste1.ciencia-id.pt.conf*
│ └── teste2.ciencia-id.pt.conf*
└── renewal-hooks/
├── deploy/
├── post/
└�