paint-brush
Explorando os certificados SSL do Azure: nossa jornada com a Let's Encryptpor@socialdiscoverygroup
3,228 leituras
3,228 leituras

Explorando os certificados SSL do Azure: nossa jornada com a Let's Encrypt

por Social Discovery Group10m2023/04/21
Read on Terminal Reader

Muito longo; Para ler

Lutando com certificados SSL? Pavel Shapurau, engenheiro líder de DevOps no Social Discovery Group, cobre tudo. No artigo, ele compartilha uma configuração de solução personalizada que utiliza certificados Let's Encrypt e as lições aprendidas ao longo do caminho.
featured image - Explorando os certificados SSL do Azure: nossa jornada com a Let's Encrypt
Social Discovery Group HackerNoon profile picture

Ao implantar um projeto da Web, a implementação do certificado SSL é um desafio comum que todo engenheiro provavelmente enfrentará – e eu não sou exceção.

Normalmente, as startups optam por certificados gratuitos como os da Let's Encrypt. No entanto, eles vêm com limitações e inconvenientes a serem considerados, que são detalhados no site do provedor do certificado .

Vamos dar uma olhada mais de perto nos problemas que encontrei pessoalmente com certificados gratuitos:

  • Em primeiro lugar, eles exigem reemissão regular e são válidos por no máximo três meses.
  • No caso do Kubernetes, os certificados precisam ser armazenados e frequentemente regenerados dentro da plataforma.
  • Os certificados curinga e sua renovação apresentam uma série de dificuldades.
  • Os protocolos e algoritmos de criptografia também têm suas próprias peculiaridades.

Tendo enfrentado esses problemas regularmente, desenvolvi uma configuração de solução personalizada que utiliza certificados Let's Encrypt. Neste artigo, compartilharei minhas descobertas e as lições que aprendi ao longo do caminho.

Recentemente, tenho me concentrado em uma pilha de tecnologia específica e gostaria de discutir uma solução de infraestrutura baseada em cluster Kubernetes no contexto de um provedor de nuvem do Azure. Embora o cert-manager seja uma solução popular neste domínio, prefiro instalá-lo por meio do Helm para maior conveniência.

Então, sem mais delongas, vamos direto ao assunto:

 helm repo add jetstack https: //charts.jetstack.io
helm repo update kubectl apply -f https: //github.com/jetstack/cert-manager/releases/download/v1.6.1/cert-manager.crds.yaml
helm install cert-manager jetstack/cert-manager -- namespace cert - manager -- create - namespace -- version v1 . 6 . 1

Em seguida, podemos criar um ClusterIssuer usando o seguinte arquivo YAML:

 apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-cluster-issuer
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: p…[email protected]   #your e-mail
    privateKeySecretRef:
      name: letsencrypt-cluster-issuer
    solvers:
      - http01:
          ingress:
            class: nginx

Seguindo em frente, existem duas opções para implementar os certificados:

  • Criando certificados adicionando "tipo: Certificado";
  • Gerenciando certificados por meio de sua entrada.

Vamos explorar as duas opções.

No primeiro cenário, meus arquivos YAML ficaram assim:

 apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: myservice2  namespace : test
Spec :  duration : 2160h
  renewBefore : 72h
  dnsNames : - myservice2 . mydomain . org # you resources
  secretName : myservice2 - tls
  issuerRef :    name : letsencrypt - cluster - issuer
    kind : ClusterIssuer

Vale ressaltar que apenas o "secretName: myservice2-tls" foi mencionado no ingresso na seção TLS para um determinado serviço.

A propósito, o arquivo YAML contém alguns parâmetros úteis, como:

  • duração: 48h – indicando a duração do certificado em horas
  • renovaBefore: 24h – especificando quantas horas antes do certificado expirar, você pode tentar renovar o certificado existente

Se você se sentir mais confortável trabalhando com o console, deixe-me fornecer uma visão abrangente do certificado como exemplo.

 kubectl describe certificates <cert name > -n <namespace name >

Então, o que temos no final?

  • Not After – a data de expiração do certificado;
  • Not Before – a data de criação do certificado (a menos que explicitamente especificado no campo Certificate YAML Resource);
  • Renewal Time – o carimbo de data/hora antes da expiração do certificado.

Pessoalmente, descobri que o gerenciamento de certificados Let's Encrypt por meio do Ingress é mais confiável e conveniente, e é por isso que o tenho usado ultimamente. Com essa abordagem, além do secretName e do hostname na seção TLS, você só precisa especificar anotações no arquivo YAML de entrada.

 annotations : cert-manager .io/cluster-issuer: "letsencrypt-cluster-issuer" cert-manager .io/renew-before: 72h

E aí está, a magia de tudo! Os certificados agora são reemitidos automaticamente, com um período de buffer de três dias antes de expirarem neste exemplo. Vale ressaltar que, no caso do Let's Encrypt, o prazo padrão é de 90 dias.

No entanto, devido às limitações dos certificados gratuitos da Let's Encrypt, nossa equipe acabou contemplando a necessidade de um certificado abrangente que pudesse proteger não apenas nosso domínio, mas também subdomínios. À medida que continuamos desenvolvendo nosso projeto no Azure, descobrimos que o Azure Key Vault fornecia um local conveniente para armazenar esses certificados. Estamos usando o utilitário akv2k8s em nosso cluster Kubernetes. Se você estiver interessado, eu o encorajo a aprender mais sobre isso .

O que é o Azure Key Vault

Depois de obter um certificado no Azure, a próxima etapa é adicioná-lo ao Azure Key Vault (AKV). Embora esse processo seja relativamente simples, verificar a propriedade do domínio pode ser um pouco complicado. No entanto, assim que todas as etapas de confirmação forem concluídas com sucesso, o certificado aparecerá na seção "Segredos" do cofre de chaves.

Um dos principais benefícios dessa abordagem é a renovação automática do certificado. O certificado será reemitido e atualizado no AKV após um ano e será sincronizado automaticamente com o Secret no Kubernetes.


Para que o cluster Kubernetes utilize o certificado adquirido, você precisará conceder a ele certas permissões e direitos de acesso.

Para fazer isso, primeiro você precisará obter o identityProfile.kubeletidentity.objectId do cluster. Você pode fazer isso usando o seguinte comando:

 az aks show -g < RG > -n < AKS_name >

O grupo de recursos (RG) é o local onde o cluster está armazenado e AKS_name é o nome do seu cluster.

Depois de obter o identityProfile.kubeletidentity.objectId, você precisa copiá-lo. Em seguida, adicione o valor ao comando para conceder permissões de acesso aos segredos:

 az keyvault set-policy --name < name AKV > --object-id < get from first step value > --secret-permissions get

Em seguida, você pode prosseguir com a instalação do akv2k8s, que pode ser feito via Helm ou outros métodos preferidos, conforme descrito no guia de instalação .

Seguindo a documentação oficial , você pode sincronizar seu certificado Azure Key Vault com Secret em um namespace específico do Kubernetes. Aqui está o meu arquivo YAML:

 apiVersion: spv.no/v1 kind: AzureKeyVaultSecret metadata: name: wildcard-cert #any name  namespace : default
spec :  vault :    name : SandboxKeyVault # name you keyvault in Azure
    object :      name : name_object_id # name object id from Azure AKV this cert
      type : secret
  output :    secret :      name : wildcard - cert # any name for secret in your namespace
      type : kubernetes . io / tls
      chainOrder : ensureserverfirst # very important values !!!

Deixe-me enfatizar a importância da última linha, pois desempenhou um papel crucial na resolução de um problema que encontrei. Inicialmente, consegui carregar o certificado no Kubernetes com sucesso, mas ele não funcionou conforme o esperado. Demorou algum tempo para diagnosticar o problema.

Acontece que, ao exportar um certificado PFX do Key Vault, o certificado do servidor às vezes é posicionado no final da cadeia em vez de no início, onde deveria estar. Isso pode causar problemas quando usado com parâmetros como ingress-nginx, pois o certificado falha ao carregar e retorna ao seu valor original. No entanto, ao definir chainOrder como ensureserverfirst, o certificado do servidor é colocado primeiro na cadeia.

Após uma inspeção mais detalhada do certificado, descobri que a corrente estava organizada na seguinte sequência:

  1. Intermediário
  2. Raiz
  3. Servidor

Tendo discutido os aspectos técnicos e as configurações, vamos nos aprofundar nas peculiaridades dos certificados do Azure.

O Azure oferece duas opções para solicitar um certificado, ambas fornecidas pela GoDaddy:

  • um certificado para um domínio ou subdomínio específico;
  • um certificado curinga.

Optamos pelo último, esperando que protegesse todos os nossos aplicativos e serviços. No entanto, havia algumas nuances.

O certificado Azure Wildcard protege apenas subdomínios de primeiro nível. Por exemplo, se tivermos um domínio chamado mydomain.com , o certificado cobrirá apenas subdomínios de primeiro nível na forma de .mydomain.com .

Portanto, o certificado funcionará para recursos como service1.mydomain.com, service2.mydomain.com, service3.mydomain.com , mas não cobrirá service1.test.mydomain.com ou mail.service1.mydomain.com .

Que opções temos então?

  • Comprar certificados Wildcard separados para todos os subdomínios necessários;
  • Adicionando registros SAN ( Nome Alternativo do Assunto ) ao certificado.

É improvável que a primeira opção seja prática, pois o número de subdomínios, principalmente os do segundo nível, pode ser enorme. Portanto, pagar por um certificado curinga para cada subdomínio ( .service1.mydomain.com, *.dev.mydomain.com… ) não é a solução mais razoável.

Quanto à segunda opção, tive uma longa conversa com a equipe de suporte do Azure sobre esse assunto, passando por todos os estágios de negação, frustração e raiva, apenas para perceber no final que o recurso SAN para certificados ainda não foi implementado.

Até o final, eu esperava que esse problema nunca ocorresse no Azure. Por outro lado, seu concorrente, AWS Amazon, oferece certificados por meio de seu AWS Certificate Manager (ACM) que oferece suporte a até 10 nomes de entidade alternativos, incluindo curingas. Ele permite criar 10 subdomínios com um caractere curinga (*) e até solicitar um aumento de cota na AWS de até 100k.

Para finalizar, compartilharei como você pode utilizar certificados com o serviço Front Door no Azure.

Compreendendo a porta frontal do Azure (AFD)

Para mim, o Azure Front Door (AFD) é um gateway global e escalonável que aproveita a rede de borda mundial da Microsoft para direcionar o tráfego de entrada para os pontos de extremidade apropriados, que podem ser aplicativos ou serviços da Web. Operando na camada HTTP/HTTPS (camada 7), o Front Door roteia as solicitações do cliente para um servidor de aplicativos disponível do pool. O lado do servidor do aplicativo pode ser qualquer serviço acessível pela Internet, seja ele hospedado dentro ou fora do Azure.


Um exemplo do site de documentação https://docs.microsoft.com/ 

O Azure Front Door é uma ferramenta conveniente que permite equilibrar e fazer proxy do tráfego de entrada que acessa aplicativos e serviços distribuídos em todo o mundo. Ele oferece uma variedade de recursos, incluindo a capacidade de vincular várias regras, configurando o manipulador de regras, ingressando em políticas e configurações de firewall. Não vou me aprofundar muito nas especificidades do serviço AFD neste artigo, mas sim nas peculiaridades do serviço de certificados.

Como você pode esperar, o tráfego de entrada para a porta frontal do Azure pode ser http ou https . Se você escolher https , terá três opções: gerar um certificado no próprio serviço Azure Front Door, carregar seu próprio certificado ou sincronizar seu certificado existente com o Azure Key Vault. Para permitir que o serviço Front Door acesse o Key Vault, você precisará configurar as permissões necessárias.

Recomendo usar a última opção e selecionar a versão mais recente do certificado para evitar a necessidade de renová-lo ou recriá-lo manualmente. Ao conectar o certificado do AKV, tudo ficará atualizado automaticamente.

Esta configuração lhe dará o seguinte resultado:


Aqui está outra peculiaridade ao direcionar o tráfego do Azure Front Door para o AKS.

Lidar com o tráfego http não é um problema, mas há um detalhe sutil a ser lembrado ao configurar um pool de recursos e especificar o endereço IP externo do cluster AKS. Certifique-se de deixar o campo "cabeçalho do nó do componente do servidor" em branco para garantir que ele seja preenchido automaticamente com os valores inseridos no campo "IP ou nome do nó".



Suponha que você tenha um certificado curinga de domínio anexado por meio de AKV que é utilizado pelo serviço Front Door e liberado no cluster AKS por meio de akv2k8s. O nome do host da interface (e o registro CNAME no DNS) para todos os seus aplicativos e serviços acessíveis por meio do Front Door serão os seguintes:

  • *.mydomain.com – com o campo "cabeçalho do nó do componente do servidor" deixado em branco;
  • Seu endereço IP AKS externo terá uma regra de redirecionamento http padrão para /.

Isso permitirá que todos os serviços no formato *.mydomain.com funcionem corretamente. Depois de concluir esta configuração, está tudo pronto.



Em determinados cenários, redirecionar o tráfego do Azure Front Door para o AKS por meio de https pode ser mais vantajoso. Para garantir o funcionamento correto do Azure Front Door nas configurações do pool de servidores, é crucial especificar um nome DNS correspondente ao seu cluster AKS , que está relacionado ao SNI e às verificações de integridade. Caso contrário, a configuração não funcionará.

No meu caso, não havia nenhum nome atribuído aos meus clusters AKS, eu tinha apenas serviços que antes funcionavam diretamente, mas tinham que funcionar por meio do Azure Front Door. Para resolver isso, tive que criar um nome DNS separado para o cluster AKS, configurar o DNS e configurar um serviço separado com um certificado anexado à entrada. Só então eu poderia redirecionar o tráfego https para os clusters AKS e garantir que funcionasse corretamente para todos os serviços disponíveis.

É importante considerar as medidas de segurança ao configurar a permissão de conexão para AKS. Para garantir uma conexão segura, você pode limitar a permissão para se conectar ao AKS somente a partir de endereços IP da porta frontal do Azure no grupo de segurança de rede para AKS (conforme mostrado na imagem abaixo).



Além disso, você pode configurar a entrada AKS para aceitar conexões exclusivamente do cabeçalho da porta frontal do Azure por ID usando o parâmetro X-Azure-FDID .

Nota final e um conselho

1. O Azure não fornece informações abrangentes sobre os recursos e desvantagens de seus certificados. No entanto, vale ressaltar que prontamente nos reembolsaram pelo certificado adquirido.

2. Durante nosso processo de desenvolvimento, continuamos a usar o Let's Encrypt. Embora tenha suas limitações, não é a pior escolha disponível.

3. Se o seu projeto exigir vários subdomínios com diferentes níveis de recursos, considere os certificados "Wildcard (também conhecidos como Multidomínio) com SAN" de fornecedores terceirizados. Esses certificados podem ser importados para o Azure e utilizados em todo o seu potencial.

4. Quando configurado corretamente, o Azure Front Door é um excelente serviço. Eu recomendo.

Escrito por Pavel Shapurau, engenheiro líder de DevOps, Social Discovery Group