Was ist der Unterschied zwischen den Nginx-Variablen $host und $http_host?

Veröffentlicht 27. August 2024

Problem: Verständnis der Nginx-Variablen $host und $http_host

Bei der Verwendung von Nginx stoßen Sie möglicherweise auf zwei ähnlich aussehende Variablen: $host und $http_host. Diese Variablen haben unterschiedliche Verwendungszwecke und können sich je nach Situation anders verhalten. Es ist wichtig, ihre Unterschiede zu kennen, um Server korrekt einzurichten und Anfragen in Nginx richtig zu handhaben.

Was sind $host und $http_host in Nginx?

$host-Variable in Nginx

Die $host-Variable in Nginx stellt den Servernamen für die zu verarbeitende Anfrage dar. Nginx setzt den Wert von $host in folgender Reihenfolge:

  1. Der Hostname aus der Anfrage-Zeile
  2. Der Hostname aus dem "Host"-Anfrage-Header-Feld
  3. Der Servername, der zur Anfrage passt

Wenn keine dieser Quellen einen gültigen Hostnamen liefert, verwendet Nginx einen leeren String als Wert für $host.

$http_host-Variable in Nginx

Die $http_host-Variable entspricht dem "Host"-Header-Feld in der HTTP-Anfrage. Dieser Header wird vom Client (normalerweise einem Webbrowser) gesendet und enthält den Domainnamen des Servers.

Im Gegensatz zu $host durchläuft $http_host keine Verarbeitung durch Nginx. Es spiegelt den exakten Wert des "Host"-Headers wider, wie er in der HTTP-Anfrage empfangen wurde. Wenn der "Host"-Header in der Anfrage fehlt, ist $http_host ein leerer String.

Hauptunterschiede zwischen $host und $http_host

Reihenfolge der Priorität

Nginx setzt den Wert von $host in einer bestimmten Reihenfolge. Zuerst wird der Hostname in der Anfrage-Zeile geprüft. Wenn nicht verfügbar, wird das "Host"-Header-Feld betrachtet. Sind beide nicht vorhanden, wird der Servername verwendet, der zur Anfrage passt. Diese Reihenfolge hilft Nginx, verschiedene Arten von Anfragen zu handhaben.

$http_host wird verwendet, wenn der "Host"-Header in der HTTP-Anfrage vorhanden ist. Fehlt der Header, bleibt $http_host leer. Im Gegensatz zu $host hat $http_host keine Backup-Option und spiegelt direkt die Anfrage des Clients wider.

Verhalten mit Servernamen und Hostnamen

Die $host-Variable arbeitet mit der server_name-Direktive in Nginx zusammen. Wenn eine Anfrage eingeht, gleicht Nginx sie mit den server_name-Werten in seiner Konfiguration ab. Wird eine Übereinstimmung gefunden, wird dieser Wert Teil der $host-Variable. Dies ermöglicht unterschiedliche Server-Block-Konfigurationen basierend auf Domainnamen.

$http_host ist mit den Anfrage-Header-Feldern verknüpft. Es spiegelt den vom Client gesendeten "Host"-Header wider. Dies macht $http_host nützlich für die Protokollierung des exakten Hostnamens, den der Client für den Zugriff auf den Server verwendet hat, der sich vom intern von Nginx verwendeten Servernamen unterscheiden kann.

Verwendung von $host und $http_host in der Nginx-Konfiguration

$host in Nginx Server-Blöcken

Die $host-Variable ist nützlich in Nginx Server-Blöcken mit server_name-Direktiven. Hier ein Beispiel:

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

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

Diese Konfiguration verwendet $host für flexible Dokumentwurzel-Pfade. Für Anfragen an "example.com" liefert Nginx Dateien aus "/var/www/example.com". Für "www.example.com" verwendet es "/var/www/www.example.com".

Dieser Ansatz:

  • Behandelt mehrere Domains in einem Server-Block
  • Vereinfacht die Konfiguration für Websites mit ähnlichen Strukturen
  • Erleichtert das Hinzufügen neuer Domains

$http_host für Logging und Weiterleitungen

$http_host ist nützlich für Logging und Weiterleitungen. Hier ein Beispiel für die Verwendung in Zugriffs-Logs:

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;

Diese Konfiguration fügt $http_host zu Ihren Zugriffs-Logs hinzu und zeigt den Hostnamen, den Clients für den Zugriff auf Ihren Server verwenden.

Für Weiterleitungen hilft $http_host, den ursprünglichen Hostnamen beizubehalten:

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

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

Diese Einrichtung leitet "www.example.com" zu "example.com" um und behält dabei das ursprüngliche Protokoll ($scheme) und den Pfad ($request_uri) bei. Die Verwendung von $http_host behält den genauen Hostnamen aus der Anfrage des Clients bei, was für genaue Weiterleitungen wichtig ist.