Esta publicação 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. Ela explica:
- A abordagem padrão para configurar SSL com o NGINX e as possíveis limitações de segurança
- Como criptografar as chaves usando senhas armazenadas separadamente da configuração do NGINX
- Como distribuir as senhas de criptografia com segurança, evitando armazená-las em disco, e revogá-las quando necessário
Para muitas implantações, a abordagem padrão é suficiente. As duas abordagens mais sofisticadas discutidas neste post impedem que um invasor obtenha chaves privadas SSL por outros meios. Também veremos mais algumas técnicas em posts futuros:
- Usar repositórios de segredos de terceiros, como o HashiCorp Vault, para distribuir senhas com segurança
- Automatização do provisionamento de certificados do Vault para o armazenamento de chave-valor do NGINX Plus, para que o material da chave privada nunca seja armazenado em disco
As abordagens apresentadas nesta publicação 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. Elas não são necessárias para usuários que executam o NGINX em ambientes que já têm integração com um repositório de segredos, como o Kubernetes.
Esta publicação se aplica tanto ao NGINX Open Source quanto ao NGINX Plus. Para facilitar a leitura, usaremos NGINX ao longo do texto.
Nota do editor – Este post é o primeiro de uma série sobre como proteger chaves privadas SSL no NGINX. Confira também os outros posts da série:
- Proteção de chaves privadas SSL no NGINX com o HashiCorp Vault – Aborda o uso do HashiCorp Vault ou de um módulo de segurança de hardware (HSM) para automatizar e dimensionar um sistema de proteção de chaves
- Como usar o armazenamento de chave-valor do NGINX Plus para proteger chaves SSL efêmeras do HashiCorp Vault – Explica como evitar o armazenamento de chaves SSL em disco gerando chaves SSL efêmeras no HashiCorp Vault e armazenando-as no armazenamento de chave-valor em memória do NGINX Plus
Por que proteger a chave privada SSL?
O 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 comprovam que são os proprietários do certificado realizando cálculos com a chave privada correspondente (que deve ser mantida em segredo).
Se a chave privada for comprometida (divulgada a outra entidade), haverá dois riscos principais.
- Risco 1: Falsificação de identidade. Um invasor que tenha a chave privada pode interceptar o tráfego de rede e, em seguida, realizar um ataque man-in-the-middle (MITM). Esse ataque captura e descriptografa todo o tráfego, podendo também modificá-lo, sem que os clientes ou o site percebam.
- Risco 2: Descriptografia. Um invasor que tenha a chave privada e tenha gravado o tráfego de rede poderá descriptografá-lo offline. Observe que esse ataque não pode ser usado contra conexões que utilizam uma cifra com Perfect Forward Secrecy (PFS).
Se a chave privada for comprometida, sua única alternativa será entrar em contato com a autoridade certificadora (CA) e solicitar a revogação do certificado; depois, você terá de confiar que os clientes verificarão e respeitarão o status de revogação.
Além disso, é recomendável usar certificados com prazos de validade curtos (por exemplo, os certificados do Let’s Encrypt expiram após 90 dias). Pouco antes de um certificado expirar, é necessário gerar uma nova chave privada e obter um novo certificado junto à AC. Isso reduz sua exposição caso a chave privada seja comprometida.
O Limite de Segurança do NGINX
Quais pessoas e processos podem acessar as chaves privadas SSL no NGINX?
Antes de tudo, qualquer usuário que obtenha acesso root ao servidor que executa o NGINX poderá ler e usar todos os recursos utilizados pelo próprio NGINX. Por exemplo, existem métodos conhecidos para extrair a chave privada SSL da memória de um processo em execução.
Portanto, independentemente de como a chave privada seja armazenada e distribuída, não é possível protegê-la de um invasor com privilégios de root no servidor host.
Além disso, qualquer usuário que possa modificar e aplicar a configuração do NGINX pode usar esse poder de várias maneiras — para permitir o acesso via proxy a serviços internos, contornar medidas de autenticação etc. Esse usuário pode modificar a configuração do NGINX para obter acesso de root ao servidor (ou equivalente), embora ferramentas como SELinux e AppArmor ajudem a reduzir essa possibilidade.
Portanto, em geral, não é possível proteger a chave privada de um invasor que possa modificar e confirmar alterações na configuração do NGINX.
Felizmente, toda organização competente conta com processos de segurança sólidos que dificultam 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 com menos privilégios 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 a um backup. As chaves privadas do NGINX geralmente 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 de um backup do sistema. Quaisquer dados armazenados no sistema de arquivos, incluindo o material da chave privada, podem estar acessíveis.
Os processos descritos neste documento bloqueiam esses dois métodos de ataque.
Configuração padrão do NGINX
Começamos analisando como é uma configuração típica do NGINX com SSL/TLS:
server {
listen 443 ssl;
server_name a.dev0;
ssl_certificate ssl/a.dev0.crt;
ssl_certificate_key ssl/a.dev0.key;
location / {
return 200 "Hello from service 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, portanto, você pode definir para ela as permissões de acesso mais restritivas possíveis:
root@web1:/etc/nginx/ssl# ls -l a.dev0.key-r-------- 1 root root 1766 Aug 15 16:32 a.dev0.keyA chave privada deve estar sempre disponível; o processo mestre do NGINX a lê sempre que o software NGINX é iniciado, a configuração é recarregada ou uma verificação de sintaxe é realizada (nginx -t).
Para obter mais informações sobre como configurar SSL/TLS, consulte o Guia do Administrador 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 obtenha acesso root ao contêiner, à máquina virtual ou ao servidor em execução que esteja executando o software NGINX.
Criptografando chaves privadas SSL
O NGINX oferece suporte a chaves privadas criptografadas, usando algoritmos seguros como o AES256:
root@web1:/etc/nginx/ssl# mv a.dev0.key a.dev0.key.plainroot@web1:/etc/nginx/ssl# openssl rsa -aes256 -in a.dev0.key.plain -out a.dev0.key
writing RSA key
Enter PEM pass phrase: secure password
Verifying - Enter PEM pass phrase: secure password againQuando você inicia o NGINX ou recarrega ou testa a configuração do NGINX, ele solicita a senha de descriptografia de forma interativa:
root@web1:/etc/nginx# nginx -tEnter PEM pass phrase: secure password
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successfulUsando um arquivo de senha SSL
Inserir senhas de forma interativa é inconveniente e difícil de automatizar, mas você pode configurar o NGINX para usar uma lista de senhas armazenada em um arquivo separado especificado pela diretiva ssl_password_file. Quando o NGINX precisa ler uma chave privada, ele tenta descriptografá-la usando, uma a uma, cada senha contida no arquivo. Se nenhuma das senhas for válida, o NGINX se recusará a iniciar.
ssl_password_file /var/lib/nginx/ssl_passwords.txt;O arquivo ssl_password_file deve ser distribuído separadamente da configuração e ter permissão de leitura apenas para o usuário root. Você pode considerá-lo um token de autorização instalado em servidores confiáveis. O NGINX só pode descriptografar as chaves privadas quando está em execução em um servidor que possui 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, pois torna a configuração do NGINX, por si só, inútil para um invasor. O invasor também precisa obter o conteúdo do arquivo ssl_password_file.
Se um invasor conseguir obter acesso root ao sistema de arquivos em que o ssl_password_file está armazenado (por exemplo, por meio de um backup ou 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 arquivo ssl_password_file em um disco RAM ou em um sistema de arquivos tmpfs. Esse tipo de armazenamento geralmente é menos acessível a invasores externos (por exemplo, seu conteúdo é apagado quando o servidor é reiniciado) e pode ser excluído dos backups do sistema. Você precisa garantir que o arquivo de senhas seja inicializado durante a 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 central de distribuição.
Sempre que o NGINX precisa descriptografar uma chave SSL, ele consulta o ponto central de distribuição e usa as senhas sem nunca armazená-las no disco local. Para se autenticar no servidor central de senhas, a instância do NGINX usa um token que você pode revogar a qualquer momento para bloquear o acesso às senhas.
Criando um ponto central de distribuição de senhas
Comece criando um ponto de distribuição de senhas (PDP). Para esta implementação simples, usamos um serviço HTTPS para fornecer a lista de senhas, com autenticação por nome de usuário e senha:
$ curl -u dev0:mypassword https://pdpserver.local/ssl_passwords.txt
password1
password2
...Em seguida, você pode 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 utilizar o tipo de token de autenticação mais adequado.
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
# Usage: connector.sh
CONNECTOR=$1
CREDS=$2
PDP_URL=$3
[ -e $CONNECTOR ] && /bin/rm -f $CONNECTOR
mkfifo $CONNECTOR; chmod 600 $CONNECTOR
while true; do
curl -s -u $CREDS -k $PDP_URL -o $CONNECTOR
doneO script precisa ser executado como um processo em segundo plano, da seguinte forma:
root@web1:~# ./connector.sh /var/run/nginx/ssl_passwords \dev0:mypassword https://pdpserver.local/ssl_passwords.txt &O conector se vincula 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:
ssl_password_file /var/run/nginx/ssl_passwords;Teste o conector lendo a partir do caminho do conector:
root@web1:~# cat /var/run/nginx/ssl_passwords
password1
password2
...Verifique se o NGINX consegue ler a senha e descriptografar as chaves SSL:
root@web1:~# nginx -tnginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successfulVocê pode usar a abordagem de PDP centralizado para distribuir com segurança qualquer recurso que o NGINX normalmente lê do disco, como chaves privadas individuais ou outros dados confidenciais.
Implicações de segurança de um PDP
Esta solução oferece vários benefícios em comparação com o 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 poderá 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 cada servidor pode ser controlado de forma centralizada. Por exemplo, quando um servidor é desativado, você revoga o token de acesso dele.
Observe que um usuário com acesso ao sistema de arquivos pode 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 as chaves privadas SSL contra exposição, com níveis crescentes de segurança e complexidade:
- Para a grande maioria das organizações, basta restringir o acesso aos ambientes que executam o NGINX para que usuários não autorizados não consigam obter acesso
rootnem visualizar a configuração do NGINX. - Em alguns ambientes, talvez não seja possível restringir totalmente o acesso à configuração do NGINX; nesse caso, pode-se usar um arquivo de senhas SSL.
- Em casos específicos, as organizações podem querer garantir que as chaves e senhas nunca sejam armazenadas em disco. O processo de ponto de distribuição de senhas apresenta uma prova de conceito para essa solução.
Os outros posts desta série descrevem medidas adicionais que você pode tomar para proteger as chaves SSL:
- Proteção de chaves privadas SSL no NGINX com o HashiCorp Vault – Mostra como configurar o HashiCorp Vault como PDP, proporcionando uma distribuição de segredos segura e escalável, com controle de acesso granular. Também aborda o uso de um módulo de segurança de hardware (HSM) para armazenar chaves privadas remotamente, disponibilizando uma API que pode ser usada sob demanda para realizar uma operação de chave.
- Como usar o armazenamento de chave-valor do NGINX Plus para proteger chaves SSL efêmeras do HashiCorp Vault – Mostra como evitar o armazenamento de chaves SSL em disco, gerando chaves SSL efêmeras no HashiCorp Vault e armazenando-as no armazenamento de chave-valor em memória do NGINX Plus.
Experimente o NGINX Plus – comece hoje mesmo sua avaliação gratuita de 30 dias ou entre em contato conosco para conversar sobre seus casos de uso.
Sobre o autor

Publicações relacionadas no blog

Como o F5 NGINX One aprimora o gerenciamento e a observabilidade
Descubra como o F5 NGINX One aprimora o gerenciamento e a observabilidade de ambientes híbridos e multicloud ao oferecer um console web centralizado baseado em SaaS, com insights em tempo real, conformidade automatizada e gerenciamento simplificado de configurações.

Do OpenAPI ao NGINX como gateway de API usando uma API declarativa
Descubra como transformar uma definição de esquema OpenAPI em uma configuração NGINX totalmente funcional, operando como um API Gateway com a segurança de um Web Application Firewall e um Portal do Desenvolvedor, usando uma abordagem declarativa de API.

Como gerenciar picos repentinos de tráfego e sobrecarga do servidor
Picos de tráfego e sobrecarga de servidores são preocupações sérias para varejistas online em qualquer época, mas especialmente durante a “Cyber Season” de compras de fim de ano. Detalhamos como você pode aproveitar as soluções de entrega de aplicações de nível de produção da NGINX para se preparar para aumentos repentinos de tráfego.

Distribuição segura de chaves privadas SSL com o NGINX
Descrevemos três maneiras progressivamente mais seguras de proteger chaves privadas SSL ao configurar o NGINX para processar tráfego HTTPS: permitir acesso de leitura apenas ao usuário root, criptografar as chaves com senhas armazenadas separadamente e distribuir as senhas a partir de um repositório central.
Agrupando solicitações de API em lotes com NGINX Plus e o módulo JavaScript do NGINX
O módulo JavaScript do NGINX lançado com o NGINX Plus R15 oferece suporte a subsolicitações, possibilitando uma classe totalmente nova de casos de uso para o NGINX Plus. Este exemplo completo também usa a API do NGINX Plus e os módulos de chave-valor para converter solicitações de API dos clientes em solicitações separadas para as APIs dos microsserviços que compõem um aplicativo.
Como superar o esgotamento de portas efêmeras no NGINX e no NGINX Plus
Confira dicas para evitar o esgotamento de portas efêmeras com ajustes no kernel do Linux, conexões keepalive e conexões vinculadas dinamicamente a endereços IP locais.