0

My current setup is that www.domain.com serves an S3-hosted static website via CloudFront, so www.domain.com CNAME points to the CloudFront distribution, which in turn points to the S3 static website URL. The CloudFront distribution has www.domain.com as an Alternate Domain Name set up.

I'd like to use Route53's Geolocation feature to route requests from North America to the current CloudFront (A), while all other requests go to another CloudFront (B) hosting another S3 static website. Since I can't add www.domain.com as an Alternate Domain Name for two CloudFront distributions, I'm using the wildcard *.domain.com instead for CloudFront A.

The wildcard works, and e.g. eu.domain.com I set up serves the CloudFront B site correctly.

I've set up the Geolocation rules correctly in Route53, and dig returns the correct CloudFront endpoint. Likewise, Route53 web testbench gives the correct endpoints depending on the IP location. However, curl and web browsers give the wrong content – i.e. CloudFront A even though I'm in the EU.

Is there something wrong in my configuration? Is there a silent failover on the DNS level to the A distribution for some reason? Or some nasty cache? Can this be done at all? Thanks!

harsa_
  • 103
  • 4

1 Answers1

1

However, curl and web browsers give the wrong content

Actually, they give the right content, in context. (Stick with me, here...)

The problem -- technically speaking -- is that you are actually wanting/expecting a response that would in fact be incorrect -- behavior that would be wrong if it actually worked the way you expected, based on the request being made.

Take a look at the request headers using curl -v. They may be connecting to an address retrieved by querying eu.example.com but check this request header:

> Host: www.example.com

The browser is actually getting exactly what it asked for.

This is why you can't assign the same alternate domain name to two CloudFront distributions. CloudFront -- like essentially all web servers -- uses the Host: header sent by the browser to understand what site the browser wants to see. Web servers can't see the DNS path that got you to them. The fact that you can do this while connecting to an IP address returned for a different site is no real surprise -- pick any CloudFront IP and forge a Host: header for a different site, and it is pretty likely to work, because there are good odds that the CloudFront equipment listening on that address can find the configuration within CloudFront and service the request.

This configuration cannot be done using only CloudFront and Route 53.

You need a proxy server in EC2 in the target region in the EU to act as a target for the eu domain in DNS, rewrite the Host: header, and forward the modified request to CloudFront.

Michael - sqlbot
  • 22,658
  • 2
  • 63
  • 86
  • Thanks, that's kinda what I suspected! I was missing the importance of the `Host:` header. It also wasn't clear to me that two CloudFront distributions under the same account (or I guess universally, even) are not fully isolated – another test I had was where a domain (e.g. test.example.com) was pointing just to CloudFront B (which had only a wildcard CNAME), but content from CloudFront A was served (due to the matching non-wildcard domain taking priority). Will set up a proxy server then. – harsa_ Jan 26 '17 at 09:32
  • @harsa_ note that what you will probably want to try is a single CloudFront distribution, with the Route 53 geo-split on the hostname *behind* CloudFront (the origin). Each CloudFront edge should resolve that back-end DNS entry to its nearest region -- the region nearest the CloudFront edge that the viewer is routed to (bucket in one regiom, proxy to bucket in the other region). – Michael - sqlbot Jan 27 '17 at 01:41