Support for External CAs via puppet_clientcert_pem fact?
Closed this issue · 5 comments
We're running an external CA setup, which means our puppetservers don't have puppet agent certs locally, and it wouldn't be viable to change that.
I was thinking about making Puppet's PEM-encoded client certificate available as a fact (e.g. puppet_clientcert_pem
), then modifying the logic of node_encrypt()
to check (and use) this fact if "#{Puppet.settings[:certdir]}/#{destination}.pem"
doesn't exist.
There's a couple of decision points to be considered:
- Is this even a good idea? If not, is there an alternative?
- Should the fact be optional? Is it even possible to somehow only enable a fact on agents if the Puppet Server's
ca
parameter (in the master section) is false? If the fact can't be made optional, would you prefer it if I kept the fact out of this module? - What's the best way for this to be implemented? I was thinking to simply check if
destpath
is readable, and if it isn't, use the fact instead. - Does anything else - other than node_encrypt() - need to change to support this? I poked around and couldn't see anything, but can you confirm?
Cheers!
We also use an external CA
As a result, modified node_encrypt to take --cert "destination.crt" - then have a simple "encrypt file" script to which downloads the target's SSL cert from IPA (in our case) and encrypts the given files content.
However, this is only 1 side of the coin
The main reason I haven't created a PR for this is that it still needs a valid CA signed key to sign the encrypted data with (the apply provider verifies) and how you do this would vary quite a bit site-to-site (we allow users to use their local hostcert ssl key for now, but will likely change to a user cert)
Given this, I feel the most flexible, non-specific option would be to parametize all 3 options: --target-cert "target.crt" --sign-cert "signing.cert" --sign-key "signing.key"
Where the defaults are as they are currently (if ca_server: cacert/cakey/signeddir, else hostcert/hostprivkey/certdir) to keep backwards compatibility.
Sounds good. But without sending the cert as a fact, we'd still need to pull the agent's PEM-encoded x509 certificate from IPA and make it available on the puppet-servers filesystem, right? If so, that's not something I'm prepared to live with ... for a few reasons:
- Our agent certs have extremely short life-spans (7 days or less), which means I have to write all sorts of funky code to deal with caching, expiring certs, not knowing when certmonger renewed a cert, race conditions, etc - which would create a huge mess.
- IPA calls (e.g. via the
ipa
CLI tool) are really, really slow, which means tying up the puppet-server's JVM threads even more. - The puppet-server will have to assume the cert pulled from IPA is the correct one - a dangerous assumption because a) IPA replication is fragile, and b) it's entirely possible for a principal to have multiple valid certificates at the same time.
But I understand if you aren't comfortable with my suggestion to use a fact. Let me know if you think it's best to create a fork.
Ah, apologies, I didn't quite understand your use-case (we didn't like the idea of sensitive material unencrypted on the puppet masters / outside of our git CM)
We do the encryption offline and throw it in hiera and send it as encrypted_content to node_encrypt::file
(As an FYI: I'm not involved in the project, just a user who stumbled upon your post and happened to be something I also happened to be looking at)
@binford2k ... your thoughts?
@earsdown so if I am reading this right, you just want a fact to expose the agent's certificate as a fact to be used during encryption?
I like that idea. It's pretty elegant, imho. It's better than that weird certificate distribution scheme I wrote. There was a reason (that I can't remember) why I chose not to do it though, after chatting with @adrienthebo. Let me noodle on this for a bit, and see if I can remember why.