Open twopir opened 8 years ago
Dumping some intermediate thoughts, since I haven't fully solved this yet.
There seem to be (at least) two ways to handle this:
www.example.com
as an extra sAN for every example.com
cert. I don't much like this, because while www.
is an extremely common subdomain, it's hardly the only one that exists. It's also aesthetically unpleasant to hardcode something like this.DirectoryStore
?
touch
trick wouldn't suffice anymore, some tool to generate a multi-name cert to start would be needed)Not necessarily a good idea, but what about adding an endpoint parameter that points to a .toml/.json/etc file with additional configuration preferences, including an "include www.
" flag for each listed domain name? e.g. le:~/certdata:configfile=~/certs.json:tcp:443
Or better, reserve a .json filename in the DirectoryStore
for this metadata? It could have a "defaults" section, plus a section for each domain name, and then flags in each section. "add www.
" would be one flag, but maybe decisions about renewal frequency or challenge mode could be there too.
I am -1 on hardcoding www
or adding an external toml file configuration.
I am ok with reserving a .json
for the default DirectoryStore implementaiton.
I am using a different directory store anyway :)
In terms of AcmeIssuingService API, maybe we can have:
AcmeIssuingService.issue_cert(server_name, sans=None)
sans
can be a list of domain names, to trigger a sANs certificate. In this case server_name
is used as certificate_name.
So you end up calling AcmeIssuingService.issue_cert('my-server-x', ['domain.com', 'www.domain.com', 'open.domain.com'])
.
AcmeIssuingService.issue_sans(cert_name, [domain.com, www.domain.com, open.domain.com])
and then AcmeIssuingService.issue_cert
can call AcmeIssuingService.issue_sans(server_name, [server_name])
There is also the option of doing something like AcmeIssuingService.issue_cert(server_name, cert_name=None)
where server_name can be Unicode or a list of unicodes. When is a list, it will trigger the SAN behaviour and cert_name is required. It can end up with a call lilk AcmeIssuingService.issue_cert([domain.com, www.domain.com, open.domain.com], cert_name)
I prefer option 2 as is explicit. The issue_sans
name can be changed, but the main idea is to have a separate API for sANs certificates.
In terms of ICertificateStore
interface with support for sANs, I think that we can continue to use the same interfance, but instead of server_name
as the storage key, use cert_name.
I am looking at certbot https://github.com/certbot/certbot/blob/b50abddb5f144d0570ce57dfa87804e781037175/docs/cli-help.txt#L70 and I see that they have Certificate name
and they use that name to create the persisted file name.
So ICertificateStore can index the stored objects based on a certificate name and not on the server_name (domain).
Beside renaming server_name
to cert_name
, I don't think there is other API change in ICertificateStore
I have not yet checked Client.request_challenges(identifier)
to see how it can be extended for sANs.
In the end I added SAN support in a quick and dirty way ... but it works :) ... see https://github.com/twisted/txacme/compare/37-san-support
Instead of server_name
I am using the storage key with the semantics of certificate_name
.
Certificate name can be a comma separated value of domain names.
I am using a simple in-memory dict based storage, but I guess that this also works with file based storage.
In this way, the API is not changed and is backward compatible.
If you want to use SAN certificates, just use comma separated domains.
I guess that "space" can also be used instead of "comma" character as the delimiter.
comma works for me; it's not valid in DNS names :)
It'd be incredibly convenient if txacme would, when renewing a certificate whose name starts with www, request that the cert contain a subjectAlternativeName without the
www
.