Using a different SSL certificate for different domains in CloudFront distribution? - amazon-web-services

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!

Related

Static Web Application hosted in Amazon S3 Bucket suddenly not working

The hosted application worked until yesterday but suddenly not working today.
What I have done?
Using Cloudfront - To host my website from Amazon’s edge locations with a custom SSL certificate setup for my domain.
Amazon
Certificate Manager - To get HTTPS Certificate
Hosted my client application in S3. They wanted to access their site using a domain name. To achieve this I have provided two records as given below.
Type Host Value TTL
A # IP of the client domain 600
CNAME www CloudFront distribution URL 600
The thing is Endpoint which I got while configuring Cloudfront "d3ajo2v2g7lf33.cloudfront.net" is working but the domain name which I added as an alias to this endpoint is not working.
Probable findings from my side:
1) Used let's encrypt to get the SSL and it's about to expire within a week.
2) Added A record with the IP address of the domain. As am using Cloudfront am doubting that the domain does not have a static IP.
Also please let me know CloudFront distribution domain name IP will change every time or will it be static.
Kindly help me to resolve this.
CloudFront has CNAME record as well. So you have to register your domain name in the CloudFront distribution.
as for the SSL certificate for your custom domain, take a look at AWS ACM. It may be easier than using lets encrypt certificate (your call).
and yes. use the cloudfront's domain URL. it won't change unless you delete the distribution.

AWS Cloudfront custom sub domain TSL / SSL: "Not secure / certificate invalid"

I am looking for some advice as how to most cost efficiently setup SSL for a subdomain e.g https://images.example.com.
Images are hosted in AWS S3 and I have a cloudfront distribution pointing to that bucket.
I have purchased a single domain SSL cert from Comodo and successfully added it to my cloudfront distribution. That part was easy as pie.
However, when loading images on the subdomain I get a "Not secure / certificate invalid" in the browser bar.
Is this because I require a wildcard SSL cert?
I have not tested that the SSL cert works on the main domain. Reason being there is currently a production site that I don't want to interfere with.
Before I rush out and purchase a much more expensive wildcard SSL cert, I want to make sure it is required.
I have a single subdomain for image hosting. I don't expect to ever ad more subdomains. What if I just purchase two single domain certs?
What are my options?
Try using ACM (https://aws.amazon.com/certificate-manager/ ) to issue an AWS issued wildcard certificate for your domain and use that instead?
As to why your existing cert won't work - does it have the domain in the cert (eg images.domain.com) as either the primary domain or as a SAN? If not, it won't work.
If you don't want to use a wildcard, you can use an ACM cert (or a cert you purchase from somewhere else) and issue it for the domain subdomain only? You don't have to use a wildcard but from a cost point of view if you are purchasing them, its often more cost-effective (although there are of course security concerns to consider). If you are using ACM, the certs are free - either domain specific or wildcard.

Root domain behind AWS CloudFront

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.

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.

AWS Cloudfront for VPC/VPN

Does AWS allow usage of Cloudfront for websites usage, eg:- caching web pages.
Website should be accessible within corporate VPN only. Is it a good idea to cache webpages on cloudfront when using Application restricted within one network?
As #daxlerod points out, it is possible to use the relatively new Web Application Firewall service with CloudFront, to restrict access to the content, for example, by IP address ranges.
And, of course, there's no requirement that the web site actually be hosted inside AWS in order to use CloudFront in front of it.
However, "will it work?" and "are all the implications of the required configuration acceptable from a security perspective?" are two different questions.
In order to use CloudFront on a site, the origin server (the web server where CloudFront fetches content that isn't in the cache at the edge node where the content is being requested) has to be accessible from the Internet, in order for CloudFront to connect to it, which means your private site has to be exposed, at some level, to the Internet.
The CloudFront IP address ranges are public information, so you could partially secure access to the origin server with the origin server's firewall, but this only prevents access from anywhere other than through CloudFront -- and that isn't enough, because if I knew the name of your "secured" server, I could create my own CloudFront distribution and access it through CloudFront, since the IP addresses would be in the same range.
The mechanism CloudFront provides for ensuring that requests came from and through an authorized CloudFront distribution is custom origin headers, which allows CloudFront to inject an unknown custom header and secret value into each request it sends to your origin server, to allow your server to authenticate the fact that the request not only came from CloudFront, but from your specific CloudFront distribution. Your origin server would reject requests not accompanied by this header, without explanation, of course.
See http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/forward-custom-headers.html#forward-custom-headers-restrict-access.
And, of course, you need https between the browser and CloudFront and https between CloudFront and the origin server. It is possible to configure CloudFront to use (or require) https on the front side or the back side separately, so you will want to ensure it's configured appropriately for both, if the security considerations addressed above make it a viable solution for your needs.
For information that is not highly sensitive, this seems like a sensible approach if caching or other features of CloudFront would be beneficial to your site.
Yes, you CloudFront is designed as a caching layer in front of a web site.
If you want to restrict access to CloudFront, you can use the Web Application Firewall service.
Put your website into public network > In CloudFront distribution attach WAF rules > In WAF rules whitelist range of your company's IP's and blacklist everything else