S3 Bucket Policy to work with CloudFront GetObject and PutObject directly to the bucket using Multer-S3 - amazon-s3

I am trying to make a S3 bucket policy that only allows GetObject from CloudFront but able to PutObject directly to the bucket.
Tried with several combinations but none of the worked.
Here is the latest attempt that I tried.
With, Block All Public Access: ALL OFF.
Bucket Policy:
{
"Version": "2012-10-17",
"Id": "Policy1604429581591",
"Statement": [
{
"Sid": "Stmt1605554261786",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::MYBUCKET/*"
},
{
"Sid": "Stmt1605557746418",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::MYBUCKET/*"
},
{
"Sid": "Stmt1605557857544",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:MYCLOUDFRONT"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::MYBUCKET/*"
}
]
}
This allows me to PutObject to the bucket but GetObject using CloudFront URL got access denied. If I removed
{
"Sid": "Stmt1605557746418",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::MYBUCKET/*"
}
I can GetObject from CloudFront as well as from bucket directly.
Please help!

Found the solution of it.
First follow the instructions here to setup CloudFront: https://aws.amazon.com/premiumsupport/knowledge-center/cloudfront-access-to-amazon-s3/. Key point is
5. For Restrict Bucket Access, select Yes.
I was using Multer-S3 to upload my image files. ACL needs to be set to
acl: 'authenticated-read',
Also I am using serverSideEncryption, in S3 bucket properties=>Default encryption
Default encryption: Enabled
Server-side encryption: Amazon S3 master-key(SSE-S3)
Multer-S3 config
serverSideEncryption: 'AES256',
S3 Bucket permission un-Block all public access and ACL only enables Bucket Owner's permissions.
The final bucket policy I have is:
{
"Version": "2008-10-17",
"Id": "PolicyForCloudFrontPrivateContent",
"Statement": [
{
"Sid": "1",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E36AHAEXL422P3"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::MYBUCKET/*"
},
{
"Sid": "Stmt1605745908405",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::MYBUCKET/*",
"Condition": {
"StringEqualsIfExists": {
"s3:x-amz-server-side-encryption": "AES256"
}
}
}
]
}
With all above configurations, this allows PubObject from anyone as long as requests have server side encryption with 'AE256'. GetObject requests directly to the bucket will be blocked. All GetObject requests need to go through CloudFront.

Related

Why bucket policy is used?

I have a question about s3 bucket access, it's so complecated for me.
my configuration for s3 bucket is "public access is denied"
when I don't specify any policy in s3 bucket policy and give a user predefined S3 readonly permission, I can bring list of buckets and list of object in buckets.
But when I only make bucket policy for the user who has no iam policy attached to list buckets and object. the user are not able to list buckets and objects.
If it is true, why bucket policy is necessary to use?
bucket policy I made is like this.
{
"Version": "2012-10-17",
"Id": "Policy1672363253371",
"Statement": [
{
"Sid": "Stmt16",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::2040:user/viewer"
},
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::test-bucket"
}
{
"Sid": "Stmt17",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::2040:user/viewer"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::test-bucket/*"
}
]
}

IAM Policy is not giving access to the accesspoint

With this policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:ListStorageLensConfigurations",
"s3:ListAccessPointsForObjectLambda",
"s3:GetAccessPoint",
"s3:PutAccountPublicAccessBlock",
"s3:GetAccountPublicAccessBlock",
"s3:ListAllMyBuckets",
"s3:ListAccessPoints",
"s3:ListJobs",
"s3:PutStorageLensConfiguration",
"s3:CreateJob"
],
"Resource": "*"
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": "s3:*",
"Resource": "*"
}
]
}
I am allowed to access a specific s3 accesspoint. However, when I try using a more specific access which only gives s3:* actions to a specific accesspoint:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:ListStorageLensConfigurations",
"s3:ListAccessPointsForObjectLambda",
"s3:GetAccessPoint",
"s3:PutAccountPublicAccessBlock",
"s3:GetAccountPublicAccessBlock",
"s3:ListAllMyBuckets",
"s3:ListAccessPoints",
"s3:ListJobs",
"s3:PutStorageLensConfiguration",
"s3:CreateJob"
],
"Resource": "*"
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": "s3:*",
"Resource": "arn:aws:s3:eu-west-1:598276570227:accesspoint/accesspointname"
}
]
}
This does not work, and the EC2 with this role stops being able to access the s3 access point (just copying a file using the AWS CLI)
First why is this happening? The role still should have access to all the actions on that accesspoint by my reckoning (which must be wrong in some way!).
Secondly, I am trying to make it such that an s3 bucket is only accessible from a certain IAM role. I tried setting this from the access policy from the access point itself. This had the opposite problem that it was too permissive and everything could still access it. What is the correct way of doing this - putting an IAM policy on the accesspoint to restrict access to the IAM role or making an IAM Role which has access to this s3 access point?
I got this working by using this:]
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:ListStorageLensConfigurations",
"s3:ListAccessPointsForObjectLambda",
"s3:GetAccessPoint",
"s3:PutAccountPublicAccessBlock",
"s3:GetAccountPublicAccessBlock",
"s3:ListAllMyBuckets",
"s3:ListAccessPoints",
"s3:ListJobs",
"s3:PutStorageLensConfiguration",
"s3:CreateJob"
],
"Resource": "*"
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": "s3:*",
"Resource": "*",
"Condition": {
"StringLike": {
"s3:DataAccessPointArn": "arn:aws:s3:eu-west-1:598276570227:accesspoint/accesspointname"
}
}
}
]
}

What should be bucket policy for a S3 that is owned by Coudfront OAI set but allow other AWS account to upload s3 objects

I have S3 that has restricted policy to serve private content. Only Cloudfront Origin Access Identity can access. But, other account should be allowed to upload new objects so that client can get new assets. What kind of policy should be set for this situation?
Currently my policy is like this
{
"Sid": "1",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity SomeID12334"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-bucket/*"
}
You can add multiple statements in your bucket policy to handle the permissions.
Provide the role ARN from another account to provide the access to do specific actions on bucket.
{
"Sid": "1",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity SomeID12334"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-bucket/*"
},
{
"Sid": "Stmt1570159952662",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<accountno>:role/rolename"
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::my-bucket"
}

AWS S3 bucket policy to block source IP address not working

I know this question has been asked a few times and I have gone through a some documents and examples on this. But I am still not able to get it working.
I want to block access to my S3 bucket from one particular IP address and allow all others. I do not want to block instances belonging to an IAM role and hence I am using NotIpAddress Condition for this. Below is the policy I applied on my bucket:
{
"Version": "2012-10-17",
"Id": "Policy1486984747194",
"Statement": [
{
"Sid": "AllowAllExceptOneIP",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:*",
"Resource": "arn:aws:s3:::my-test-bucket",
"Condition": {
"NotIpAddress": {
"aws:SourceIp": "52.38.90.46"
}
}
}
]
}
But this policy isn't working. I am able to upload files to my bucket from this machine, I am using s3-curl.pl to temporarily upload my files.
Can someone please help me find what is wrong here. Thanks.
To block all actions to an S3 bucket from a particular IP, policy needs to have separate deny effect statement for that IP, sample:
{
"Version": "2012-10-17",
"Id": "Policy1487062767078",
"Statement": [
{
"Sid": "AllowAll",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::my-test-bucket",
"arn:aws:s3:::my-test-bucket/*"
]
},
{
"Sid": "DenyIP",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::my-test-bucket",
"arn:aws:s3:::my-test-bucket/*"
],
"Condition": {
"IpAddress": {
"aws:SourceIp": "52.38.90.46"
}
}
}
]
}
Action and Resource can be changed based on what one needs to block.
Thanks a lot #SergeyKovalev for helping me with this solution.

Aws s3 read only bucket policy not working with cloudfront

I have made a S3 bucket policy for readonly access to cloudfront, i want to restrict s3 bucket for public and just allow it from referrer urls via cloudfront how ever it is not applying my s3 bucket policy.
{
"Version": "2012-10-17",
"Id": "http referer",
"Statement": [
{
"Sid": "Allow get requests referred by www.def.com and dev.def.com.",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity XXXXXXXXXXX"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::devmb/*",
"Condition": {
"StringLike": {
"aws:Referer": [
"http://www.def.com/*",
"http://dev.def.com/*"
]
}
}
},
{
"Sid": "Explicit deny to ensure requests are allowed only from specific referer.",
"Effect": "Deny",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity XXXXXXXXXXXXX"
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::devmb/*",
"Condition": {
"StringLike": {
"aws:Referer": [
"http://dev.xyx.com/*",
"http://blog.xyz.com/*"
]
}
}
}
]
}
My content is public right now.
Referer does not work when using CloudFront because the referer does not appear in the HTTP request header itself. You'll have to use S3 without CloudFront if you wish to restrict access using conditional aws:Referer in the bucket policy.