skipper icon indicating copy to clipboard operation
skipper copied to clipboard

HTTP header HOST always modified when externalName is used in service backend

Open pshen opened this issue 1 year ago • 4 comments

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.

pshen avatar Dec 12 '24 16:12 pshen

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.

AlexanderYastrebov avatar Dec 12 '24 18:12 AlexanderYastrebov

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.

pshen avatar Dec 13 '24 07:12 pshen

As a workaround for now you may consider using RouteGroup CRD with a network backend instead of ExtrenalName service.

AlexanderYastrebov avatar Dec 13 '24 10:12 AlexanderYastrebov

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

pshen avatar Dec 13 '24 11:12 pshen