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).
Related
I'm trying to create a policy in which the user exam can access only to the region eu-west-1.
I tried to find a solution but didn't found the right one.
the policy looks something like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "*",
"Resource": "user_arn",
"Condition": {
"StringEquals": {
"aws:RequestedRegion": "eu-west-1"
}
}
}
]
}
but it does not seem to work no matter what I do.
what is the best way to do so that the user can do whatever he wants but only in this region?
found a solution
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "ec2:*",
"Resource": "*",
"Condition": {
"StringEquals": {
"aws:RequestedRegion": "eu-west-1"
}
}
}
]
}
This should work as well, however you are granting full access to EC2 limited to one region. In the example below you "deny" any ec2 action outside the region or regions defined below, however you are not granting any privileges (they should be assigned in a separate policy or use an Allow statement. Normally this is used as an SCP in AWS organizations,a and you jusy deny action "*", to force all users to create resources only in the designated regions, and deny any API action in regions not authorized.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Action": "ec2:*",
"Resource": "*",
"Condition": {
"StringNotEquals": {
"aws:RequestedRegion": "eu-west-1"
}
}
}
]
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.
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"}
}
}
]
}
I want to use condition of StringLike aws:Referer for a particular folder and make rest of the folder publicly accessible.
Here is my bucket policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AddPerm",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": [
"arn:aws:s3:::bucketName/folderName/*"
]
},
{
"Sid": "",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::bucketName/folderName/users/*",
"Condition": {
"StringLike": {
"aws:Referer": [
"https://example.com/*"
]
}
}
}
]
}
When I am using above policy, it is not working with first one.
Try with below policy:
{
"Sid": "",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::bucketName/folderName/users/*",
"Condition": {
"StringNotLike": {
"aws:Referer": [
"https://example.com/*"
]
}
}
}
The first part of your policy is granting GetObject access for anything in the folderName path of your bucket. This includes folderName/users/*.
Therefore, the second part of your policy is not being used (since the first policy is already granting access to the folderName/users/* path.
You could solve it by using different buckets, or you could convert the second policy into a Deny with StringNotLike (effectively saying that access is denied to folderName/users/* if the referer is not example.com.
Frankly, your policy looks strange because it is granting access to the entire users path hierarchy, which probably isn't what you'd want it to do. (I'm assuming you'd want to grant access only to a particular user's data based upon who is accessing your application.)
Please note that referer is not secure — it is easy to fake this value in a browser and in web-scraping softare.
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",
]
}
}
}
]
}