S3 Bucket Policy for Limiting Access to Cloudflare IP Addresses

Viewed 823

I will be using Cloudflare as a proxy for my S3 website bucket to make sure users can't directly access the website with the bucket URL.

  • I have an S3 bucket set up for static website hosting with my custom domain: www.mydomain.com and have uploaded my index.html file.

  • I have a CNAME record with www.mydomain.com -> www.mydomain.com.s3-website-us-west-1.amazonaws.com and Cloudflare Proxy enabled.

Issue: I am trying to apply a bucket policy to Deny access to my website bucket unless the request originates from a range of Cloudflare IP addresses. I am following the official AWS docs to do this, but every time I try to access my website, I get a Forbidden 403 AccessDenied error.

This is my bucket policy:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "CloudflareGetObject",
            "Effect": "Deny",
            "NotPrincipal": {
                "AWS": [
                    "arn:aws:iam::ACCOUNT_ID:user/Administrator",
                    "arn:aws:iam::ACCOUNT_ID:root"
                ]
            },
            "Action": "s3:GetObject",
            "Resource": [
                "arn:aws:s3:::www.mydomain.com/*",
                "arn:aws:s3:::www.mydomain.com"
            ],
            "Condition": {
                "NotIpAddress": {
                    "aws:SourceIp": [
                        "2c0f:f248::/32",
                        "2a06:98c0::/29",
                        "2803:f800::/32",
                        "2606:4700::/32",
                        "2405:b500::/32",
                        "2405:8100::/32",
                        "2400:cb00::/32",
                        "198.41.128.0/17",
                        "197.234.240.0/22",
                        "190.93.240.0/20",
                        "188.114.96.0/20",
                        "173.245.48.0/20",
                        "172.64.0.0/13",
                        "162.158.0.0/15",
                        "141.101.64.0/18",
                        "131.0.72.0/22",
                        "108.162.192.0/18",
                        "104.16.0.0/12",
                        "103.31.4.0/22",
                        "103.22.200.0/22",
                        "103.21.244.0/22"
                    ]
                }
            }
        }
    ]
}
1 Answers

By default, AWS Deny all the request. Source

Your policy itself does not grant access to the Administrator [or any other user], it only omits him from the list of principals that are explicitly denied. To allow him access to the resource, another policy statement must explicitly allow access using "Effect": "Allow". Source

Now, we have to create Two Policy Statment's:- First with Allow and Second with Deny. Then, It is better to have only One Policy With "allow" only to Specific IP.

It is better not to complicate simple things like using Deny with Not Principal and NotIPAddress. Even AWS says :

Very few scenarios require the use of NotPrincipal, and we recommend that you explore other authorization options before you decide to use NotPrincipal. Source

Now, the questions come on how to whitelist Cloudflare IP's???.

Let's go with a simple approach. Below is the Policy. Replace your bucket name and your Cloudflare Ip's. I have tested it and it is running.

{
"Version": "2012-10-17",
"Statement": [
    {
        "Sid": "AllowCloudFlareIP",
        "Effect": "Allow",
        "Principal": "*",
        "Action": "s3:getObject",
        "Resource": [
            "arn:aws:s3:::my-poc-bucket",
            "arn:aws:s3:::my-poc-bucket/*"
        ],
        "Condition": {
            "IpAddress": {
                "aws:SourceIp": [
                    "IP1/32",
                    "IP2/32"
                ]
            }
        }
    }
 ]
}
Related