How to make Google Cloud Load Balancer respect the received X-Forwarded-Proto?

My app structure uses GKE and CloudFlare. It looks like this:

CloudFlare -> GKE -> Ingress -> My app running nginx

I'm using the flexible SSL in CloudFlare, so only the connection between the user and CloudFlare uses HTTPS, all the remaining uses HTTP. I know CloudFlare sets the X-Forwarded-Proto to https in this situation, but when I see the headers my nginx app is receiving, it gets X-Forwarded-Proto: http.

I'm pretty sure this happens somewhere between GKE's Load Balancer and Ingress, as I can see that the CF-Visitor: {"scheme": "https"} header configured by CloudFlare is set to HTTPS. My understanding is that this means that CloudFlare did set X-Forwarded-Proto to https, but it got overwritten along the way.

Unfortunately, I couldn't get the header logs from the GKE Load Balancer (it seems they don't log the X-Forwarded-* headers at all), so I can't confirm 100% that CloudFlare is actually setting the headers, but I'd be pretty surprised if it isn't.

If that's true, Google Cloud is overwriting the X-Forwarded-Proto header with http. How can I avoid it doing so?

Edit: I have configured an nginx ingress instead of gce following https://cloud.google.com/community/tutorials/nginx-ingress-gke, and the X-Forwarded-Proto is set to https as expected. This is another signal that it's the gce ingress controller that is overwriting the X-Forwarded-Proto header.


Solution 1:

As described in this article Cloudflare appends an X-Forwarded-Proto header which can either be HTTP or HTTPS depending on the protocol the user used to visit the site. If you believe the value of X-Forwarded-Proto should be maintained but was changed by GCLB, I'd recommend opening a feature request for this on Google issue tracker.