icinga2 icon indicating copy to clipboard operation
icinga2 copied to clipboard

Maximal length of Endpoint name is 64 chars du to x509 restrictions

Open RincewindsHat opened this issue 3 years ago • 2 comments

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

RincewindsHat avatar Mar 31 '22 11:03 RincewindsHat

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?

fireba11 avatar Mar 31 '22 15:03 fireba11

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.

julianbrost avatar Mar 31 '22 15:03 julianbrost

So the only option is limiting the CN earlier in the setup wizard?

Al2Klimov avatar Nov 15 '22 11:11 Al2Klimov

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

Al2Klimov avatar Oct 11 '23 08:10 Al2Klimov

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.

Al2Klimov avatar Oct 11 '23 08:10 Al2Klimov

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?

julianbrost avatar Oct 11 '23 12:10 julianbrost

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?

Al2Klimov avatar Oct 11 '23 12:10 Al2Klimov

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)

Al2Klimov avatar Oct 26 '23 16:10 Al2Klimov