Routing requests using cloudflare to different web applications

2.5k views Asked by At

I currently have two web apps that are set up in cloudflare with the following CNAMEs. Both are keystonejs applications.

app1.example.com ===pointing to ===> AWS ALB 1
app2.example.com ===pointing to ===> AWS ALB 2

I have Cloudflare Enterprise set up, so i'm able to use the "Render Override" feature in my page rules. I have 2 page rules set up using the following:

www.example.com ===render override ===> app1.example.com
www.example.com/app2/* ===render override ===> app2.example.com

Now in order to access the keystonejs application on app2.example.com. The application is called using app2.example.com/pa

The problem that i'm facing is that render override doesnt allow me to use sub paths, and i do not want to use the forwarding rule. Do i need to make my keystone application accessible through the root url, namely app2.example.com/ ? or is there another way to do this? Otherwise, would i need to use a reverse proxy? such as nginx ? Thanks

1

There are 1 answers

0
Kenton Varda On BEST ANSWER

Note: Since you are an enterprise customer, I highly recommend contacting your Customer Success Manager and/or Solutions Engineer at Cloudflare. They are there to help with exactly these kinds of questions. That said, I'll answer the question here for the benefit of self-serve customers.

I think when you say "Render Override" you actually mean "Resolve Override". This setting changes the DNS lookup for the request such that it is routed to a different origin IP address than it would be normally.

Note that Resolve Override does not rewrite the request in any way; it only routes it to a different server. So, a request to www.example.com/app2/foo will go to the server app2.example.com, but the path will still be /app2/foo (not /foo), and the Host header will still be Host: www.example.com.

It sounds like in your case you really want /app2/* to be rewritten to /pa/*, in addition to redirecting to a different origin. You can accomplish this using Cloudflare Workers, which lets you execute arbitrary JavaScript on Cloudflare's edge. Here's what the script might look like:

addEventListener("fetch", event => {
  event.respondWith(handle(event.request));
});

async function handle(request) {
  let url = new URL(request.url)  // parse the URL

  if (url.pathname.startsWith("/app2/")) {
    // Override the target hostname.
    url.host = "app2.example.com"

    // Replace /app2/ with /pb/ in the path.
    url.pathname = "/pb/" + url.pathname.slice("/app2/".length)

    // Send the request on to origin.
    return fetch(url, request)
  } else {
    // Just override the hostname.
    url.host = "app1.example.com"

    // Send the request on to origin.
    return fetch(url, request)
  }
}

With this deployed, you can remove your Resolve Override page rules, as they are now covered by the Worker script.

Note that the above script actually does rewrite the Host header in addition to the path. If you want the Host header to stay as www.example.com, then you will need to use the cf.resolveOverride option. This is only available to enterprise customers; ask your CSM or SE if you need help using it. But, for most cases, you actually want the Host header to be rewritten, so you probably don't need this.