HTTP/2 permite enviar muchas peticiones en paralelo sobre una sola conexión TCP, comprime las cabeceras y reduce la latencia frente a HTTP/1.1, sobre todo en páginas con muchos recursos. Todos los navegadores actuales lo soportan, pero solo sobre HTTPS, y lo negocian durante el handshake TLS mediante ALPN. En este tutorial activarás HTTP/2 en Nginx y en Apache en Ubuntu 24.04 y comprobarás que el servidor lo usa realmente.
Requisitos previos
Para seguir esta guía necesitas:
- Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath, y un usuario no root con privilegios
sudo. - Nginx o Apache instalado desde los repositorios de Ubuntu.
- Un sitio que ya sirva HTTPS con un certificado válido, por ejemplo de Let's Encrypt. En la guía se usa
your_domaincomo marcador de tu dominio. - El puerto 443 abierto en el firewall.
Las versiones de Ubuntu 24.04 son Nginx 1.24 y Apache 2.4.58, ambas con soporte HTTP/2 incluido. No necesitas compilar nada ni añadir repositorios.
Paso 1: Comprobar el protocolo actual
Antes de cambiar nada, comprueba qué protocolo negocia hoy el servidor. La opción --http2 de curl pide HTTP/2 y vuelve a HTTP/1.1 si el servidor no lo ofrece:
curl -sI --http2 https://your_domain | head -n 1
HTTP/1.1 200 OK
Si ya aparece HTTP/2 200, HTTP/2 está activo y no necesitas continuar.
Paso 2: Activar HTTP/2 en Nginx
El paquete de Nginx de Ubuntu está compilado con el módulo HTTP/2. Puedes confirmarlo:
nginx -V 2>&1 | grep -o with-http_v2_module
with-http_v2_module
Abre el archivo de tu sitio:
sudo nano /etc/nginx/sites-available/your_domain
En Nginx 1.24, que es la versión de Ubuntu 24.04, HTTP/2 se activa con el parámetro http2 en las directivas listen del puerto 443. Si Certbot configuró el sitio, las líneas terminarán con # managed by Certbot; basta con añadir http2:
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name your_domain www.your_domain;
ssl_certificate /etc/letsencrypt/live/your_domain/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your_domain/privkey.pem;
# resto de la configuración del sitio
}
Notaa partir de Nginx 1.25.1, el parámetro
http2delistenestá obsoleto y se sustituye por la directivahttp2 on;dentro del bloqueserver. Si instalaste Nginx desde el repositorio oficial de nginx.org, usalisten 443 ssl;junto conhttp2 on;. En la versión de Ubuntu 24.04,http2 on;no existe ynginx -tfallará conunknown directive "http2".
HTTP/2 se aplica a nivel de dirección y puerto: si varios sitios escuchan en 443, basta con activarlo en uno para que lo usen todos, pero es más claro añadirlo en cada bloque.
Valida la sintaxis y recarga:
sudo nginx -t
sudo systemctl reload nginx
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Pasa al paso 5 para verificarlo.
Paso 3: Activar HTTP/2 en Apache
En Ubuntu, el módulo mod_http2 viene incluido en el paquete apache2, pero no está habilitado. Actívalo:
sudo a2enmod http2
La directiva Protocols indica qué protocolos ofrece Apache y en qué orden de preferencia. Declárala en el VirtualHost HTTPS de tu sitio para que el comportamiento quede explícito. Si Certbot creó el sitio, el archivo será your_domain-le-ssl.conf:
sudo nano /etc/apache2/sites-available/your_domain-le-ssl.conf
Añade la línea Protocols dentro del bloque <VirtualHost *:443>:
<VirtualHost *:443>
ServerName your_domain
Protocols h2 http/1.1
# resto de la configuración del sitio
</VirtualHost>
h2 es HTTP/2 sobre TLS; los clientes que no lo soporten seguirán usando http/1.1. Si quieres aplicarlo a todos los sitios, puedes poner la misma línea fuera de cualquier <VirtualHost>, por ejemplo al final de /etc/apache2/apache2.conf.
Valida la configuración, pero no recargues todavía: primero revisa el MPM en el paso siguiente.
sudo apache2ctl configtest
Syntax OK
Paso 4: Usar el MPM event en Apache
Apache procesa las conexiones con un MPM (módulo de multiprocesamiento). HTTP/2 funciona correctamente con event, que es el predeterminado en Ubuntu. Con prefork, mod_http2 se desactiva: Apache sigue funcionando, pero solo con HTTP/1.1, y lo avisa en el log de errores. El caso típico es haber instalado libapache2-mod-php, que cambia el servidor a prefork. Comprueba cuál usas:
sudo apache2ctl -V | grep -i mpm
Server MPM: event
Si ves event, recarga Apache y pasa al paso 5:
sudo systemctl reload apache2
Si ves prefork porque usas PHP como módulo, cambia a PHP-FPM. Ubuntu 24.04 incluye PHP 8.3. Instala PHP-FPM:
sudo apt install php8.3-fpm
Desactiva el módulo de PHP y prefork, y activa event junto con los módulos que conectan Apache con PHP-FPM:
sudo a2dismod php8.3 mpm_prefork
sudo a2enmod mpm_event proxy_fcgi setenvif
sudo a2enconf php8.3-fpm
La configuración php8.3-fpm que proporciona el paquete envía los archivos .php al socket /run/php/php8.3-fpm.sock. Valida y reinicia Apache (el cambio de MPM necesita un reinicio completo, no basta con recargar):
sudo apache2ctl configtest
sudo systemctl restart apache2
Confirma que ahora usa event y que PHP-FPM está activo:
sudo apache2ctl -V | grep -i mpm
systemctl is-active php8.3-fpm
Server MPM: event
active
Abre una página PHP de tu sitio para asegurarte de que sigue funcionando. Ten en cuenta que los ajustes de PHP ya no se leen de /etc/php/8.3/apache2/php.ini sino de /etc/php/8.3/fpm/php.ini.
Paso 5: Verificar HTTP/2
Repite la petición del paso 1:
curl -sI --http2 https://your_domain | head -n 1
HTTP/2 200
Para ver la negociación ALPN en detalle, usa el modo detallado de curl:
curl -sv --http2 -o /dev/null https://your_domain 2>&1 | grep -i alpn
* ALPN: curl offers h2,http/1.1
* ALPN: server accepted h2
En el navegador, abre las herramientas de desarrollo, ve a la pestaña Red (Network), haz clic derecho sobre el encabezado de las columnas y activa Protocolo. Las peticiones a tu dominio deben mostrar h2.
Si quieres medir el rendimiento, el paquete nghttp2-client incluye h2load, un generador de carga para HTTP/2:
sudo apt install nghttp2-client
h2load -n 1000 -c 10 -m 10 https://your_domain/
-n es el número total de peticiones, -c el de conexiones simultáneas y -m el de flujos paralelos por conexión. Ejecútalo desde otra máquina para no medir la carga del propio generador. La línea requests: del resumen debe mostrar todas las peticiones como succeeded.
Solución de problemas
curlsigue mostrandoHTTP/1.1: comprueba que accedes porhttps://; los navegadores y--http2no usan HTTP/2 sobre HTTP sin cifrar. En Nginx, revisa que todas las directivaslistendel puerto 443 tenganhttp2. En Apache, confirma que el módulo está cargado consudo apache2ctl -M | grep http2.- Apache escribe en el log
The mpm module (prefork.c) is not supported by mod_http2: sigue el paso 4 para pasar aeventy PHP-FPM. nginx: [emerg] unknown directive "http2": estás usandohttp2 on;con Nginx 1.24. Usa el parámetrohttp2enlisten, como en el paso 2.nginx: [warn] the "listen ... http2" directive is deprecated: tu Nginx es 1.25.1 o posterior. Cambia alisten 443 ssl;yhttp2 on;.- Error
ERR_HTTP2_INADEQUATE_TRANSPORT_SECURITYen Chrome: la configuración TLS permite cifrados que HTTP/2 prohíbe. Limita los protocolos a TLS 1.2 y 1.3 y usa la lista de cifrados predeterminada del servidor.
Conclusión
Has activado HTTP/2 en Nginx o Apache, has cambiado Apache al MPM event con PHP-FPM cuando era necesario y has comprobado con curl y con el navegador que el servidor negocia h2. Los clientes antiguos siguen usando HTTP/1.1 sin ningún cambio.
Como siguientes pasos puedes:
- Revisar tu estrategia de recursos: con HTTP/2 ya no compensa unir todos los archivos CSS o JS en uno ni repartir recursos entre subdominios.
- Evitar HTTP/2 Server Push, que los navegadores han dejado de soportar y que Nginx eliminó en la versión 1.25.1; usa en su lugar
<link rel="preload">. - Estudiar HTTP/3 (QUIC), disponible en las versiones recientes de Nginx del repositorio oficial de nginx.org.
