¿Cuál es la diferencia entre las variables Nginx $host y $http_host?

Publicado 27 de agosto de 2024

Problema: Comprender las variables de Nginx $host vs $http_host

Al usar Nginx, es posible que veas dos variables que parecen similares: $host y $http_host. Estas variables tienen diferentes usos y pueden comportarse de manera distinta según la situación. Conocer cómo difieren es importante para configurar servidores y manejar solicitudes en Nginx correctamente.

¿Qué son $host y $http_host en Nginx?

Variable $host en Nginx

La variable $host en Nginx representa el nombre del servidor para la solicitud que se está procesando. Nginx establece el valor de $host usando este orden:

  1. El nombre de host de la línea de solicitud
  2. El nombre de host del campo de encabezado "Host" de la solicitud
  3. El nombre del servidor que coincide con la solicitud

Si ninguna de estas fuentes proporciona un nombre de host válido, Nginx usa una cadena vacía como valor para $host.

Variable $http_host en Nginx

La variable $http_host coincide con el campo de encabezado "Host" en la solicitud HTTP. Este encabezado es enviado por el cliente (generalmente un navegador web) y contiene el nombre de dominio del servidor.

A diferencia de $host, $http_host no pasa por el procesamiento de Nginx. Refleja el valor exacto del encabezado "Host" tal como se recibió en la solicitud HTTP. Si el encabezado "Host" está ausente en la solicitud, $http_host será una cadena vacía.

Diferencias clave entre $host y $http_host

Orden de precedencia

Nginx establece el valor de $host en un orden específico. Primero verifica el nombre de host en la línea de solicitud. Si no está disponible, mira el campo de encabezado "Host". Si ambos están ausentes, usa el nombre del servidor que coincide con la solicitud. Este orden ayuda a Nginx a manejar diferentes tipos de solicitudes.

$http_host se usa cuando el encabezado "Host" está en la solicitud HTTP. Si falta el encabezado, $http_host permanece vacío. A diferencia de $host, $http_host no tiene una opción de respaldo y refleja directamente la solicitud del cliente.

Comportamiento con nombres de servidor y nombres de host

La variable $host funciona con la directiva server_name en Nginx. Cuando llega una solicitud, Nginx la compara con los valores de server_name en su configuración. Si encuentra una coincidencia, ese valor se convierte en parte de la variable $host. Esto permite diferentes configuraciones de bloques de servidor basadas en nombres de dominio.

$http_host está vinculado a los campos de encabezado de la solicitud. Refleja el encabezado "Host" enviado por el cliente. Esto hace que $http_host sea útil para registrar el nombre de host exacto que el cliente usó para acceder al servidor, que puede ser diferente del nombre de servidor que Nginx usa internamente.

Uso de $host y $http_host en la configuración de Nginx

$host en bloques de servidor de Nginx

La variable $host es útil en bloques de servidor de Nginx con directivas server_name. Aquí hay un ejemplo:

server {
    listen 80;
    server_name example.com www.example.com;

    location / {
        root /var/www/$host;
    }
}

Esta configuración usa $host para rutas de raíz de documentos flexibles. Para solicitudes a "example.com", Nginx sirve archivos desde "/var/www/example.com". Para "www.example.com", usa "/var/www/www.example.com".

Este enfoque:

  • Maneja múltiples dominios en un solo bloque de servidor
  • Simplifica la configuración para sitios con estructuras similares
  • Facilita la adición de nuevos dominios

$http_host para registro y redirecciones

$http_host es útil para registro y redirecciones. Así es cómo usarlo en logs de acceso:

log_format custom '$remote_addr - $remote_user [$time_local] '
                  '"$request" $status $body_bytes_sent '
                  '"$http_referer" "$http_user_agent" "$http_host"';

access_log /var/log/nginx/access.log custom;

Esta configuración agrega $http_host a tus logs de acceso, mostrando el nombre de host que los clientes usan para acceder a tu servidor.

Para redirecciones, $http_host ayuda a mantener el nombre de host original:

server {
    listen 80;
    server_name example.com www.example.com;

    if ($http_host = "www.example.com") {
        return 301 $scheme://example.com$request_uri;
    }
}

Esta configuración redirige "www.example.com" a "example.com", manteniendo el protocolo original ($scheme) y la ruta ($request_uri). Usar $http_host mantiene el nombre de host exacto de la solicitud del cliente, lo cual es importante para redirecciones precisas.