2

I have this policy rule in my S3 bucket called aws-coes:

 {
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AddPerm",
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::aws-coes/*"
            ],
            "Condition": {
                "StringEquals": {
                    "aws:sourceVpc": "vpc-foo"
                }
            }
        }
    ]
}

I was expecting that only the machines under my VPC "vpc-foo" could get the resources from my bucket, but no machine can get anything.

Did I do something wrong here?

Also I follow the steps of this post but nothing https://blog.adminfactory.net/allow-access-to-s3-bucket-only-from-ec2-instances.html

user7440787
  • 831
  • 7
  • 22
paul
  • 12,873
  • 23
  • 91
  • 153
  • 1
    Did you create the vpc endpoint? How are you trying to access the endpoint? What is syntax you are using? – Jim P. May 12 '16 at 18:02
  • yes I did. What do you mean by syntax? – paul May 12 '16 at 23:15
  • You said you followed the steps in the post from adminfactory. That tutorial showed that you CANT simply use a web browser to browse to the end point, you have to use wget or something similar. So that was my question, are you using wget, and if so what is the exact command you are issuing, url included, ie. syntax... When I followed the steps, trying to use the url "s3-us-west-2.amazonaws.com" didnt work. I had to use "s3.us-west-2.amazonaws.com" instead.. A Period after s3 instead of a dash. – Jim P. May 13 '16 at 00:26
  • I dont know where do you see that you have to change the - by a . that´s not working for me. If I change the url the resource is not found – paul May 13 '16 at 08:00
  • @paul - you don't mention the API calls your attempting to make, nor the errors you're receiving. I read the guide you referenced, and noticed that a key element is missing, namely the requisite EC2 Instance Profile. You need to create an IAM role with access to S3 and a trust policy for EC2. Create an Instance Profile for that role, and attach it to your instance(s). Also, I'm assuming that when you say `vpc-foo`, you're referring to a VPC ID and not a name you've assigned to a VPC. – cerberus Apr 22 '20 at 04:39
  • @cerberus the IAM role attached to the instance is not critical. I am able to access a bucket with the above policy and without an IAM role attached to the EC2 instance granting me permissions. Eeven though, as Martin says in his response, that's perhaps the safest approach. It looks to me that the critical part is first to have a VPC enpoint associated with the VPC and second, that endpoint needs to be in the same region as the bucket. – user7440787 Apr 22 '20 at 15:22

2 Answers2

4

I once had a similar issue. The following comes into my mind:

  • The policy looks good. The s3:GetObject action does not need to reference the bucket as resource. A wildcard path pointing at objects is sufficient. The policy examples [1] in the docs clearly state that fact.
  • You must use the vpc id as value for the aws:sourceVpc condition. Just mentioning it to make sure that you are not using the VPC ARN accidentally. [2]
  • What is also interesting, is that people most likely use the aws:sourceVpc condition to restrict access (i.e. a deny policy) - not to whitelist traffic. This is most likely not a functional issue, but I want to mention it nonetheless. From a security perspective it is probably safer to restrict access to the S3 bucket (as described in the aws docs) and attaching an EC2 instance role which grants access to the S3 bucket. This way, all EC2 instances within a particular VPC are able to access an S3 bucket, but other (possibly malicious) network entities are not.
  • I would double check if the requests from your EC2 instance are really routed through the VPC endpoint. As mentioned by the docs [3], it is crucial for the traffic to originate from an AWS VPC endpoint. This is accomplished inside the VPC by routing the traffic over a dedicated route inside the AWS network instead of the Internet Gateway. Could you please double check that you added the VPC endpoint to your route table correctly? One way you could check this is to make a public S3 bucket and access it from the EC2 instance. Subsequently, attach a vpc endpoint policy which denies all S3 traffic. Then, try to access the S3 bucket from your EC2 instance again. If the second time, access is denied, you know that probably the VPC endpoint is used and traffic is routed correctly inside the VPC.
  • Depending on the size of your organization there might be other IAM controls in place which deny the access. This is probably not an issue, but it might be worth checking if your company uses AWS Organizations and has an SCP which denies access. Also check, if there is no explizit deny, e.g. for your EC2 instance role. Take a look at the IAM evaluation logic [4] for more information.
  • You did not mention in your question if you are using one single AWS account or if you are in a multi-account scenario, e.g. an S3 bucket in account A and a VPC in account B. Iff this is the case, please check out the docs in [5], since it changes the policy evaluation logic when context authority and bucket owner differ. Using the aws:sourceVpc condition cross-account is probably not even possible. [6]

I hope some of these points are helpful to track the issue down.

References

[1] https://docs.aws.amazon.com/AmazonS3/latest/dev/example-policies-s3.html#iam-policy-ex0
[2] https://docs.aws.amazon.com/AmazonS3/latest/dev/example-bucket-policies-vpc-endpoint.html#example-bucket-policies-restrict-access-vpc
[3] https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourcevpc
[4] https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_evaluation-logic.html#policy-eval-denyallow
[5] https://docs.aws.amazon.com/AmazonS3/latest/dev/access-control-auth-workflow-object-operation.html
[6] https://stackoverflow.com/a/52517646/10473469

Martin Löper
  • 6,471
  • 1
  • 16
  • 40
  • 1
    I think it is also worth pointing that both the bucket and the VPC need to be in the same region. If the bucket is in eu-west-2 and the VPC endpoint in eu-east-1, the policy will not work. – user7440787 Apr 21 '20 at 08:34
  • @Martin Löper - In cloudtrail data events on my bucket, I could not find sourceVpc in the request contexts (only VPCe is present). How does aws:sourceVpc clause work in a Bucket Policy without needing to specify "Ifexists" clause in "StringNotEquals": {"aws:sourceVpc": "vpc-xyz-abcd"} - It seems to work magically fine with statement above but I thought StringNotEqualsIfexists was very much required - Any thoughts? – Abhishek Palakkal Kaliyath May 16 '20 at 18:09
  • It is hard to tell for me what exactly is going on. Could you post your full bucket policy for me to understand? – Martin Löper May 16 '20 at 18:31
  • Thanks for asking more details - I have posted my question here - https://stackoverflow.com/q/61839977/7865060 Appreciate if you could help ! I am trying to find out - if a condition key is not available in request context (at least I cant see it), where does AWS get it from when evaluating permissions? For example - aws:sourceVpc is not seen on Cloudtrail event but it can be used without an "Ifexists" clause in a Bucket policy and everything still works fine i.e. access is denied. – Abhishek Palakkal Kaliyath May 16 '20 at 19:07
2

FYI, internally in the EC2-->S3 networking stack there are certain edge cases where the SourceVPC header is not passed on requests to S3, in those cases you'll need to use a VPC endpoint condition instead.

Source (I used to do a lot of S3 support at AWS).

Ian Smith
  • 879
  • 1
  • 12
  • 23