Criar um certificado SSL auto-assinado para Nginx no Debian 10

Escrito por

em

TLS, ou transport layer security (segurança da camada de transporte), e seu antecessor SSL, que significa secure sockets layer (camada de soquetes seguros), são protocolos da internet usados ​​para encriptar o tráfego normal num invólucro protegido.

Pré-requisitos:

  • Servidor Debian 10 “buster”, utilizador que não seja root mas que tenha privilégios de sudo. E para melhor segurança com uma Firewall ativa. No Debian 10 o pacote ufw vem instalado mas desativado.
  • O nginx instalado. Seguir a parte do tutorial em “Instalar Linux, Nginx, MariaDB, PHP (LEMP stack) no Debian 10“.

Criar o certificado SSL

Criar um ficheiro de configuração que pode ficar guardado para futuras utilizações:

mkdir ~/certs_req
nano ~/certs_req/o.teu.site.req.cnf

Colocar no ficheiro que se segue fazer as alterações necessárias:

[req]
distinguished_name = req_distinguished_name
x509_extensions = v3_req
prompt = no
[req_distinguished_name]
C = PT
ST = LX
L = LxCity
O = MinhaEmpresa
OU = Secção
CN = o.teu.dominio
[v3_req]
keyUsage = critical, digitalSignature, keyAgreement
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = www.o.teu.dominio
DNS.2 = o.teu.dominio
DNS.3 = outro.qualquer.dominio

Depois de criado o ficheiro de requisitos req.cnf , podemos criar uma chave auto-assinada e o certificados com o OpenSSL numa única linha:

sudo openssl req -x509 -nodes -days 365 -newkey rsa:4096 -keyout /etc/ssl/private/nginx-selfsigned.key -out /etc/ssl/certs/nginx-selfsigned.crt -config ~/certs_req/o.teu.site.req.cnf -sha256

Os dois ficheiros criados serão colocados nas sub-diretorias para o efeito “/etc/ssl/private” para a chave e .”/etc/ssl/certs” para o certificado.

Também devemos criar um forte grupo Diffie-Hellman, usado na negociação do Perfect Forward Secrecy com os clientes. isto vai demorar uns minutos dependendo da performance hardware que estiver na máquina.

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

E ficou assim concluído a criação do certificado SSL. A seguir é a configuração do Nginx para usar os ficheiros que acabamos de criar.

Configurar o Nginx para usar SSL

1 – Criar um novo snippet (um troço de configuração usado para incorporar na configuração principal do servidor) de configuração apontado para a chave e para o certificado SSL.

sudo nano /etc/nginx/snippets/auto-assinado.conf

Neste ficheiro “auto-assinado.conf” vamos colocar, com a diretiva “ssl_certificate” o certificado e a chave criados anteriormente.

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

Depois de adicionado os ficheiro “auto-assinado.conf“, fazer ctrl+x em seguida <enter> para guardar na pasta e nome de ficheiro apresentado.

2 – Criar mais um snippet de configuração com configurações de criptografia forte:

sudo nano /etc/nginx/snippets/ssl-params.conf

Copiar o que está a seguir no seu ficheiro snippet “ssl-params.conf“:

ssl_protocols TLSv1.3;# Requires nginx >= 1.13.0 else use TLSv1.2
ssl_prefer_server_ciphers on; 
ssl_dhparam /etc/nginx/dhparam.pem; # openssl dhparam -out /etc/nginx/dhparam.pem 4096
ssl_ciphers EECDH+AESGCM:EDH+AESGCM;
ssl_ecdh_curve secp384r1; # Necessita nginx >= 1.1.0
ssl_session_timeout  10m;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off; # Necessita nginx >= 1.5.9
ssl_stapling on; # Necessita nginx >= 1.3.7
ssl_stapling_verify on; # Necessita nginx => 1.3.7
resolver $DNS-IP-1 $DNS-IP-2 valid=300s;
resolver_timeout 5s; 
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";

Esta config foi contruída por https://cipherli.st/ com base numa configuração muito forte mas à custa de compatibilidade com browsers. Para garantir compatibilidade outras configurações terão que ser usadas.

3 – Alterar a configuração do Nginx para usar SSL

Antes de mais, melhor é fazer um backup das configurações do servidor a aplicar o SSL.

sudo cp /etc/nginx/sites-available/o.teu.dominio /etc/nginx/sites-available/o.teu.dominio.bak

Abrir o ficheiro de configuração para fazer alterações:

sudo nano /etc/nginx/sites-available/o.teu.dominio

Se os pré-requisitos foram criados, o bloco do servidor terá a seguinte aparência:

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

    root /var/www/o.teu.dominio/html;
    index index.html index.htm index.nginx-debian.html;

    server_name o.teu.dominio www.o.teu.dominio;

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

}

Pode não estar exatamente como em cima, pode a ordem ser diferente ou alguma atualização à configuração final.

No ficheiro de configuração existente, alterar as duas instruções “listen” para usar a porta 443 e SSL e, em seguida, inclua os dois ficheiro de snippet que criamos anteriormente e criar um bloco de “server” para redirecionar http para https:

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

    root /var/www/o.teu.dominio/html;
    index index.html index.htm index.nginx-debian.html;

    server_name o.teu.dominio www.o.teu.dominio;

    #...outras instruções e diretivas
}

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

    server_name o.teu.dominio www.o.teu.dominio;

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

Guardar com a combinação de teclas “ctrl+x” e <enter> para aplicar a reescrita. Fazer teste às configurações:

sudo nginx -t

Se estiver ok e com com sucesso reiniciamos o servidor nginx com:

sudo systemctl restart nginx

4 – Alterar a firewall

Se o servidor tem ativo o ufw (Uncomplicated Firewall), fazemos o seguinte para permitir a porta 80 e porta 443:

sudo ufw allow 'Nginx Full'
sudo ufw delete allow 'Nginx HTTP'

Testar com “https://o.teu.dominio” num browser.