Created: 2021-04-14 13:20 Updated: 2021-08-27 13:56

Introdução

Neste artigo, vamos ver como criar um certificado autoassinado para uso no NGinx no Debian 10. Com algumas pequenas alterações, as instruções servem para a instalação de certificados oficiais.

O TLS (Transport Layer Security) e seu predecessor SSL (Secure Socket Layer) são protocolos usados para proteger o tráfego normal em envelopes criptografados. O termo envelope que usei aqui refere-se a uma camada de criptografia, ou seja, os dados trafegados são criptografados na origem e decifrados no destino. Desta forma, os dados são protegidos, não podendo ser lidas (decifradas) mesmo que forem interceptadas.

O uso de certificado digital também permite que os usuários verifiquem a identidade do site acessado.

É importante deixar claro, no entanto, que um certificado autoassinado, como o que vamos criar neste artigo, permite criptografar o tráfego entre o servidor e o cliente, no entanto, pelo fato deste certificado não ser assinado por uma autoridade certificadora acreditada, os usuários (navegadores) não serão capazes de validar a identidade do servidor automaticamente.

Um certificado autoassinado pode ser apropriado se você não tiver um nome de domínio associado ao servidor e também para instâncias em que a interface web criptografada não seja voltada a usuário como, por exemplo, em comunicações M2M. Obviamente, sempre que possível deve-se dar preferência para certificados assinados por entidades certificadoras acreditadas já que estes certificados adicionam a possibilidade de verificação da identidade do servidor.

Para fins didáticos, vamos utilizar o certificado autoassinado.

Criação do certificado autoassinado

O TLS/SSL funciona pelo uso da combinação de um certificado público e uma chave privada. A chave é mantida no servidor e é usada para criptografar o conteúdo enviado para os clientes. O certificado SSL é publicamente compartilhado com qualquer um que requisite algum conteúdo. ele pode ser usado para decifrar o conteúdo assinado pela chave SSL associada.

Um cerificado autoassinado e sua respectiva chave podem ser criados com o seguinte comando:

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
    -keyout /etc/ssl/private/nginx-selfsigned.key \
    -out /etc/ssl/certs/nginx-selfsigned.crt

Os detalhes do comando são os seguintes:

Serão solicitadas várias informações para a configuração do certificado, similar ao seguinte exemplo (preencha apropriadamente):

Country Name (2 letter code) [AU]:BR
State or Province Name (full name) [Some-State]:São Paulo
Locality Name (eg, city) []:Nova Odessa
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Fábrica de Software
Organizational Unit Name (eg, section) []:Redes e Comunicações
Common Name (e.g. server FQDN or YOUR name)[]:nome_do_domínio_ou_IP_do_servidor
Email Address []:admin@your_domain.com

A informação mais importante é o Common Name: você precisa preenchê-la com o nome do domínio associado ao seu servidor ou o endereço IP do mesmo.

Os arquivos do certificado e chave privada serão criados nos diretórios de configuração do OpenSSL.

Precisamos criar também um grupo Diffie-Hellman forte, que é usado na negociação do Perfect Forward Secrecy com os clientes. Para fazer isso, devemos usar o seguinte comando:

sudo openssl dhparam -out /etc/nginx/dhparam.pem 4096

O processo de criação pode demorar alguns minutos. Após a finalização do comando, o grupo DH forte estará criado em /etc/nginx/dhparam.pem.

Configurando o NGinx para usar o SSL

Depois de criados o certificado e a chave privada no diretório /etc/ssl, o próximo passo será modificar a configuração do NGinx para que ele use o certificado.

O processo consiste nos seguintes passos:

Para executar os dois primeiros passos, vamos criar arquivos de configuração em /etc/nginx/snippets, que é um diretório onde podem ser criadas configurações específicas do NGinx. Se você preferir não usar este diretório, também é possível realizar as configurações no arquivo de configuração principal do NGinx.

Configuração do certificado e da chave privada

Crie o arquivo /etc/nginx/snippets/self-signed.conf com o seguinte conteúdo:

ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt; ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;

Neste arquivo foram configuradas as localizações dos arquivos do certificado digital e da chave privada.

Configuração de Criptografia forte

O próximo passo será configurar os parâmetros do SSL. Estas configurações dirão ao NGinx qual suíte de cifras fortes do SSL usar, e habilitar alguns recursos avançados que ajudarão a manter o serviço mais seguro.

Para configurar o NGinx de forma segura, as configurações apresentadas seguem as recomendações de Remy van Elst em seu site.

Crie o arquivo /etc/nginx/snippets/ssl-params.conf com o seguinte conteúdo:

# Disable strict transport security for now.
# You can uncomment the following line if you understand the implications.
# add_header Strict-Transport-Security "max-age=63072000; \
#  includeSubDomains; preload";

# Requires nginx >= 1.13.0 else use TLSv1.2
ssl_protocols TLSv1.3;
ssl_prefer_server_ciphers on;

# openssl dhparam -out /etc/nginx/dhparam.pem 4096
ssl_dhparam /etc/nginx/dhparam.pem;
ssl_ciphers EECDH+AESGCM:EDH+AESGCM;

# Requires nginx >= 1.1.0
ssl_ecdh_curve secp384r1;
ssl_session_timeout  10m;
ssl_session_cache shared:SSL:10m;

# Requires nginx >= 1.5.9
ssl_session_tickets off;

# Requires nginx >= 1.3.7
ssl_stapling on;

# Requires nginx => 1.3.7
ssl_stapling_verify on;

# Use your DNS settings
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;

add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";

Nota: as configurações sugeridas Remy em seu site oferecem segurança forte, no entanto, algumas vezes isso tem um custo relacionado à compatibilidade com navegadores. Se o site precisa suportar clientes antigos, será necessário utilizar um conjunto de configurações não tão forte.

Uma das configurações recomendadas por Remy foi propositalmente comentada no exemplo, que é a linha que define o cabeçalho de segurança de transporte estrito (HTTP Strict Transport Security - HSTS). Antes de habilitar o HSTS, reserve um momento para obter mais informações sobre ele, principalmente a funcionalidade de pré-carregamento. O pré-carregamento do HSTS fornece maior segurança, mas pode ter consequências fortes se ativado acidentalmente ou incorretamente.

Pelo fato de estarmos usando um certificado autoassinado, o SSL stapling não será usado. O NGinx irá reclamar disso na inicialização, mas funcionará normalmente.

Ajustar as configurações do NGinx para uso do SSL:

Para fins didáticos, vamos considerar que a configuração do nosso site usa um arquivo de configuração específico para o nosso domínio no diretório /etc/nginx/sites-available. Vamos supor que o arquivo se chame meudomínio.conf.

As configurações devem ser parecidas com o exemplo a seguir:

# /etc/nginx/sites-available/meudominio.conf
server {
    listen 80;
    listen [::]:80;

    root /var/www/meudominio/html;
    index index.html index.htm index.nginx-debian.html;

    server_name meudominio www.;

    location / {
        try_files $uri $uri/ =404;
    }
}

Basicamente, o que iremos fazer é incluir os arquivos de parâmetros SSL que criamos nos passos anteriores e modificar a porta padrão (80) para a porta padrão SSL (443). Para finalizar, vamos adicionar um bloco de configurações de forma a redirecionar as requisições da porta 80 para a 443.

Na configuração atual de seu domínio no NGinx, altere os doi parâmetros de porta de escuta (listen) conforme exemplo a seguir e adicione os arquivos de configuração do SSL e certificado:

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    include snippets/self-signed.conf;
    include snippets/ssl-params.conf;

    root /var/www/meudominio/html;
    index index.html index.htm index.nginx-debian.html;

    server_name meudominio www.meudominio;

    # . . .
}

Para forçar o navegador que tentar acessar o site via HTTP (porta 80), basta adicionar um novo bloco de configuração no mesmo arquivo de configuração, conforme exemplo a seguir:

# . . .
server {
    listen 80;
    listen [::]:80;

    server_name meudominio www.meudominio;

    return 301 https://$server_name$request_uri;
}

Esta é uma configuração básica que escuta na porta 80 e executa o redirecionamento para HTTPS.

Teste as configurações:

sudo nginx -t

Se ocorrer algum problema, leia atentamente as mensagens de erro e revise as configurações. Observe que o NGinx pode emitir uma mensagem de advertência relacionada ao SSL stapling. Como mencionado anteriormente, esta mensagem pode ser ignorada, já que ela está relacionada ao uso do certificado autoassinado.

Caso nenhum problema seja detectado, basta reiniciar o NGinx:

sudo systemctl restart nginx.service

Firewall

Para que o servidor seja acessível por outros computadores, as portas 80 e 443 devem ser liberadas no firewall local.

A configuração do firewall depende, essencialmente, de qual ferramenta é utilizada no servidor para a manipulação das regras do firewall. No Debian, a aplicação mais ou menos padrão é o UFW. Eu, particularmente, gosto de usar o FirewallD, que é o mesmo usado em sistemas Red Hat e similares, e está disponível no repositório do Debian também.

Teste

Para testar, abra seu navegador e acesse http://meudominio. Como estamos usando um certificado autoassinado, o navegador irá apresentar uma mensagem informando que a identidade do servidor não pôde ser verificada porque o certificado não pôde ser validado por uma entidade certificadora. Esta advertência só desaparecerá se for utilizado um certificado assinado por uma entidade certificadora acreditada.