BLOG | NGINX

Distribuição segura de chaves privadas SSL com NGINX

NGINX-Parte-de-F5-horiz-preto-tipo-RGB
Miniatura de Owen Garrett
Owen Garrett
Publicado em 02 de abril de 2019

Esta postagem do blog descreve vários métodos para distribuir com segurança as chaves privadas SSL que o NGINX usa ao hospedar sites criptografados com SSL. Ele explica:

Para muitas implantações, a abordagem padrão é suficiente. As duas abordagens mais sofisticadas discutidas nesta postagem bloqueiam outras maneiras pelas quais um invasor pode obter chaves privadas SSL. Também veremos mais algumas técnicas em postagens de acompanhamento:

  • Usando armazenamentos secretos de terceiros, como o HashiCorp Vault, para distribuir senhas com segurança
  • Automatizar o provisionamento de certificados do Vault para o armazenamento de chave-valor do NGINX Plus, para que o material da chave privada nunca seja armazenado no disco

As abordagens apresentadas nesta postagem se aplicam a usuários que precisam gerenciar suas próprias chaves e criar sua própria estratégia segura de distribuição de chaves. Eles não são necessários para usuários que executam o NGINX em ambientes que já se integram a um armazenamento secreto, como o Kubernetes .

Esta postagem se aplica tanto ao NGINX Open Source quanto ao NGINX Plus. Para facilitar a leitura, faremos referência ao NGINX ao longo do texto.

Editor – Este post é o primeiro de uma série sobre como proteger chaves privadas SSL no NGINX. Veja também os outros posts da série:

 

Por que proteger a chave privada SSL?

SSL/TLS é usado para autenticar, criptografar e verificar a integridade das transações de rede. Os sites se autenticam usando um certificado público assinado por uma Autoridade Certificadora (CA) e demonstram que são donos do certificado realizando cálculos usando a chave privada correspondente (que deve ser mantida em segredo).

Se a chave privada for comprometida (divulgada a outra entidade), há dois riscos principais.

  • Risco 1: Representação . Um invasor que tenha a chave privada pode interceptar o tráfego de rede e então montar um ataque do tipo man-in-the-middle (MITM). Este ataque captura e descriptografa todo o tráfego, talvez até mesmo modificando-o, sem que os clientes ou o site saibam.
  • Risco 2: Descriptografia . Um invasor que possui a chave privada e registrou o tráfego de rede pode então descriptografar o tráfego de rede offline. Observe que esse ataque não pode ser usado contra conexões que usam uma cifra Perfect Forward Secrecy (PFS).

Se a chave privada for comprometida, seu único recurso é entrar em contato com a CA e solicitar que seu certificado seja revogado; você deve então confiar nos clientes para verificar e honrar o status de revogação.

Além disso, é uma boa prática usar certificados com prazos de validade curtos (por exemplo, os certificados Let's Encrypt expiram após 90 dias). Pouco antes de um certificado expirar, você precisa gerar uma nova chave privada e obter um novo certificado da CA. Isso reduz sua exposição caso a chave privada seja comprometida.

O limite de segurança do NGINX

Quais pessoas e processos podem acessar chaves privadas SSL no NGINX?

Em primeiro lugar, qualquer usuário que obtenha acesso root ao servidor que executa o NGINX é capaz de ler e usar todos os recursos que o próprio NGINX usa. Por exemplo, existem métodos conhecidos para extrair a chave privada SSL da memória de um processo em execução.

Portanto, não importa como a chave privada é armazenada e distribuída, não é possível protegê-la de um invasor com privilégios de root no servidor host.

Em seguida, qualquer usuário que possa modificar e confirmar a configuração do NGINX pode usar esse poder de muitas maneiras: para abrir acesso proxy a serviços internos, para ignorar medidas de autenticação, etc. Ele ou ela pode modificar a configuração do NGINX para obter acesso root (ou equivalente) ao servidor, embora ferramentas como SELinux e AppArmor ajudem a mitigar essa possibilidade.

Portanto, geralmente não é possível proteger a chave privada de um invasor que pode modificar e confirmar a configuração do NGINX.

Felizmente, qualquer organização competente tem processos de segurança sólidos para dificultar que um invasor obtenha privilégios de root ou modifique a configuração do NGINX.

No entanto, há duas outras maneiras pelas quais um invasor menos privilegiado pode obter acesso à chave privada:

  • Um usuário pode ter um motivo legítimo para precisar visualizar a configuração do NGINX ou pode obter acesso a um banco de dados de configuração ou backup. As chaves privadas do NGINX normalmente são armazenadas na configuração.
  • Um usuário pode obter acesso ao sistema de arquivos do servidor NGINX, talvez por meio de um hipervisor ou backup do sistema. Todos os dados armazenados no sistema de arquivos, incluindo o material da chave privada, são potencialmente acessíveis.

Os processos descritos neste documento selam esses dois métodos de ataque.

Configuração padrão do NGINX

Começamos revisando a aparência de uma configuração típica do NGINX com SSL/TLS:

servidor { ouvir 443 ssl; nome_do_servidor a.dev0; certificado_ssl ssl/a.dev0.crt; chave_do_certificado_ssl ssl/a.dev0.key; localização / { retornar 200 "Olá do serviço A\n"; } }

O certificado público SSL ( a.dev0.crt ) e a chave privada ( a.dev0.key ) são armazenados no sistema de arquivos, em /etc/nginx/ssl/ . A chave privada é lida apenas pelo processo mestre do NGINX, que normalmente é executado como root , para que você possa definir as permissões de acesso mais rigorosas possíveis:

root@web1:/etc/nginx/ssl# ls -l a.dev0.key -r-------- 1 root root 1766 15 de agosto 16:32 a.dev0.key

A chave privada deve estar disponível o tempo todo; o processo mestre NGINX a lê sempre que o software NGINX é iniciado, a configuração é recarregada ou uma verificação de sintaxe é executada ( nginx -t ).

Para obter mais informações sobre como configurar SSL/TLS, consulte o Guia de administração do NGINX Plus .

Implicações de segurança da configuração padrão

Conforme observado acima, a chave privada SSL pode ser lida por um invasor que obtém acesso root ao contêiner em execução, à máquina virtual ou ao servidor que está executando o software NGINX.

Criptografando chaves privadas SSL

O NGINX oferece suporte a chaves privadas criptografadas, usando algoritmos seguros como AES256:

root@web1:/etc/nginx/ssl# mv a.dev0.key a.dev0.key.plain root@web1:/etc/nginx/ssl# openssl rsa -aes256 -in a.dev0.key.plain -out a.dev0.key escrevendo chave RSA Insira a frase-senha PEM: senha segura Verificando - Insira a frase-senha PEM: senha segura novamente

Quando você inicia o NGINX, ou recarrega ou testa a configuração do NGINX, o NGINX solicita a senha de descriptografia interativamente:

root@web1:/etc/nginx# nginx -t Insira a frase-senha PEM: senha segura nginx: a sintaxe do arquivo de configuração /etc/nginx/nginx.conf está correta nginx: o teste do arquivo de configuração /etc/nginx/nginx.conf foi bem-sucedido

Usando um arquivo de senha SSL

Inserir senhas interativamente é inconveniente e difícil de automatizar, mas você pode configurar o NGINX para usar uma lista de senhas armazenadas em um arquivo separado nomeado pela diretiva ssl_password_file . Quando o NGINX precisa ler uma chave privada, ele tenta descriptografar a chave usando cada uma das senhas no arquivo. Se nenhuma das senhas for válida, o NGINX se recusará a iniciar.

arquivo_senha_ssl /var/lib/nginx/ssl_passwords.txt;

O ssl_password_file deve ser distribuído separadamente da configuração e ser legível apenas pelo usuário root . Você pode considerá-lo como um token de autorização que é colocado em servidores confiáveis. O NGINX só pode descriptografar as chaves privadas quando estiver em execução em um servidor com o token de autorização.

Implicações de segurança de chaves criptografadas em um arquivo separado

Esse método reduz a superfície de ataque, tornando a configuração do NGINX inútil para um invasor. O invasor também deve obter o conteúdo do ssl_password_file .

Se um invasor obtiver acesso root ao sistema de arquivos onde o ssl_password_file está armazenado (por exemplo, de um backup ou por meio do sistema host), ele poderá ler o arquivo e usar as senhas para descriptografar as chaves privadas SSL.

Você pode reduzir esse risco armazenando o ssl_password_file em um disco RAM ou tmpfs . Esse armazenamento geralmente é menos acessível a um invasor externo (por exemplo, ele é limpo quando o servidor é reiniciado) e pode ser excluído dos backups do sistema. Você precisa garantir que o arquivo de senha seja inicializado na inicialização do sistema.

Distribuindo listas de senhas SSL com mais segurança

O processo abaixo descreve uma maneira mais segura de distribuir listas de senhas SSL a partir de um ponto de distribuição central.

Sempre que o NGINX precisa descriptografar uma chave SSL, ele consulta o ponto de distribuição central e usa as senhas sem nunca armazená-las no disco local. Para se autenticar com o servidor de senhas central, a instância NGINX usa um token que você pode revogar a qualquer momento para cortar o acesso às senhas.

Criando um ponto de distribuição central de senhas

Comece criando um ponto de distribuição de senhas (PDP). Para esta implementação simples, estamos usando um serviço HTTPS para entregar a lista de senhas, autenticada por nome de usuário e senha:

$ curl -u dev0:minhasenha https://pdpserver.local/ssl_passwords.txt senha1 senha2 ...

Você pode então habilitar ou revogar o acesso adicionando ou removendo tokens de autenticação no PDP, conforme necessário. Você pode implementar o servidor de distribuição de senhas usando um servidor web como o NGINX e usar qualquer tipo de token de autenticação que for apropriado.

Em seguida, precisamos configurar o NGINX para recuperar as senhas do PDP. Começamos criando um script de shell chamado connector.sh com o seguinte conteúdo:

#!/bin/sh
# Uso: connector.sh 

CONNECTOR=$1
CREDS=$2
PDP_URL=$3

[ -e $CONNECTOR ] && /bin/rm -f $CONNECTOR

mkfifo $CONNECTOR; chmod 600 $CONNECTOR

enquanto verdadeiro; faça
curl -s -u $CREDS -k $PDP_URL -o $CONNECTOR
feito

O script precisa ser executado como um processo em segundo plano, invocado da seguinte maneira:

root@web1:~# ./connector.sh /var/run/nginx/ssl_passwords \dev0:minhasenha https://pdpserver.local/ssl_passwords.txt &

O conector é anexado ao caminho local especificado ( /var/run/nginx/ssl_passwords ) e você usa a diretiva ssl_password_file para configurar o NGINX para acessar esse caminho:

arquivo_senha_ssl /var/run/nginx/senhas_ssl;

Teste o conector lendo o caminho do conector:

root@web1:~# cat /var/run/nginx/ssl_passwords senha1 senha2 ...

Verifique se o NGINX pode ler a senha e descriptografar as chaves SSL:

root@web1:~# nginx -t nginx: a sintaxe do arquivo de configuração /etc/nginx/nginx.conf está ok nginx: o teste do arquivo de configuração /etc/nginx/nginx.conf foi bem-sucedido

Você pode usar a abordagem PDP central para distribuir com segurança qualquer recurso que o NGINX normalmente lê do disco, por exemplo, chaves privadas individuais ou outros dados confidenciais.

Implicações de segurança de um PDP

Esta solução tem vários benefícios em comparação ao armazenamento de senhas SSL em disco:

  • As senhas SSL nunca são armazenadas no sistema de arquivos do servidor , portanto, um invasor que tenha acesso ao sistema de arquivos não pode acessá-las diretamente.
  • As senhas são distribuídas a partir de um ponto de acesso central , facilitando o monitoramento e a auditoria.
  • O acesso de servidores individuais pode ser controlado centralmente . Por exemplo, quando um servidor é desativado, você revoga seu token de acesso.

Observe que um usuário que tenha acesso ao sistema de arquivos pode potencialmente extrair as credenciais usadas para acessar o PDP. É importante revogar essas credenciais quando elas não forem mais necessárias.

Resumo

Há muitas maneiras de proteger chaves privadas SSL contra divulgação, com níveis crescentes de segurança e complexidade:

  • Para a grande maioria das organizações, é suficiente restringir o acesso aos ambientes que executam o NGINX para que usuários não autorizados não possam obter acesso root e não possam visualizar a configuração do NGINX.
  • Em alguns ambientes, pode não ser possível restringir totalmente o acesso à configuração do NGINX, portanto, um arquivo de senha SSL pode ser usado.
  • Em casos limitados, as organizações podem desejar garantir que chaves e senhas nunca sejam armazenadas em disco. O processo de ponto de distribuição de senha ilustra uma prova de conceito para esta solução.

As outras postagens desta série descrevem etapas adicionais que você pode seguir para proteger chaves SSL:

Experimente o NGINX Plus você mesmo – comece seu teste gratuito de 30 dias hoje mesmo ou entre em contato conosco para discutir seus casos de uso .


"Esta postagem do blog pode fazer referência a produtos que não estão mais disponíveis e/ou não têm mais suporte. Para obter as informações mais atualizadas sobre os produtos e soluções F5 NGINX disponíveis, explore nossa família de produtos NGINX . O NGINX agora faz parte do F5. Todos os links anteriores do NGINX.com redirecionarão para conteúdo semelhante do NGINX no F5.com."