Pesquisa de site

Implementando SSL Perfect Forward Secrecy no servidor Web NGINX


Este COMO FAZER descreve o processo de implementação do Perfect Forward Secrecy com o servidor web NGINX em sistemas Debian e Ubuntu. O processo pode ser facilmente adaptado a outros sistemas GNU/Linux.

Resumindo, Perfect Forward Secrecy garante: "...que o comprometimento de uma mensagem não pode levar ao comprometimento de outras, e também que não existe um único valor secreto que possa levar ao comprometimento de múltiplas mensagens." Para obter mais informações, consulte http://en.wikipedia.org/wiki/Forward_secrecy#Perfect_forward_secrecy.

Quando a vulnerabilidade Heartbleed no OpenSSL foi revelada no início de 2014, ficou cada vez mais claro que o PFS é obrigatório para qualquer sistema que empregue SSL/TLS de forma séria.

Caso você queira comparar seus resultados com os meus, minha implementação de referência pode ser testada em https://www.ssllabs.com/ssltest/analyze.html?d=indietorrent.org, e a cadeia de certificados SSL e os cabeçalhos NGINX que são enviados pode ser revisado em https://indietorrent.org.

Sem mais delongas, vamos configurar o NGINX para implementar o PFS.

Vamos para o diretório de configuração do NGINX:

cd /etc/nginx/

Precisamos gerar parâmetros Diffie-Hellman que sejam suficientemente fortes. Alguns argumentam que 4.096 bits é um exagero e causará uma carga indevida na CPU do sistema, mas com o poder da computação moderna, isso parece um compromisso que vale a pena. Para obter mais informações, consulte a seção Referências, abaixo.

openssl dhparam -out dh4096.pem 4096

É útil ter esse arquivo de configuração, específico para a tarefa em questão, compartimentado em um arquivo de inclusão; isso simplifica a implementação do PFS em um grande número de sistemas.

vi /etc/nginx/perfect-forward-secrecy.conf

Cole o seguinte no arquivo acima:

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 \
EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 \
EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !MEDIUM";
ssl_dhparam dh4096.pem;

Modifique a configuração do NGINX para incluir o arquivo acima, inserindo a seguinte linha no arquivo de configuração principal do NGINX (por padrão, /etc/nginx/nginx.conf), na parte inferior (e dentro) do Bloco http {}:

# See: https://community.qualys.com/blogs/securitylabs/2013/08/05/configuring-apache-nginx-and-openssl-for-forward-secrecy
# This MUST come AFTER the lines that includes .../sites-enabled/*, otherwise SSLv3 support may be re-enabled accidentally.
include perfect-forward-secrecy.conf;

Reinicie o NGINX para que as alterações tenham efeito:

service nginx restart

Se o teste em https://www.ssllabs.com/ssltest/analyze.html exibir Retomada de sessão (armazenamento em cache) Não (IDs atribuídos, mas não aceitos) em vermelho e o servidor implementar SNI, adicione o seguinte ao nível superior Bloco http {} (ou seja, adicione ao nginx.conf, logo abaixo de onde fizemos as adições anteriores):

# See: http://forum.nginx.org/read.php?2,152294,152401#msg-152401
ssl_session_cache shared:SSL:10m;

Novamente, reinicie o NGINX para que as alterações tenham efeito:

service nginx restart

O teste acima não deverá mais reportar esse problema (mesmo que o problema não reduza a pontuação geral do teste).

Indo além: implementando HTTP Strict Transport Security (HSTS) com longa duração

Esta é uma tarefa fácil e que vale a pena fazer, desde que:

  1. Você deseja forçar SSL para todos os recursos de qualquer host para o qual esse cabeçalho esteja definido (ou seja, todas as páginas do site em questão).
  2. Você pode conviver sem a capacidade de aceitar e ignorar avisos SSL para qualquer recurso solicitado de qualquer host para o qual este cabeçalho esteja definido, como "Incompatibilidade de nome de domínio", etc. A própria natureza do HSTS é que as condições de aviso e erro relacionadas ao certificado SSL não pode ser substituído.

Eu vasculhei a Internet em busca de informações sobre se a configuração desse cabeçalho pode ou não ter consequências indesejadas em navegadores que não suportam o cabeçalho e não encontrei nada. Porém, consegui acalmar minhas preocupações testando essa implementação no Internet Explorer 6, por exemplo, e os navegadores nos quais o HSTS não está implementado simplesmente ignoram o cabeçalho. Perfeito!

Basta adicionar as seguintes linhas ao final de /etc/nginx/perfect-forward-secrecy.conf e salvar as alterações:

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
# This will prevent certain click-jacking attacks, but will prevent
# other sites from framing your site, so delete or modify as necessary!
add_header X-Frame-Options SAMEORIGIN;

Uma recarga (em vez de uma reinicialização) será suficiente para forçar o NGINX a captar estas alterações específicas:

service nginx reload

É possível confirmar se o HSTS está funcionando conforme planejado testando sua implementação em https://www.ssllabs.com/ssltest/analyze.html. Se o HSTS for implementado corretamente, você verá uma caixa verde logo abaixo de sua pontuação, informando: "Este servidor suporta HTTP Strict Transport Security com longa duração. Nota definida como A+."

Parabéns!

Agora você tem uma das implementações SSL/TLS mais seguras da Internet.

Referências:

  • https://community.qualys.com/blogs/securitylabs/2013/08/05/configurando-apache-nginx-and-openssl-for-forward-secrecy

Direitos autorais © 2014 Ben Johnson

Artigos relacionados: