Cannot seem to write to S3 bucket set up as website - amazon-s3

I'm trying to do the following scenario:
bucket set up called share.example.com.
My website will be writing to this bucket - dynamically (User generated content).
I want the bucket to be a website, with index.html as the default document.
So a user does something on my site, app then writes to
share.example.com/foo/bar1/index.html
I then want the user to be able to browse to
http://share.example/foo/bar1/ (<-- note, no index.html)
I thought this would be trivial:
set up bucket as website with index.html as default doc
only I have permissions to write to the bucket
set up a bucket policy to allow anonymous read
create CNAME for share.example.com to share.example.com.s3-website-us-east-1.amazonaws.com
However, a problem.
In the above configuration, when I try the write, I get a 405.
If I change the CNAME to point to share.example.com.s3.amazonaws.com, the write succeeds, but now the website won't work as required.
What is the solution here?
Thanks a stack for any help.

The trick was to not use the vanity domain for the writing aspect.
I.e. instead of trying to do the PUT to share.example.com/foo/bar1, do it to s3.amazonaws.com/share.example.com/foo/bar1
The CNAME to share.example.com can then point to share.example.com.s3-website-us-east-1.amazonaws.com and it all works.

Related

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

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/

URL to S3 file in private bucket

I've uploaded a file using the SDK to my private S3 bucket.
I can access this file through the S3 UI.
However, I cannot access this file through a direct link. It gives me some XML that includes "AccessDenied" as a code and message.
It seems reasonable that since I'm authenticated in the browser and am clicking on a direct link to the file from the same browser, that I should be allowed through. At the very least, I should be directed to a login page.
Does anyone have any experience with this?
So after working on this for a bit, I discovered the best thing is to simply publish the console URL to the file.
https://s3.console.aws.amazon.com/s3/object/{your bucket}/{your file path}?region={the region of your bucket}&tab=overview
Be mindful to specify the correct region. If you're forming this programmatically, then use Amazon.RegionEndpoint.SystemName.
If you're not logged in, it will ask you for your login!
No signed URL is necessary.
Thanks to everyone who contributed!
There are 2 places that you need to make sure are set correctly based on how you want to setup access to the bucket. It will either have public or private access.
The properties tab:
Here you can set what you will use the bucket for.
The Permissions tab -> Bucket Policy:
With this, you can then setup access. I was able to generate a policy with this site:
http://awspolicygen.s3.amazonaws.com/policygen.html
EDIT:
Mine is working with the settings I have shown. I recommend asking the AWS boards if to get to the bottom of it. You could also try this:
You can use the direct link if you are inside a VPC. You have to :
1- Create a VPC endpoint for Amazon S3.
2- Add a bucket policy that allows access from the VPC endpoint.
All steps are described in the following link :
https://aws.amazon.com/premiumsupport/knowledge-center/s3-private-connection-no-authentication/?nc1=h_ls

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.

Why must the Amazon S3 bucket name be the same as website name when hosting a static website

I want to host a static website on S3, i.e. example.com. It requires a bucket name the same as example.com.
Then I found example.com had been occupied by other people.
So that's my question, why bucket name must be the same as the website name? For there are Route 53 to map the website to the bucket endpoints, it appears no necessary for this limitation.
Is there any reason for this?
The brief answer is, "that's how Amazon designed it."
If the bucket name weren't the same as the domain name, how would S3 know which bucket to use to serve requests for a given domain?
You can't say "Route 53," because S3 was created before Route 53, and web site hosting in S3 works the same even if you aren't using Route 53 for DNS.
Similarly, it can't be a configuration option on the bucket, because that would just create a new series of problems -- if the previous owner of a domain still had their bucket configured with your domain, you'd have exactly the same problem as you do, now.
You can still host your site on S3, but with a mismatched bucket name, you need either a reverse proxy server in EC2 in the same region, to rewrite the host header in each request to match the bucket name, or, you can use CloudFront to accomplish a similar purpose, because the bucket name, then, does not need to match -- CloudFront will rewrite the Host header also.
There's a pretty simple reason for this: by the time Amazon gets the request from your browser, the main information available is the domain in the URL, which isn't enough to figure it out.
Suppose your site is example.com, but that bucket name is taken, so you make the bucket my-example. Then you'll have an URL something like http://my-example.s3-website.us-east-1.amazonaws.com/. That will work just fine in your browser, because it gets resolved to some AWS web server, which looks at the Host HTTP header, pulls out your bucket name, and grabs your bucket content.
Now suppose you add something to Route53 to make example.com work. You can either add A records, which let your browser turn example.com directly into an IP address for some AWS S3 webserver. Or you can put in a CNAME, which points from example.com to the full my-example hostname. Either way, your browser's going to look up an IP address, contact an Amazon webserver, and send a Host header that just says example.com. So if that isn't the bucket name, it doesn't know what to do.
Admittedly, it could go an extra step. After all, you told it the hostname when you set up the bucket for serving websites. So at first thought, it seems like it would be nice if it used that as well. However, that won't really solve your problem either, because whoever set up the example.com bucket could well have set it up for hosting.
It seems like the best way to work around this is Cloudfront, which can associate domain names with arbitrary buckets.
I think is the way AWS have designed this and that's it : Check this
I have this done for my company's website and it works great!
Create an S3 bucket and configure it to host a website
Amazon S3 lets you store and retrieve your data from anywhere on the
internet. To organize your data, you create buckets and upload your
data to the buckets by using the AWS Management Console. You can use
S3 to host a static website in a bucket. The following procedure
explains how to create a bucket and configure it for website hosting.
To create an S3 bucket and configure it to host a website
Open the Amazon S3 console at https://console.aws.amazon.com/s3/.
Choose Create bucket.
Enter the following values:
Bucket name - Enter the name of your domain, such as example.com.
Region - Choose the region closest to most of your users.
Make note of the region that you choose; you'll need this information later in the process.
Choose Next.
On the Configure options page, choose Next to accept the default values.
On the Set permissions page, uncheck the Block all public access check box, and choose Next.
Note
The console displays a message about public access to the bucket. Later in this procedure, you add a bucket policy that limits access to the bucket.
On the Review page, choose Create bucket.
On the list of S3 buckets, choose the name of the bucket that you just created.
Choose the Properties tab.
Choose Static website hosting.
Choose Use this bucket to host a website.
For Index document, enter the name of the file that contains the main page for your website.
Note
You'll create an HTML file and upload it to your bucket later in the process.
Choose Save.
Choose the Permissions tab.
Choose Bucket policy.
Copy the following bucket policy and paste it into a text editor. This policy grants everyone on the internet ("Principal":"*") permission to get the files ("Action":["s3:GetObject"]) in the S3 bucket that is associated with your domain name ("arn:aws:s3:::your-domain-name/*"):
{
"Version":"2012-10-17",
"Statement":[{
"Sid":"AddPerm",
"Effect":"Allow",
"Principal":"*",
"Action":[
"s3:GetObject"
],
"Resource":[
"arn:aws:s3:::your-domain-name/*"
]
}]
}
In the bucket policy, replace the value your-domain-name with the name of your domain, such as example.com. This value must match the name of the bucket.
Choose Save.
Create another S3 Bucket, for www.your-domain-name
In the preceding procedure, you created a bucket for your domain name, such as example.com. This allows your users to access your website by using your domain name, such as example.com.
If you also want your users to be able to use www.your-domain-name, such as www.example.com, to access your sample website, you create a second S3 bucket. You then configure the second bucket to route traffic to the first bucket.
Note
Websites typically redirect your-domain-name to www.your-domain-name, for example, from example.com to www.example.com. Because of the way S3 works, you must set up the redirection in the opposite direction, from www.example.com to example.com.
To create an S3 bucket for www.your-domain-name
Choose Create bucket.
Enter the following values:
Bucket name - Enter www.your-domain-name. For example, if you registered the domain name example.com, enter www.example.com.
Region -Choose the same region that you created the first bucket in.
Choose Next.
On the Configure options page, choose Next to accept the default values.
On the Set permissions page, choose Next to accept the default values.
On the Review page, choose Create bucket.
n the list of S3 buckets, choose the name of the bucket that you just created.
Choose the Properties tab.
Choose Static website hosting.
Choose Redirect requests.
Enter the following values:
Target bucket or domain
Enter the name of the bucket that you want to redirect requests to. This is the name of the bucket that you created in the procedure To create an S3 bucket and configure it to host a website.
Protocol - Enter http. You're redirecting requests to an S3 bucket that is configured as a website endpoint, and Amazon S3 doesn't support HTTPS connections for website endpoints.
Choose Save.