Make one S3 bucket public - amazon-web-services

Currently I have 5 S3 buckets in my account, and all of them are Block all public access -> ON and the same setting is also there for Block Public Access settings for this account -> ON.
Now I want to create a new bucket that should be public, and I don't want to change any of my existing buckets. So for the newly created bucket I have set Block all public access = OFF. But when I try to save below policy, it gives Access denied error. So I guess I have to Turn Off Block Public Access settings for this account.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Action": "s3:GetObject",
"Effect": "Allow",
"Resource": "arn:aws:s3:::MyNewImageBucketS3/*",
"Principal": "*"
}
]
}
I want to know that if I turn off account level setting, then will it affect my existing buckets?
As a second option I can configure CloudFront and serve files publicly but want to know about the public access change at the account level.

Block all public access = OFF; this setting is for individual s3 buckets provided you are doing it from bucket settings, so for that specific bucket you can turn this off and you are good to go.
If you want specific objects to be publicly accessible then this can be achieved via similar IAM policy you shared but to make this work turn on public access on that bucket and then you can apply IAM policy to allow specific objects and deny remaining.
Below image describes that if you change it in bucket setting, its going to effect on that specific bucket and the objects within bucket only
For more guidelines please check below AWS doc
https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-policy-alternatives-guidelines.html

Related

How to make S3 objects readable only from certain IP addresses?

I am trying to setup Cloudflare to cache images from S3. I want to be as restrictive (least permissive) as possible in doing this. I assume I need to accept requests from Cloudflare to read my S3 images. I want all other requests to be rejected.
I followed this guide: https://support.cloudflare.com/hc/en-us/articles/360037983412-Configuring-an-Amazon-Web-Services-static-site-to-use-Cloudflare
I did not enable static website hosting on my bucket, because it's not necessary for my case.
In my bucket permissions I turned off "Block all public access" and temporarily turned off "Block public access to buckets and objects granted through new public bucket or access point policies". I needed to do this in order to add a bucket policy.
From the link above, I then added a bucket policy that looks something like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::www.example.com/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": [
<CLOUDFLARE_IP_0>,
<CLOUDFLARE_IP_1>,
<CLOUDFLARE_IP_2>,
...
]
}
}
}
]
}
At this point, a message appeared in the AWS console stating:
"This bucket has public access
You have provided public access to this bucket. We highly recommend that you never grant any kind of public access to your S3 bucket."
I then turned back on "Block public access to buckets and objects granted through new public bucket or access point policies" and turned off "Block public and cross-account access to buckets and objects through any public bucket or access point policies".
At this point, the S3 image request behavior seems to be working as intended, but I am not confident that I set everything up to be minimally permissive, especially given the warning message in the AWS console.
Given my description, did I properly set things up in this bucket to accept read requests only from Cloudflare and deny all other requests? I want to make sure that requests from any origin other than Cloudflare will be denied.
Sounds good! If it works from CloudFlare, but not from somewhere else, then it meets your requirements.
Those Block Public Access warnings are intentionally scary to make people think twice before opening their buckets to the world.
Your policy is nicely limited to only GetObject and only to a limited range of IP addresses.

AWS Lambda to revert back S3 "block all public access" if someone changed it to allow public access

I'm trying to use AWS Lambda to check periodically (maybe use a cron job) if the S3 block public access is turned on. If it ever finds that S3 block public access is turned off (i.e, if S3 is public), the lambda needs to revert the setting back to "block public access". Not sure where to begin with this.. please advice.
S3 Block Public Access provides controls across an entire AWS Account or at the individual S3 bucket level. You could set it at account level and ensure that all users have policies that deny permission on the s3:PutAccountPublicAccessBlock action, as follows:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "denyaccountbpa",
"Effect": "Deny",
"Action": "s3:PutAccountPublicAccessBlock",
"Resource": "*"
}
]
}
Also, be aware of the no-cost Trusted Advisor option.

Having trouble granting public read permissions in S3 bucket

I'm trying to understand the specific permissions I need to set on my Amazon S3 bucket. I've looked for this information already, but have only seen 1 or 2 examples of the new ACL/Policies that Amazon has implemented.
My use case: I'm using S3 to store images for my website (hosted elsewhere). I would like to upload images on S3 and be able to access them through their link on my own site.
I've used https://awspolicygen.s3.amazonaws.com/policygen.html to generate a GetObject policy:
{
"Id": "Policyxxxxxxxxxxxxxxxxx",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmtxxxxxxxxxxxxxxx",
"Action": [
"s3:GetObject"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::xxxxxx-xxxxx-xxxxxxx/*",
"Principal": "*"
}
]
}
These are my current Block public access settings:
Block all public access: Off
Block public access to buckets and objects granted through new access control lists (ACLs): On
Block public access to buckets and objects granted through any access control lists (ACLs): On
Block public access to buckets and objects granted through new public bucket policies: Off
Block public and cross-account access to buckets and objects through any public bucket policies: Off
In Access Control List, I have not added any permissions.
In Bucket Policy, I placed the policy I generated.
In CORS configuration, I specified localhost and my domain name as allowed origins and GET's as allowed methods.
Is this correct for my usage? It currently works, but I'm not 100% sure I've gotten the permissions right. All I need is public access to my photos (so my website can grab them) and to deny anything else (besides me logging in and uploading more photos).

What combination of Block Public Access settings makes my s3 bucket viewable to everyone?

I am new to AWS and created an s3 bucket for static site hosting. I want to allow Read-Only access to everyone so they can access the website. What combination of settings gives me this scenario? Do I need to uncheck all 4 settings in the Block Public Access settings? Do I even need to add a bucket policy if all 4 settings are set to off? I just want to make sure the bucket is never written to but the account holder. Thanks.
Block Public Access acts as an additional layer of protection to prevent Amazon S3 buckets from being made public accidentally.
By default, all content in Amazon S3 is private. You can then make content accessible in several different ways:
At the bucket-level, by creating a Bucket Policy on the desired bucket. The rules added to this bucket can be used to grant access to objects (GetObject), list contents, upload, delete, etc. The policies can also get quite specific, such as allowing access only to specific IP addresses.
At the object-level, by configuring Access Control Lists (ACLs) on each individual object. For example, an object can be made publicly accessible.
At the IAM User or IAM Group level, by adding an IAM Policy directly the to the user/group. This is great for granting access to only specific sets of IAM users (as opposed to publicly).
By using Pre-Signed URLs that are generated programmatically and provide time-limited access to a specific object. This is typically used by applications to grant access to private objects. For example, a photo-sharing website would keep all photos private, but an authorized user would be able to view their own pictures, or pictures shared with them via the application.
So, in your question, you say you would like to "allow Read-Only access to everyone so they can access the website". This would normally be done by creating a Bucket Policy such as:
{
"Version":"2012-10-17",
"Statement":[
{
"Sid":"MakeItPublic",
"Effect":"Allow",
"Principal": "*",
"Action":["s3:GetObject"],
"Resource":["arn:aws:s3:::my-bucket/*"]
}
]
}
You should first deactivate the two Block Public Access settings that refer to Bucket Policies (the bottom two).
You need Amazon CloudFront distribution. In addition to providing the benefits of an integrated CDN, you can configure an Origin Access Identity that ensures that the bucket can only be accessed through CloudFront, not through public S3.
Client -> Route53 -> Cloudfront -> S3 (blocked public access)
In Cloudfront
Create cloudfront function (from left menu), this will redirect any
request with index.html appended. For ex: example.com/home to
example.com/home/index.html
'use strict';
function handler(event) {
var request = event.request;
var uri = request.uri;
// Check whether the URI is missing a file name.
if (uri.endsWith('/')) {
request.uri += 'index.html';
}
// Check whether the URI is missing a file extension.
else if (!uri.includes('.')) {
request.uri += '/index.html';
}
return request;
}
Create the origin access (from left menu), this will be used in
distribution's origin
In Distributions
In origin tab
Create origin as S3 type, by choosing the s3 bucket
Click on origin access control settings that create at first step
Edit general settings and put index.html in default root object.
Edit Behaviours, In Function associations, select cloudfront function
in viewer request. Don’t need to go with lambda function
In S3
In properties, disable static s3 website hosting
In permissions
Block all public access
Edit the bucket policy with below:
{
"Version": "2008-10-17",
"Id": "PolicyForCloudFrontPrivateContent",
"Statement": [
{
"Sid": "AllowCloudFrontServicePrincipal",
"Effect": "Allow",
"Principal": {
"Service": "cloudfront.amazonaws.com"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::BUCKET_NAME/*",
"Condition": {
"StringEquals": {
"AWS:SourceArn": "arn:aws:cloudfront::ACC_NUMBER:distribution/DISTRIBUTION_ID"
}
}
}
]
}
In Route53
Create A record by selecting cloudfront distribution

Amazon S3 access control-Who can upload files?

I have a static website created with Amazon S3. The only permissions I have set are through the bucket policy provided in Amazons tutorial:
{
"Version":"2012-10-17",
"Statement": [{
"Sid": "Allow Public Access to All Objects",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::example.com/*"
}
]
}
Clearly, this policy enables the public to view any file stored on my bucket, which I want. My question is, is this policy alone enough to prevent other people from uploading files and/or hijacking my website? I wish for the public to be able to access any file on the bucket, but I want to be the only one with list, upload, and delete permissions. Is this the current behavior of my bucket, given that my bucket policy only addresses view permissions?
Have a look at this: http://docs.aws.amazon.com/IAM/latest/UserGuide/AccessPolicyLanguage_EvaluationLogic.html#policy-eval-basics
From that document:
When a request is made, the AWS service decides whether a given
request should be allowed or denied. The evaluation logic follows
these rules:
By default, all requests are denied. (In general, requests made using
the account credentials for resources in the account are always
allowed.)
An explicit allow overrides this default.
An explicit deny overrides any allows.
So as long as you don't explicitly allow other access you should be fine. I have a static site hosted on S3 and I have the same access policy.