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:
- 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).
- 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