Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Intermediate CA for client auth does not work #7719

Closed
pboguslawski opened this issue Dec 17, 2019 · 8 comments · May be fixed by #9026
Closed

Intermediate CA for client auth does not work #7719

pboguslawski opened this issue Dec 17, 2019 · 8 comments · May be fixed by #9026
Labels
area/cli Command line helpers area/distributed Distributed monitoring (master, satellites, clients) enhancement New feature or request help wanted Extra attention is needed

Comments

@pboguslawski
Copy link

Hello,

icinga2 does no allow one to specify only intermediate CA as allowed to verify client certificates.

If you put only intermediate cert in file /var/lib/icinga2/certs/ca.crt, server sends to client correct list of allowed CAs for client certs but after API client sends correct cert, icinga2 throws error

information/ApiListener: New client connection for identity '[...]' from [...] (certificate validation failed: code 2: unable to get issuer certificate)

and connection is aborted (icinga2 does not know root CA which is not present in /var/lib/icinga2/certs/ca.crt).

If you put root CA and intermediate CA in /var/lib/icinga2/certs/ca.crt, sever sends to client both CAs and client cert is accepted successfully, but this is too much in scenario when you want to trust only_one intermediate_ and not other intermediate CAs signed by the same root CA.

Checked in icinga2 (2.10.3-2~bpo9+1) from debian stretch-backports; see also similar issue in haproxy:

haproxy/haproxy#404

icinga2 should allow one to specify separate cert files for:

  • API client certificate selection (to generate required CA list for client certs; this should allow one to put here only intermediate CA cert)
  • client certificate verification (this one may contain additional certs, like root + intermediate CAs)

Regards,
Paweł

@dnsmichi
Copy link
Contributor

I understand the feature request, though I do think it will add more complexity to the setup. So if anyone wants to look into a patch and add this functionality including cluster tests, much appreciated.

@dnsmichi dnsmichi added area/cli Command line helpers area/distributed Distributed monitoring (master, satellites, clients) enhancement New feature or request help wanted Extra attention is needed labels Dec 18, 2019
@dnsmichi
Copy link
Contributor

@sircubbi
Copy link

I am not sure if I am seeing the same issue as the OP here, but I guess it is somehow related, since the new CA policy of puppet is mentioned here too.

Trying to use the puppet CA and puppetnode-certificates for the master<->agent-communication in icinga2 does not work, because each certificate is issued by an intermediate from the puppetmaster and the trust-chain is incomplete.

As far as I see, only the first certificate from /var/lib/icinga/certs/ca.crt is read and there is no way to provide a complete chain (looking at https://github.com/Icinga/icinga2/blob/master/lib/remote/jsonrpcconnection-pki.cpp and https://github.com/Icinga/icinga2/blob/master/lib/base/tlsutility.cpp). So I guess there is currently no way to use the PuppetCA together with Icinga at the moment, or am I completely wrong here?

To be precise, in a newer puppet setup you will have two certificates for the CA:

  1. the root-ca (which is a cold-certificate and not used for signing node-certificate). In our case this is "CN = Puppet Root CA: 9bf8c56a6ec228". (this is a self-signed)
  2. the intermediate-ca (which is the regular signing certifcate for all nodes). In our case this is "CN = "Puppet Enterprise CA generated at +2021-02-15 18:26:49 +0100"" (this is signed by "Puppet Root CA")

Regardless if I put the intermediate-ca or the root-ca, or both into /var/lib/icinga/certs/ca.crt it will not be accepted upon connecting to an agent which presents a certificate signed by the intermediate. Depending if the intermediate-ca or the root-ca comes first in the ca.crt-file I will either get

  • "is NOT signed by CA: unable to get issuer certificate (code 2)", or
  • "is NOT signed by CA: unable to get local issuer certificate (code 20)"

Please clarify that it is currently not supported to use the PuppetCA on a recent Puppetmaster-setup.

@lazyfrosch
Copy link
Contributor

lazyfrosch commented Oct 6, 2021

I think one of the best solutions would be to disable RequestCertificateHandler when external CAs are used.

The endpoints should still connect and work, but the Certificate handling complains and stores the cert as pending request.

InitSslContext() should support multiple CAs, as well as intermediates. But I'm not sure if the server can send intermediates with the connection, so that the CA file would only have to contain a root CA.

Suggested steps:

  • Add a ApiListener setting for "external CA"
  • Disable RequestCertificateHandler, SendCertificateRequest and UpdateCertificateHandler when the flag is set
  • Rewrite VerifyCertificate to use the CA Store from InitSslContext / ApiListener's runtime instance for validation (currently only used in RequestCertificateHandler and PKIVerifyCommand)

Apart from that the current handling should merely a nuisance in logging and CSR files on disk, but please correct me if I'm wrong.

ref/NC/729576

@lazyfrosch
Copy link
Contributor

And of course:

  • Ensure chain certificates are sent out on connection, we use SSL_CTX_use_certificate_chain_file in InitSslContext, so it should work already when additional certs are added to FQDN.crt

@Al2Klimov
Copy link
Member

Hello Paweł!

Your feature request (OP) is pretty clear to me. You don't have a root Icinga CA. You have a root corporation CA, an intermediate Icinga CA and e.g. an intermediate Puppet CA. Because corporation policy says so. Now you want the Icinga cluster to trust only the intermediate Icinga CA, so it effectively plays the role of the root CA in the Icinga cluster.

This is already possible without modifications in Icinga as follows. The... Chief CA Officer(?) cross signs the intermediate Icinga CA certificate with itself. So they create a new root CA (self-signed of course) with the existing Icinga CA public and private key. The public key for the mentioned re-usage and the private key for self-signing.

Now the... Chief Icinga Officer(?) can use the above cross-self-signed root Icinga CA as... well... root Icinga CA. Everything signed by the intermediate Icinga CA will be automatically considered also being signed by the root Icinga CA as long as they have the same keypair.

Just don't mix the intermediate Icinga CA and the root Icinga CA in your trust store. One chain path is enough.

Best,
A/K

@Al2Klimov Al2Klimov closed this as not planned Won't fix, can't repro, duplicate, stale Apr 4, 2023
@Al2Klimov Al2Klimov removed their assignment Apr 4, 2023
@Al2Klimov
Copy link
Member

You could even self-cross-"sign" the int. CA w/o its private key:

https://security.stackexchange.com/a/18992

@sircubbi
Copy link

I would consider that a workaround for a limited scenario. It would still not allow to mix certificates from different sources (consider running a big cluster with some hosts using lets-encrypt with official certificates and others with a Puppet CA for example).

It really should be possible to provide a store with all of the CAs that Icinga should trust, like it is common in almost any software using SSL.

I already presented a possible solution in #8859 which is pretty uninvasive to the code and wouldn't break any existing setup.

sircubbi added a commit to sircubbi/icinga2 that referenced this issue Jun 20, 2023
Similar to Icinga#8859 this patch works
around Icinga#7719 by allowing the
intermediate certificate presented by the icinga2-agent.

To make this work the icinga2-master only holds to root-ca in its local
ca.crt, while the icinga2-agent has the intermediate-cert in its local
ca.crt (or the intermediate together with the root in the ca.crt / or
the intermediate in the cert.pem - doesn't matter).
sircubbi added a commit to sircubbi/icinga2 that referenced this issue Jun 20, 2023
Similar to Icinga#8859 this patch works
around Icinga#7719 by allowing the
intermediate certificate presented by the icinga2-agent.

To make this work the icinga2-master only holds to root-ca in its local
ca.crt, while the icinga2-agent has the intermediate-cert in its local
ca.crt (or the intermediate together with the root in the ca.crt / or
the intermediate in the cert.pem - doesn't matter).
Al2Klimov pushed a commit to sircubbi/icinga2 that referenced this issue Mar 8, 2024
Similar to Icinga#8859 this patch works
around Icinga#7719 by allowing the
intermediate certificate presented by the icinga2-agent.

To make this work the icinga2-master only holds to root-ca in its local
ca.crt, while the icinga2-agent has the intermediate-cert in its local
ca.crt (or the intermediate together with the root in the ca.crt / or
the intermediate in the cert.pem - doesn't matter).
Al2Klimov pushed a commit to sircubbi/icinga2 that referenced this issue Mar 8, 2024
Similar to Icinga#8859 this patch works
around Icinga#7719 by allowing the
intermediate certificate presented by the icinga2-agent.

To make this work the icinga2-master only holds to root-ca in its local
ca.crt, while the icinga2-agent has the intermediate-cert in its local
ca.crt (or the intermediate together with the root in the ca.crt / or
the intermediate in the cert.pem - doesn't matter).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/cli Command line helpers area/distributed Distributed monitoring (master, satellites, clients) enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants