3

I have an S3 static website and I want to redirect all the requests to the index page. So if you go to mysite.com/this_doesnt_exist it should redirect to mysite.com.

I was able to configure this behavior with a Custom Error Response like the one on the image above, but the thing is that when I visit mysite.com/this_doesnt_exist I see the index page but the URL doesn't change on the address bar. I want it to change.

enter image description here

I've tried also using the Redirection rules section on the S3 bucket but it doesn't seem to work when CloudFront is configured. I have another bucket for testing environment without CloudFront configured and it worked there with this rule:

<RoutingRules>
  <RoutingRule>
    <Condition>
      <HttpErrorCodeReturnedEquals>403</HttpErrorCodeReturnedEquals>
    </Condition>
    <Redirect>
      <ReplaceKeyWith/>
    </Redirect>
  </RoutingRule>
</RoutingRules>
fsinisi90
  • 155
  • 2
  • 8

1 Answers1

5

Change your Origin Domain Name from example-bucket.s3.amazonaws.com to example-bucket.s3-website.${region}.amazonaws.com (substituting your bucket's actual region) so that the S3 redirect rules will work. The default bucket choices in CloudFront are for the REST endpoints of your buckets, which won't process redirect rules.

Change the <Redirect> block in your redirect rule, so that the Location header generated by the S3 redirect sends you to the right hostname (otherwise it would tend to redirect the browser directly to the bucket's website hosting endpoint). Here, www.example.com is the hostname pointing to your CloudFront distribution.

<Redirect>
    <Protocol>https</Protocol>
    <HostName>www.example.com</HostName>
    <ReplaceKeyWith/>
</Redirect>

Remove the custom error settings.

Create a CloudFront invalidation for /*.

Wait for everything to propagate, and retest.

Michael - sqlbot
  • 21,988
  • 1
  • 57
  • 81
  • It worked, thanks. I also had to leave the `Error document` field empty and set `HttpErrorCodeReturnedEquals` to 404 instead of 403. – fsinisi90 Dec 12 '18 at 17:29
  • 2
    Needing to use 404 instead of 403 is a red flag. It suggests that you have allowed public access to the object *listings* in your bucket, so you may want to check that. Public download is fine if your content is public, but public listing is probably more than you want to reveal. A quirk of the design of the S3 security model means that 404 becomes 403 when an object does not exist *and* the accessing user (anonymous in this case) doesn't have permission to list the objects. – Michael - sqlbot Dec 12 '18 at 20:07
  • I was checking my bucket policy and I only granted access for the `s3:GetObject` action, not for listing (the recommended policy on the [official docs](https://docs.aws.amazon.com/AmazonS3/latest/dev/WebsiteAccessPermissionsReqd.html)). So, why it's a red flag if I want to redirect to my home page when the URL isn't found? – fsinisi90 Apr 22 '19 at 20:21
  • @fsinisi90 the error code is 403 on nonexistent objects unless bucket listing is allowed by either policy or ACL. Check your bucket ACLs. – Michael - sqlbot Apr 22 '19 at 23:30
  • Are you sure? I've checked ACL and public listing is disabled. Also found this on the docs: _On the website endpoint, if a user requests an object that doesn't exist, Amazon S3 returns HTTP response code 404 (Not Found). If the object exists but you haven't granted read permission on it, the website endpoint returns HTTP response code 403 (Access Denied). The user can use the response code to infer whether a specific object exists. If you don't want this behavior, you should not enable website support for your bucket._ – fsinisi90 Apr 23 '19 at 12:54
  • @fsinisi90 interesting. I will revalidate my understanding of these internals and let you know what I find. – Michael - sqlbot Apr 23 '19 at 12:56