Grant Access to AWS S3 bucket from specific IP without credentials - amazon-web-services

I do not want to make my S3 bucket publicly accessible. But I expect it to be accessible from my local organization network without the AWS CLI or any credentials. How can I achieve it?.
I tried bucket policy with principal as * and source IP as the public IP of organization network.

If the intention is to grant anonymous access to a particular CIDR range, while also permitting IAM policies to grant additional access to specific people (eg Administrators), then this would not be appropriate.
IF you were to follow the initial example laid out by the AWS documentation - you’ll end up with a policy that probably looks similar to this.
{
"Id": "S3PolicyId1",
"Statement": [
{
"Sid": "IPAllow",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::examplebucket/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "x.x.x.x/xx"
}
}
}
]
}
What you’re going to find, after banging your head on the table a few times, is that this policy does not work. There does not appear to be an implied deny rule with S3 buckets (similar to how IAM access policies are setup).
By default accounts are restricted from accessing S3 unless they have been given access via policy.
However, S3 is designed by default to allow any IP address access. So to block IP's you would have to specify denies explicitly in the policy instead of allows.
Once You learn this - the policy is easy to adjust. You just flipp around the policy from allowing access from only my IP address to denying access from everywhere that was NOT my IP address.
{
"Id": "S3PolicyId1",
"Statement": [
{
"Sid": "IPDeny",
"Effect": "Deny",
"Principal": {
"AWS": "*"
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::examplebucket/*",
"Condition": {
"NotIpAddress": {
"aws:SourceIp": "xxx.x.x/xx"
}
}
}
] }
Hope this helps!

Yes, that is the correct way to do it.
From Bucket Policy Examples - Amazon Simple Storage Service:
{
"Version": "2012-10-17",
"Id": "S3PolicyId1",
"Statement": [
{
"Sid": "IPAllow",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::examplebucket/*",
"Condition": {
"IpAddress": {"aws:SourceIp": "54.240.143.0/24"}
}
}
]
}

Related

Having trouble creating a policy in AWS

I have been tasked with an assignment to create what I believe is a bucket policy in AWS. I have uploaded a video to an S3 bucket, and I have to create a policy to limit who can view it based on their IP address. Currently I need to make it so only somebody at my home network can watch it.
I am also supposed to restrict who can watch it based on their username. The bucket is publicly viewable right now and so is the video file.
I have two policies below that I have tried and neither of them are working.
First Policy: I have tried using both my private and public IP addresses.
{
"Version": "2012-10-17",
"Id": "Policy1607205862213",
"Statement": [
{
"Sid": "Stmt1607205861134",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": "arn:aws:s3:::internshipbucket12",
"Condition": {
"NotIpAddress": {
"aws:SourceIp": "10.1.10.1"
}
}
}
]
}
Second Policy: Whenever I try using the arn of my bucket, it gives an error of some kind. When I put in the arn of the video file I am using, it accepts it just fine.
{
"Version": "2012-10-17",
"Id": "S3PolicyId1",
"Statement": [
{
"Sid": "IPAllow",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::DOC-EXAMPLE-BUCKET;",
"arn:aws:s3:::DOC-EXAMPLE-BUCKET/*"
],
"Condition": {
"NotIpAddress": {
"aws:SourceIp": "54.240.143.0/24"
}
}
}
]
}
Amazon S3 buckets are private by default. Therefore, there is no need to 'Deny' access, since it is already denied by default. Instead, you should use an 'Allow' policy to permit access.
Turn off Block S3 Public Access (or at least the two parts that refer to Bucket Policies)
Add a policy that permits access to objects from a given IP address:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::internshipbucket12/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "54.240.143.0"
}
}
}
]
}
Note that this is granting access to a public IP address, and is only permitting GetObject, so the user will need to know the exact filename (Key) of the object they want (since it does not grant permission to list the contents of the bucket).

How can I add IP restrictions to s3 bucket(in the bucket Policy) already having a User restriction

I have a few s3 buckets, for which I have given access to only a specific IAM user. I did it by setting the following bucket policies :
Effect : "Deny"
NotPrincipal : { "AWS " : "<My_IAM_User>" }
I'm able to access the buckets only from the IAM user, so the policy works as expected, but I also want to restrict the bucket access to only a specific IP. This IP is the ec2 IP address my server is running on. The policy values I've used is as :
"Condition": {
"NotIpAddress": {
"aws:SourceIp": [
"<My_EC2_Server_IP_Address>"
]
}
}
I was expecting the above policy would allow only my EC2 server to access the s3 bucket objects, but if I'm making a call from any other IP ( eg : running the server on my local machine and trying to access the buckets. ) it's still responds with valid objects from the bucket.
The above policy does NOT seem to block any request to access the bucket is made from other random IP addresses.
My entire bucket policy looks like :
{
"Version": "<Version_value>",
"Statement": [
{
"Sid": "<Sid_value>",
"Effect": "Deny",
"NotPrincipal": {
"AWS": "<My_IAM_User>"
},
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::<My_Bucket_name>/*",
"Condition": {
"NotIpAddress": {
"aws:SourceIp": "<My_EC2_Server_IP_Address>"
}
}
}
]
}
My References :
1. https://aws.amazon.com/premiumsupport/knowledge-center/block-s3-traffic-vpc-ip/
2. https://medium.com/#devopslearning/100-days-of-devops-day-11-restricting-s3-bucket-access-to-specific-ip-addresses-a46c659b30e2
If your intention is to deny all AWS credentials except a given IAM user and to deny all IP addresses other than a given IP, then I would write that policy as two, independent deny statements.
Something like this:
{
"Version": "<Version_value>",
"Statement": [
{
"Sid": "deny1",
"Effect": "Deny",
"NotPrincipal": {
"AWS": "<My_IAM_User>"
},
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::<My_Bucket_name>/*"
},
{
"Sid": "deny2",
"Effect": "Deny",
"Principal": {
"AWS": "*"
},
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::<My_Bucket_name>/*",
"Condition": {
"NotIpAddress": {
"aws:SourceIp": "<My_EC2_Server_IP_Address>"
}
}
}
]
}
Be careful with the IP address condition. Unless you are using an Elastic IP, your EC2 instance's IP can change e.g. if you stop then restart the instance.
Also note: you should not be using IAM User credentials on an EC2 instance. Instead, you should be using IAM Roles.

SOS AWS S3 Bucket Policy

I am trying to restrict access to my AWS S3 Bucket, so that only a few domains, 1 IP-address and AWS Lambda functions will have access to it.
This is what I have written, but it is not working :-(
{
"Version": "2012-10-17",
"Id": "httpRefererPolicy",
"Statement": [
{
"Sid": "AllowRequestsReferred",
"Effect": "Allow",
"Principal": "*",
"Action": ["s3:GetObject","s3:GetObjectAcl"],
"Resource": "arn:aws:s3:::example/*",
"Condition": {
"StringLike": {
"aws:Referer": [
"https://www.example.com/*",
"https://example.com/*",
"https://example.herokuapp.com/*",
"https://dfgdsfgdfg.cloudfront.net/*"
]
},
"IpAddress": {
"aws:SourceIp": "219.77.225.296"
}
}
},
{
"Sid": "DenyRequestsReferred",
"Effect": "Deny",
"NotPrincipal": {
"Service": "lambda.amazonaws.com"
},
"Action": ["s3:GetObject","s3:GetObjectAcl"],
"Resource": "arn:aws:s3:::example/*",
"Condition": {
"StringNotLike": {
"aws:Referer": [
"https://www.example.com/*",
"https://example.com/*",
"https://example.herokuapp.com/*",
"https://dfgdsfgdfg.cloudfront.net/*"
]
},
"NotIpAddress": {
"aws:SourceIp": "219.77.225.296"
}
}
}
]
}
What have I written wrong?
Your policy says:
ALLOW GetObject access from an (invalid) IP address if the request was referred from certain websites.
DENY GetObject access if the request is not from Lambda and is not an (invalid) IP address and was not referred from certain websites.
So, the first thing is that IpAddress needs to be in CIDR notation, so you should use:
"aws:SourceIp": "219.77.225.296/32"
Second, there is nothing in this policy that is granting access to the Lambda function (since it is not on the IP address in the ALLOW statement). Also, your method of granting access looks unlikely to work. I would recommend granting access to the IAM Role being used by the Lambda function.
I would suggest you only create ALLOW statements, and give access to each source independently. If you want to grant access based on referer OR IpAddress OR Lambda, you'd need:
ALLOW based on referer
ALLOW based on IpAddress
ALLOW based on Lambda (You'll need to do this by permitting access from the IAM Role used by the Lambda function)
Only use DENY if you need to override a permission that was previously granted via ALLOW. It is best to avoid DENY if possible, to keep things easier to understand.

Is it possible to combine IP-based and IAM-based access control policies?

I have an AWS ElasticSearch cluster to which I want to restrict access.
Ideally I want to use both IAM access (to allow our other service components to contact the cluster) and IP-based access (to allow ad-hoc testing via Sense from within our local network), but when I just tried to add both options to the access control policy it didn't allow access from the listed IP addresses.
Is it possible to combine the two policy styles like this? I assumed from "Statement": [] in the autogenerated JSON that it would be.
An anonymised MWE:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "es:*",
"Resource": "PLACEHOLDER",
"Condition": {
"IpAddress": {
"aws:SourceIp": [
"PLACEHOLDER",
"PLACEHOLDER",
"PLACEHOLDER"
]
}
}
},
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"AWS": "PLACEHOLDER"
},
"Action": "es:*",
"Resource": "PLACEHOLDER"
}
]
}
The IpAddress section had previously worked, but I have no easy way to test if the IAM section worked as we lost access to ad hoc testing when trying it (as expected - the ad hoc testing is not from inside the AWS account).

AWS S3 Bucket Policy Limit GETs to a set of IPs?

I currently have a bucket named mets-logos. It has this bucket policy currently, which allows GetObjects from anyone.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AddPerm",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::mets-logos/*"
}
]
}
I wish to only allow GetObjects from a whitelist of IPs. Here is what I tried, but it does not work (outside IP's can still get objects)
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AddPerm",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::mets-logos/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": [
"100.77.17.80/32",
"100.77.26.210/32",
]
}
}
}
]
}
Side question: If my bucket policy is correct, do I need to wait for AWS to reflect this change, or should it be reflected immediately?
Try adding a Deny, along with exceptions, like this:
{
"Version":"2012-10-17",
"Id":"S3PolicyId1",
"Statement":
[
{
"Sid" : "IPAllow",
"Effect" : "Deny",
"Principal": "*",
"Action" : "s3:GetObject",
"Resource" : "arn:aws:s3:::mets-logos/*",
"Condition": {
"IpAddress" : {
"aws:SourceIp": "0.0.0.0/0"
},
"NotIpAddress": {
"aws:SourceIp": "100.77.17.80/32"
},
"NotIpAddress": {
"aws:SourceIp": "100.77.26.210/32"
}
}
}
]
}
This explicitly denies access to all IP addresses but allows the two addresses that you are whitelisting to perform GetObject.
I can see how this would be useful if you are accessing S3 under IAM credentials but you want to further control access at the bucket level. The Deny in this policy will override existing IAM user policies.
To answer your side question, policy changes take effect immediately.
Access to S3 buckets is governed by both the S3 bucket policy and the IAM access policies that are attached to the principals accessing the bucket.
So it's possible that an IAM access policy may "overrule" an S3 bucket policy.
Your S3 bucket policy says "allow get if the IP is such-and-such". But there's nothing in the bucket policy that's saying "don't allow anyone else".
If your IAM user/role that's accessing the bucket allows s3:GetObject on your bucket (or *), then that policy lets them access the bucket.
If the IAM user/role does not have an explicit "allow" for "s3:GetObject" (or "s3:*"), then your policy would work.
To prevent users/roles that would otherwise be permitted access to the bucket, to be restricted to the IP addresses, then you need to change your policy to "deny" anyone NOT in an allowed IP address. An explicit "deny" in the bucket policy would overrule any "allow" in the IAM user/role's policy.
Try this policy.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyAllButFromAllowedIp",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::mets-logos/*",
"Condition": {
"NotIpAddress": {
"aws:SourceIp": [
"100.77.17.80/32",
"100.77.26.210/32",
]
}
}
}
]
}