Cloudflare for SaaS more than one fallback domain
Background
I have a couple of different SaaS products, one with a couple hundred Vanity domains and another with less than 100. I have the potential of adding say another 1,000 vanity domains to each product as most current customers don't use vanity domains but it's something I'd like to encourage.
Objectives 1. For each product I want to give customers a single CNAME that they can point their vanity domain at. example vanity.customer1.com -> product1.company.com 2. I want to be able to direct traffic to more than one output point example vanity.customer1.com - >CNAME-> product1.company.com proxied to my-host-site.aws.net vanity.customer2.com >CNAME-> product1.company.come proxied to my-host-site-beta-program.aws.net Problems 1. Looking at the /ssl-tls/custom-hostnames dashboard site I am only seeing one "fallback". This is problematic as I have two different SaaS products (with plans for a third) and it doesn't let me direct traffic to a specific host. 2. My current host isn't AWS (each product is on a different host) but both of my hosting providers have a limit of between 50 and 500 domains that I can point to a single application and it looks like the domain reported once the traffic comes out of the proxy is the "vanity.customer1.com" and not "product1.company.com" so after configuring Cloudflare I would still have to configure each app to respond to every vanity domain which is problematic.
Maybe Cloudflare for SaaS isn't the solution to my Saas issues? Or am I missing something on setting this up?
Objectives 1. For each product I want to give customers a single CNAME that they can point their vanity domain at. example vanity.customer1.com -> product1.company.com 2. I want to be able to direct traffic to more than one output point example vanity.customer1.com - >CNAME-> product1.company.com proxied to my-host-site.aws.net vanity.customer2.com >CNAME-> product1.company.come proxied to my-host-site-beta-program.aws.net Problems 1. Looking at the /ssl-tls/custom-hostnames dashboard site I am only seeing one "fallback". This is problematic as I have two different SaaS products (with plans for a third) and it doesn't let me direct traffic to a specific host. 2. My current host isn't AWS (each product is on a different host) but both of my hosting providers have a limit of between 50 and 500 domains that I can point to a single application and it looks like the domain reported once the traffic comes out of the proxy is the "vanity.customer1.com" and not "product1.company.com" so after configuring Cloudflare I would still have to configure each app to respond to every vanity domain which is problematic.
Maybe Cloudflare for SaaS isn't the solution to my Saas issues? Or am I missing something on setting this up?
12 Replies
Feedback
Feedback has been submitted! Thank you :)
I've experimented a bit more, and it works kind of. Whether it works with your specific hosts is something you would need to test, but it's pretty simple:
For every Custom Hostname, you can set a Custom Origin.
So that takes care of having different hosts for different custom hostnames.
The second is a bit more problematic. What you call "the domain coming out of the proxy" are actually 2 domains:
1. The Host header
2. The SNI
Custom Origins do change the SNI to the custom origin domain, but not the Host header.
Nginx just ignores the Host Header and uses the SNI domain to select which site to serve, but Apache checks if the Host is configured correctly, so it doesn't work without adding each domain to the hosting.
Much easier would be if you used different domains for your different SaaS applications. In that case, you could use a Snippet to fetch the correct page from your host and serve it for the Custom Hostname.
So setting the "Custom Origin" does change the SNI so theoretically depending on the architecture I can have an app just accept one domain and I can read the Host header to see the original domain the user came from to know what content to serve. That does seem to clarify and help some
It does sound like I still have the issue where all traffic has to be routed to just one fallback domain. I can't put any rules in place for A-B testing or rolling out a new build to just a few customer for example. Also couldn't slowly migrate some customers to a different hosting setup, it's all or nothing
You can set an individual Origin for every single custom hostname. So you can set every single customer to a new hosting setup if you want to.
Things such as A/B testing aren't really a part of the SaaS offering, but would rather be implemented using Workers/Snippets.
But tbh, those work best if you have one domain per SaaS product. If you use the same domain for multiple SaaS products, it becomes difficult to manage which Worker is supposed to work on which custom hostname.
On Enterprise, you can solve this using Subdomain Setups, but on the Paygo plans, using a different domain for each SaaS works best.
Really looking at this without the ability to alter the Host header it's not usable in my scenario. I'd have to deploy a worker and pay for that overhead on each and every request
All the hosting providers apps serve based on the Host header so I'd still have to map every domain on the hosting provider side which is what I'm looking to get away from
Snippets are the same as Workers (in this case) but don't charge extra per request, just a Pro plan required.
But yes, Cloudflare for SaaS really expects that the origin is correctly configured for each host, and everything else is patchwork.
Though it does work well if there's only a single site that's the same for all custom hostnames. A Snippet can easily fetch the site and you can pass the custom hostname as a custom header or something to distinguish between sites.
So it'd look something like this
export default {
async fetch(request) {
const originalHost = request.headers.get("Host") || "unknown-host"
const url = new URL(request.url)
// Rewrite to fallback domain
url.hostname = "fallback.company.com"
// Clone and modify the request
const modifiedRequest = new Request(url.toString(), request)
modifiedRequest.headers.set("Host", "fallback.company.com")
modifiedRequest.headers.set("X-Forwarded-Host", originalHost)
return fetch(modifiedRequest)
}
}
The host header is automatically set to the request url in Workers, you don't need to set that manually
Cloudflare Docs
Change origin and modify paths
Route requests to a different origin, prepend a directory to the URL path, and remove specific segments.
You just get the old Host and set it as a custom header on the new request
You probably also want to add a "secret header" to the request to make sure others can't point whatever custom domain they want at your origin.
So I tried out a Snippet and it just about works the way you'd expect it to. You can change the Host but you don't have access to "cf.hostMetadata" which contains that elusive origin information needed to change the Host to the origin your sending it to. It seems that is only available in a Worker which has cost overhead.
The Host is always the URL you are sending the request to.
So when you change the request URL, it also changes the host header.