Root domain behind AWS CloudFront - amazon-web-services

As per this Amazon's article I was trying to make the whole WordPress website work behind AWS CloudFront. Not just the static files but the whole website (it can be done with setting up proper cache behaviors). However if you use the bare domain (example.com, without www) it seems that's impossible.
Namely, if the origin of a CloudFront distribution is example.com, and if you put a CNAME for example.com in that same distribution CloudFront will sporadically produce 403 Error. After some digging I found out that this is expected behavior since with this setup, where origin and the CNAME values are the same, CloudFront will look for the origin onto itself and produce error.
So how can one use naked domain and use CloudFront as a proxy at the same time?
Update:
I've implemented the origin.example.com solution suggested in the comments. I was getting an error but now it works.
The origin in the CF distribution is origin.example.com.
CNAME in the CF distribution is example.com.
In the Cache Behavior settings in the CF distribution the Host header is whitelisted.
In DNS origin.example.com points to the server's IP with an A record.
In DNS example.com points to the CF distribution with an ALIAS-A record.
The only beef I have with this workaround is that this way the origin server's IP address is discoverable on the net. A script kiddie can accidentally access origin.example.com and the server's true IP address is in the open, thus you're prone to DDoS. One of the many benefits of a proxy is that with it you're hiding the true server's IP address.
I'm currently using Cloudflare as a proxy mainly because of that reason. In the past I was hit with massive DDoS attack and my server's IP address was null-routed by the host, so I had to quickly hide behind Cloudflare and change the server's static IP. No headaches since then. I wanted to switch to CloduFront but using the bare domain seems not viable.

You have to create another hostname in DNS, pointed to the instance, such as origin.example.com. But the instance does not need to know about this name.
Create a CloudFront origin using this new hostname as the origin domain name, and then in the Cache Behavior, whitelist the Host header for forwarding to the origin.
In DNS, point example.com only to CloudFront.
CloudFront will then use the alternate name to find the instance's actual IP address, but will preserve the original hostname (example.com) in the request that is sent to the origin.

If anyone else runs into this issue, the problem may be with the certificate. If your certificate is for "*.example.com" make sure it also has "example.com" added. If not, create a new one.

When using CloudFront to cache an entire web site, use an A-ALIAS record for both the naked domain (example.com) and for www (www.example.com) that resolves to the CloudFront Domain Name. If you are using SSL on CloudFront, ensure that both domain names are in the certificate.

Related

Cloudfront hosting S3 static site, Google Domains issue

I've been trying to point my custom domain to the cloudfront distribution that's serving an s3 bucket.
I've been following this guide, but it doesn't work. I cannot figure out what's going wrong.
The cloudfront-s3 connection is working, becuase when I open the auto-assigned dns from cloudfront, it opens the site.
There's something wrong with the dns names. I have two certificates, one for root domain, one for *.. I use the second one, as I cannot work with root domain on google domains side, and as the guide suggested, I reroute to www. on Google Domains (doesn't seem to work though, if I try to open , it doesn't redirect me to www.).
When I try to open the address, it says:
This site can’t be reachedCheck if there is a typo in www.<root-domain>.
DNS_PROBE_FINISHED_NXDOMAIN
So in summary in Google Domains I have 2 CNAMEs, one for the certificate, one for the cloudfront distribuiton. The host name for the cloudfront distribution is wwww., and for the cert it's auto assigned by aws.
The certificates are confirmed that are issued, and assigned to the cloudfront distribution, also alternative domain names contain www..
I have a route 53 hosted zone created for www., and an alias created for cloudfront distribution.
Any clue what may have I done wrong?

Amazon Cloudfront and EC2 Redirection setup

First time here but have used help from here a lot.
I managed to find some answers from this thread
Cloudfront and EC2
But as it is mentioned in answer, this issue is happening for me
“Be sure, when you connect through CloudFront, that the server doesn't redirect you back to the EC2 hostname or IP (the address bar in the browser will change, if it does, and you'll want to fix your web server's config if that happens).”
So for this do I need to change anything on httpd.conf?
Or ec2’s firewall? I am using amazon AMI with LAMP
Thanks
Pramit
It means that when your application points to another page in the app (eg index.html pointing to about.html), you should use relative references (/about.html rather than http://1.2.3.4/about.html).
This way, traffic coming in through CloudFront will continue to come in through CloudFront rather than be redirected elsewhere.
Update:
Let's say your configuration is:
A single Amazon EC2 instance with an Elastic IP address
A CloudFront distribution
Your own domain name that you'd like to point to CloudFront
In this case, you would:
Configure a CNAME record (eg www.example.com) on your Domain (on Route 53 or your DNS provider) to point to the CloudFront distribution URL
Configure Alternate Domain Names (CNAMEs) in CloudFront with your CNAME (www.example.com) -- this is so that it knows what domain name is being used to send requests to CloudFront
Set origin to the Elastic IP address of your EC2 instance -- this is where CloudFront obtains the information that it should cache and serve
If you want CloudFront to fetch data from a sub-path (sub-directory) of the origin, then set origin path to that path. For example, you might want to serve content from /dev or /prod.
See: Values That You Specify When You Create or Update a Web Distribution - Amazon CloudFront

Using a different SSL certificate for different domains in CloudFront distribution?

I have a CloudFront distribution which I'm using to serve static files (images etc) on my website. As of today it uses the default foo.cloudfront.net domain (with Amazon's free, built-in SSL certificate).
I want to switch this distribution over to a "real" domain that's part of my site (eg. media.mysite.com). As soon I make this change in CloudFront (eg. switch from its Default CloudFront Certificate to my own *.mysite.com cert), will this break my existing files being served over https://foo.cloudfront.net?
If this is the case then I'll need to somehow switch all the image sources on my site over to the new domain at the same time as enabling the custom SSL certificate for the distribution, which will be tricky.
On the other hand, reading the docs suggests that CloudFront might be doing some work to determine which certificate to use:
CloudFront uses the IP address to identify your distribution and to determine which SSL/TLS certificate to return to the viewer.
... possibly?
Does anyone have any experience with this sort of changeover, or is there a better way to switch domains without having to change a non-trivial amount of URL references simultaneously?
If I understood the concern,
Your CloudFront URL https://foo.cloudfront.net will work after a switch to media.mysite.com.
All you need to do is add a CNAME foo.cloudfront.net to domain media.mysite.com & define media.mysite.com as CNAME in cloudfront distribution settings. Also, add your cutom SSL certificate to the distribution.
No, it won't break any of your contents until & unless you have hardcoded some dependency to the Cloudfront URL. Such as the requests Origin should be the Cloudfront URL etc.
CloudFront uses the IP address to identify your distribution and to determine which SSL/TLS certificate to return to the viewer.
Answer -
This happens only if you have opted for Dedicated IP which means you want to serve all the users including the clients which doesn't support SNI.
Below is what happens when you use SNI & not a dedicated IP -
When CloudFront receives the request, it finds the domain name in the request header and responds to the request with the applicable SSL/TLS certificate.
I guess you have not opted for a dedicated IP.
PS - I did this yesterday & it went smooth. It takes some time for Cloudfront deployment on Edge locations, be patient. Hope this helps!

Using CloudFront to split traffic between origin servers – is this configuration right?

I'm replacing a legacy website with a new one, in stages. From a user perspective, all existing URLs must remain the same, but certain paths should serve new pages.
I have two origin servers: the legacy one (www.mysite.com) and the new, EC2 one (www.ec2-loadbalancer.com) – obviously mock URLs for privacy reasons.
I've created an AWS CloudFront distribution with a CNAME setting of www.mysite.com. Within this distribution I've created two origins domains:
www.mysite.com
www.ec2-loadbalancer.com
Within CloudFront I've configured some behaviours so that paths like /foo are sent to my EC2 load balancer origin, and all other paths (eg. default) are sent to www.mysite.com.
From a DNS perspective, I've added a CNAME record of www.mysite.com which points to my Cloudfront host domain (eg. foo.cloudfront.net.). The A record for this domain points to the IP of the legacy server.
I launched all of this today and it seems to have worked, but I'm seeing intermittent 403 errors on the site, and two hours after making the change (there was no "www" CNAME before, so TTL shouldn't make a difference), some browsers are still serving the site from the original IP (rather than the CloudFront one).
Have I configured this properly? I couldn't work out how to do this via the A record – that points to the IP of the legacy server, and CloudFront doesn't allow me to enter an IP address as an origin. Should I have pointed the www CNAME at the IP address, made the A record point at CloudFront instead? I'm a bit lost here.
On the other hand, it could all be a propagation thing, but I'm wary having seen 40x errors hours after making the change.
i think you should create an A record (for the named domain name) with an alias pointing to the cloudfront distribution. It should solve the problem.
i.e. Use Alias name instead of IP address and point your domain to cloudfront:
It's a shame you can't share the domains with us to help debugging, but at the very least, dig is your friend. For instance:
$ dig membership.theguardian.com
...
;; ANSWER SECTION:
membership.theguardian.com. 367 IN CNAME i.global-ssl.fastly.net.
i.global-ssl.fastly.net. 12 IN A 151.101.128.67
i.global-ssl.fastly.net. 12 IN A 151.101.64.67
i.global-ssl.fastly.net. 12 IN A 151.101.0.67
i.global-ssl.fastly.net. 12 IN A 151.101.192.67
...tells you that membership.theguardian.com is pointing to Fastly by CNAME. You can check with alternate DNS servers, like Google's DNS on 8.8.8.8, by doing this:
$ dig #8.8.8.8 membership.theguardian.com
...so you can see how other people are resolving your domains.
From a DNS perspective, I've added a CNAME record of www.mysite.com
which points to my Cloudfront host domain (eg. foo.cloudfront.net.).
The A record for this domain points to the IP of the legacy server.
I'm not a DNS expert, so it's possible I'm not understanding you here, but this sound like it introduces ambiguity? To me this sounds like you have two different records for the same www.mysite.com domain, one of which points to CloudFront, and the other to the IP of your legacy server. Depending on how that gets resolved a browser could be sent to one or the other?!
www.mysite.com should point only to CloudFront. I would personally just use a CNAME for this.
You should have unambiguous addresses for both your legacy server and your EC2 Elastic Load Balancer - I would personally give them their own clear domain names, to avoid confusion (eg. legacy.mysite.com & beta.mysite.com) - and in CloudFront refer to only to those clear names when you're directing traffic (eg. passing traffic on to www.mysite.com as a way of going to the legacy server would be confusing).
Good luck!

How to get an SSL certificate installed using Amazon Certificate Manager up on using CloudFront for a single EC2 instance?

I’m using an Amazon EC2 instance to host my web application. The EC2 instance is in the APAC region. I wanted to use an SSL certificate from Amazon Certificate Manager.
For the above scenario, I have to go for either Elastic Load Balancing option or CloudFront.
Since my instance is in APAC region, I cannot go for Elastic Load Balancing, as load balancing is available only for instances in US East (N. Virginia) region.
The other option is to go for CloudFront. CloudFront option would have been easier if I was hosting my web application using Amazon S3 bucket. But I’m using an EC2 instance.
I requested and got an ACM certificate in the US East (N. Virginia) region.
I went ahead with CloudFront, and gave in my domain name (example.com) in the origin field, in the origin path; I gave the location of the application directory (/application), and filled in the http and https ports.
When the CloudFront distribution was deployed, I could only see the default self-signed certificate for the web application, and not the ACM certificate.
Your comments and suggestions are welcome to solve this issue. Thank you.
I went ahead with CloudFront, and gave in my domain name (example.com) in the origin field,
This is incorrect. The origin needs to be a hostname that CloudFront can use to contact the EC2 instance. It can't be your domain name, because once you finish this setup, your domain name will point directly at CloudFront, so CloudFront can't use this to access the instance.
Here, use the public DNS hostname for your instance, which you'll find in the console. It will look something lke ec2-x-x-x-x.aws-region.compute.amazonaws.com.
in the origin path; I gave the location of the application directory (/application),
This, too, is incorrect. The origin path should be left blank. Origin path is string you want CloudFront to prepend to every request. If you set this to /foo and the browser requests /bar then your web server will see the request as coming in for the page /foo/bar. Probably not what you want.
and filled in the http and https ports.
Here, you will need to set the origin protocol policy to HTTP Only. CloudFront will not make a back-end connection to your server using HTTPS unless you have a certificate on the server that is valid and not self-signed. The connection between the browser and CloudFront can still be HTTPS, but without a valid certificate on the instance, CloudFront will refuse to make an HTTPS connection on the back side.
Also, under the Cache Behaviors, you will need to configure CloudFront to either forward all request headers to the origin server (which also disables caching, so you may not want this) or you at least need to whitelist the Host: header so your origin server recognizes the request. Add any other headers you need to see, such as Referer.
Enable query string forwarding if you need it. Otherwise CloudFront will strip ?your=query&strings=off_the_requests and your server will never see them.
If your site uses cookies, configure the cookies you need CloudFront to forward, or forward all cookies.
That should have your CloudFront distribution configured, but is not yet live on your site.
When the CloudFront distribution was deployed,
This only means that CloudFront has deployed your settings to all of its edge locations around the world, and is ready for traffic, not that it is actually going to receive any.
I could only see the default self-signed certificate for the web application, and not the ACM certificate.
Right, because you didn't actually change the DNS for "example.com" to point to CloudFront instead of to your web server.
Once the distribution is ready, you need to send traffic to it. In Route 53, find the A record for your site, which will have the EC2 instance's IP address in the box, and the "Alias" radio button set to "No." Change this to Yes, and then select the CloudFront distribution from the list of alias targets that appears. Save the changes.
Now... after the old DNS entry's time to live (TTL) timer expires, close your browser (all browser windows), close your eyes, cross your fingers, open your eyes, open your browser, and hit your site.
...which should be served via CloudFront, with the ACM certificate.
This probably sounds complicated, but should be something you can do in far less time that it took me to type this all out.
Elastic Load Balancer is available in all the regions. The assumption that it is available only in US East is wrong. Check it out, maybe this alone solves your issue.
About SSL termination, you can enable the service on the ELB.
If in single node, you can SSL terminate on the web server itself, a cheaper solution.
Firstly, thank you so much for taking your time and helping me with the query. I proceeded with your suggestions.
'Also, under the Cache Behaviors, you will need to configure CloudFront to either forward all request headers to the origin server (which also disables caching, so you may not want this) or you at least need to whitelist the Host: header so your origin server recognizes the request. Add any other headers you need to see, such as Referer.'
I don't know what you mean by whitelisting the host. Under the whitelist box, what value do I have to give?
Since I wasn't sure about whitelisting the header, I proceeded with allow all header. And I forwarded all cookies.
In the origin settings, I don’t know what to give in the header name and header value. So, I gave the header name as ‘header1’, and value as my domain name ‘www(.)example(.)com’.
I have made the DNS change in Route 53 as you have suggested.
Now when I click www(.)example(.)com, I’m able to see https://www.example(.)com with a valid ACM certificate.
However, when I tried to access my application, https://www(.)example(.)com/application, the webpage is navigating to https://ec2-x-x-x-x.ap-southeast-1.compute.amazonaws.com/application/, and it’s showing the self-signed cert again.
I’m guessing there is some problem with DNS configuration in Amazon Route 53. Can you please tell me what changes do I have to do so that when I hit my application I can see a valid certificate?
Also, when I hit my application, my URL is changing to show ec2-x-x-x-x, instead of my domain name? Can you please tell me how to correct that?
Thank you so much.