Doppelter Hostname in Header bei Kubernetes Ingress Backend – Connections Component Pack: Bad Request

Doppelter Hostname in Header bei Kubernetes Ingress Backend – Connections Component Pack: Bad Request

Für eine Connections 6.5 Testinstallation wurde der IBM HTTP Server hinter einem Standard Kubernetes Ingress betrieben. Bis zur Installation des Component Pack funktionierte dies: Auf der OrientMe-Seite waren keine Inhalte zu sehen, sondern die o.g. Fehlermeldung. Mehrere Ajax-Anfragen endeten mit einem 500er internen Serverfehler. In der Fehlerlog vom IHS sind folgende Einträge zu sehen:

[Fri Mar 06 09:30:27 2020] [debug] vhost.c(791): [client 1.2.3.4:54252] [strict] Invalid host name 'cnx65.k8s.internal cnx65.k8s.internal', problem near: , cnx6
[Fri Mar 06 09:30:27 2020] [debug] vhost.c(886): [client 1.2.3.4:54252] Client sent malformed Host header: cnx65.k8s.internal cnx65.k8s.internal
[Fri Mar 06 09:30:27 2020] [debug] protocol.c(1412): [client 1.2.3.4:54252] client sent HTTP/1.1 request without hostname (see RFC2616 section 14.23): /search/atom/mysearch

Das Problem wurde durch eine Verkettung verschiedener Umstände verursacht: Anfragen des Component-Pack erhalten einen X-Forwarded-Host Header. Er ist dafür gedacht, um den anfragenden Host hinter einem Reverse Proxy zu übermitteln. In der aktuellen Version 6.5.0.0 des Component Pack ist dieser fehlerhaft und enthält den Connections Hostname doppelt mit Komma getrennt – beispielsweise

x-forwarded-host: cnx65.k8s.internal, cnx65.k8s.internal

Dies ist zwar fehlerhaft, aber nicht zwingend ein Problem. Das wird es erst durch das Standardverhalten vom Kubernetes Ingress: Dieser setzt den X-Forwarded-Host Header automatisch als Host-Header. Der Host Header ist jedoch nicht optional sondern essenziell, da er z.B. zur Zuordnung von virtuellen Hosts genutzt wird. Durch dieses Verhalten erhält der IHS hinter dem Ingress folgende Anfrage:

GET /xyz
Host: cnx65.k8s.internal, cnx65.k8s.internal
...

Somit entsteht die obige Fehlermeldung über den ungültigen Host-Header. Der IHS bricht die Abfrage darauf hin mit einem 500 Fehlercode ab.

Lösung: Host auf den Eintrag im Host-Header setzen

Die Lösung ist im Grunde recht simpel: Der Ingress-Reverseproxy vor dem IHS muss angepasst werden, sodass er den Hostname in den Host-Header schreibt – anstelle des X-Forwarded-Host Headers. Hierzu ediert man den entsprechenden Ingress – hier external-service:

kubectl edit ing external-service

Unterhalb von metadata.annotations muss folgendes Snippet eingefügt werden:

metadata:
  annotations:
    nginx.ingress.kubernetes.io/configuration-snippet: |
      more_clear_input_headers "Host" "X-Forwarded-Host";
      proxy_set_header Host $http_host;
      proxy_set_header X-Forwarded-Host $http_x_forwarded_host;

Damit wird sichergestellt, dass der Host-Header auf den tatsächlichen Host gesetzt ist. Ferner übermitteln wir den X-Forwarded-Host Header in seiner ursprünglichen Form. Letzteres ist nicht zwingend notwendig, aber schadet auch nicht. Möglicherweise wird der Header zukünftig verwendet.

Nach dem Speichern (in vim mit [ESC] den Ediermodus verlassen, dann :wq) die Seite neu laden – und OrientMe zeigt Inhalte statt Fehler:

Leave a Reply