HTTP header HOST always modified when externalName is used in service backend
Describe the bug I observed strange behavior when externalName type is used in the service backend, the HTTP header HOST of request is always modified to the value of externalName.
To Reproduce
in namespace NS-1: ingress -- Host: foo.com -- backend: ingressgateway
svc -- name: ingressgateway -- externalName: bar.NS-2.svc.cluster.local
When the traffic of foo.com comes, the data flow looks like below: ingress:foo.com(NS-1) -> svc:ingressgateway(NS-1) -> bar.NS-2.svc.cluster.local(NS-2)
However the request to bar.NS-2.svc.cluster.local, whose HTTP header HOST is always modified to bar.NS-2.svc.cluster.local, I actually expected the HTTP header HOST is still foo.com.
Expected behavior The HTTP header HOST in the request to externalName backend should be kept, or this behavior is configurable.
Observed behavior The HTTP header HOST in the request to externalName backend is always modified to the value of externalName.
I checked the documentation, but I can't find any configuration to control this behavior to keep the HOST value or change it to the destination.
Hello, looks like skipper always sets Host header (via setRequestHeader) equal to external name (see #1815): https://github.com/zalando/skipper/blob/f5afdbabcc4fa4b534cc3519b4cdf99410e80906/dataclients/kubernetes/ingress.go#L118-L147
I think we may consider adding a flag to disable this and let user control which host to use via preserveHost filter and -proxy-preserve-host flag.
Hi @AlexanderYastrebov ,
I can understand sometimes this behavior is wanted if the externalName is an internet website, like google.com. Of course google.com expects the HOST header in the request is also "google.com".
However if the externalName is some other ingress in the same k8s cluster, like in my case bar.NS-2.svc.cluster.local, I don't want skipper to always modify the HOST header in the request.
An annotation configuration could solve this issue.
As a workaround for now you may consider using RouteGroup CRD with a network backend instead of ExtrenalName service.
Thanks Alex for the tip, we prefer to use ingress and its annotation configs. Currently we're working on completely avoiding externalName in the setup.
Hopefully one day, this behavior can be configurable in skipper. :-D