Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Got example.com certified and working. Now how to make www.example.com work as well? #516

Open
sscarduzio opened this issue Dec 5, 2016 · 22 comments
Labels
aws certify related to `zappa certify`, ACM, Let's Encrypt, R53, or other hostname/Custom Domain Name things.

Comments

@sscarduzio
Copy link

Problem

As of title, I have no problem with my website running on my naked domain example.com.
But now need to get www.example.com working: i.e. redirecting to the naked domain.

Resolution Attempts

At this stage I'm using Route 53 and trying to add www as a CNAME, my alias list is empty.
I also tried adding www.example.com -> example.com as a non-alias CNAME, but it does not work.

@chromakey
Copy link

Howdy. There's not a way to do this natively with Zappa. There's a couple of different things you could do:

1.) Use a standard CNAME (not an ALIAS record) to point to example.com for the www.example.com entry.

2.) Create a bucket in S3 that's named www.example.com and use the static website hosting section of the properties to redirect all traffic to example.com. Then in Route 53, create an ALIAS record for www.example.com pointing to the S3 bucket.

Hope this helps.

@sscarduzio
Copy link
Author

how would that work? Shouldn't I need a certificate also for www.example.com?

@chromakey
Copy link

Here's where it can get tricky. Let me outline the different scenarios.

1.) You do option 1 (CNAME to example.com). This will just point to your API Gateway endpoint and try to render the page as www.example.com which is not a valid endpoint yet. To remedy this, you can add an additional profile to your zappa_settings.json, deploy, and certify it separately. This becomes a pain because now you're managing two deployments for the same thing. If you application is not big, you automate your deployments, and/or you have an application level redirect to the preferred URL, this is not a big deal.

2.) You do option 2 (S3 bucket redirect). This will force all traffic going to www.example.com to go to example.com instead where you have a valid endpoint. Here are the cases where it works as you would expect and doesn't work as expected:

Scenario 1 - http://www.example.com -> https://example.com: OK!
Scenario 2 - https://www.example.com -> https://example.com: FAILS!

S3 doesn't do direct HTTPS forwarding which is a common complaint, but there's architectural reasons for that. The only way to get seamless coverage for both scenarios is to do Option 1 with an application redirect to the URL you want to be standard or set up your own reverse proxy and own SSL certificates to do the redirection correctly.

If someone else has some thoughts, I'd appreciate them since this is an issue I deal with regularly (we opt for option 2 since manually typing https://example.com is so exceedingly rare that we can live with the consequences).

@Miserlou
Copy link
Owner

Miserlou commented Dec 5, 2016

This is something I'd certainly like to address as well!

I am of the opinion that a domain should exist at either the apex or the www., preferring the Apex, and that one should resolve to the other. If there are both, then they should be separate Lambda functions.

HTTPS S3 forwarding not working sucks! A hack there could be to use an HTML page to perform the redirect but I don't know how spiderbots will like that.

@sscarduzio
Copy link
Author

Can we have Zappa adding two entries (and two certificates) into the "custom domain name" feature of API gateway? This way the redirect would be optional, and managed at the application level.

@Miserlou
Copy link
Owner

Miserlou commented Dec 5, 2016

Yeah, I think that should be doable. It seems like you can point to the same function twice now.

@sscarduzio
Copy link
Author

@Miserlou amazing 👍 Where about in the roadmap would you put this?

@Miserlou
Copy link
Owner

Miserlou commented Dec 6, 2016

Whenever you submit the PR :)

@sscarduzio
Copy link
Author

@Miserlou, I'd love to. But I'm not great at python or have time to become better, so I attempted creating a separate Zappa project for the www (containing a simple redirect to the non-www).

Epic fail:

Calling certify for environment dev..
Certifying domain www.readonlyrest.com..
Setting DNS challenge..
Waiting for DNS to propagate..
Deleting DNS challenge..
An error occurred (InvalidChangeBatch) when calling the ChangeResourceRecordSets operation: RRSet of type CNAME with DNS name www.readonlyrest.com. is not permitted as it conflicts with other records with the same DNS name in zone readonlyrest.com.
Failed to generate or install certificate! :(

The issue is that - of course - I have already the zone "readonlyrest.com".

So I think this is a broader issue: it's apparently impossible to have two websites under the same domain and the same AWS account, say: this.domain.com and that.domain.com.

How to handle this? New issue?

@bxm156
Copy link
Contributor

bxm156 commented Oct 13, 2017

I think it should be fairly easy to support multiple domains. I do this in production for my sites. I just have multiple domains setup to point to the same API Gateway at the same path/stage. This allows me to run www.example.com and example.com at the same time. Each domain uses their own certificate_arn (though i suppose one could use a single wildcard cert as well).

I would imagine the settings file could reflect this, something like this:

    domains:
      - name: example.com
        certificate_arn: us-east-1-arn
      - name: www.example.com
        certificate: ...
        certificate_key: ...
        certificate_chain:  ...
         
      # Example for lets encrypt
      - name: example.com
        lets_encrypt_key: womp

Would be happy to take a stab at it.

@Miserlou
Copy link
Owner

Yep, that's the solution I'd imagine as well. Want to submit a PR, BMX? :D :D :D #

@bxm156
Copy link
Contributor

bxm156 commented Oct 16, 2017

Alas, this should be easy. However AWS's API Gateway API limits itself to 2 Create Domain API requests per min. :(

It can still be done, if a user tries to add too many domains, the cli will create what it can and then fail. The user can than run certify a second time (after a few minutes) to cert the next domain.

Maybe another option would be to instead ask the user to use the domain name they want to certify in the command line, like: zappa certify dev example.com. This would allow the user to choose which domain in the list to certify, and the user will just have run the command multiple times (once for each domain) with a few minutes in-between, so that the API limit isn't an issue.

Thoughts?

It might look something like this:

> zappa certify dev
Due to AWS APIGateway limitations, please run certify for each domain.
> zappa certify dev example.com
> sleep 60
> zappa certify dev www.example.com

@bxm156
Copy link
Contributor

bxm156 commented Oct 20, 2017

Making some decent progress on this. I have manually tested my change with the cert_arn and Lets Encrpyt.

Todo:

  • Manual test manual cert files
  • Cleanup
  • Update tests

@bxm156
Copy link
Contributor

bxm156 commented Oct 22, 2017

I also discovered that we are not updating Route53 DNS routes in the Let's Encrypt stuff. I fixed it in my branch.

@bxm156
Copy link
Contributor

bxm156 commented Oct 26, 2017

My branch should fix #762 ,#934, #1141, which are all duplicates.

@jgroszko
Copy link

Is there a way to get zappa to set up a LE certificate for a static files domain connected to an S3 bucket too?

@bxm156
Copy link
Contributor

bxm156 commented Oct 29, 2017

@jgroszko I don't believe, so, LE functionality right now is tied to the API Gateway's custom domain. The functionality just uses LE and generate a certificate body and key, and then uploads it to Lambda, true it could be extended to support s3 resources, but I think that might go out of the scope of lambda. AWS Resource management might be better served by something like Terraform.

@scoates scoates added aws certify related to `zappa certify`, ACM, Let's Encrypt, R53, or other hostname/Custom Domain Name things. labels Feb 28, 2018
@isaac-jordan
Copy link
Contributor

Hi, I have a WWW redirect working using a combination of CloudFront and S3. This successfully does a www.domain.com -> domain.com redirect as well as HTTP -> HTTPS. So http://www.domain.com becomes https://domain.com.

Route 53 (WWW entry) points to a dedicated CloudFront distribution with an S3 WWW redirect bucket (of the type mentioned above), and the CloudFront distribution settings have a "Redirect HTTP to HTTPS" viewer protocol policy.

I'll try and write up a blog post with every detail in the future.

@JimiPedros
Copy link

Hi there, you can simply navigate to Amazon API Gateway > Custom Domain Names and click Create Custom Domain Name.

Select HTTP and enter your domain name, www.[domain name]... Select TLS 1.0 and Edge optimized. Then select the certificate for your exisiting domain and click save.

Click update base path mappings, you will need to enter in the path which is most likely /, and the destination. If you get an error about your domain name including www does not exist on the certificate, navigate to Amazon Certificate Manager and create a new certificate for the www domain.

Once your certificate has been issued, go back and repeat the steps. Select this newly created certificate. Your site should be live at https://www.domain.... Hope this helps!

@cubocicloide
Copy link

cubocicloide commented Dec 27, 2019

Hi, I have a WWW redirect working using a combination of CloudFront and S3. This successfully does a www.domain.com -> domain.com redirect as well as HTTP -> HTTPS. So http://www.domain.com becomes https://domain.com.

Route 53 (WWW entry) points to a dedicated CloudFront distribution with an S3 WWW redirect bucket (of the type mentioned above), and the CloudFront distribution settings have a "Redirect HTTP to HTTPS" viewer protocol policy.

I'll try and write up a blog post with every detail in the future.

Hi sheepzez. Any chance that you already published a blog post on this topic?

@nabazm
Copy link

nabazm commented Jan 15, 2020

not sure if anyone is still looking for solution for this problem, but this is how I solved it:

  • request for a domain cert and additional domain name *.domainname.ext
  • Zappa certify for domainname.ext
  • manually add custom domain on api gateway for the *.domainname.ext and (rest and edge optimized, select new *.domainname.ext cert) map it to the same api gateway and stage
  • on route 53 create alias A record and point to cloudfront url from the new api custom domain

that should do it

@Alex-Mackie
Copy link

not sure if anyone is still looking for solution for this problem, but this is how I solved it:

  • request for a domain cert and additional domain name *.domainname.ext
  • Zappa certify for domainname.ext
  • manually add custom domain on api gateway for the *.domainname.ext and (rest and edge optimized, select new *.domainname.ext cert) map it to the same api gateway and stage
  • on route 53 create alias A record and point to cloudfront url from the new api custom domain

that should do it

Thank you @nabazm. For anyone who might be interested, this also works fine the other way round (using the www. in Zappa settings and following the above steps for domainname.ext). In my case if someone visits domainname.ext I just redirect them to www.domainname.ext in the code of my app.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
aws certify related to `zappa certify`, ACM, Let's Encrypt, R53, or other hostname/Custom Domain Name things.
Projects
None yet
Development

No branches or pull requests