Is it possible to hide the S3 endpoints from the public so that they
can only access website via the set domain name?
Well, as far as I'm aware, there is no official solution so far, however there is a workaround suggested by AWS. So here is an implementation that worked out for me:
Create an S3 bucket and enabled website hosting. Go to Bucket Policy section of Permissions and enter a policy similar to this one:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadForGetBucketObjects",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::[YOUR_WEBSITE_BUCKET_NAME]/*",
"Condition": {
"StringEquals": {
"aws:Referer": "[SOME_LONG_SECRET_VALUE]"
}
}
}
]
}
Create CloudFront distribution and configure:
- the following origin:
[YOUR_WEBSITE_BUCKET_NAME].s3-website-[AWS_REGION_NAME].amazonaws.com
. Addressing this concern, from CloudFront perspective, this is not an S3 Bucket Origin, but rather just a Custom Origin.
- the following Origin Custom Header:
- Header Name:
Referer
- Value:
[SOME_LONG_SECRET_VALUE]
(from your bucket policy)
- Configure the rest of your CloudFront distribution settings as usual.
As a result, bucket policy will allow object GETs if only the request contains Referer
header with specified secret value, which will block direct request to you S3 website and allow requests sent via CloudFront. And, obviously, you might think of rotating this secret value every now and then.
Please note that by doing this, CloudFront will overwrite Referer
header (if present) of any incoming request before forwarding it to the origin, so if you rely on it, this solution won't work.