Amazon Cloudfront and EC2 Redirection setup - amazon-web-services

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

Related

Path based routing to cloudfront and ec2

So currently we have two ec2 instances (lets say A and B) and a cloudfront.
If the user goes to www.appdomain.com/app the user should get routed to the cloudfront SPA page. However if the user goes www.appdomain.com the user should be routed to the EC2 instance A, and if user goes to www.appdomain.com/api be routed to EC2 instance B.
All of these applications must be on the same domain.
Now we found out how to set path rules using an application load balancer, but would like to know how to set it to cloudfront as well.
Update:
So in summary the question is how do we route /app to cloudfront / and /api to ec2.
All of these applications must be on the same domain.
In this scenario, every request for that domain must pass through CloudFront first.
Your DNS record will need to point to CloudFront (not the ALB) and CloudFront is then responsible for routing the request to the appropriate target -- to an EC2 instance via an ALB, to an S3 bucket, to wherever you need the requests to go -- and each of these things is called a content origin.
Once the origins are specified by their individual domain name (not your site's domain name, but a domain name specifically for the resource in question), you define CloudFront path patterns to select which origin is to receive the request for each pattern (e.g. /api*).
Once your DNS is changed to point to CloudFront, all requests go there first, and are handed off to the next service, unless CloudFront has a cached copy of the requested object -- in which case, CloudFront will serve it from its cache, and nothing will be sent to the origin.
You can't route from ALB to CloudFront, but you can route from CloudFront to ALB.
You can't subdivide a domain into multiple, different path-based content origins without using a reverse proxy that is able to match the paths and fetch the content on behalf of the requester -- HTTP and DNS don't support such functionality. CloudFront, in addition to providing the CDN service, is also a reverse proxy.
ALB, of course, is also a reverse proxy, but does not support as many different types of content origins as CloudFront does -- ALB only supports EC2 instances, servers in your data center (in which case, ALB must have a VPN path in order to reach them), and Lambda functions as content origins. CloudFront can use literally anything as a content origin as long as it speaks HTTP/HTTPS and is accessible via the Internet. (To choose a somewhat random example, CloudFront can even use a service from another vendor -- like a Google Cloud Storage bucket -- as a content origin, if that was something you needed to do, for whatever reason... because these are accessible via HTTP across the public Internet.)

AWS ELB DNS failover to S3

I am trying to stay sane here, but this config was checked several times now against several tutorials and it is just not working.
I am having a public facing ELB for my website with EC2 instance behind it. What I need is to setup a maintenance website, hosted from S3 bucket.
What I did is, I created dns entry A alias for healthcheck xxx-healthcheck.xxx.com pointing to ELB internal AWS domain name.
I created an A alias for my website xxx.xxx.com pointing to my ELB internal address. Then I marked settings as failover, added above healthcheck and marked this as evaluate its health.
I added next record - for my S3 bucket (S3 bucket name is xxx.xxx.com). Alias A, again. Name of alias is same as primary address, so xxx.xxx.com. I marked it as failover and secondary.
I turned service off on both instances, healthcheck is marked as unhealthy. It is timeing out, when I try to access the website - no under maintenance site.
Please.
Please, help.
Cheers
A
Are you using TLS/SSL? If your website from ELB is being served over HTTPS, the browser tries to use HTTPS even with S3 after the failover (this is normal and it's called HSTS). Your content will still be served if you use HTTP. To verity that, use a different browser or clear all history related to your domain (if that does't work, google "chrome delete hsts domain" if you're on Chrome), and open your domain using http://<domain>.
If you enabled static website hosting on S3 and added that static S3 URL (via A record Alias) as your failover secondary route in Route53, this will not work since S3 is not configured to receive traffic using HTTPS via your domain.
The solution for this is to create a CloudFront distribution and add your S3 bucket as the origin, add CNAME value in CloudFront as your domain name and attach/configure SSL certificates on CloudFront. Now, in your Route53, add the CloudFront distribution's URL as the failover entry (A record Alias).

Redirecting a custom subdomain to a static website hosted in AWS S3 bucket

I have a static website hosted in S3 inside the bucket client1.examplecorp.com with a corresponding R53 record client1.examplecorp.com. A ALIAS s3-website-us-east-1.amazonaws.com.
I want my client's (client1.com) webadmin to create a dns record for the subdomain quotes.client1.com which will point to AWS (The client1.com does not use R53).
Should it point to client1.examplecorp.com ?
Or directly at the S3 bucket endpoint ?
The concept is that, the final user will see only the quotes.client1.com subdomain and not know about client1.examplecorp.com .
I hope I describe it well enough...
I have read the AWS docs about Setting Up a Static Website Using a Custom Domain , Virtual Hosting of Buckets and also this SO post.
I have a feeling that what I am searching for is described here How to redirect domains using Amazon Web Services .
I just do not understand how the registrar of the client will redirect traffic for that specific subdomain (quotes.client1.com) to client1.examplecorp.com by adding the 4 nameservers.
Moreover, will the redirect affect only this subdomain or the whole client1.com .
Finally, will it be completely transparent? Meaning that, the client1.examplecorp.com will not be shown to the end user?
I have not a firm grasp on explaining it , so please bear with me.
Here are two possible solutions:
In these examples, the client's main domain is example.com.
Option 1:
Create a bucket whose name is the same as the desired hostname, and have the client create a CNAME record pointing to the web site endpoint for the bucket.
Bucket name:
quotes.example.com
Web site endpoint (assuming us-east-1 region):
quotes.example.com.s3-website-us-east-1.amazonaws.com.
Client DNS:
quotes.example.com. CNAME quotes.example.com.s3-website-us-east-1.example.com.
The client does not need to be using Route 53 for their DNS, but the bucket name must exactly match the hostname they are pointing to the bucket, because that is how S3 works.
Option 2:
Send the traffic through CloudFront. In this scenario, the bucket name does not matter, because CloudFront will translate it to the correct bucket name.
Bucket name:
example-bucket
Web site endpoint:
example-bucket.s3-website-us-east-1.amazonaws.com
New CloudFront Distribution system-assigned hostname:
djozxyqkexample.cloudfront.net
CloudFront Origin (do not select the bucket name from the dropdown list, type in the S3 website hostname as shown in the S3 console):
example-bucket.s3-website-us-east-1.amazonaws.com
CloudFront alternate domain name:
quotes.example.com
Client creates a DNS CNAME
quotes.example.com. CNAME djozxyqkexample.cloudfront.net.
This solution also does not require that the client use Route 53, and -- importantly -- the bucket name does not need to match the hostname -- the hostname simply needs to be configured as a CloudFront alternate domain name so that CloudFront recognizes the Host: header when it arrives.
If you want to reuse the same bucket for multiple sites, you can add more hostnames to the CloudFront alternate domain name setting, or you can create multiple distributions pointing to the same bucket.
Note also that using CloudFront in front of S3 is effectively free, because S3 will no longer bill you for bandwidth when you use CloudFront -- instead, CloudFront will bill you for bandwidth, at the CloudFront rate, which is often slightly lower that the S3 rate.
In both cases, above, the client does not need to use Route 53, because they hostname in question is not the zone apex hostname (the "naked domain"). To use a naked domain with either solution requires Route 53, but that isn't applicable here.
Unfortunately, I think this is not possible. I am assuming that you own the corporation domain in this case.
For you to use client1.corporation.com, you had to use Route 53, right?
You also could not configure some DNS record in your other NameServer and do the same.
Similarly, for you to use quotes.client1.com point to the S3 bucket, you also need to ask the client use Route 53.
Hope that helped
Cheers!

Routing example.at to S3 bucket and *.example.at to load balancer with HTTPS

I have set up a multi tenant application which should be available to clients via a subdomain (e.g. https://client1.example.at). Requests to *.example.at are routed to a load balancer via Route 53. The load balancer has an AWS signed wildcard certificate (e.g. supporting example.at and *.example.at). From this side, everything is working as expected and I can access https://client1.example.at, https://client2.example.at, etc.
Based on this setup, I wanted to route specific request without subdomain (except www) such as https://www.example.at or https://example.at to a bucket (which is also named www.example.com) and not to the load balancer (I just want to serve a static site for requests to the "main domain"). It works but I can only access www.example.at and example.at without using HTTPS. My setup can be seen below:
I then found out that I have to use Cloudfront in order to use HTTPS for a custom domain with S3 buckets (if that is correct?). Now I have a few questions:
Is it necessary to use Cloudfront to serve content from my S3 bucket for www.example.at and example.at via HTTPS?
If Cloudfront is necessary then I have to request a new certificate for www.example.at and example.at in region US EAST according to the official AWS docs. Is it possible to create two certificates for the same domain with AWS certificate manager or can I get some conflicts with this setup?
Is it ok to use *.example.at as A type record with alias to the load balancer at all?
Generally speaking, is my Route 53 setup valid at all?
I wanted to route specific request without subdomain (except www) such as https://www.example.com or https://example.com to a bucket (which is also named www.example.com)
Each of those "domains" must route to a different bucket unless you are using a proxy (which reroutes the hostname passed from the browser) in front of S3, the domain name must match the bucket name. If they don't then your requests are going to a bucket matching the DNS name you routed from, the routing has nothing to do with the hostname of the S3 bucket endpoint.
In other words, let's say your hostname was www.example.com, and you set the CNAME to example.com.s3.amazonaws.com (or you could use the website endpoint, it doesn't matter for this example).
When a request hits the DNS name www.example.com it then is sent to the S3 server which is behind the S3 hostname. That request from the browser is for hostname "www.example.com", the actual CNAME referenced which pointed to the S3 endpoint is irrelevant because S3 never knows what actual CNAME was used to by your browser to connect to S3. So S3 will attempt to pull the requested object from the www.example.com bucket.
URL -> S3 Bucket
https://www.example.com -> s3://www.example.com
https://example.com -> s3://example.com
It works but I can only access www.example.at and example.at without using HTTPS.
CNAME DNS routing like this when using SSL to an S3 bucket does not work. The reason for this is that the S3 wild card certificates are 1 level deep (*.s3.amazonaws.com) so your bucket www.example.com.s3.amazonaws.com will fail to match it because it has 2 extra levels above the wild card. So your browser rejects the certificate as invalid for the hostname.
To accomplish this you must use a proxy of some sort in front of S3 with your own certificates for the domain in question.
Is it necessary to use Cloudfront to serve content from my S3 bucket for www.example.at and example.at via HTTPS?
CloudFront is an excellent option for addressing the HTTPS with CNAME routed DNS to an S3 bucket issue we just mentioned.
If Cloudfront is necessary then I have to request a new certificate for www.example.at and example.at in region US EAST according to the official AWS docs. Is it possible to create two certificates for the same domain with AWS certificate manager or can I get some conflicts with this setup?
I can't answer that one, I can only suggest you try and find out what happens. If it doesn't work then it's not an option. It shouldn't take much time to figure this one out.
Is it ok to use *.example.at as A type record with alias to the load balancer at all?
To clarify, an A Record can only ever be an IP address, an A Alias is similar to a CNAME (but is Route53 specific).
I highly recommend CNAMES (or ALIASES, they are similar). Pointing directly at one of S3's A-Records is a bad idea because you don't know if or when that IP will be removed from service. By referencing the hostname with a CNAME/ALIAS you don't have to worry about that. Unless you can be 100% sure that the IP will remain available then you shouldn't reference it.
Generally speaking, is my Route 53 setup valid at all?
I don't see any issues with it, based on what you described it sounds like like things are working as expected.
If Cloudfront is necessary then I have to request a new certificate for www.example.at and example.at in region US EAST according to the official AWS docs. Is it possible to create two certificates for the same domain with AWS certificate manager or can I get some conflicts with this setup?
As suggested by #JoshuaBriefman I simply tried to create another certificate for the same domain in another region now and it worked. I could also use the certificate for the CloudFront distribution (additional certificate was created in US EAST) and all works now without any problems so far.

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.