That's why CNAMEs often aren't the best choice for the dns-01
challenge, because that single CNAME wouldn't "redirect" the _acme-challenge
label: you'd need a "zone redirect" (not sure if that's an official thing) using a NS record for that.
That's a great point, @Osiris! I'm slightly off my game there. It would need to be a DNAME to hit underlying subdomain names (like _acme-challenge) or two CNAMEs to cover both service subdomain for HTTP requests (booking) and challenge subdomain for DNS-01 requests (_acme-challenge.booking). Hence my advice on using HTTP-01 challenges here holds more than ever.
If you want to be better than the majority of TPVs with whom I've worked, please make your links/references in your website content domain-agnostic, meaning relative (by not specifying a domain name at all). There should be no trace of your domain name in your content so that your clients can brand on top of your content without their users being distracted/redirected by links/references to your domain name. This is positively critical for security posturing as well. Your site needs to appear and function as part of their site in every way possible.
Certainly!
Personally I'm not really familiar with DNAMEs and I'm not sure every DNS zone editor actually supports those.
You are 100% right about that. Many/most don't (support DNAMEs), which results in needing to use multiple CNAMEs and knowing their mappings since the "wildcard" DNAME isn't available.
Or, you could have the client just add two CNAMEs, one for their name directly, and one for _acme-challenge.
Your ACME client would need to support updating your zone when trying to get a certificate for the client's name, which certbot I don't think does but others do handle.
But agreed that HTTP-01 is probably easiest.
Also, if you've got a CNAME to your name, you probably want to set up a CAA record for it, so that you're in control of which CAs your system can use instead of your clients.
Also, be sure to read through the Integration Guide if you haven't yet, it's got a bunch of tips.
That is definitely the idea.
Il will investigate HTTP-01 challenges, then DNAMEs, both sound promising.
Many thanks for the fast & in-depth assistance, I'll report back with what I end up with.
Franck
Good luck, Franck! If/when you have any more questions, you know where to find us! There's some really sage advice posted above that will save you lots of time and money, so be sure to summarize and understand. There are a lot of TPVs out there who really wish they did this due diligence, of that I can absolutely assure you.
Chiming in late here.
I've done a lot of work with hosted systems and white label saas like this.
My 2¢:
-
The easiest solution is to have your subscribers CNAME onto your server and validate certificates via the HTTP-01 challenge. You can either do this via scheduled tasks on your backend, or utilizing a gateway server that can do "certificate on demand" aka "autossl". Some servers that offer this can even do cloud coordination across multiple machines. The big drawback of the autossl design is that you need to code around "dogpile" effects caused by multiple requests to a non-existent or expired cert. You can also do this without an auto-ssl, by having a backend service. Since your clients will need to enroll their domain with your service so you know how to map the domain to a client, your backend will have all the necessary info to obtain certs.
-
Another option is to use DNS-01 challenges. Personally I prefer this when possible, because you don't have to do any complex routing on the gateway for an ACME-client. The way I recommend handling this is as follows:
- you host an instance of acme-dns
- your customers CNAME an acme_challenge instead of TXT record onto your acme-dns server
- your acme-client will modify the acme-dns system to pass challenges
There are 2 drawbacks to the DNS-01 approach like this:
1- your client will cname two domains onto your systems. one CNAME for the challenge, another CNAME for the web traffic domain.
2- the stock acme-dns system uses random uuids for the subdomains, but their team was kind enough to merge a PR from me that allows valid subdomains to be used (Merged PR). this implementation detail allows you to pre-generate a bunch of acme-dns credentials, then run a third party script (like this one I wrote) as-needed to replace an unused domain with a custom domain you decide. all combined, this technique will allow you to either pre-assign domains to clients, or base the acme-dns domain (which they cname onto) on their actual domain name.
Conclusion:
IMHO, it is easiest for your subscriber to only CNAME the domain, but the engineering and maintenance effort is quite a bit higher. If you were doing something like "custom domains for your tumblr page", where the subscriber is not tech savvy, I would go this route.
If your subscribers are companies with existing websites or teams of IT people, I would sell-in the second DNS entry as a method of making customer support and servicing more streamlined. With that approach, the customer can remove/re-enable the CNAME to your service whenever they want, so long as the CNAME used for DNS persists. That gives them full control of routing traffic to your system, while allowing you to keep the certificates current even if disabled. The engineering and maintenance on this setup is significantly smaller, because the ACME server will only interact with your acme-dns server and does not care about your web-server -- so you don't have to worry about routing acme-traffic to your server(s) that handle certificate procurement.
In my experience I discourage true CNAMEing though since just having clients reverse-proxy to the TPV with Host header rewrites means that the TPV doesn't need to even get certs for clients' domain names since all the backend HTTP requests are made directly to the TPV's domain name. Cloudflare unfortunately has CNAME in their (fake) DNS pulling double duty for reverse-proxying (orange mode/cloud) and delegation (if the DNS is actually hosted through Cloudflare). I get the "convenience", but it causes some confusion/complexity in situations like this.
Great minds think alike.
I still stand behind my strategy of avoiding acquiring certs for clients entirely through simple reverse-proxying. Why solve a problem when the problem can simply be avoided altogether?
30 Helens Agree! https://www.youtube.com/watch?v=qahhsoDeqs8
Great advice all around, thanks! I haven't made up my mind yet, however:
-
Reverse-proxying is out since many of our clients will not be tech-savvy and setting up a reverse-proxy will be heavily dependent on the CDN provider they happen to use. I need a one-size-fits-all approach
-
HTTP-01 is tricky on AWS CloudFront because CloudFront won't serve requests from aliases for which it doesn't already have a valid certificate. For now I don't have and I don't want a load balancer or an API gateway in front of CF (for cost reasons), so getting the first certificate would require a one-time setup for a server that will handle the challenge, to be replaced with CloudFront.
-
DNS-01 will require the client creating 2 DNS records (or a DNAME record), but it allows me to run the certbot independently of the CNAMEd domain, so that may well be the easiest route in my case.
Franck
So, if the only place you need to install the certificates is in CloudFront, why aren't you just using AWS's built in Certificate Manager with certificates that they issue and handle renewal for? You'd need to have your clients create two CNAMEs still (one to you for your service, and one to AWS for the certificate), but it'd still just be a one-time setup and then you wouldn't need to be running certbot on some other system or whatnot.
Yes, good point, if I go the DNAME route I will definitely use AWS certificates.
Franck
This is turning out to be quite an adventure...
- Cloudflare doesn't support DNAME records
- ACM uses CNAME not TXT records for validation, and apparently won't follow a CNAME pointing to another CNAME. I created
dig _ab04b9631a6fdcaf776fe37587eab64e.reservations.client.com
;; ANSWER SECTION:
_ab04b9631a6fdcaf776fe37587eab64e.reservations.client.com. 202 IN CNAME _ab04b9631a6fdcaf776fe37587eab64e.proxy.greatbookings.io.
_ab04b9631a6fdcaf776fe37587eab64e.proxy.greatbookings.io. 202 IN CNAME _1452ae0a18b0c909a0ece144e5c1a7cc.mhbtsbpdnt.acm-validations.aws.
For now I'll have the client enter the CNAME value directly.
From adventure, to nightmare, to eventually success
The validation still failed with the perfect CNAME record in the client's DNS. That was because of existing CAA records in their root zone.
I was able to create a CAA record in Route53 in the CNAMEd domain... which didn't work until I added a second line in the record as described in this post:
I will definitely reconsider using HTTP-01, even if it involves standing up a temporary server for the first challenge.
Franck
Note: HTTP-01
authentication won't bypass/circumvent any client domain CAA restrictions.
This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.