Cloudflare Load Balancer - redirect reveals backend server hostname

Viewed 17

I have a Cloudflare Load Balancer configuration with two origin servers:

app.example.com -> backend1.example.com
                -> backend2.example.com

This works fine most of the time. However, when a backend server does an HTTP redirect, it reveals the backend server hostname to the browser. For example, if there is a redirect from /a to /b the request/response would look like this (with some headers omitted for brevity):

Request

GET /a HTTP/1.1
Host: app.example.com

Response

HTTP/1.1 302 Found
Location: https://backend1.example.com/b

This means the browser tries to connect to the backend server directly, bypassing the load balancer.

What I want

Is it possible for the Location to be corrected by the Cloudflare Load Balancer, similar to what ProxyPassReverse does in an Apache reverse proxy?

For example:

HTTP/1.1 302 Found
Location: https://app.example.com/b

or even

HTTP/1.1 302 Found
Location: /b

Or do I need to find a way to fix this on the backend server?

1 Answers

Here's an approach that may work, if the backend supports it.

The X-Forwarded-Host request header is (a) injected by some reverse proxies and (b) honoured by some application servers. It allows the application to see what original hostname the browser connected to before it was reverse proxied, and then use that hostname when constructing redirects.

It's easily spoofed by the reverse proxy so it's often not automatically trusted by the application server.

Here's how to use it.

Add a Cloudflare Transform Rule:

Rule Name: Add X-Forwarded-Host, When: Hostname equals app.example.com

HTTP Request Header Modification, Set Dynamic, Header Name: X-Forwarded-Host, Value: http.host

Deploy

Now on the backend, configure the application server to support it (if required).

For example, JBoss or Wildfly:

/subsystem=undertow/server=default-server/https-listener=default:write-attribute(name=proxy-address-forwarding,value=true)

Express for Node.js: Use the trust proxy setting

Your application server may support it out of the box, it may need a bit of configuration, or it may not support it at all. Look for X-Forwarded-Host in the docs.

Related