HTTP/3 es la versión de HTTP que funciona sobre QUIC, un transporte basado en UDP que establece la conexión cifrada en menos viajes de ida y vuelta y evita que un paquete perdido bloquee todas las peticiones de la conexión. La mejora se nota sobre todo en redes móviles y con pérdida de paquetes. En este tutorial activarás HTTP/3 en Ubuntu 24.04 con Nginx desde el repositorio oficial de nginx.org, verás la alternativa con Caddy y comprobarás que los clientes lo usan de verdad.
Requisitos previos
- Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath.
- Un usuario no root con privilegios
sudo. - Un dominio (
tudominio.com) con registros A (y AAAA si usas IPv6) apuntando al servidor. - Los puertos 80/tcp, 443/tcp y 443/udp accesibles desde Internet.
Cómo funciona la negociación de HTTP/3
El navegador no puede saber de antemano si un servidor habla QUIC. La primera visita se hace por TCP con HTTP/2 o HTTP/1.1, y el servidor responde con la cabecera Alt-Svc: h3=":443". A partir de ahí el navegador intenta QUIC por UDP 443 y, si el puerto está bloqueado, sigue usando TCP sin que el usuario note nada. Por eso HTTP/3 siempre se configura junto a HTTP/2, nunca en su lugar.
Paso 1: Instalar Nginx desde el repositorio oficial
El paquete nginx de Ubuntu 24.04 es la versión 1.24, que no incluye QUIC: el soporte llegó en Nginx 1.25. Los paquetes de nginx.org sí se compilan con el módulo http_v3.
Advertenciasi ya tienes instalado el Nginx de Ubuntu, haz una copia de
/etc/nginxantes de continuar y elimínalo consudo apt remove nginx nginx-common. Los paquetes de nginx.org usan una estructura distinta: los sitios van en/etc/nginx/conf.d/*.confy no existesites-enabled.
Instala las dependencias y la clave de firma del repositorio:
sudo apt update
sudo apt install curl gnupg2 ca-certificates lsb-release ubuntu-keyring
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo gpg --dearmor -o /etc/apt/keyrings/nginx.gpg
Añade el repositorio de la rama estable y dale prioridad sobre el paquete de Ubuntu:
echo "deb [signed-by=/etc/apt/keyrings/nginx.gpg] https://nginx.org/packages/ubuntu $(lsb_release -cs) nginx" \
| sudo tee /etc/apt/sources.list.d/nginx.list
printf "Package: *\nPin: origin nginx.org\nPin: release o=nginx\nPin-Priority: 900\n" \
| sudo tee /etc/apt/preferences.d/99nginx
Instala Nginx y comprueba que incluye el módulo:
sudo apt update
sudo apt install nginx
nginx -V 2>&1 | grep -o with-http_v3_module
with-http_v3_module
Arranca el servicio:
sudo systemctl enable --now nginx
Paso 2: Abrir los puertos en el firewall
QUIC usa UDP, así que no basta con el 443/tcp habitual. Con UFW:
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 443/udp
sudo ufw enable
sudo ufw status
To Action From
-- ------ ----
OpenSSH ALLOW Anywhere
80/tcp ALLOW Anywhere
443/tcp ALLOW Anywhere
443/udp ALLOW Anywhere
Si tu proveedor aplica un firewall externo o grupos de seguridad, abre también allí el 443/udp.
Paso 3: Obtener el certificado TLS
HTTP/3 exige TLS 1.3, que Nginx negocia automáticamente con un certificado válido. Crea el directorio del sitio y un bloque HTTP mínimo que Certbot pueda usar para validar el dominio:
sudo mkdir -p /var/www/tudominio.com
echo '<h1>HTTP/3 funciona</h1>' | sudo tee /var/www/tudominio.com/index.html
sudo mv /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.disabled
sudo nano /etc/nginx/conf.d/tudominio.com.conf
server {
listen 80;
listen [::]:80;
server_name tudominio.com www.tudominio.com;
root /var/www/tudominio.com;
}
Recarga Nginx, instala Certbot con el plugin de Nginx y pide solo el certificado, sin que Certbot modifique la configuración:
sudo nginx -t && sudo systemctl reload nginx
sudo apt install certbot python3-certbot-nginx
sudo certbot certonly --nginx -d tudominio.com -d www.tudominio.com
Certificate is saved at: /etc/letsencrypt/live/tudominio.com/fullchain.pem
Key is saved at: /etc/letsencrypt/live/tudominio.com/privkey.pem
Paso 4: Configurar HTTP/3 en Nginx
Sustituye el contenido de /etc/nginx/conf.d/tudominio.com.conf por la configuración completa:
sudo nano /etc/nginx/conf.d/tudominio.com.conf
server {
listen 80;
listen [::]:80;
server_name tudominio.com www.tudominio.com;
return 301 https://$host$request_uri;
}
server {
# HTTP/1.1 y HTTP/2 sobre TCP
listen 443 ssl;
listen [::]:443 ssl;
# HTTP/3 sobre QUIC (UDP)
listen 443 quic reuseport;
listen [::]:443 quic reuseport;
http2 on;
http3 on;
server_name tudominio.com www.tudominio.com;
root /var/www/tudominio.com;
index index.html;
ssl_certificate /etc/letsencrypt/live/tudominio.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/tudominio.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
# Anuncia HTTP/3 a los navegadores durante 24 horas
add_header Alt-Svc 'h3=":443"; ma=86400' always;
location / {
try_files $uri $uri/ =404;
}
}
Puntos importantes:
reuseportsolo puede aparecer una vez por dirección y puerto en toda la configuración. Si alojas más sitios, ponlisten 443 quic;sinreuseporten los demás bloquesserver.- La cabecera
Alt-Svces la que hace que el navegador pruebe HTTP/3. Si algúnlocationdefine sus propiosadd_header, repite ahí tambiénAlt-Svc, porque Nginx no hereda las cabeceras del nivel superior en ese caso. - No actives
ssl_early_data(0-RTT) salvo que tu aplicación sea inmune a peticiones repetidas: permite ataques de repetición.
Comprueba y recarga:
sudo nginx -t
sudo systemctl reload nginx
Verifica que Nginx escucha también en UDP:
sudo ss -ulnp | grep ':443'
UNCONN 0 0 0.0.0.0:443 0.0.0.0:* users:(("nginx",pid=2231,fd=8),...)
UNCONN 0 0 [::]:443 [::]:* users:(("nginx",pid=2231,fd=9),...)
Paso 5: Comprobar que los clientes usan HTTP/3
Primero confirma que el servidor anuncia HTTP/3:
curl -sI https://tudominio.com/ | grep -i alt-svc
alt-svc: h3=":443"; ma=86400
El curl de Ubuntu 24.04 no está compilado con soporte QUIC. Compruébalo con curl -V | grep HTTP3; si tu equipo local tiene un curl con HTTP3 (por ejemplo el de Homebrew en macOS), puedes forzar la conexión por QUIC:
curl --http3-only -sI https://tudominio.com/ | head -n 1
HTTP/3 200
En el navegador, abre las herramientas de desarrollo, pestaña Red, activa la columna Protocolo y recarga la página dos veces: la primera petición llega por h2 y las siguientes por h3. En el servidor, el log de acceso muestra el protocolo en cada petición:
sudo tail -n 5 /var/log/nginx/access.log
203.0.113.25 - - [25/Sep/2026:10:12:03 +0000] "GET / HTTP/3.0" 200 24 "-" "Mozilla/5.0 ..."
Alternativa: HTTP/3 con Caddy
Caddy activa HTTP/3 por defecto, junto con el certificado automático de Let's Encrypt. Si prefieres Caddy a Nginx en un servidor nuevo, instálalo desde su repositorio oficial:
sudo apt install debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' \
| sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' \
| sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy
Edita el Caddyfile:
sudo nano /etc/caddy/Caddyfile
tudominio.com, www.tudominio.com {
root * /var/www/tudominio.com
file_server
encode zstd gzip
}
No hace falta ninguna directiva para HTTP/3. Recarga y comprueba el puerto UDP:
sudo systemctl reload caddy
sudo ss -ulnp | grep caddy
Con los mismos puertos abiertos del paso 2, la verificación del paso 5 funciona igual.
Solución de problemas
La cabecera Alt-Svc aparece, pero el navegador sigue en h2. Casi siempre es el UDP 443 bloqueado en un firewall externo o en la red del cliente (algunas redes corporativas filtran QUIC). Prueba desde otra red y revisa el firewall del proveedor.
nginx: [emerg] duplicate listen options for 0.0.0.0:443. Has puesto reuseport en más de un bloque server. Déjalo solo en uno.
unknown directive "http3". Sigues usando el Nginx de Ubuntu 1.24. Comprueba el origen con apt policy nginx y revisa el archivo de preferencias del paso 1.
Caddy avisa de failed to sufficiently increase receive buffer size. El kernel limita el buffer UDP que necesita QUIC. Auméntalo:
printf "net.core.rmem_max=7500000\nnet.core.wmem_max=7500000\n" | sudo tee /etc/sysctl.d/60-quic.conf
sudo sysctl --system
sudo systemctl restart caddy
Conclusión
Tu servidor sirve ahora HTTP/3 sobre QUIC con respaldo automático a HTTP/2, lo que reduce la latencia de conexión en redes móviles sin afectar a los clientes antiguos. Como siguientes pasos, activa la compresión Brotli, configura cabeceras de caché largas para los estáticos y mide el TTFB antes y después con PageSpeed Insights.
