NGINX hinter einem Reverse-Proxy führt zu falschem Port und Domain

Manchmal muss man NGINX hinter einen Reverse-Proxy legen, statt davor. Durch eine vereinfachte Konfiguration kann es passieren, das ungewollte und ungültige Umleitungen auf das falsche Protokoll, Domain oder Port entstehen.

Gehen wir von dem folgenden Setup aus:

example.com:443 (traefik) > localhost:8080 (nginx) 

Das Fehlverhalten lässt sich mit einem einfachen Test provozieren: Man legt einen Ordner mit einer index.html an, z. B. test/index.html.

Rufen wir nun https://example.com/test auf, bekommen wir einen 301 Moved Permanently-Status mit dem folgenden Header:

curl -s -D - https://example.com/test -o /dev/null
# HTTP/2 301
# Location: http://localhost:8080/test/

In dieser Header-Anweisung stimmen weder Hostname noch der Port. Zudem ist es ein 301-HTTP-Status der uns SEO-technisch richtig hart einen Nackenschlag verpasst, sollte die Suchmaschine das mitbekommen. Das Ziel ist für diese weder valide, erreichbar noch indizierbar.

Hier gibt es zwei Ansätze wie dieses Problem gelöst werden kann:

Die erste Variante nutzt die port_in_redirect -Direktive. Sie kann sehr allgemein im http, server und location-Kontext verwendet werden und löst zumindest die falsche Port-Angabe.

server {
    port_in_redirect off;
}

In einigen Fällen reicht dieser Ansatz schon aus. Doch meist geht der Location-Header weiterhin auf die falsche Domain, nämlich localhost statt example.com.

curl -s -D - https://example.com/test -o /dev/null
# HTTP/2 302
# Location: location: https://localhost/test/

Um diesen Umstand unter Kontrolle zu bekommen, verwenden wir die absolute_redirect -Direktive, welche ebenfalls im http, server und location-Kontext verwendet werden kann.

server {
    absolute_redirect off;
}

Diese Direktive hat eine höhere Priorität als port_in_redirect und macht diese überflüssig. Sie sorgt am Ende nur noch für relative Umleitungen, die keinerlei Host-Informationen mehr beinhaltet:

curl -s -D - https://example.com/test -o /dev/null
# HTTP/2 302
# Location: location: /test/

Das löst die meisten Schmerzen dann auch schon in Wohlgefallen auf.

Für SEO sollte aber darauf geachtet werden, das die eigenen Links aber die korrekten Verweise auf /test/ und nicht /test verwenden, da wir hier nur einen 302-HTTP-Status nutzen können.