1

I have a static website setup on aws s3 using Cloudfront and route 53. Currently I can correctly access the site correctly via https://www.example.com

I'm trying to redirect http://example.com and https://example.com to https://www.example.com (http://www.example.com already redirects correctly).

It seems that the only way to set this up is with two cloudfront distributions and two s3 buckets (and two alias A records in route 53).

I have configured an example.com bucket to redirect to www.example.com using https protocol.

One of the cloudfront distributions points to the www.example.com bucket with http to https redirect and the default root object as index.html and the alternate domain name as www.example.com The other cloudfront distributions points to example.com bucket with no http to https redirect and nothing set in the default root object (I've also tried index.html but that didn't help) and the alternate domain name as example.com.

Both distributions use the same certificate setup in ACM that covers *.example.com and example.com (other settings use the defaults).

I'm not clear why I'm getting an access denied error when I try to access via https://example.com (or http://example.com) and what is wrong about my setup?

<Error>
<Code>AccessDenied</Code>
<Message>Access Denied</Message>
<RequestId>....</RequestId>
<HostId>.....</HostId>
</Error>

Update with more details on the buckets:

As mentioned below in the comments the root domain s3 bucket, redirects correctly without cloudfront. Adding cloudfront back in and the access denied errors reappear.

both buckets have public access ie Block all public access is set to off.

The bucket policy for both is set to:

{
    "Version": "2012-10-17",
    "Id": "Policy1595518880784",
    "Statement": [
        {
            "Sid": "Stmt1595518834954",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::example.com/*"
        }
    ]
}

and for the subdomain bucket it has a ..:::www.example.com/* in the resourse.

The buckets origin used in cloudfront is example.com.s3.amazonaws.com and www.example.com.s3.amazonaws.com

Yunti
  • 4,812
  • 9
  • 42
  • 85

4 Answers4

4

The issue is with the cloudfront distribution in front of the redirect bucket. Although the autocomplete of the origin for the www bucket in cloudfront works fine, it does not work for the redirect bucket. Instead you need to add this manually and it not to be of the s3 rest api format but of the static site version. So instead enter something of the form example.com.s3-website-us-east-1.amazonaws.com This seems a bit of like a bug in the aws console and it shouldn't autocomplete invalid bucket names infront of s3 redirecting buckets.

Yunti
  • 4,812
  • 9
  • 42
  • 85
1

To troubleshoot Access Denied errors, you must know if your distribution’s origin domain name is an S3 website endpoint or an S3 REST API endpoint. Try this:

  1. Open the CloudFront console.
  2. Choose your CloudFront distribution, and then choose Distribution Settings.
  3. Choose the Origins and Origin Groups tab.
  4. Review the domain name under Origin Domain Name and Path, and then determine the endpoint type based on the format of the domain name.

Keep in mind that, REST API endpoints use this format:

AWSDOC-EXAMPLE-BUCKET.s3.amazonaws.com

Website endpoints use this format:

AWSDOC-EXAMPLE-BUCKET.s3-website-us-east-1.amazonaws.com

Also, don't forget that if your distribution is using a website endpoint, verify the following requirements to avoid Access Denied errors:

  • Objects in the bucket must be publicly accessible.
  • Objects in the bucket can't be encrypted by AWS Key Management Service (AWS KMS).
  • The bucket policy must allow access to s3:GetObject.
  • If the bucket policy grants public access, then the AWS account that owns the bucket must also own the object.
  • The requested objects must exist in the bucket.
  • Amazon S3 block public access must be disabled.
  • If Requester Pays is enabled, then the request must include the request-payer parameter.

Finally, you might want to check these posts:

How do I use CloudFront to serve a static website hosted on Amazon S3?

I’m using an S3 REST API endpoint as the origin of my CloudFront distribution. Why am I getting 403 Access Denied errors?

baduker
  • 12,203
  • 9
  • 22
  • 39
  • Thanks, for your post, I've updated with more details for the buckets. Both seem to have the rest api format if it follows the convention you mentioned. not sure why they are rest api? (The www sub domain bucket has it too and works though).? – Yunti Aug 03 '20 at 13:29
0

The reason for this that when your CloudFront distribution connects to your S3 bucket it will forward the Host header.

If your bucket is example.com.s3.amazonaws.com it expects the host header to be either example.com.s3.amazonaws.com or example.com. If it receives a host header of www.example.com this will be denied as the S3 bucket is not for that domain.

These bucket names must exactly match your domain name. In this example, the domain name is example.com. You host your content out of the root domain bucket (example.com). You create a redirect request for the subdomain bucket (www.example.com). If someone enters www.example.com in their browser, they are redirected to example.com and see the content that is hosted in the Amazon S3 bucket with that name.

The solution unfortunately is as you're using separate S3 buckets with separate CloudFront distributions.

Chris Williams
  • 23,842
  • 4
  • 14
  • 39
  • Thanks for your response, but I wasn't clear how that would help fix the access denied error I'm getting or what action I should take to remedy? Your suggestion at the end to use separate s3 buckets and separate Cloudfront distributions is what I'm alrready using. – Yunti Jul 31 '20 at 15:10
  • Ah perhaps I have misunderstood your question, so one of the buckets is returning a 403 the other is not? – Chris Williams Jul 31 '20 at 15:15
  • Yes thanks the www one works fine but the other (the root domain one) returns a 403. If I remove the cloudfront distribution in front of that bucket and amend route 53 to point direct to the s3 bucket then the redirect from `http://example.com` -> `https;//www.example.com` works correctly. However as one of the cloudfront distributions have now gone `https://example.com` doesn't work. So something seems wrong with the cloudfront distribution in front of the root domain redirect buckets as reactivating it (and amending route 53) gives a 403. – Yunti Jul 31 '20 at 15:41
  • Is it a custom origin or are you using an S3 origin? – Chris Williams Jul 31 '20 at 15:50
  • It's an s3 origin `example.com.s3.amazonaws.com`. Not sure what the default root object should be when the s3 bucket is only a redirect though? – Yunti Jul 31 '20 at 15:59
0

The answer provided by Yunti helped, and in addition I had to do the following in order to get it to work, as it would still give me 403 Forbidden error,

  1. Edit the CloudFront distribution to include the other CNAME's which are used to access the site, enter image description here

    This is a requirement of AWS if you're going to access the CloudFront distribution by an address other than the CloudFront auto-generated one (E.g. xyadjfjfg.cloudfront.net).

  2. (This applies if you want to support HTTPS for the users of your site) Had to request a new certificate in AWS Certificate Manager replace the old one, to include the additional host name example.com in my example (notice there's no subdomain at all in front of example.com). The certificate is issued for subject *.example.com but needed explicit host without any subdomain. My original certificate was issued to *.example.com only with no additional domain names specified, aka Subject Alternative Name, or SAN. AWS CloudFront will not let you save the distribution changes if the chosen ACM certificate does not mention all the CNAME's you have provided in the comma-separated list.

Jose Quijada
  • 339
  • 1
  • 10