# Configuración de Nginx con HTTP/2 y HTTP/3 (QUIC) en Múltiples Servidores Virtuales

- Link: https://binariocero.com/linux/configuracion-de-nginx-con-http-2-y-http-3-quic-en-multiples-servidores-virtuales
- Published: 2025-09-23T08:04:06+02:00
- Author: Juan José Fernández Durán

![Loading](https://binariocero.com/wp-content/plugins/page-views-count/ajax-loader-
2x.gif)

Nginx es uno de los servidores web y proxies inversos más utilizados en entornos
de producción gracias a su rendimiento y flexibilidad. Con la evolución de los protocolos
de transporte en la web, resulta imprescindible aprovechar las mejoras que ofrecen**
HTTP/2** y **HTTP/3 (QUIC)** para garantizar un mejor rendimiento, latencia reducida
y mayor seguridad en las aplicaciones modernas.

En esta guía veremos cómo configurar Nginx para habilitar **HTTP/2 y HTTP/3 simultáneamente**
en varios servidores virtuales (`server blocks`), evitando errores comunes de duplicación
de configuraciones en el puerto 443.

## 1. Contexto: HTTP/2 vs HTTP/3

### HTTP/2

 * Protocolo basado en **TCP**.
 * Mejora respecto a HTTP/1.1 gracias al **multiplexado** de peticiones sobre una
   sola conexión.
 * Compatible con la mayoría de navegadores modernos.
 * En Nginx se activa con 
   `listen 443 ssl; ``http2 on;`.

### HTTP/3

 * Protocolo basado en **QUIC**, el cual utiliza **UDP** en lugar de TCP.
 * Permite conexiones más rápidas y con menor latencia, especialmente en redes móviles.
 * Requiere **TLS 1.3**.
 * En Nginx se activa con `listen 443 quic reuseport;`.

## 2. Problema típico: `duplicate listen options`

Al intentar configurar varios servidores virtuales con líneas de `listen 443` diferentes,
Nginx puede arrojar errores como:

    ```wp-block-code
    duplicate listen options for 0.0.0.0:443
    nginx: configuration file /etc/nginx/nginx.conf test failed
    ```

Esto ocurre porque:

 * HTTP/2 (TCP) permite múltiples `listen` en el mismo puerto con distintos `server_name`.
 * HTTP/3 (UDP) es distinto: si no se usa `reuseport`, **no se pueden repetir las
   opciones de escucha** en varios bloques de servidor.

## 3. Solución: Uso de `reuseport` en HTTP/3

La clave está en la opción **`reuseport`**, que permite a varios procesos de Nginx
compartir el mismo puerto UDP 443 para manejar conexiones QUIC.

### Reglas básicas:

 1. **Todos los server blocks deben usar exactamente las mismas opciones de `listen`**
    para QUIC.
    Ejemplo: `listen 443 quic; ``listen [::]:443 quic;`
 2. Solo se puede usar reuseport en un uno de los servidores declarados ya que se sera
    ese quien gestione las conexiónes.
    Ejemplo:`listen 443 quic reuseport; ``listen[::]:
    443 quic reuseport;`
 3. Cada server block debe tener un **`server_name` único**.
 4. HTTP/2 se activa en paralelo con: 
    `http2 on;``listen 443 ssl ``listen [::]:443
    ssl; `

## 4. Ejemplo completo: 4 servidores virtuales con HTTP/2 y HTTP/3

A continuación, un ejemplo práctico de cómo configurar cuatro servidores virtuales
en Nginx con HTTP/2 y HTTP/3 habilitados en todos ellos.

### Servidor 1

    ```wp-block-code
    server {
        http2 on;
        http3 on;
        listen 443 ssl;
        listen 443 quic reuseport;
        listen [::]:443 ssl;
        listen [::]:443 quic reuseport;

        server_name ejemplo1.tld;
        root /var/www/ejemplo1;

        ssl_certificate /etc/letsencrypt/live/ejemplo1.tld/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/ejemplo1.tld/privkey.pem;
        ssl_protocols TLSv1.2 TLSv1.3;

        add_header Alt-Svc 'h3-23=":443"';
        add_header QUIC-Status $quic;
    }
    ```

### Servidor 2

    ```wp-block-code
    server {
        http2 on;
        http3 on;
        listen 443 ssl;
        listen 443 quic;
        listen [::]:443 ssl;
        listen [::]:443 quic;

        server_name ejemplo2.tld;
        root /var/www/ejemplo2;

        ssl_certificate /etc/letsencrypt/live/ejemplo2.tld/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/ejemplo2.tld/privkey.pem;
        ssl_protocols TLSv1.2 TLSv1.3;

        add_header Alt-Svc 'h3-23=":443"';
        add_header QUIC-Status $quic;
    }
    ```

### Servidor 3

    ```wp-block-code
    server {
        http2 on;
        http3 on;
        listen 443 ssl;
        listen 443 quic;
        listen [::]:443 ssl;
        listen [::]:443 quic;

        server_name ejemplo3.tld;
        root /var/www/ejemplo3;

        ssl_certificate /etc/letsencrypt/live/ejemplo3.tld/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/ejemplo3.tld/privkey.pem;
        ssl_protocols TLSv1.2 TLSv1.3;

        add_header Alt-Svc 'h3-23=":443"';
        add_header QUIC-Status $quic;
    }
    ```

### Servidor 4

    ```wp-block-code
    server {
        http2 on;
        http3 on;
        listen 443 ssl;
        listen 443 quic;
        listen [::]:443 ssl;
        listen [::]:443 quic;

        server_name ejemplo4.tld;
        root /var/www/ejemplo4;

        ssl_certificate /etc/letsencrypt/live/ejemplo4.tld/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/ejemplo4.tld/privkey.pem;
        ssl_protocols TLSv1.2 TLSv1.3;

        add_header Alt-Svc 'h3-23=":443"';
        add_header QUIC-Status $quic;
    }
    ```

## 5. Consideraciones de seguridad y compatibilidad

 * **TLS 1.3 es obligatorio**: HTTP/3 no funcionará si el certificado está limitado
   a TLS 1.2 o inferior.
 * **Certificados SSL únicos por dominio**: cada `server_name` debe tener su propio
   certificado o usar un wildcard válido.
 * **Headers opcionales**:
    - `Alt-Svc` informa al cliente de que el servidor soporta HTTP/3.
    - `QUIC-Status` permite debugging (no es crítico en producción).
 * **Compatibilidad de navegadores**:
    - Chrome, Firefox y Edge soportan HTTP/3 de forma nativa.
    - Safari lo soporta parcialmente en versiones recientes.

## 6. Validación de la configuración

Antes de aplicar cambios, siempre verificar la configuración:

    ```wp-block-code
    sudo nginx -t
    ```

Si no hay errores, reiniciar el servicio:

    ```wp-block-code
    sudo systemctl restart nginx
    ```

Para comprobar que HTTP/3 funciona:

    ```wp-block-code
    curl -I --http3 https://ejemplo1.tld
    ```

El resultado debería incluir cabeceras TLS1.3 y mostrar que la conexión se realizó
con HTTP/3.

## Conclusión

Configurar **HTTP/2 y HTTP/3 en múltiples servidores virtuales de Nginx** requiere
entender la diferencia entre TCP y UDP, así como las restricciones de duplicación
en las directivas `listen`. Gracias a la opción **`reuseport`**, es posible que 
varios `server blocks` compartan el puerto 443 para QUIC, garantizando compatibilidad
con HTTP/3 en todos los dominios alojados.

Con esta configuración, tus aplicaciones estarán preparadas para ofrecer un rendimiento
moderno y seguro, aprovechando lo último en protocolos web.
