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:
- Un servidor Ubuntu 22.04 configurado siguiendo la guía de configuración inicial del servidor Ubuntu 22.04, incluyendo un usuario sudo no root y un firewall.
- Nginx instalado en tu servidor, lo cual puedes hacer siguiendo Cómo instalar Nginx en Ubuntu 22.04.
- A domain name configured to point to your server. You can purchase one on Namecheap or get one for free on Freenom. You can learn how to point domains to DigitalOcean Droplets by following the documentation on How To Manage Your Domain With DigitalOcean.
- A TLS/SSL certificate configured for your server. You have two options:
- Puedes obtener un certificado gratuito de Let’s Encrypt siguiendo Cómo asegurar Nginx con Let’s Encrypt en Ubuntu 22.04.
- También puedes generar y configurar un certificado autofirmado siguiendo Cómo Crear un Certificado SSL Autofirmado para Nginx en Ubuntu 22.04.
- Nginx configurado para redirigir el tráfico del puerto
80
al puerto443
, lo cual debería estar cubierto por los requisitos previos. - Nginx configurado para utilizar una clave Diffie-Hellman Efímera (DHE) de 2048 bits o superior, lo cual también debería estar cubierto por los requisitos previos.
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:
En el archivo, localiza las variables listen
asociadas al puerto 443
:
...
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
:
...
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:
Si la sintaxis no tiene errores, recibirás una salida como la siguiente:
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:
# include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
Debajo de esa línea, agrega esta línea para definir los cifrados permitidos:
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:
Localiza la siguiente línea:
...
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:
...
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
:
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
:
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:
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:
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í:
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:
Finalmente, reinicia el servidor Nginx para aplicar los cambios.
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.