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

Wildcard domains (*.example.com) #52

Closed
shravanshetty1 opened this issue Dec 4, 2019 · 10 comments
Closed

Wildcard domains (*.example.com) #52

shravanshetty1 opened this issue Dec 4, 2019 · 10 comments
Labels
feature request Request for new feature or functionality

Comments

@shravanshetty1
Copy link

shravanshetty1 commented Dec 4, 2019

Would like to have wildcard domain support, right now certificates are issued for every subdomain i.e
1234.example.com
43443.example.com
have separate certificates.

We should create 1 certificate with *.example.com, and use it instead for every subdomain.

This would be helpful for services which serve subdomains.

Can start working on this if i have your ok @mholt

@shravanshetty1 shravanshetty1 added the feature request Request for new feature or functionality label Dec 4, 2019
@shravanshetty1 shravanshetty1 changed the title Wildcard domains Wildcard domains (*.example.com) Dec 4, 2019
@mholt
Copy link
Member

mholt commented Dec 4, 2019

You can already use wildcards, just give CertMagic a domain like *.example.com instead of giving it each subdomain. (You'll also have to configure the DNS challenge.)

@mholt mholt closed this as completed Dec 4, 2019
@shravanshetty1
Copy link
Author

@mholt this does not work for ondemand certificates

@mholt
Copy link
Member

mholt commented Dec 5, 2019

Can you be more specific about what you need then?

@mholt
Copy link
Member

mholt commented Dec 5, 2019

Also, what is your use case for on-demand TLS with wildcard certificates?

@DSpeichert
Copy link

@mholt I think the use case can be summarized like this:

  • application wants on-demand TLS because the whitelist is large and generating them ahead of time would be wasteful (all the usual reasons for on-demand TLS apply)
  • application knows that if ONE certificate is to be requested, wildcard certificate makes sense because additional requests are likely to follow using subdomains of the same level

Practical examples:

  • SaaS app where end user brings in their own Registered Domain and servers traffic for unlimited subdomains
  • Mail servers that handles a large number of Registered Domains and acts as e.g. imap.<domain>, smtp.<domain>, webmail.<domain>, mx.<domain>, mta-sts.<domain>, autoconfig.<domain>, autodiscover.<domain>, .etc.

In both cases there are two major considerations:

  • requesting certificates may have to be delayed (customer "onboards" domain but the DNS propagation hasn't finished), hence on-demand TLS
  • Let's Encrypt's limit of Certificates per Registered Domain (50 per week) may become an issue.

Potentially, adding a function DecisionWildcardFunc to certmagic.OnDemandConfig (in addition to DecisionFunc) could be a nice way to let CertMagic know when to go this route.

@mholt
Copy link
Member

mholt commented Jun 4, 2020

@DSpeichert Thanks, let me bounce back some thoughts on that:

SaaS app where end user brings in their own Registered Domain and servers traffic for unlimited subdomains

Using Let's Encrypt at least, this is an impractical scenario for wildcard certificates, because getting a wildcard from Let's Encrypt requires the DNS challenge. So if customers are in charge of their own domains, you can't configure the DNS challenge.

It remains to be seen what requirements are from other ACME CAs regarding wildcard certs.

Mail servers that handles a large number of Registered Domains and acts as e.g. imap., smtp., webmail., mx., mta-sts., autoconfig., autodiscover., .etc.

Assuming in this scenario, you are in control of the domains? Or not?

I ask about whether you're in control of the domains or know about them, because if you are, it is very easy to tell CertMagic to manage wildcards: magic.ManageAsync([]string{"*.sub.example.com"}) for example.

Am willing to add a feature of some sort, but need to be convinced of the need for it first. Further clarity and specifics would be helpful.

@DSpeichert
Copy link

Using Let's Encrypt at least, this is an impractical scenario for wildcard certificates, because getting a wildcard from Let's Encrypt requires the DNS challenge. So if customers are in charge of their own domains, you can't configure the DNS challenge.

Assuming in this scenario, you are in control of the domains? Or not?

Let me try to clarify the example. In this scenario, for the SaaS provider hosts (or controls) the DNS servers that the domain name should be parked on. However, it does not own the domain. Throughout the signup process, a customer is asked to point the NS records for the domain name to be the DNS servers of the SaaS provider.

Therefore, the SaaS provider can then complete the challenge for DNS-based wildcard certificate validation. However, the timing of that is uncertain for the SaaS provider. They need to be ready the moment the domain is actually "live" (pointed at their DNS) but that may never happen (customers change their mind).

That's where the on-demand functionality offered by certmagic fits very well - an incoming request asking for a certificate for a given domain name is a pretty good indication that the DNS change has propagated and the SaaS provider indeed (in this example) controls DNS.

Thanks for mentioning magic.ManageAsync([]string{"*.sub.example.com"}, as it is in fact what almost works for this case, with one caveat. It instantly attempts to get the certs (and yes - will retry) but unnecessarily burns through failed attempts by starting too early, and it some cases the DNS control may never work.

Having an on-demand option with a whitelist of allowed domain names is just like ManageAsync with delayed fuse to avoid hitting limits on open validations with e.g. Let's Encrypt.

Naturally, the problem of verifying whether the app actually can control DNS could be shifted to the app and only after positive verification would the app call magic.ManageAsync(). It just seems like a desirable feature to be able to utilize the on-demand functionality at the time of actual TLS connection instead of background polling on a timer ("is it ready yet?").

@mholt
Copy link
Member

mholt commented Jun 7, 2020

What if the DNS challenge takes an hour to complete? (This is not uncommon.)

@DSpeichert
Copy link

That would be equally bad as waiting an hour for a DNS challenge that will never actually succeed (as a result of magic.ManageAsync() called prematurely).

I guess the desired outcome, to answer your question, would be to simply behave as if magic.ManageAsync() was called at that point in time. In the on-demand flow, the TLS handshake should probably time out after a short while(I imagine clients would bail anyway). At least that hour or so would kick off.

I would understand if you deem this problem too specific to accommodate in the library by default.

@mholt
Copy link
Member

mholt commented Jun 8, 2020

That would be equally bad as waiting an hour for a DNS challenge that will never actually succeed (as a result of magic.ManageAsync() called prematurely).

No, because with on-demand that waiting happens in the foreground. (I think we actually terminate it after a couple of minutes because a client is waiting to finish the connection. That might even be too long as-is.) In the current setup, it all happens in the background, all the meanwhile falling back to a staging environment that doesn't count against your rate limits.

At least that hour or so would kick off.

Maybe a better solution is to poll DNS or something?

I would understand if you deem this problem too specific to accommodate in the library by default.

We just need to find a workable solution before implementing it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request Request for new feature or functionality
Projects
None yet
Development

No branches or pull requests

3 participants