Volver al Blog
José Manuel Requena Plens

Dominando QUIC y HTTP/3 con Nginx: La Guía Completa

Inmersión profunda en QUIC y HTTP/3 — arquitectura técnica, seguridad y configuración paso a paso de Nginx para despliegue en producción.

Imagen de portada de Dominando QUIC y HTTP/3 con Nginx: La Guía Completa

La web ha dependido de TCP durante más de cuatro décadas. Pero las aplicaciones modernas —con sus exigencias de interactividad en tiempo real, conectividad móvil y cargas de página instantáneas— han expuesto las limitaciones fundamentales de TCP. Llegan QUIC y HTTP/3: una reinvención completa del transporte web que abandona TCP en favor de UDP para ofrecer un internet más rápido, seguro y resiliente.

En esta guía completa, exploraremos la historia y la arquitectura de QUIC, entenderemos por qué resuelve problemas que TCP no puede, y recorreremos una configuración completa de Nginx lista para producción.


Breve historia: de Google al estándar IETF

El protocolo QUIC tiene una evolución interesante desde un experimento propietario de Google hasta un estándar IETF completo.

Cronología de QUIC
AñoHitoImportancia
2012Google comienza el desarrollo de QUICProyecto interno para reducir la latencia web
2013Primer tráfico QUIC en ChromePrimeros experimentos con servicios de Google
2014Despliegue a gran escala de gQUICChrome de escritorio usa QUIC para las propiedades de Google
2016Se forma el Grupo de Trabajo QUIC del IETFComienza el proceso de estandarización formal
2017IETF QUIC diverge de gQUICIntegración de TLS 1.3, transporte de propósito general
2021Se publica el RFC 9000Protocolo de transporte QUIC estandarizado
2022Se publica el RFC 9114HTTP/3 estandarizado

La familia de RFCs de QUIC

La especificación completa de QUIC abarca múltiples RFCs:

Documentos estándar de QUIC
RFCTítuloDescripción
RFC 9000QUIC TransportProtocolo base: paquetes, frames, streams, gestión de conexiones
RFC 9001Using TLS to Secure QUICIntegración de TLS 1.3, derivación de claves, niveles de cifrado
RFC 9002Loss Detection and Congestion ControlRecuperación de paquetes perdidos, estimación de RTT, algoritmos de congestión
RFC 8999Version-Independent PropertiesComportamientos comunes a todas las versiones de QUIC
RFC 9114HTTP/3Semántica HTTP sobre QUIC

¿Por qué QUIC? Entendiendo las limitaciones de TCP

Para apreciar QUIC, debemos entender por qué TCP —la columna vertebral de internet desde 1974— tiene dificultades con las demandas modernas de la web.

El problema del head-of-line (HOL) blocking

Este es el problema fundamental que QUIC resuelve. Imagina una autopista con un solo carril (conexión TCP). Si un coche se avería (pérdida de paquete), todos los que van detrás deben parar y esperar, aunque vayan a destinos diferentes.

ClienteRedServidorClienteRedServidor**HTTP/2 sobre TCP: HOL Blocking**TODOS los streams bloqueadosesperando retransmisión**HTTP/3 sobre QUIC: Streams Independientes**Solo Stream A espera¡B y C continúan!Stream A: Paquete 1Stream B: Paquete 1Stream A: Paquete 2 (PERDIDO)Stream C: Paquete 1Stream A: Paquete 1Stream B: Paquete 1 (¡BLOQUEADO!)(Esperando Stream A: Paquete 2...)Stream A: Paquete 1Stream B: Paquete 1Stream A: Paquete 2 (PERDIDO)Stream C: Paquete 1Stream A: Paquete 1Stream B: Paquete 1 (¡Entregado!)Stream C: Paquete 1 (¡Entregado!)
Head-of-Line Blocking: TCP vs QUIC

El problema de la latencia del handshake

Establecer una conexión TCP segura requiere múltiples viajes de ida y vuelta:

Comparativa de establecimiento de conexión
ProtocoloConexión nuevaConexión reanudadaRTTs totales
TCP + TLS 1.2TCP handshake + TLS handshakeTCP + TLS abreviado3 RTT → 2 RTT
TCP + TLS 1.3TCP handshake + TLS 1.3TCP + TLS 0-RTT2 RTT → 1 RTT
QUICHandshake combinado0-RTT early data1 RTT → 0 RTT

El problema de la migración de conexión

Las conexiones TCP se identifican por una 4-tupla: (IP origen, puerto origen, IP destino, puerto destino). Cuando cambias de Wi-Fi a datos móviles, tu IP cambia — y tu conexión TCP se rompe.


Arquitectura de QUIC en profundidad

Transporte sobre UDP

QUIC se construye sobre UDP en lugar de crear un nuevo protocolo IP. Fue una elección pragmática:

  • No requiere cambios en el kernel: UDP tiene soporte universal
  • Implementación en espacio de usuario: Iteración y despliegue más rápidos
  • Traversal de middleboxes: UDP atraviesa la mayoría de NATs y firewalls

Estructura de paquetes

QUIC utiliza dos tipos de paquetes:

Tipos de paquetes QUIC
TipoCabeceraUsoCifrado
Long HeaderInformación completa de conexiónInitial, Handshake, 0-RTT, RetryClaves específicas por nivel
Short HeaderMínima (post-handshake)Datos de aplicación (1-RTT)Claves de aplicación

Streams y control de flujo

Los streams QUIC son canales ligeros y multiplexados dentro de una conexión:

No

0 (Par)

1 (Impar)

0 (Bidi)

1 (Uni)

0 (Bidi)

1 (Uni)

No

Frame de Stream entrante

¿Límite MAX_DATA de conexión OK?

Conexión bloqueada

Decodificar Stream ID

¿Último bit: Iniciador?

Iniciado por cliente

Iniciado por servidor

¿Penúltimo bit: Dirección?

¿Penúltimo bit: Dirección?

Tipo 0x0: Cliente Bidi

Tipo 0x2: Cliente Uni

Tipo 0x1: Servidor Bidi

Tipo 0x3: Servidor Uni

¿Límite MAX_STREAM_DATA OK?

Stream bloqueado

Buffer de recepción

Lógica de procesamiento de streams QUIC

Decodificación del Stream ID: El Stream ID es un entero de 62 bits donde los 2 bits menos significativos funcionan como cabecera de tipo:

  • Bit 0 (Iniciador): 0 = Cliente, 1 = Servidor
  • Bit 1 (Dirección): 0 = Bidireccional, 1 = Unidireccional

Esto crea 4 espacios de direcciones distintos:

  • …00: Petición/Respuesta del cliente
  • …01: Server Push (obsoleto)
  • …10: Stream de control del cliente
  • …11: Stream de control del servidor (QPACK)

Control de flujo de doble capa: Para que un paquete sea procesado, debe pasar dos comprobaciones independientes:

  1. Nivel de conexión: ¿Hay crédito MAX_DATA para toda la conexión?
  2. Nivel de stream: ¿Hay crédito MAX_STREAM_DATA para este stream específico? Si cualquiera se agota, la transmisión se bloquea hasta que llegue un frame WINDOW_UPDATE.

El handshake de QUIC: velocidad y seguridad

QUIC combina los handshakes de transporte y criptográficos en un único intercambio, reduciendo drásticamente la latencia.

Handshake 1-RTT (primera conexión)

ServidorClienteServidorCliente**Handshake 1-RTT de QUIC**Contiene SCID, DCID, versiónEl servidor envía las claves de datos de aplicación¡Puede enviar petición HTTP inmediatamente!Total: 1 viaje de ida y vuelta hasta los primeros datosPaquete InitialClientHello + Parámetros de transporte QUICPaquetes Initial + HandshakeServerHello + Cert + FinishedHandshake completo + Primera peticiónDatos de respuesta
Handshake 1-RTT de QUIC

Handshake 0-RTT (conexión reanudada)

Para clientes que se han conectado previamente, QUIC permite enviar datos cifrados en el primer paquete:

ServidorClienteServidorCliente**QUIC 0-RTT (Conexión reanudada)**¡Datos enviados antes de completar el handshake!Total: 0 viajes de ida y vuelta para enviar la peticiónPaquetes Initial + 0-RTTClientHello + Early Data (HTTP GET)Initial + Handshake + 1-RTTServerHello + Cert + Datos de respuesta
Reanudación 0-RTT de QUIC

Arquitectura de seguridad

La seguridad de QUIC no es opcional —está integrada en el protocolo desde su diseño.

Cuatro niveles de cifrado

Niveles de cifrado de QUIC
NivelClaves derivadas deUsoForward Secrecy
InitialDestination Connection IDPrimeros paquetes, negociación de versiónNo
0-RTTClave precompartida (PSK)Datos de aplicación tempranosNo
HandshakeSecretos del handshake TLSCompletar el handshakeParcial
Application (1-RTT)Secretos de tráfico TLSTodos los datos post-handshakeCompleto (ECDHE)

Protección de paquetes

Cada paquete QUIC (excepto Initial) está protegido con cifrado AEAD:

Estructura y protección de paquetes QUIC
Sección del paqueteComponenteNivel de protección
CabeceraFlagsProtegido (Header Protection)
Connection IDTexto claro (para enrutamiento)
Número de paqueteCifrado (Header Protection)
Carga útilDatos de aplicaciónTotalmente cifrado (AEAD)
PieEtiqueta de autenticaciónMAC de integridad de 16 bytes

Connection ID y privacidad

Mecanismos de protección contra DoS

QUIC incluye varias medidas anti-amplificación y anti-suplantación:

  1. Validación de dirección: Los servidores envían paquetes RETRY para validar las direcciones de los clientes
  2. Anti-amplificación: Los servidores limitan los datos enviados antes de la validación de dirección (3x los datos del cliente)
  3. Stateless Reset: Terminación limpia de conexión sin estado

HTTP/3: HTTP sobre QUIC

HTTP/3 es el mapeo de la semántica HTTP sobre el transporte QUIC. Reemplaza el framing binario de HTTP/2 con streams QUIC.

HTTP/2 vs HTTP/3
CaracterísticaHTTP/2HTTP/3
TransporteTCP + TLSQUIC (UDP + TLS 1.3)
MultiplexingFrames de stream en una única conexiónStreams nativos de QUIC
HOL BlockingSí (en la capa TCP)No (streams independientes)
Compresión de cabecerasHPACKQPACK (maneja el desorden)
Server PushSoportadoObsoleto (poco usado)
Migración de conexiónNo

Adopción actual

A fecha de 2026, la adopción de HTTP/3 es significativa y creciente:

Estadísticas de adopción de HTTP/3
MétricaValorFuente
Sitios web usando HTTP/336,6%W3Techs (2026)
Uso de QUIC en Chrome (subsiguiente)40%APNIC Labs
Mejora en carga de página (global)12,4%Cloudflare Benchmarks
Mejora en regiones de alta latencia13,8%DebugBear

Configuración de Nginx: guía completa

Ahora vamos a implementar HTTP/3 en Nginx. Esta sección cubre todo, desde los prerrequisitos hasta el despliegue en producción.

Prerrequisitos

Verifica tu instalación de Nginx:

nginx -V 2>&1 | grep -E 'version|http_v3_module|OpenSSL|BoringSSL'

nginx version: nginx/1.28.0 built with OpenSSL 3.5.0 8 Apr 2025 (running with OpenSSL 3.5.4 30 Sep 2025) configure arguments: … —with-http_v3_module …

Cómo instalar Nginx con soporte HTTP/3

Este repositorio (ampliamente usado para PHP y Nginx) proporciona las últimas versiones mainline con soporte HTTP/3 y muchos módulos adicionales para Debian y Ubuntu.

# Para Debian:
sudo apt install curl gpg
curl -fsSL https://packages.sury.org/nginx/README.txt | sudo bash -x

# Para Ubuntu:
sudo add-apt-repository ppa:ondrej/nginx-mainline
sudo apt update

# Instalar Nginx:
sudo apt install nginx
# Add official Nginx mainline repository
sudo apt install curl gnupg2 ca-certificates lsb-release

# Create keyring directory if it doesn't exist
sudo mkdir -p /etc/apt/keyrings

# Download and add the Nginx signing key (modern approach)
curl -fsSL https://nginx.org/keys/nginx_signing.key \
    | sudo gpg --dearmor -o /etc/apt/keyrings/nginx.gpg

# Add repository with signed-by keyring
echo "deb [signed-by=/etc/apt/keyrings/nginx.gpg] http://nginx.org/packages/mainline/ubuntu $(lsb_release -cs) nginx" \
    | sudo tee /etc/apt/sources.list.d/nginx.list

sudo apt update
sudo apt install nginx
# Download Nginx and QuicTLS
wget https://nginx.org/download/nginx-1.25.3.tar.gz
git clone --depth 1 https://github.com/quictls/openssl quictls

# Build QuicTLS
cd quictls
./Configure --prefix=$PWD/build linux-x86_64
make -j$(nproc)
make install_sw
cd ..

# Configure and build Nginx
tar xzf nginx-1.25.3.tar.gz
cd nginx-1.25.3
./configure \
    --with-http_v3_module \
    --with-http_ssl_module \
    --with-http_v2_module \
    --with-cc-opt="-I../quictls/build/include" \
    --with-ld-opt="-L../quictls/build/lib"

make -j$(nproc)
sudo make install

Configuración básica

Esta es la configuración mínima para habilitar HTTP/3:

/​etc/​nginx/​sites-available/​example.com.conf
server {
    server_name example.com;
    root /var/www/example.com;

    # ==========================================
    # LISTENERS: TCP (HTTP/1.1, HTTP/2) + UDP (HTTP/3)
    # ==========================================
    
    # Standard HTTPS over TCP
    listen 443 ssl;
    listen [::]:443 ssl;
    http2 on;
    
    # QUIC/HTTP/3 over UDP
    # 'reuseport' is critical for multi-worker performance
    listen 443 quic reuseport;
    listen [::]:443 quic reuseport;

    # ==========================================
    # SSL/TLS CONFIGURATION
    # ==========================================
    
    # TLS 1.3 is REQUIRED for QUIC
    ssl_protocols TLSv1.3 TLSv1.2;
    ssl_prefer_server_ciphers off;
    
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    # ==========================================
    # HTTP/3 CONFIGURATION
    # ==========================================
    
    http3 on;
    
    # Advertise HTTP/3 support to browsers
    # ma=86400 means "cache this info for 24 hours"
    add_header Alt-Svc 'h3=":443"; ma=86400' always;

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

Configuración completa de producción

Aquí tienes una configuración exhaustiva con todas las optimizaciones. La configuración se divide en dos archivos: el nginx.conf principal para ajustes globales y un archivo de configuración específico del sitio.

/​etc/​nginx/​nginx.conf
# Main context
worker_processes auto;
error_log /var/log/nginx/error.log warn;

events {
    worker_connections 4096;
    use epoll;
    multi_accept on;
}

http {
    # ==========================================
    # HTTP/3 GLOBAL SETTINGS
    # ==========================================
    # Explicit for clarity (http3 defaults to 'on' in nginx 1.25.0+)
    http3 on;
    
    # Custom log format to track HTTP/3 connections
    log_format quic '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent" '
                    'proto="$server_protocol" quic="$http3"';

    # MIME types
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    # Performance optimizations
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    
    # Gzip compression
    gzip on;
    gzip_vary on;
    gzip_min_length 1024;
    gzip_types text/plain text/css application/json application/javascript 
               text/xml application/xml application/xml+rss text/javascript;

    # Include site configurations
    include /etc/nginx/sites-enabled/*;
}

La configuración específica del sitio incluye todas las directivas para QUIC, TLS, cabeceras y logging:

/​etc/​nginx/​sites-available/​example.com.conf
server {
    server_name example.com www.example.com;
    root /var/www/example.com;

    # ==========================================
    # DUAL-STACK LISTENERS
    # ==========================================
    
    # TCP: HTTP/1.1 and HTTP/2 fallback
    listen 443 ssl;
    listen [::]:443 ssl;
    http2 on;
    
    # UDP: QUIC/HTTP/3
    listen 443 quic reuseport;
    listen [::]:443 quic reuseport;

    # ==========================================
    # TLS CONFIGURATION (Required for QUIC)
    # ==========================================
    
    ssl_protocols TLSv1.3 TLSv1.2;
    # TLS 1.3 ciphersuites (handled separately for better OpenSSL compatibility)
    ssl_conf_command Ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256;
    # TLS 1.2 ciphers only (ECDHE for forward secrecy)
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
    ssl_prefer_server_ciphers off;
    ssl_ecdh_curve X25519:P-256:P-384;
    
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    
    # Session resumption for performance
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 1d;
    ssl_session_tickets off;  # Better security
    
    # OCSP Stapling
    ssl_stapling on;
    ssl_stapling_verify on;

    # ==========================================
    # QUIC-SPECIFIC SETTINGS
    # ==========================================
    
    # Enable 0-RTT early data (with security considerations)
    ssl_early_data on;
    
    # DoS protection: require address validation
    quic_retry on;
    
    # Performance: Generic Segmentation Offload (Linux 4.18+)
    quic_gso on;

    # ==========================================
    # HEADERS
    # ==========================================
    
    # Advertise HTTP/3 availability
    add_header Alt-Svc 'h3=":443"; ma=86400' always;
    
    # Warn backends about 0-RTT replay risk
    add_header Early-Data $ssl_early_data always;
    
    # Security headers
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-Frame-Options "DENY" always;

    # ==========================================
    # LOGGING
    # ==========================================
    
    access_log /var/log/nginx/example.com.access.log quic;
    error_log /var/log/nginx/example.com.error.log;

    # ==========================================
    # LOCATIONS
    # ==========================================
    
    location / {
        try_files $uri $uri/ =404;
    }
    
    # Static assets with long cache
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ {
        expires 1y;
        add_header Cache-Control "public, immutable" always;
        add_header Alt-Svc 'h3=":443"; ma=86400' always;
        
        # Security headers (inherited from server block may not apply with add_header in location)
        add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
        add_header X-Content-Type-Options "nosniff" always;
        add_header X-Frame-Options "DENY" always;
    }
}

# HTTP to HTTPS redirect
server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;
    return 301 https://$host$request_uri;
}

Referencia de todas las directivas QUIC

Directivas QUIC de Nginx
DirectivaPor defectoContextoDescripción
http3onhttp, serverHabilita la negociación del protocolo HTTP/3
http3_hqoffhttp, serverHabilita HTTP/0.9 sobre QUIC (solo para pruebas)
http3_max_concurrent_streams128http, serverMáximo de streams concurrentes por conexión
http3_stream_buffer_size64khttp, serverTamaño del buffer para lectura/escritura de streams
quic_active_connection_id_limit2http, serverMáximo de Connection IDs almacenados por conexión
quic_bpfoffmainEnrutamiento eBPF para migración de conexión (Linux 5.7+)
quic_gsooffhttp, serverGeneric Segmentation Offload (Linux 4.18+)
quic_host_key-http, serverArchivo con clave secreta para tokens de validación de dirección
quic_retryoffhttp, serverHabilita la validación de dirección mediante paquetes Retry

Configuración del firewall

Crítico: HTTP/3 usa UDP en el puerto 443, no TCP. Si tu firewall solo permite TCP/443, QUIC fallará silenciosamente y los clientes retrocedarán a HTTP/2.

# Check current rules
sudo ufw status

# Allow UDP on port 443
sudo ufw allow 443/udp comment 'QUIC/HTTP3'

# Verify
sudo ufw status verbose
# Allow incoming UDP 443
sudo iptables -A INPUT -p udp --dport 443 -j ACCEPT

# Save rules (Debian/Ubuntu)
sudo iptables-save | sudo tee /etc/iptables/rules.v4

# For IPv6
sudo ip6tables -A INPUT -p udp --dport 443 -j ACCEPT
sudo ip6tables-save | sudo tee /etc/iptables/rules.v6
# Add UDP 443 to default zone
sudo firewall-cmd --permanent --add-port=443/udp

# Reload
sudo firewall-cmd --reload

# Verify
sudo firewall-cmd --list-ports

Añade una regla de entrada:

  • Tipo: Custom UDP
  • Rango de puertos: 443
  • Origen: 0.0.0.0/0 (o tu CIDR)
  • Descripción: QUIC/HTTP3

Ajuste del kernel para alto tráfico

Para servidores con alto tráfico, aumenta los tamaños de buffer UDP:

/​etc/​sysctl.d/​99-quic.conf
# Increase UDP buffer sizes for QUIC
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.rmem_default = 1048576
net.core.wmem_default = 1048576

# UDP memory limits
net.ipv4.udp_mem = 65536 131072 262144
net.ipv4.udp_rmem_min = 8192
net.ipv4.udp_wmem_min = 8192

# Allow more local ports for connections
net.ipv4.ip_local_port_range = 1024 65535

Aplica los ajustes:

sudo sysctl --system

Verificación y pruebas

Tras la configuración, verifica que HTTP/3 funciona correctamente.

Método 1: curl

Las versiones modernas de curl (7.66+ con soporte HTTP/3) permiten probar directamente:

# Test HTTP/3 specifically curl -I --http3-only https://jmrp.io # Or allow fallback curl -I --http3 https://jmrp.io

HTTP/3 200 server: jmrp.io date: Wed, 14 Jan 2026 20:02:32 GMT content-type: text/html; charset=utf-8 alt-svc: h3=“:443”; ma=86400 strict-transport-security: max-age=63072000; includeSubDomains; preload

Método 2: DevTools del navegador

  1. Abre Chrome o Firefox
  2. Navega a tu sitio
  3. Abre DevTools (F12) → pestaña Red (Network)
  4. Haz clic derecho en las cabeceras de columna → Activa la columna Protocolo
  5. Recarga la página
  6. Busca h3 en la columna Protocolo

Método 3: herramientas online

Herramientas de prueba HTTP/3
HerramientaURLCaracterísticas
HTTP/3 Checkhttp3check.netTest rápido de aprobado/suspenso con detalles
Cloudflare HTTP/3 Testcloudflare-quic.comPrueba de conexión en vivo
Qualys SSL Labsssllabs.comAnálisis exhaustivo de TLS

Método 4: comprobar los logs de Nginx

Usa el formato de log personalizado para verificar el tráfico HTTP/3:

# Check for HTTP/3 connections grep 'quic="h3"' /var/log/nginx/access.log | tail -5

192.168.1.100 - - [14/Jan/2026:20:02:32 +0000] “GET / HTTP/3” 200 15234 ”-” “Mozilla/5.0…” proto=“HTTP/3” quic=“h3”


Guía de resolución de problemas

Problemas comunes de HTTP/3 y soluciones
SíntomaCausa probableSolución
El protocolo se queda en HTTP/2Firewall bloqueando UDP/443Abre el puerto UDP 443 en el servidor y en el proveedor cloud
El protocolo se queda en HTTP/2Falta la cabecera Alt-SvcAñade add_header Alt-Svc ‘h3=“:443”; ma=86400’ always;
Errores de conexiónTLS 1.3 no habilitadoHabilita TLSv1.3 para QUIC (obligatorio); TLSv1.2 puede seguir habilitado como fallback para HTTP/2
Los navegadores se niegan a usar QUICCertificado autofirmadoUsa un certificado válido (Let’s Encrypt)
Nginx no arrancaFalta —with-http_v3_moduleRecompila Nginx con el módulo HTTP/3
Uso alto de CPUGSO no soportado por el kernelDesactiva quic_gso o actualiza el kernel
0-RTT no funcionaVersión de OpenSSL demasiado antiguaUsa OpenSSL 3.5.1+, QuicTLS o BoringSSL

Modo depuración

Activa el logging de depuración temporalmente:

NGINX
error_log /var/log/nginx/error.log debug;

Comprueba los mensajes específicos de QUIC:

grep -i quic /var/log/nginx/error.log | tail -20

2026/01/14 10:42:15 [debug] 12345#0: *1 quic handle packet: fd:16, addr:192.0.2.1:54321 2026/01/14 10:42:15 [debug] 12345#0: *1 quic packet rx dcid len:8 87654321 2026/01/14 10:42:15 [debug] 12345#0: *1 quic packet rx scid len:8 12345678 2026/01/14 10:42:15 [info] 12345#0: *1 quic SSL_do_handshake() failed: SSL_ERROR_SSL: error:14094416:SSL routines:ssl3_read_bytes:sslv3 alert certificate unknown 2026/01/14 10:42:15 [debug] 12345#0: *1 quic close connection: 0:


Lista de verificación para producción

Antes de desplegar HTTP/3 en producción, verifica:

Lista de verificación para HTTP/3 en producción
CategoríaElementoVerificación
BuildNginx compilado con —with-http_v3_modulenginx -V 2>&1 | grep http_v3
BuildBiblioteca SSL compatible (QuicTLS/BoringSSL/OpenSSL 3.5.1+)nginx -V 2>&1 | grep -i ssl
RedUDP/443 abierto en el firewall del servidorsudo ss -ulnp | grep 443
RedUDP/443 abierto en el proveedor cloud (AWS/GCP/Azure)Comprueba las reglas del security group/firewall
Configlisten 443 quic reuseport; presentenginx -T | grep quic
ConfigTLS 1.3 habilitadonginx -T | grep ssl_protocols
ConfigCabecera Alt-Svc configuradacurl -I https://site | grep alt-svc
CertificadoCertificado válido (no autofirmado)openssl s_client -connect site:443
PruebaHTTP/3 confirmado y funcionandocurl —http3 https://site
MonitorizaciónFormato de log incluye $http3Comprueba la configuración del formato de log

Cuándo NO usar QUIC

Aunque QUIC ofrece beneficios significativos, hay escenarios donde TCP puede ser preferible: