How to make a public bucket only accessible from cloudfront without OAI? - amazon-web-services

I have a bucket that contains some images. The bucket is publicly accessible using the following policy.
{
"Version": "2008-10-17",
"Id": "s3BucketPolicy",
"Statement": [
{
"Sid": "1",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::Bucketname/*"
}
]
}
Also I have a cloudfront distribution that points to the same bucket. My problem now is that my file is accessible from both cloudfront link and bucket link.
CloudfrontLink: www.xxxxxx.xxxx/xxxx
BucketLink: www.bucketname/xxx
My question how can i make my bucket publicly accessible using cloudfront only. I don't want signed urls or cookies. I want any my anyone with cloudfrontlink to be able to access the image and prevent anyone with bucketlink from accessing the image.

Change the S3 bucket policy principal to the OAI of the CloudFront Distribution. For example:
{
"Version": "2008-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity ABCDABCDABCDAB"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::mybucket/*"
}
]
}
This will prevent access to the bucket contents outside of CloudFront. You don't need signed URLS here. See the documentation for more details.

Related

How to set access level as "Public" for all files uploading to an S3 bucket?

I have created an S3 bucket and also an API through the AWS API Gateway to upload images to the bucket. The problem is, when I upload an image, to view that image I need to update the Access control list (ACL) to Public for each image separately. Even though I set everything to the public in the bucket permissions, still I have to update the ACL in each image to access them. How can I set the access level to "Public" for the whole bucket once?
This is my bucket permissions:
Access: Public
Block all public access: Off
Bucket policy:
{
"Version": "2012-10-17",
"Id": "Policy1647249671911",
"Statement": [
{
"Sid": "Stmt1647249649218",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:*",
"Resource": "arn:aws:s3:::mybucketname"
}
]
}
Access control list (ACL):
Your current policy is highly insecure and allows anyone to do pretty much anything with your bucket, including changing it policy or deleting it.
The correct bucket policy for public, read-only access is:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicRead",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:GetObject",
"s3:GetObjectVersion"
],
"Resource": [
"arn:aws:s3:::DOC-EXAMPLE-BUCKET/*"
]
}
]
}

Static web hosting on AWS S3 giving me "403 permission denied"

I will appreciate if anyone can point me out where I'm doing wrong. see below steps
I have a domain name in route53.
Based on the domain name, I have created a bucket name ( for sake of my question lets stick to bucket and domain name as abc.nl)
Created the bucket, without changing any default provided check-list.
Clicked the bucket(abc.nl) and added below "bucket policy"
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::1234567:user/usrname"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::abc.nl/*"
}
]
}
I have provided my username policy of AmazonS3FullAccess in IAM.
My Block public access (account settings) also unchanged.
Now I uploaded my all static files to the bucket(abc.nl).
In properties tab, I have added index.html under static website hosting block.
Now, as per the manual, I should able to click the link and access the page.
But for some reason, it's throwing me 403 access forbidden error.
In my understanding, by simply adding bucket policy you turn on public access. But for me, I don't see "public" tag. So, don't know what's going on. (My understanding could be wrong, hence this post.)
In case you are wondering which manual, I'm following, https://docs.aws.amazon.com/AmazonS3/latest/dev/website-hosting-custom-domain-walkthrough.htmlhow to host static web site.
Anyway, anyone points me out, where I'm doing wrong and which options should I choose from the permissions for the bucket? I could be missing out some lines.
PS: I have created and deleted the same bucket multiple times, just to start fresh every time.
The Principal value of your bucket policy is wrong. Copied from the Example: Setting up a Static Website Using a Custom Domain that you have linked to:
To grant public read access, attach the following bucket policy to the example.com bucket, substituting the name of your bucket for example.com.
{
"Version":"2012-10-17",
"Statement":[{
"Sid":"PublicReadGetObject",
"Effect":"Allow",
"Principal": "*",
"Action":["s3:GetObject"],
"Resource":["arn:aws:s3:::example.com/*"]
}]
}
To make the bucket public (= everyone), you need to set * as principal in your bucket policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::abc.nl/*"
}
]
}
Please also check that you don't have Block public access settings on the bucket because it will prevent you from making the bucket public.
Follow the below Steps 100% working.
Under Buckets, choose the name of your bucket.
Choose Permissions.
Under Bucket Policy, choose Edit.
To grant public read access to your website, copy the following bucket policy, and paste it into the Bucket policy editor.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::**YOUR-BUCKET-NAME**/*"
]
}
]
}
NOTE: AWS documentation Link
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicRead",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:GetObject",
"s3:GetObjectVersion"
],
"Resource": "arn:aws:s3:::pasteyourbucketname(copy&pasteARNName)/*"
}
]
}

I cannot access domain is set Amazon routes&S3

I cannot access domain whose bluehacking.com is set Amazon routes&S3.
I bought bluehacking.com in Amazon routes.Now I want to access bluehacking.com.So,I went to Amazon S3,made bucket whose name is bluehacking.com and set Permission of Bucket Policy like
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AddPerm",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::bluehacking.com/*"
}
]
}
I upload index.html in Static website hosting.
However when I access bluehacking.com,"You cannot access this site" is shown.index.html is not shown. What is wrong in my setting?How should I fix this?
You need to set public read access to your bucket:
{
"Version":"2012-10-17",
"Statement":[{
"Sid":"PublicReadGetObject",
"Effect":"Allow",
"Principal": "*",
"Action":["s3:GetObject"],
"Resource":["arn:aws:s3:::bluehacking.com/*"
]
}
]
}

AWS S3 sharing access to static website - 403 access denied

I've configured my bucket policy (for a static website hosted on an S3 bucket) so that another account can perform actions on this bucket. The policy looks something like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::mybucket.com/*"
},
{
"Sid": "Example permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::00000000000:user/username"
},
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::mybucket.com"
},
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::000000000000:user/username"
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::mybucket.com/*"
}
]
}
The first object in "Statement" specifies that this bucket should be readable by the public, so that anyone can access the site (I am using Route 53 as well).
The second account is able to upload files to the bucket, however once he uploads a file, then access is restricted to that file, i.e. if he uploads index.html to the top-level directory of the bucket, then navigating to the website will produce a 403 access denied error.
I have looked into IAM roles, which I think may be related but would appreciate any help with this.

How to set S3 bucket policy to (mostly) private when object acl is public?

I can't work out how to set my bucket policy to achieve what I want. Any help would be much appreciated! My desired rules are:
users in my account have access via user policies, so shouldn't need access specifically granted to them
anonymous users (or anyone outside my AWS account) should have no access, except:
one folder /temp_public should have a public GetObject (i.e. if you know the URL you can get the file)
these policies should override the object ACL on the files in the bucket, as the object ACLs are sometimes set to public read.
The reason for creating the bucket policy is that many of the objects in the bucket have a public read ACL (inadvertently set when the files were uploaded, but could also happen in future so I want to override the object ACL with the bucket ACL).
Ignoring the temp_public folder, I hoped I could just do this:
{
"Version": "2008-10-17",
"Id": "Policy123456789",
"Statement": [
{
"Sid": "Stmt1",
"Effect": "Deny",
"NotPrincipal": {
"AWS": "arn:aws:iam::123456789012:root"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-bucket-name/*"
}
]
}
(where 123456789012 is my AWS account number), but I get access denied for all users with that bucket policy. I guess the NotPrincipal isn't working in this case?
thanks for any suggestions!
Rory
UPDATE: cross-posted here on AWS forums, and answered!
Many thanks to IP from AWS Forums for this answer, which I've confirmed is working for me:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::BucketName/temp_public/*"
}
]
}
This statement will give anyone Read access to objects inside temp_public folder, regardless ACLs on those files.
To override the public access on all other files, you should provide a +Deny+-type statement. The explicit Deny overrides any Allow access, so you must exclude already given permissions. so use NotResource as an exclusion mask (NOT FINAL YET, read below):
{
"Effect": "Deny",
"Principal": "*",
"Action": "s3:GetObject",
"NotResource": "arn:aws:s3:::BucketName/temp_public/*"
}
However, this will deny access to ALL users including your account too, because principal is set to "*". Therefore, you must exclude your account from this Deny (STILL NOT FINAL):
{
"Effect": "Deny",
"NotPrincipal": { "AWS": "arn:aws:iam::XXXXYYYYZZZZ:root" },
"Action": "s3:GetObject",
"NotResource": "arn:aws:s3:::BucketName/temp_public/*"
}
(where XXXXYYYYZZZZ is your 12-digit AWS account Id)
There's still problem: the statement above denies access to all IAM users (except root account).
You'd like to exclude all your IAM users too, but this is tricky. For some reasons, Amazon S3 doens't support wildcards for specifying IAM users in a bucket policy. You cannot write "arn:aws:iam::XXXXYYYYZZZZ:user/*" as Principal (it gives an error: "Invalid principal in policy"). You have to specify exact user names:
{
"Effect": "Deny",
"NotPrincipal": {
"AWS": [
"arn:aws:iam::XXXXYYYYZZZZ:root",
"arn:aws:iam::XXXXYYYYZZZZ:user/user1",
"arn:aws:iam::XXXXYYYYZZZZ:user/user2",
"arn:aws:iam::XXXXYYYYZZZZ:user/user3",
"arn:aws:iam::XXXXYYYYZZZZ:user/user4" ]
}
"Action": "s3:GetObject",
"NotResource": "arn:aws:s3:::BucketName/temp_public/*"
}
NB from Rory: The S3 docs suggest you can use arn:aws:iam::XXXXYYYYZZZZ:root to cover all users in the account, but that just doesn't seem to work
So the final policy will look like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::BucketName/temp_public/*"
},
{
"Effect": "Deny",
"NotPrincipal": {
"AWS": [
"arn:aws:iam::XXXXYYYYZZZZ:root",
"arn:aws:iam::XXXXYYYYZZZZ:user/user1",
"arn:aws:iam::XXXXYYYYZZZZ:user/user2",
"arn:aws:iam::XXXXYYYYZZZZ:user/user3",
"arn:aws:iam::XXXXYYYYZZZZ:user/user4" ]
}
"Action": "s3:GetObject",
"NotResource": "arn:aws:s3:::BucketName/temp_public/*"
}
]
}