Cómo configurar Nginx con soporte HTTP/2 en Ubuntu 22.04

A previous version of this tutorial was written by Sergey Zhukaev.

Introducción

Nginx es un servidor web de código abierto rápido y confiable. Ganó popularidad debido a su bajo consumo de memoria, alta escalabilidad, facilidad de configuración y soporte para una amplia variedad de protocolos.

HTTP/2 es una versión más nueva del Protocolo de Transporte de Hipertexto, que se utiliza en la web para entregar páginas desde el servidor al navegador. HTTP/2 es la primera actualización importante de HTTP en casi dos décadas: HTTP1.1 fue introducido al público en 1999 cuando las páginas web eran mucho más pequeñas en tamaño. Internet ha cambiado drásticamente desde entonces, y ahora nos enfrentamos a las limitaciones de HTTP 1.1. El protocolo limita las velocidades de transferencia potenciales para la mayoría de los sitios web modernos porque descarga partes de una página en una cola: la parte anterior debe descargarse completamente antes de que comience la descarga de la siguiente parte, y una página web moderna promedio descarga docenas de activos individuales de CSS, javascript e imagen.

HTTP/2 resuelve este problema porque introduce algunos cambios fundamentales:

  • Todas las solicitudes se descargan en paralelo, no en una cola
  • Los encabezados de HTTP se comprimen
  • Las páginas se transfieren como un archivo binario, no como un archivo de texto, lo que es más eficiente
  • Los servidores pueden “empujar” datos incluso sin la solicitud del usuario, lo que mejora la velocidad para usuarios con alta latencia

Aunque HTTP/2 no requiere cifrado, los desarrolladores de los dos navegadores más populares, Google Chrome y Mozilla Firefox, han declarado que por razones de seguridad solo admitirán HTTP/2 para conexiones HTTPS. Por lo tanto, si decides configurar servidores con soporte para HTTP/2, también debes asegurarlos con HTTPS.

Este tutorial te ayudará a configurar un servidor Nginx rápido y seguro con soporte para HTTP/2.

Prerrequisitos

Antes de comenzar, necesitarás algunas cosas:

Paso 1 — Habilitar Soporte para HTTP/2

Si seguiste el paso de configuración del bloque del servidor en el tutorial de instalación de Nginx, deberías tener un bloque de servidor para tu dominio en /etc/nginx/sites-available/tu_dominio con la directiva server_name ya configurada adecuadamente. El primer cambio que haremos será modificar el bloque de servidor de tu dominio para utilizar HTTP/2.

Abre el archivo de configuración para tu dominio usando nano o tu editor preferido:

  1. sudo nano /etc/nginx/sites-enabled/your_domain

En el archivo, localiza las variables listen asociadas al puerto 443:

/etc/nginx/sites-enabled/your_domain
...
    listen [::]:443 ssl ipv6only=on; 
    listen 443 ssl; 
...

El primero es para conexiones IPv6. El segundo es para todas las conexiones IPv4. Habilitaremos HTTP/2 para ambos.

Modifica cada directiva listen para incluir http2:

/etc/nginx/sites-enabled/your_domain
...
    listen [::]:443 ssl http2 ipv6only=on; 
    listen 443 ssl http2; 
...

Esto indica a Nginx que utilice HTTP/2 con los navegadores compatibles.

Guarda el archivo de configuración y sal del editor de texto. Si estás utilizando nano, presiona Ctrl+X y luego, cuando se te solicite, Y y después Enter.

Cada vez que realices cambios en los archivos de configuración de Nginx, debes verificar la configuración en busca de errores, utilizando la bandera -t, que ejecuta el comando de verificación de sintaxis integrado de Nginx:

  1. sudo nginx -t

Si la sintaxis no tiene errores, recibirás una salida como la siguiente:

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

A continuación, configurarás tu servidor Nginx para utilizar una lista de cifrados más restrictiva para mejorar la seguridad del servidor.

Paso 2 — Eliminar Suites de Cifrado Antiguas e Inseguras

HTTP/2 tiene una lista negra de cifrados antiguos e inseguros que se deben evitar. Las suites de cifrado son algoritmos criptográficos que describen cómo se debe cifrar los datos transferidos.

El método que utilizarás para definir los cifrados depende de cómo hayas configurado tus certificados TLS/SSL para Nginx.

Si utilizaste Certbot para obtener tus certificados, también creó el archivo /etc/letsencrypt/options-ssl-nginx.conf que contiene cifrados que no son lo suficientemente seguros para HTTP/2. Sin embargo, modificar este archivo evitará que Certbot aplique actualizaciones en el futuro, así que simplemente diremos a Nginx que no utilice este archivo y especificaremos nuestra propia lista de cifrados.

Abre el archivo de configuración del bloque del servidor para tu dominio:

sudo nano /etc/nginx/sites-enabled/your_domain

Localiza la línea que incluye el archivo options-ssl-nginx.conf y coméntala agregando un carácter # al principio de la línea:

/etc/nginx/sites-enabled/your_domain

# include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot

Debajo de esa línea, agrega esta línea para definir los cifrados permitidos:

/etc/nginx/sites-enabled/your_domain

ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;

Guarda el archivo y sal del editor.

Si utilizaste certificados autofirmados o utilizaste un certificado de un tercero y lo configuraste según los requisitos previos, abre el archivo /etc/nginx/snippets/ssl-params.conf en tu editor de texto:

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

Localiza la siguiente línea:

/etc/nginx/snippets/ssl-params.conf
...
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
...

Modifícala para usar la siguiente lista de cifrados:

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

...
ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;

Guarda el archivo y sal del editor.

Nuevamente, verifica la configuración en busca de errores de sintaxis usando el comando nginx -t:

  1. sudo nginx -t

Si encuentras algún error, soluciónalo y vuelve a probar.

Una vez que tu configuración pase la comprobación de sintaxis, reinicia Nginx usando el comando systemctl:

  1. sudo systemctl reload nginx.service

Con el servidor reiniciado, verifiquemos que funcione.

Paso 3 — Verificar que HTTP/2 está habilitado

Asegurémonos de que el servidor esté en funcionamiento y trabajando con HTTP/2.

Utiliza el comando curl para hacer una solicitud a tu sitio y ver los encabezados:

  1. curl -I -L --http2 https://your_domain

Recibirás una salida como la siguiente:

HTTP/2 200
**Server**: nginx/1.18.0 (Ubuntu)
**Date**: Tue, 21 Jun 2022 22:19:09 GMT
**Content-Type**: text/html
**Content-Length**: 612
**Last-Modified**: Tue, 21 Jun 2022 22:17:56 GMT
**Connection**: keep-alive
**ETag**: "62b24394-264"
**Accept-Ranges**: bytes

También puedes verificar que se esté utilizando HTTP/2 en Google Chrome. Abre Chrome y navega a https://tu_domino. Abre las Herramientas para desarrolladores de Chrome (Ver -> Desarrollador -> Herramientas para desarrolladores) y recarga la página (Ver -> Recargar esta página). Ve a la pestaña Red, haz clic derecho en la fila del encabezado de tabla que comienza con Nombre y selecciona la opción Protocolo del menú emergente.

Tendrás una nueva columna Protocolo que contiene h2 (que significa HTTP/2), lo que indica que HTTP/2 está funcionando.

En este punto, estás listo para servir contenido a través del protocolo HTTP/2. Mejoremos la seguridad y el rendimiento habilitando HSTS.

Paso 4 — Habilitar HTTP Strict Transport Security (HSTS)

Aunque tus solicitudes HTTP redirijan a HTTPS, puedes habilitar HTTP Strict Transport Security (HSTS) para evitar tener que hacer esas redirecciones. Si el navegador encuentra un encabezado HSTS, no intentará conectarse al servidor a través de HTTP regular nuevamente durante un período de tiempo dado. En cualquier caso, intercambiará datos utilizando solo una conexión HTTPS cifrada. Este encabezado también nos protege de ataques de degradación de protocolo.

Abre nuevamente el archivo de configuración del bloque del servidor para tu dominio:

sudo nano /etc/nginx/your_domain

Agrega esta línea al mismo bloque del archivo que contiene los cifrados SSL para habilitar HSTS:

/etc/nginx/your_domain
server {
...
    ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
    add_header Strict-Transport-Security "max-age=15768000" always;
}
...

El max-age está establecido en segundos. El valor 15768000 equivale a 6 meses.

Por defecto, este encabezado no se agrega a las solicitudes de subdominio. Si tienes subdominios y quieres que HSTS se aplique a todos ellos, debes agregar la variable includeSubDomains al final de la línea, así:

/etc/nginx/your_domain
add_header Strict-Transport-Security "max-age=15768000; includeSubDomains" always;

Guarda el archivo y sal del editor.

Una vez más, verifica la configuración en busca de errores de sintaxis:

  1. sudo nginx -t

Finalmente, reinicia el servidor Nginx para aplicar los cambios.

  1. sudo systemctl reload nginx.service

Conclusión

Su servidor Nginx ahora está sirviendo páginas HTTP/2. Si desea probar la fortaleza de su conexión SSL, visite Qualys SSL Lab y ejecute una prueba contra su servidor. Si todo está configurado correctamente, debería obtener una calificación A+ en seguridad.

Para obtener más información sobre cómo Nginx analiza e implementa las reglas de bloques de servidor, intente leer Comprendiendo los algoritmos de selección de bloques de servidor y ubicación de Nginx.

Source:
https://www.digitalocean.com/community/tutorials/how-to-set-up-nginx-with-http-2-support-on-ubuntu-22-04