Guia Prático: Automatizando o gerenciamento de certificados TLS com o Cert-Manager

Guia Prático: Automatizando o gerenciamento de certificados TLS com o Cert-Manager

O cert-manager é um projeto sob o guarda-chuvas de projetos da CNCF e tem por objetivo automatizar a gerência do ciclo de vida de certificados TLS de aplicações em ambientes de Kubernetes. Recentemente, no dia 12 de novembro de 2024, o Cert-Manager atingiu o status de graduado entre os projetos da CNCF.

A Cloud Native Computing Foundation (CNCF) faz parte da Linux Foundation e é uma fundação sem fins lucrativos que hospeda projetos de ferramentas, frameworks e componentes críticos da infraestrutura tecnológica global. Dentre os projetos mais populares estão Kubernetes, Prometheus, ContainerD, Etcd, Istio, ArgoCD e OpenTelemetry. A CNCF também opera como um HUB para os principais desenvolvedores da indústria, usuários finais e fornecedores, além de organizar as maiores conferências de desenvolvedores de código aberto do mundo.

Projetos em incubação e graduados são projetos considerados estáveis para uso em ambiente produtivo. Projetos graduados porém, são empoderados por uma sólida infraestrutura, um framework de governança e suporte jurídico patrocinados pela CNCF.

O projeto Cert-Manager atualmente registra 500 milhões de downloads por mês e as pesquisas internas da CNCF sugerem que 86% dos novos clusters de produção já são criados com o cert-manager como prática padrão para gerenciar a emissão e renovação de certificados TLS e mTLS.

O Cert-Manager permite que desenvolvedores de aplicações e engenheiros de plataforma automatizem a emissão e renovação de certificados de Segurança da Camada de Transporte (TLS) e Segurança Mútua da Camada de Transporte (mTLS) garantindo a comunicação segura de sistemas distribuídos ao automatizar e simplificar a emissão, renovação e gerenciamento do ciclo de vida de certificados X.509 em plataformas Kubernetes. Isso elimina o processo manual de geração e gerenciamento de certificados e ajuda a garantir que os sistemas permaneçam seguros sem intervenção manual constante.

O Cert-Manager pode obter certificados de uma variedade de autoridades de certificados incluindo: Let’s Encrypt, AWS, Google Cloud, FreeIpa, GoDaddy, HashiCorp Vault e certificados privados.

O Cert-manager é um CRD (Cluster Resource Definition), uma espécie de plugin que pode ser instalado em seu Cluster Kubernetes adicionando recursos extras ao cluster e pode ser instalado de várias maneiras. Neste artigo vamos realizar a instalação através do Helm Chart oficial.

Para tanto será necessário acesso a um cluster Kubernetes com o Nginx Ingress Controller e um DNS público de sua propriedade.

Instalação do Cert-Manager

O Cert-Manager pode ser instalado de várias maneiras. Neste exemplo iremos instalar através do Helm chart oficial. Inicialmente é necessario adicionar o repositório ao Helm:

helm repo add jetstack https://charts.jetstack.io --force-update

Em seguida basta instalar o chart no Cluster com o comando abaixo. O Chart irá criar o namespace cert-manager e realizar o deploy dos recursos do Cert-Manager neste namespace.

helm install \
  cert-manager jetstack/cert-manager \
  --namespace cert-manager \
  --create-namespace \
  --set crds.enabled=true

Primeiros passos – Criando um Emissor (Issuer)

A primeira coisa que você precisará configurar após instalar o cert-manager é um Issuer ou um ClusterIssuer. Esses são recursos que representam autoridades certificadoras (CAs) capazes de assinar certificados em resposta a solicitações de assinatura de certificados.

Um emissor, ou Issuer, é um recurso com o escopo de um namespace definido e não é possível emitir certificados a partir de um Issuer para recursos fora de seu namespace. Isso significa que você precisará criar um Issuer em cada namespace em que deseja obter certificados com escopo.

Caso seja necessario criar um único Issuer que possa ser utilizado em vários namespaces, você deve considerar criar um recurso ClusterIssuer. Este é quase idêntico ao recurso Issuer mas seu escopo é a nível de Cluster, podendo ser usado para emitir certificados em todos os namespaces, ou para todo o cluster.

Em nosso Guia iremos utilizar criar um ClusterIssuer para resolução de um desadio ACME HTTP01 utilizando o Let’s Encrypt e gerar um certificado para a nossa aplicação executada em um namespace diferente do namespace cert-manager.

Um Issuer do tipo ACME representa uma única conta registrada no servidor da Autoridade Certificadora do Ambiente de Gerenciamento de Certificados Automatizado (Automated Certificate Management Environment – ACME). Quando você cria um novo Issuer do tipo ACME, o Cert-Manager irá gerar uma chave privada que é usada para identificá-lo junto ao servidor ACME.

O nosso ClusterIssuer será criado utilizando manifesto abaixo no manifesto ClusterIssuer.yaml:

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: 4linux-test
  namespace: cert-manager
spec:
  acme:
    # Você precisará substituir este e-mail pelo seu
    # O Let's Encrypt usará o e-mail para contactar sobre
    # certificados expirados e problemas com a sua conta.
    email: exemplo@4linux.com.br
    # Usaremos o servidor Staging do Lets Encript
    # Certificados irão durar apenas algumas horas
    server: https://acme-staging-v02.api.letsencrypt.org/directory
    privateKeySecretRef:
      # Nome do Secret que será criado para armazenar sua chave no Kubernetes
      name: 4linux-acme-test-key
    # Adicione um resolvedor de desafios HTTP01 utilizando a 
    # classe de Ingress nginx (Neste caso, a classe do nosso Ingress Controller)
    solvers:
    - http01:
        ingress:
          ingressClassName: nginx

O recurso pode ser criado utilizando o comando Kubectl apply. Este comando irá criar um recurso do tipo clusterissuers com nome 4linux-test e o Secret com o nome 4linux-acme-test-key:

kubectl apply -f ClusterIssuer.yml

Criando nosso ClusterIssuer

Solicitando um Certificado

Agora que já temos um emissor em nosso cluster, podemos solicitar nosso primeiro certificado. Existem vários casos de uso e métodos para solicitar certificados através do cert-manager. Neste artigo iremos aborar a solicitação de um certificado para proteção de DNS em um Ingress Kubernetes.

Um dos casos de uso mais comuns para o cert-manager é solicitar certificados TLS assinados para proteger seus recursos de ingress. Isso pode ser feito simplesmente adicionando anotações aos seus recursos de Ingress e o cert-manager facilitará a criação do recurso de Certificado para você. Um pequeno subcomponente do cert-manager, o ingress-shim, é responsável por esta automação.

Preparando o ambiente

Antes de solicitar nosso certificado, primeiro é necessário realizarmos o deploy da nossa aplicação. Neste caso utilizaremos um Deployment do Nginx e um Service que irá expor este Deployment. Os recursos serão criados com o Kubectl apply no namespace 4linux-test-nginx através do manifesto abaixo com o nome de nginx.yml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  namespace: 4linux-test-nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80

---

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
  namespace: 4linux-test-nginx
spec:
  selector:
    app: nginx
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

Realizando deploy da nossa aplicação

Criando um Ingress Anotado

Agora iremos criar um Ingress com o DNS 4ltest.4linux.com.br para a nossa aplicação. Para tanto iremos criar um Ingress com a anotação do Cert-Manager indicando o nome do ClusterIssuer que irá solicitar o certificado. Também é necessário informar na configuração de TLS o nome DNS do host e o nome do Secret que irá armazenar o certificado.

O subcomponente ingress-shim irá monitorar os recursos de Ingress em todo o seu cluster e se observar um Ingress com as anotações suportadas, garantirá que exista um recurso de Certificado com o nome fornecido no campo tls.secretName e configurado conforme descrito no Ingress, no namespace do Ingress.

O Ingress anotado abaixo será criado com o comando kubectl apply com nome nginx-ingress.yml:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: 4ltest-nginx-ingress
  namespace: 4linux-test-nginx
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    cert-manager.io/cluster-issuer: 4linux-test # Anotação com o nome do ClusterIssuer
spec:
  ingressClassName: nginx
  rules:
  - host: 4ltest.4linux.com.br
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx-service
            port:
              number: 80
  tls: # Adicionar um host na configuração de TLS irá determinar o que estará presente no campo subjectAltNames do certififado
    - hosts:
      - 4ltest.4linux.com.br
      secretName: 4ltest-certificado # O Cert-Manager irá armazenar o certificado criado neste secret

Criando nosso Ingress Anotado

No exemplo acima podemos verificar que o Cert-Manager criou também o Ingress cm-acme-http-solver-6spv6 e o Secret 4ltest-certificado-wjp9m onde está armazenado o certificado gerado pelo Let’s Encrypt.

Agora vamos analisar o nosso novo Ingress Anotado:

Analisando nosso Ingress Anotado

Neste momento o Cert-Manager irá realizar a solicitação de um novo certificado ao nosso emissor configutado. Nesse caso, o Let’s Encrypt configurado em nosso recurso ClusterIssuer. Todo este processo pode ser observado através do comando kubectl get nos seguinte recursos adicionados ao nosso cluster pelo Cert-Manager: certificates, certificatesigningrequests, orders e challenges

O processo irá seguir os seguintes passos:

  • O Cert-Manager irá criar um recurso do tipo certificates que, neste momento estará com o status READY como false
  • O Certificado irá criar um recurso do tipo certificatesigningrequests enviando ao Let’s Encrypt uma solicitação de assinatura do certificado
  • Esta solicitação irá gerar um recurso do tipo orders com o registro das informações da solicitação enviada ao emissor
  • Em seguida será criado um desafio do tipo HTTP01 no recurso challenges para que o Let’s Encrypt possa validar que nós, de fato, possuímos o domínio o qual solicitamos o certificado
  • O recurso challenges irá criar o ingress temporário cm-acme-http-solver para responder ao desafio enviado pela entidade emissora
  • Ao concluir o desafio o recurso certificates irá alterar o status READY para true
  • Os recursos certificatesigningrequests, challenges e o ingress cm-acme-http-solver cirado por ele serão removidos pois já não são mais necessários

Recursos do Cert-Manager

A partir deste momento nossa aplicação já está acessível através de HTTPS com um certificado gratuito emitido por uma entidade confiável e totalmente gerenciado pelo Cert-Manager que irá notificar seu vencimento ao e-mail cadastrado no manifesto do ClusterIssuer e realizar a renovação automaticamente:

Nosso site seguro

Conclusão

Com o Cert-Manager podemos automatizar todo o gerenciamento do ciclo de vida de certificados TLS possibilitando desde o deploy da aplicação, reduzindo o nosso overhead operacional antes alocado para este tipo de tarefa repetitiva.


Fontes:

Anterior Aprenda SQL e domine o gerenciamento de dados com o novo curso da 4Linux!
Próxima O que é FinOps e por que sua empresa precisa?

About author

Você pode gostar também

Uncategorized

Como organizar e manipular rotas com Node.js e Express

O Express.js é conhecido como o framework minimalista e flexível para Node.js, uma biblioteca muito utilizada para desenvolvimento de aplicativos web. Neste artigo vamos falar sobre um recurso muito específico:

Banco de Dados

Monitoramento de Dados: Como Utilizar o PostgreSQL e o PgPool com Zabbix

Com o mercado tecnológico cada vez mais crescente, o volume de dados aumenta significativamente a cada minuto, e esse volume é armazenado em diversos sistemas de banco de dados distribuídos.

Cloud

Crie sua própria Wiki: Guia passo a passo para instalação e uso

Uma wiki é uma coleção de páginas da web interconectadas e editáveis colaborativamente. O termo “wiki” é derivado da palavra havaiana “wiki wiki”, que significa “rápido” ou “veloz”. A característica