DEV Community

Ashish Ranjan
Ashish Ranjan

Posted on • Edited on

How to access a private S3 bucket via Cloudflare

Hero Image Cloudflare + S3
In this blog post, we'll explore how to access a private S3 bucket via Cloudflare. Most of the tutorials on the internet suggest that you need to enable static hosting on your S3 bucket and use the same name for your bucket and your domain. For example, if your domain is example.com, your bucket name should be example.com too.

However, this approach has some drawbacks. Amazon S3 website endpoints do not support HTTPS. Using the same name for your bucket and your domain is not always possible or desirable. Bucket names have to be unique across all of AWS, so you might not get the name you want. Also, you might want to map multiple domains to the same bucket, or use an existing bucket with a different domain name.

The solution

In this demo, I will show you how to access a private S3 bucket with a different name than your domain via Cloudflare. Let’s assume that we have a bucket named test-bucket in the eu-central-1 region, and we want to map it to our domain test.ashish.link.

Cloudflare dashboard to add CNAME records

Step 1: Add a CNAME record on Cloudflare

The first step is to add a CNAME record on Cloudflare that points to the S3 endpoint of our bucket. The S3 endpoint has the format <bucket-name>.s3.<region>.amazonaws.com. In our case, it is test-bucket.s3.eu-central-1.amazonaws.com.

Step 2: Add a bucket policy for Cloudflare IPs

The second step is to add a bucket policy on our S3 bucket that allows Cloudflare IPs to access our objects. You can find the list of Cloudflare IPs on their website. The bucket policy should look something like this:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowCloudFlareIP",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": [
                "arn:aws:s3:::test-bucket",
                "arn:aws:s3:::test-bucket/*"
            ],
            "Condition": {
                "IpAddress": {
                    "aws:SourceIp": [
                        <list of ips>
                    ]
                }
            }
        }
    ]
}
Enter fullscreen mode Exit fullscreen mode

This policy grants read access to our bucket and its objects only to the requests that come from Cloudflare IPs. You can find the list of cloudflare IPs from here.

Step 3: Set a Host header override on Cloudflare

The final step is to set a Host header override on Cloudflare that tells S3 which bucket we want to access. By default, S3 uses the Host header of the request to determine the bucket name. For example, if we request example.com/image.jpg, S3 will look for a bucket named example.com. However, since our bucket has a different name, we need to override this behavior and tell S3 to use test-bucket.s3.eu-central-1.amazonaws.comas the Host header instead.
To do this, we need to create a Origin rule on Cloudflare that sets the Host header override as follows:
This origin rule tells Cloudflare to forward all requests for test.ashish.link/* to our S3 endpoint with the correct Host header.

Cloudflare dashboard to add origin rules

Conclusion:

By following these steps, you can successfully access a private S3 bucket via Cloudflare, regardless of whether your bucket name matches your domain name or not. This setup allows you to securely and efficiently serve your assets while maximizing control over access.

I hope you found this post helpful. If you have any questions or feedback, please leave a comment below.

Top comments (0)