Serve S3 behind cloudfront with 2 origins - amazon-web-services

I've a CF distribution with 2 origins:
S3
ALB
This distribution has an alternate CNAME.
Depending on the path, I want some files being served by S3, other by the ALB.
I've 3 behaviours with the following paths:
assets/* with S3 as origin
uploads/* with the alb as origin
default with the same uploads/*'s origin but with a different cache policy
In the S3 bucket there are 2 folders: svg and v2
when I try
curl -I https://myalternate.domain.name/assets/svg/mysvg.svg or
curl -I https://xxxxxx.cloudfront.net/assets/svg/mysvg.svg
I've 404.
If I get them from web I can see
<Error>
<Code>NoSuchBucket</Code>
<Message>The specified bucket does not exist</Message>
<BucketName>myalternate.domain.name or cloudfront endpoint</BucketName>
<RequestId>Q7Z1NAP8HV0PCEM4</RequestId>
</Error>
For the other paths everything is alright.
What did I miss?

What the CloudFront does when it receives the https://myalternate.domain.name/assets/svg/mysvg.svg request is that it will fetch the object stored in S3 using the key assets/svg/mysvg.svg. That's why it returns 404 since the actual key of that object is svg/mysvg.svg. The solution is to either add assets/ prefix to every object in S3 or use a Lambda#Edge function to rewrite the origin request.

Related

Unable to access S3 objects via Cloudfront URL

I am unable to access S3 objects and Bucket via cloud front URL.
I have created CLOUDFRONT Distribution ( Web ) and setup origin path to media folder in my S3 bucket. ( /media)
CF url is pointing to bucket/media , but i am unable to access it from my web application as well as browser.
I am trying to access like below:
http://d1xdpXXXXX.cloudfront.net/media/images/Tiger.jpg
Tiger.jpg can be accessed via s3 url.
I also tried http://d1xdpXXXXX.cloudfront.net but i am getting below error:
<Error>
<Code>NoSuchBucket</Code>
<Message>The specified bucket does not exist</Message>
<BucketName>d1xdpwiqgrffrd.cloudfront.net</BucketName>
<RequestId>484BBB2F7907172F</RequestId>
<HostId>+bLr4Qx+uawbq4YNIOuKGCQVDGQQQsifGnNt9J5Pn+r3mqbDiVYcpNZRUfnCyPnHxewfMVp3QYc=</HostId>
</Error>
Please help.
CF Distribution settings
Access denied error
You have already added the path in cloudfront origin.
So, you don't have to add that in cloudfront url you are using to download.
Just use
http://d1xdpXXXXX.cloudfront.net/images/Tiger.jpg
as /media is already part of the distribution.

AWS Get Pre-Signed URL with custom domain

Following is what I'm doing. I'm generating a pre-signed URL using a custom domain for my s3 bucket resources which are not public.
https://files.customdomain.com/file123?AWSAccessKeyId=XXX&Expires=1541220685&Signature=XXXX
Also to add the certificate I've created a cloudfront distribution for the bucket having following origin settings
Origin Domain Name: bucket-name.s3.amazonaws.com
Origin Id : s3.bucket-name
Restrict Bucket Access: No
Yet I'm unable to access my resources. Throws access denied error. Any help would be appreciated.
There are two cases:
If your bucket has regular name.
In this case you should use CloudFront to access your bucket.
And like mentioned above URL looks like in this answer:
https://cloudfront-url/file123?AWSAccessKeyId=XXX&Expires=1541220685&Signature=XXXX
If your bucket has s3 static website name.
In this case your bucket name looks like files.customdomain.com and you can generate pre-signed url for this bucket:
https://files.customdomain.com/file123?AWSAccessKeyId=XXX&Expires=1541220685&Signature=XXXX
In your DNS you will have CNAME files.customdomain.com points to files.customdomain.com.s3.[bucket-region].amazonaws.com.
NOTICE
When I generate pre-signed URL via aws-cli:
aws s3 presign s3://files.customdomain.com/file123 --endpoint-url https://files.customdomain.com
I get URL with duplicate bucket name in the path:
https://files.customdomain.com/files.customdomain.com/file123?AWSAccessKeyId=XXX&Expires=1541220685&Signature=XXXX
instead of:
https://files.customdomain.com/file123?AWSAccessKeyId=XXX&Expires=1541220685&Signature=XXXX
I don't know if it has the same behavior via SDK.
Have you tried initializing S3 with the custom url var S3 = new AWS.S3({endpoint: 'media.domain.com', s3BucketEndpoint: true});
More info https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html
Also, make sure signature is correct as well https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingAWSSDK.html#specify-signature-version
Ref : https://github.com/aws/aws-sdk-js/issues/891
When using S3 with CloudFront, you don't want an S3 signed URL... you want a CloudFront signed URL.
Read Configuring Security and Limiting Access to Content in the CloudFront developer guide.
I found a solution for this question. The signed url needs to be generated for cloudfront url endpoint from s3 bucket. Therefore instead of
https://files.customdomain.com/file123?AWSAccessKeyId=XXX&Expires=1541220685&Signature=XXXX
it needs to be
https://cloudfront-url/file123?AWSAccessKeyId=XXX&Expires=1541220685&Signature=XXXX
and DNS records had to resolve custom domain to cloudfront url.

Cloudfront url synchronized with s3 path

I was using s3 for for my static websites, we had three websites/paths in s3:
example.com
example.com/website1
example.com/website2
Website1 and Website2 were folders inside the bucket example.com as expected. But now we need https urls so we decided to go with aws cloudfront for the redirects. Cloudfront generated for example a url like this, https://123455678.cloudfront.net .
When I navigate to the url, it gets the example.com correctly, but when I try to put like https://123455678.cloudfront.net/website1 it seems like its not entering the /website1 path in the s3. So it gives me this error because it's not finding the index.html inside the /website1 path.
<Error>
<Code>AccessDenied</Code>
<Message>Access Denied</Message>
<RequestId>C5259E1658595A69</RequestId>
<HostId>
B1HYQsr0Xv4M1avKlJ3G8t0rkVfCvbOoJadxm5z1BwapblBeERm3c6Ni+jZWxB8FlXEaF6bUAik=
</HostId>
</Error>
I guess I have to do something in the origins and behaviours of my cloudfront distribution, but I can't figure out what to do there...
I fixed my problem by changing the origin domain name in my cloudfront distribution to my s3 bucket endpoint, located in the properties of my bucket in Static Website Hosting area.
Saved, waited for cloudfront to use the updated changes and it worked. Also my Default Root Object is set to index.html .
Hope it helps someone =)

how to access cloudfront to s3 bucket object simple url

i am trying to access cloudfront to s3 bucket object response "AccessDenied".
xxxxxxxxxxxxx.cloudfront.net/bucket_name/35.jpg
inside bucket i can access url this is "public" url.
https://s3.ap-south-1.amazonaws.com/bucket_name/35.jpg
I am also try another bucket with another cloudfront ID with signed URL result is same. Please view code here =>
amazon cloudfront Error "AccessDenied"
You should:
Configure your CloudFront distribution with an Origin to point to your S3 bucket
Access the content via: xxxx.cloudfront.net/35.jpg
See:
Using Amazon S3 Origins and Custom Origins for Web Distributions
Using CloudFront with Amazon S3
Task List for Creating a Web Distribution

AWS CloudFront redirecting to S3 bucket

I have created a CloudFront distribution to serve the static website. S3 is origin server.
Now if we access CloudFront URL, it redirects to S3 location.
d2s18t7gwlicql.cloudfront.net
or
test.telekha.in
In the browser it is showing
https://telekha-test-www.s3.ap-south-1.amazonaws.com/index.html#/dashboard
I am expecting https://test.telekha.in/#/dashboard
If I access https://test.telekha.in through curl it returns my index.html document
If I access http://test.telekha.in through curl it returns
<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr><center>CloudFront</center>
</body>
</html>
But in browser both HTTP and HTTPS are redirecting to https://telekha-test-www.s3.ap-south-1.amazonaws.com/index.html#/
Please let me know how to resolve this issue.
Quick Solution
Use the regional domain name of your S3 bucket to configure the CloudFront distribution's origin, e.g.: {bucket-name}.s3.{region}.amazonaws.com.
Explanation
According to the discussion on AWS Developer Forums: Cloudfront domain redirects to S3 Origin URL (via archive.org), it takes time for DNS records to be created and propagated for newly created S3 buckets. The issue is not visible for buckets created in US East (N. Virginia) region, because this region is the default one (fallback).
Each S3 bucket has two domain names, one global and one regional, i.e:
global — {bucket-name}.s3.amazonaws.com
regional — {bucket-name}.s3.{region}.amazonaws.com
If you configure your CloudFront distribution to use the global domain name, you will probably encounter this issue, due to the fact that DNS configuration takes time.
However, you could use the regional domain name in your origin configuration to escape this DNS issue in the first place.
CloudFormation Template
If you are using CloudFormation, you can use the RegionalDomainName output attribute of the AWS::S3::Bucket resource:
S3Bucket:
Type: AWS::S3::Bucket
CloudFrontDistribution:
Type: AWS::CloudFront::Distribution
Properties:
DistributionConfig:
Origins:
- DomainName: !GetAtt S3Bucket.RegionalDomainName
More information
As well, I would highly recommend to read this blog post on the future of S3 different path formats:
Amazon S3 Path Deprecation Plan – The Rest of the Story
I found the issue. It is with cloudfront configuration.
This blog helped me.
While defining the origin I have directly selected S3 bucket. We should enter the domain of the S3 bucket like telekha-test-www.s3-website.ap-south-1.amazonaws.com
The first thing to check if you think you are seeing this is to run the curl command below. If it returns HTTP/1.1 307 Temporary Redirect, then you are seeing this issue.
$ curl -I https://YOUR_CF_DOMAINNAME.cloudfront.net/
HTTP/1.1 307 Temporary Redirect
Content-Type: application/xml
Content-Length: 0
Connection: keep-alive
x-amz-bucket-region: ap-southeast-2
Location: http://yourS3bucketname.s3-ap-southeast-2.amazonaws.com/
Date: Wed, 12 Jul 2017 00:20:27 GMT
Server: AmazonS3
Age: 1775
X-Cache: Hit from cloudfront
Via: 1.1 someid.cloudfront.net (CloudFront)
X-Amz-Cf-Id: someguid==
The best description I found of this issue is:
S3 updates the DNS for the global REST endpoint hierarchy *.s3.amazonaws.com with a record sending requests to the right region for the bucket within a short time after bucket creation, and CloudFront appears rely on this for sending the requests to the right place. Before that initial update is complete, S3 will return a redirect and CloudFront returns that redirect to the browser. ~ michael-sqlbot
Given this issue is actually due to the internal DNS propagation of the S3 bucket name (which is not 100% clear, but seems highly likely) that occurs when you configure the bucket in S3, then it should be possible to avoid this issue by configuring a public web site in S3 prior to configuring the Cloudfront distro, and per the doco, configure the S3 public web name as the cloudfront origin rather than the s3 bucketname.
For reference, I have both S3 bucket names and S3 website names configured as Cloudfront origins and I can say that they do both work! (eventually?)
References:
AWS official setup guide
AWS Forum topic
Turns out this is just a timing issue which fixes itself after a while if everything is configured correctly. More information can be found in this AWS forum thread.
Current accepted answer here and linked blog article suggest enabling static website for your S3 bucket and then changing CF origin to point to that static website. This solution does solve the redirect problem but with the side effect that you website is now available using both CF URL or your custom CNAME as well as using S3 URL.
To expand on the accepted answer, this part at the end of the referenced blog post in particular is helpful:
I found a subtle “bug” some days ago: when using URLs like
www.example.com/about/, Amazon S3 will in fact return the “index.html”
file inside the folder (because it is configured as a static website
bucket).
The funny thing is that if you omit the trailing slash
(www.example.com/about), S3 will first check if an object called
“about” exists. If it does not, it will consider that about is a
folder, and will issue a 301 redirection to about/. When using
CloudFront, this means that CloudFront will in fact cache… the
redirection instead of the file itself! Therefore, you must make sure
that all your URLs end by a trailing slash to avoid a useless
redirect.