CloudFront or S3 ACL: This XML file does not appear to have... AccessDenied / Failed to contact the origin - amazon-s3

I'm using custom domain and CloudFront for S3 static hosting site to serve https.
It's working fine when I open the pages through the app's internal buttons or link,
but if I input direct URL in the address bar, or click the browser refresh button, it shows
This XML file does not appear to have any style information associated with it. The document tree is shown below.... Access Denied error screen.
I searched related answers and tried to /index.html in the CloudFront general setting as Default Root Object but it didn't work. (Before this try, it was index.html)
When I updated it as /index.html, even the domain itself didn't work.
I have another S3 static hosting site without CloudFront and certificate just for testing.
This site is working fine even I input direct url or click the refresh button.
Above two S3 bucket have same settings (root object is index.html and error document is also index.html)
After this, I changed CloudFront Origin Domain Name from REST endpoint to website endpoint referred to this docs (https://aws.amazon.com/premiumsupport/knowledge-center/s3-website-cloudfront-error-403/)
But now getting this error when I refresh the screen.
All the object in S3 is owned to bucket owner and has public access.
This app is made by React and using react-router-dom.
Could you give me any hint or advice?
Thanks.

Solved...
My S3 bucket region requires . instead of - when I use website endpoint for cloudfront.
And FYI..
In my case, there are some little difference with the document and some tutorial. My CloudFront distribution doesn't need to use default root object, and individual objects in S3 has no public access but the bucket has it.

There are some specific endpoints to be used for website hosting buckets, which are listed in the Amazon Simple Storage Service endpoints and quotas document. For example, when hosting in eu-west-1, cloudfront will prepopulate the dropdown with example.s3.eu-west-1.amazonaws.com, but if you look into the bucket settings, Static website hosting section, it will show you the correct url example.s3-website-eu-west-1.amazonaws.com
Carefully read the table! The url scheme is not fully consistent, eg. s3-website.us-east-2.amazonaws.com but s3-website-us-east-1.amazonaws.com - just to make your day a bit more joyful.

So I had the exact same issue and was able to resolve it after taking the s3 bucket endpoint located in the properties of the s3 bucket and then pasting it into the cloudfront origins section into the origin domain. I removed the beginning of the endpoint for example: "http://website.com.s3-website.us-east-2.amazonaws.com" you would just remove the "http://" and then post the rest into the cloudfront origin domain and click save. That should solve the problem!
I tried all kinds of different options such as making sure every object was public as well in the s3 bucket. Make sure your s3 bucket is also publicly available.
Certain regions do have different endpoints for your s3 buckets. Here is a link that shows more of that: https://aws.amazon.com/premiumsupport/knowledge-center/s3-rest-api-cloudfront-error-403/

Related

Cannot access subpages of my NextJS static site on S3 via cloudfront when public access is blocked

I have configured cloudfront to serve my NextJS static site from an S3 buckets. I have intentionally blocked all public access to my S3 bucket, so the only way to access this site would via the cloudfront URL (I've set up Origin access control "OAC" on the cloudfront distribution, so that's how cloudfront is able to access my S3 bucket. For the cloudfront origin domain, I have added the S3 bucket URL and not the static hosting endpoint, because S3 static hosting endpoint requires S3 objects to be publicly accessible, which is what I am trying to block).
I am able to go to my website and click around using the cloudfront URL. It navigates to subpages and content shows up as expected. However, refreshing on a subpage results in the 'AccessDenied' page.
For example, this is the name of the website: https://example.com
Going to https://example.com works fine, it shows the index.html like I have configured. And then, clicking a button on the website takes me to https://example.com/another-page, which also shows up just fine. However, if I refresh on https://example.com/another-page, that's when the 'AccessDenied' error shows up
Are there ways to get around it, so I can go straight to the subpages? It feels like it is possible, given that I was able to navigate to https://example.com/another-page within the app itself.

CloudFront - Editing Origin - Restrict Bucket Access

I have a situation which I am unable to understand easily why and I am not able to find any documentation either.
I have done the following:
Created a S3 bucket
Given public access to it
Enabled it for static website hosting
Created a CloudFront distribution to it
Enabled HTTPS at cloudfront
Now I am trying to restrict the access of S3 bucket only to CloudFront.
I tried the steps presented at
https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-restricting-access-to-s3.html
Unfortunately, when I tried to edit the origin I don't see all the options in the UI especially Restrict Bucket Access is missing.
I only see options to edit Origin Domain Name, Origin Path, Origin Id (grayedout), Origin Custom Headers - No option to enter OAI or setting Restrict Bucket Access etc.
Is it because of enabling HTTPS?
S3 masters, please help!
Origin access identities are only applicable when using the S3 REST endpoint (e.g. example-bucket.s3.amazonaws.com) for the bucket -- not when you are using the website hosting endpoint (e.g. example-bucket.s3-website.us-east-2.amazonaws.com), because website hosting endpoints do not support authenticated requests -- they are only for public content... but OAI is an authentication mechanism.
When using the website endpoint, CloudFront does not treat the origin as an S3 Origin -- it is treated as a Custom Origin, and these options are not available, because if they were available, they wouldn't work anyway (for the reason mentioned above).
For those who have since changed some S3 settings to not be public and intend it to be only retrievable via Cloudfront, it is now there but hidden. You just have to cut copy the value from Origin Domain Name in origin tab and then re-paste it in again (if its the name bucket) and the UI will now render with the Restrict Access input options.

ListBucketResult xml trying to show home page of site in S3 thorugh CloudFront

I created a bucket where I´m hosting my static website.
I set the properties to use it as static website hosting (which index document value index.html)
The URL was: http://mywebsitelearningcurve.s3-website-us-east-1.amazonaws.com (not currently up, just to explain)
I exposed it as public (permission).
Overview of my bucket
/images
/static
/asset-manifest.json
/favicon.ico
/index.html
/manifest.json
/service-worker.js
Using http://mywebsitelearningcurve.s3-website-us-east-1.amazonaws.com I could access to my site. However I decided to use CloudFront in front of my bucket.
I created a new distribution for WEB.
On Origin Domain Name I used mywebsitelearningcurve.s3.amazonaws.com
Origin ID: S3-mywebsitelearningcurve
In Viewer Protocol Policy I selected: Redirect HTTP to HTTPS.
Once it finished and I waited for a prudential time to propagate, I had the url https://d2qf2r44tssakh.cloudfront.net/ (not currently up, just to explain).
The issue:
When I tried to use https://d2qf2r44tssakh.cloudfront.net/ it showed me a xml
<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Name>mywebsitelearningcurve</Name>
...
...
...
</ListBucketResult>
However, when I tried https://d2qf2r44tssakh.cloudfront.net/index.html it works properly.
I go through several tutos and post but I can´t still make it work. Anyone can provide help?
Thanks
I had the same problem today and was able to fix it by adding index.html to the Default Root Object in the distribution settings:
Optional. The object that you want CloudFront to return (for example,
index.html) when a viewer request points to your root URL
(http://www.example.com) instead of to a specific object in your
distribution (http://www.example.com/index.html).
i had 5 years prod experience on AWS with 5 certifications in place.
When it comes to s3 + cloudfront, i got always in troubles
I tried to automate that using Cloudformation, but Cloudformation does not support everything needed (.i.e. custom origin in cloudfront).
At the end, i relies only on terraform to automate this part:
https://github.com/riboseinc/terraform-aws-s3-cloudfront-website/blob/master/sample-site/main.tf
If you don't mind to use terraform, i highly recommend to jump there.

Prevent view of individual file in AWS S3 bucket

I'm currently looking to host an app with the Angular frontend in a AWS S3 bucket connecting to a PHP backend using the AWS Elastic Beanstalk. I've got it set up and it's working nicely.
However, using S3 to create a static website, anyone can view your code, including the various Angular JS files. This is mostly fine, but I want to create either a file or folder to keep sensitive information in that cannot be viewed by anyone, but can be included/required by all other files. Essentially I want a key that I can attach to all calls to the backend to make sure only authorised requests get through.
I've experimented with various permissions but always seems to be able to view all files, presumably because the static website hosting bucket policy ensures everything is public.
Any suggestions appreciated!
Cheers.
The whole idea of static website hosting on S3 means the content to be public, for example, you have maintenance of your app/web, so you redirect users to the S3 static page notifying there is maintenance ongoing.
I am not sure what all have you tried when you refer to "experimented with various permissions", however, have you tried to setup a bucket policy or maybe setup the bucket as a CloudFront origin and set a Signed URL. This might be a bit tricky considering you want to call these sensitive files by other files. But the way to hide those sensitive files will either be by using some sort of bucket policy or by restricting using some sort of signed URL in my opinion.

Create my own error page for Amazon S3

I was wondering if it's possible to create my own error pages for my S3 buckets. I've got CloudFront enabled and I am using my own CNAME to assign the S3 to a subdomain for my website. This helps me create tidy links that reference my domain name.
When someone tries to access a file that has perhaps been deleted or the link isn't quite correct, they get the XML S3 error page which is ugly and not very helpful to the user.
Is there a way to override these error pages so I can display a helpful HTML page instead?
If you configure your bucket as a 'website', you can create custom error pages.
For more details see the Amazon announcement of this feature and the AWS developer guide.
There are however some caveats with this approach, a major one being that your objects need to be publicly available.
It also works with Cloudfront, but the same public access limitations apply. See https://forums.aws.amazon.com/ann.jspa?annID=921.
If you want, you can try these out
right away by configuring your Amazon
S3 bucket as a website and making the
new Amazon S3 website endpoint a
custom origin for your CloudFront
distribution. A few notes when you do
this. First, you must set your custom
origin protocol policy to “http-only.”
Second, you’ll need to use a tool that
supports CloudFront’s custom origin
feature – the AWS Management Console
does not at this point offer this
feature. Finally, note that when you
use Amazon S3’s static website
feature, all the content in your S3
bucket must be publicly accessible, so
you cannot use CloudFront’s private
content feature with that bucket. If
you would like to use private content
with S3, you need to use the S3 REST
endpoint (e.g., s3.amazonaws.com).