Configuración de Nginx para entornos de producción

Conjunto de ajustes en Nginx para mejorar el rendimiento, fortalecer la seguridad y facilitar el despliegue en producción.

Después de cada cambio verifica la sintaxis y reinicia el servicio.

sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
sudo service nginx restart

1. Certificados SSL con Let's Encrypt

Sigue la guía Instalación de certificados SSL con Let's Encrypt y Nginx en Debian para emitir un certificado con Let's Encrypt y luego usa la siguiente configuración.

sudo nano /etc/nginx/sites-available/your_domain.com

your_domain.com

server {
    listen 443 ssl default_server;
    listen [::]:443 ssl default_server;

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

    server_name your_domain.com www.your_domain.com;

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

    ssl_certificate /etc/letsencrypt/live/your_domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/your_domain.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
}

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

    server_name your_domain.com www.your_domain.com;
    return 301 https://$host$request_uri;
}

2. Certificados SSL autofirmados

Para generar certificados SSL autofirmados en Debian 10 instala el paquete ssl-cert.

sudo apt-get update && sudo apt-get install -y ssl-cert

Luego ajusta el bloque del sitio de la siguiente manera:

sudo nano /etc/nginx/sites-available/your_domain.com

your_domain.com

server {
    listen 443 ssl default_server;
    listen [::]:443 ssl default_server;

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

    server_name your_domain.com www.your_domain.com;

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

    include snippets/snakeoil.conf;
}

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

    server_name your_domain.com www.your_domain.com;
    return 301 https://$host$request_uri;
}

3. Verifica la navegación HTTPS

Si accedes con un certificado autofirmado, verás un error similar:

curl https://your_domain.com
curl: (60) SSL certificate problem: self signed certificate
More details here: https://curl.haxx.se/docs/sslcerts.html

curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.

Utiliza la opción -k para ignorar la advertencia y continuar.

curl -k https://your_domain.com
<html>
  <head>
    <title>Welcome to your_domain.com!</title>
  </head>
  <body>
    <h1>Success! The your_domain.com server block is working!</h1>
  </body>
</html>

Finalmente prueba la redirección de HTTP a HTTPS:

curl http://your_domain.com
<html>
  <head>
    <title>301 Moved Permanently</title>
  </head>
  <body bgcolor="white">
    <center><h1>301 Moved Permanently</h1></center>
    <hr />
    <center>nginx/1.14.2</center>
  </body>
</html>

4. Habilita el control de caché

Especifica qué extensiones deben almacenarse en caché y durante cuánto tiempo.

sudo nano /etc/nginx/sites-available/your_domain.com

your_domain.com

server {
    listen 443 ssl default_server;
    listen [::]:443 ssl default_server;

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

    server_name your_domain.com www.your_domain.com;

    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
        expires 10m;
        add_header Cache-Control "public, no-transform";
    }

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

    include snippets/snakeoil.conf;
}

5. Habilita la compresión de ficheros

Activa la compresión gzip para reducir el peso de las respuestas estáticas.

sudo nano /etc/nginx/sites-available/your_domain.com

your_domain.com

server {
    listen 443 ssl default_server;
    listen [::]:443 ssl default_server;

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

    server_name your_domain.com www.your_domain.com;

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

    gzip on;
    gzip_comp_level 3;
    gzip_min_length 1000;
    gzip_types  text/xml text/css;
    gzip_http_version 1.1;
    gzip_vary  on;
    gzip_disable "MSIE [4-6] \.";

    include snippets/snakeoil.conf;
}

6. Páginas de error personalizadas

Define una página HTML personalizada y referencia el archivo desde el bloque del sitio.

sudo nano /usr/share/nginx/html/custom_404.html

custom_404.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>404 Not Found</title>
  </head>
  <body>
    404 Not Found
  </body>
</html>
sudo nano /etc/nginx/sites-available/your_domain.com

your_domain.com

server {
    listen 443 ssl default_server;
    listen [::]:443 ssl default_server;

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

    server_name your_domain.com www.your_domain.com;

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

    error_page 404 /custom_404.html;
    location = /custom_404.html {
        root /usr/share/nginx/html;
        internal;
    }

    include snippets/snakeoil.conf;
}

7. Proxy para aplicaciones de NodeJS

Canaliza el tráfico hacia tu aplicación Node.js que se ejecuta en un puerto interno.

sudo nano /etc/nginx/sites-available/your_domain.com

your_domain.com

server {
    listen 443 ssl default_server;
    listen [::]:443 ssl default_server;

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

    server_name your_domain.com www.your_domain.com;

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

    location /node-app/ {
        proxy_pass http://127.0.0.1:3000;
    }

    include snippets/snakeoil.conf;
}

8. Remueve la extensión .html

Permite servir rutas amigables sin incluir la extensión .html en la URL.

sudo nano /etc/nginx/sites-available/your_domain.com

your_domain.com

server {
    listen 443 ssl default_server;
    listen [::]:443 ssl default_server;

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

    server_name your_domain.com www.your_domain.com;

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

    include snippets/snakeoil.conf;
}

Por ejemplo, si la petición es: https://your_domain.com/page, buscará la ruta en el siguiente orden:

  1. El archivo /page.html
  2. El archivo /page
  3. La carpeta /page/

Si no lo encuentra muestra la página de error 404.

Referencias

Publicado: 8 de junio de 2020