Multiple UCC/SAN (multiple subdomain) certs, single common name?

I have a service where customers sign up and add 1 or more of their own subdomains that will be handled by my service. So:

There will be more than 99 customer subdomains added, so my question is very specific: can assets.my-service.com be the common name (the first subdomain) for many letsencrypt issued certificates (so it gets displayed in browsers) in a production setting, say in haproxy or via many CDN APIs?


Edit: Ok, investigating ssl certificate transparency logs for cloudflare-issued 3rd party subdomain SAN certs, the common name used is a unique subdomain (eg sni115847.cloudflaressl.com) as the common name for each of their shared certs.

I assume that anyone attempting what I’m doing would have to do the same - and that it’s not issuer-specific, but technical limitations of https in the browser?

I’d appreciate confirmation/correction on the above! Thank you!

Yes. But, you’re much more likely to run into the 20 certificates per domain rate limit that way.

1 Like

Given your statement, would using assets1.my-service.com, assets2.my-service.com, etc (unique common name per cert) avoid this rate limit? I thought the rate limit was at the domain level, not subdomain?

You’re correct. That would also be affected by the 20 certificates per domain rate limit, in exactly the same way. You’d need to either request a rate limit increase or… choose not to create more than 20 certificates per domain per week. :sweat:

For $0.66 you could get the domain my-service-00.cricket.

Edit:

Keep in mind that every certificate you issue affects the rate limit of every customer domain included.

The most rate-limit friendly thing to do is to issue 1 certificate per customer domain. (Or temporarily more than 1 if customers add different domains at different times, consolidated when the oldest one is later renewed.)

Even though you would actually be managing 99+ times as many certificates.

I’m guessing you’re looking into this in order to avoid a situation where someone inspecting the certificate of a site sees the subdomain of a different customer on the same certificate?

I’m not 100% certain if this is enabled in production yet, but I think Let’s Encrypt lets you issue certificates without a common name if you don’t set one in the CSR. In that case, Let’s Encrypt would set the subject to the certificate’s serial number. That might solve your issue without having to think about rate limits. I’m not aware of any compatibility issues in mainstream browsers due to no common name being set, but you might want to double-check that.

1 Like

Understood, thanks.

Ewwww, I don't really want to manage a growing set of domains if at all possible, but you're right, this is an option.

Right, I remember reading that in the limits doc - thanks for the reminder.

That was my thinking: issue individual certs for 99+ of customer domains, then consolidate them (and discard/ignore the old certs) into a SAN cert at that point.

What I'm not sure of is how to deal with churning customers who remove their CNAMEd subdomain from my service - do they automatically get removed on the next SAN cert renew? If so, can I add in a different customer subdomain to keep the number of customer domains in the SAN cert at 99?

My understanding was if I changed any domains in an existing SAN cert, it counts as a 'new' cert instead of a 'renew' - and so impacts domain limits?

Indeed, this is the case yes.

Sounds neat, that is interesting. How would I find out if this is actually the case and planned for a future release?

Generating a CSR that doesn’t have a Common Name manually and submitting that using certbot’s --csr flag should do the trick. Something like this should do for OpenSSL, or you could use this go code.

1 Like

It’s up to your client. I would guess that most would bail out and refuse to renew if a single subdomain failed.

Certbot, for example, will do so by default. But it also has a --allow-subset-of-names option to drop names that fail.

On the other hand, it would be terrible if a client’s DNS had a brief outage at just the wrong time and their certificate got permanently dropped.

Well, you can. You’d probably have to script it.

Correct. For purposes of the renewal rate limit exemption, it has to be an exact match. Adding or removing names, or combining two certificates’ names into one, would count as a “new” certificate.

1 Like

You're a fountain of information - thanks. This is something to investigate further! Not sure how to find out the level of browser support for SAN certs without a common name though. Tips to where I might look?

Hmmm. I presume if a domain fails with this option enabled, it wouldn't be included in the resulting cert. If so...

Does --allow-subset-of-names mean it does a 'new' cert (affecting domain limits) or does it continue with a normal 'renew' if a domain fails? Meaning, are domain rate limits affected if there is a single failed domain during a renew of a SAN cert?

Yes, that's understood, thanks.

This sort of implies that rate domain rate limits aren't affected as long as the submitted domains are identical (thus, remains a cert 'renewal'), even if one fails. Is this accurate?

I’m not aware of any large-scale tests on this. Common names were deprecated ages ago in favour of SAN, so in theory, there should be no issues. That said, you never know what some weird, outdated TLS middlebox might do. The only report I could find is this post saying they experienced no issues without a common name.

If you want to be absolutely certain, I’d suggest running a small subset of your sites with a common name-less configuration and watching if there’s a noticeable drop in requests or increase in errors.

1 Like

Replying to myself here…

I found https://cabforum.org/wp-content/uploads/CA-Browser-Forum-BR-1.4.5.pdf which to me implies that there is strong mainstream browser support for ‘no common name’ in SAN certs, but no specific list of browsers/browser versions. One would think this list would be readily available on https://cabforum.org/

Thanks for pointing me at that github issue. That’s helpful.

Support for Subject Alternative Names goes way back, to IE on Windows 98 even. Any TLS client following the letter of the spec should ignore the common name completely in favor of the Subject Alternative Name.

And browsers have most likely gotten it right, it’s corporate filters and antivirus programs that MitM HTTPS traffic that are of concern. And it’s really hard to test all those. :wink:

You can use https://no-common-name.badssl.com if you want to so some testing on your own, BTW.

2 Likes

There are 3 different factors:

  1. Supports SAN.
  2. Ignores CN.
  3. Supports certificate with no CN.

Virtually all clients support number 1, of course. But who knows how many clients have brittle certificate parsers that assume CN will exist, whether or not it’s used. It can’t just be assumed.

Chrome started entirely ignoring CN literally two months ago, in M58. It caused big problems for enterprise users and they added a (temporary) policy flag to turn it back on.

2 Likes

I was just pointing out the correct behavior with or without a common name has been specified for a long time, as long as SANs have been a thing, and therefore well-behaved TLS clients should have gotten this right for a long time. Whether they do or not in practice is a different matter. :wink:

Browsers are pretty good about getting this stuff right by and large, it's really just corporate filters and non-browser clients where you'll run into trouble.

IIRC, they dropped support for common names entirely, and of course that broke crappy MitM boxes that don't include SANs in their generated certificates. I doubt they ever accepted a certificate with a common name that wasn't also listed in the SAN, and they probably have supported certificates without common names for their entire existence.

2 Likes

Thanks for the useful banter - it pretty much shows me that I can’t assume compatibility, so I had better have a unique san<unique-id>.my-service.com (ie san3342.my-service.com, san3343.my-service.com, etc) as both the common name and the first item in the SAN list for each cert of 99 customer domains.

Great discussion, thanks to you both. If there’s any other input, it’s welcome - but I think my next post will be trying to establish the issuance strategy to avoid rate limits as well as limit the number of certs I need to have active on my servers (or push up to my CDN) at any given time…

Actually, I still don’t know the answer to this - any thoughts?

It’s always a “new” cert if the list of names is different. The certificate API doesn’t really know or care how the list was generated.

Even if I submit the exact same list of names for renewal, but one or more fails http validation? If so, any large service provider will easily hit rate limits, no?

On an API level, they’re separate operations. There’s a “validate a single name” flow and an “issue a certificate for a list of names” flow.

You could validate 200 names, one at a time, and then issue two certificates. You could validate 200 names and then issue zero certificates.

You could issue a certificate without (recently) validating any names at all, consisting of names validated weeks ago.

Additionally, the API largely doesn’t have a concept of renewal. The rate limiting code checks if the list of names is an exact match for a previous certificate’s list of names, but that’s it (as far as i know). Otherwise it’s just “issue a certificate”.

Edit: In other words, you’re never forced to issue an unwanted certificate. You can abort after validating the names and before issuing the certificate,

1 Like