Maximal length of Endpoint name is 64 chars du to x509 restrictions
Describe the bug
The maximal length of the name of an Endpoint is limited to 64 chars due to the limitations on CommonName in x509 (look for ub-common-name-length). This presents a problem, if you want to strictly adher to a Endpoint.name == FQDN policy, especially on the cloud foo nowadays.
To Reproduce
# icinga2 node wizard
Welcome to the Icinga 2 Setup Wizard!
We will guide you through all required configuration details.
Please specify if this is an agent/satellite setup ('n' installs a master setup) [Y/n]: n
Starting the Master setup routine...
Please specify the common name (CN) [*****]: loooooooooooooooooooooooooooooooooooooong.Hostname.topleveldomain
Reconfiguring Icinga...
Checking for existing certificates for common name 'loooooooooooooooooooooooooooooooooooooong.Hostname.topleveldomain'...
Certificates not yet generated. Running 'api setup' now.
critical/SSL: Error with x509 NAME getting text by NID: 218603671, "error:0D07A097:asn1 encoding routines:ASN1_mbstring_ncopy:string too long"
critical/Application: Error: std::exception
Additional information is available in '/var/log/icinga2/crash/report.1648724548.906294'
[1] 62641 IOT instruction icinga2 node wizard
Expected behavior
I would expect to be allowed hostnames of about 255 chars.
Possible Fix
Put something like "Icinga_Host" in Extensions and prefer it in the future until the usage of Common Name can be deprecated
current policy is to expect the FQDN as a SAN entry that should have no such limits anyway, so CN could have some shortended name?
Unfortunately not. Icinga uses TLS mutual authentication, i.e. client certificates. The node that is connected to (i.e. the one in the TCP/TLS server role) uses the certificate sent by the other node to derive it's endpoint name using the CN attribute. As there can be multiple SAN entries, this would require some weird limitations if we decide to use SAN in this case, something like only the first DNS name would be considered.
So the only option is limiting the CN earlier in the setup wizard?
As there can be multiple SAN entries, this would require some weird limitations if we decide to use SAN in this case, something like only the first DNS name would be considered.
Would it be really that bad? I'd even suggest taking the first non-wildcard DNS SAN matching a known Endpoint if there's no CN.
I mean, how does it work at the moment? You can (just because you can) have 2+ DNS SANs. But you must have one CN which decides. My above suggestion just adds the option to omit the CN (which Icinga has to do to actually fix this issue) along with a reasonable fallback identification strategy (which doesn't cause any trouble with Icinga 2's own 1-SAN certificates anyways).
Putting it on the next .0 milestone, while keeping the TBD label for discussion. Not to forget it. (Changing how our PKI works is a long-term thing.) My plan:
- 2.X.0: fallback as see above
- 2.{X+1}.0, or even 2.X.0 if we're brave enough: actually issue certs w/o CN if necessary
taking the first non-wildcard DNS SAN matching a known Endpoint if there's no CN.
Or, if that's too magic, we can require no-CN client certs to have exactly one DNS SAN.
taking the first non-wildcard DNS SAN matching a known Endpoint if there's no CN
I'd avoid any such magic that depends on the configuration. A certificate should uniquely identify the node name it resolves to, without needing extra information. Otherwise, there would be situations where you add or remove endpoints from the config and suddenly the very same certificate identifies as another endpoint.
omit the CN (which Icinga has to do to actually fix this issue)
What exactly would then be the subject of these certificates and following, how would these behave with existing Icinga 2 versions?
I'd avoid any such magic that depends on the configuration. A certificate should uniquely identify the node name it resolves to, without needing extra information. Otherwise, there would be situations where you add or remove endpoints from the config and suddenly the very same certificate identifies as another endpoint.
I agree. Then only this one is left:
if that's too magic, we can require no-CN client certs to have exactly one DNS SAN.
omit the CN (which Icinga has to do to actually fix this issue)
What exactly would then be the subject of these certificates and following, how would these behave with existing Icinga 2 versions?
Technically they can be empty, as per openssl blah -subj /. I guess we have no alternatives. Existing Icinga 2 versions always take the CN, see ApiListener#NewClientHandlerInternal(). So they won't recognise a peer w/o one. Which is IMAO not worse than not having a cert at all as per OP. Do you agree?
TODO
- [ ] PkiUtility::SignCsr(): become SAN/ext. aware
- [ ] CreateCertIcingaCA(): take SAN/ext. explicitly
- [ ] MakeX509CSR(): take SAN/ext. explicitly
- [ ] CreateCert(): take SAN/ext. explicitly
- [ ] CreateCert(): don’t use GetX509NameCN()
- [ ] GetCertificateCN(): assimilate GetX509NameCN() to become the monopoly
- [x] GetCertificateCN(): fall back to DNS SAN
- [ ] Issue w/o CN if >64 (v2.16)