While we’re still converting our puppet controlled infra to Ansible, we still have some nodes “controlled” by puppet, as converting some roles isn’t something that can be done in just one or two days. Add to that other items in your backlog that all have priority set to #1 and then time is flying, until you realize this for your existing legacy puppet environment (assuming false FQDN here, but you’ll get the idea):
1 2 |
Warning: Certificate 'Puppet CA: puppetmasterd.domain.com' will expire on 2019-05-06T12:12:56UTC Warning: Certificate 'puppetmasterd.domain.com' will expire on 2019-05-06T12:12:56UTC |
So, as long as your PKI setup for puppet is still valid, you can act in advance, resign/extend CA and puppetmasterd and distribute newer CA certs to agents, and go forward with other items in your backlog, while still converting from puppet to Ansible (at least for us)
Puppetmasterd/CA
Before anything else, (in case you don’t backup this, but you should), let’s take a backup on the Puppet CA (in our case, it’s a Foreman driven puppetmasterd, so foreman host is where all this will happen, YMMV)
1 |
tar cvzf /root/puppet-ssl-backup.tar.gz /var/lib/puppet/ssl/ |
CA itself
We first need to regenerate the CSR for the CA cert, and sign it again Ideally we confirm that the ca_key.pem and the existing ca_crt.pem “matches” through modulus (should be equals)
1 2 3 4 5 |
cd /var/lib/puppet/ssl/ca ( openssl rsa -noout -modulus -in ca_key.pem 2> /dev/null | openssl md5 ; openssl x509 -noout -modulus -in ca_crt.pem 2> /dev/null | openssl md5 ) (stdin)= cbc4d35f58b28ad7c4dca17bd4408403 (stdin)= cbc4d35f58b28ad7c4dca17bd4408403 |
As it’s the case, we can now Regenerate from that private key and existing crt a CSR
1 2 3 |
openssl x509 -x509toreq -in ca_crt.pem -signkey ca_key.pem -out ca_csr.pem Getting request Private Key Generating certificate request |
Now that we have the CSR for CA, we need to sign it again, but we have to add extensions
1 2 3 4 5 6 7 |
cat > extension.cnf << EOF [CA_extensions] basicConstraints = critical,CA:TRUE nsComment = "Puppet Ruby/OpenSSL Internal Certificate" keyUsage = critical,keyCertSign,cRLSign subjectKeyIdentifier = hash EOF |
And now archive old CA crt and sign (new) extended one
1 2 3 4 5 6 7 8 9 10 |
cp ca_crt.pem ca_crt.pem.old openssl x509 -req -days 3650 -in ca_csr.pem -signkey ca_key.pem -out ca_crt.pem -extfile extension.cnf -extensions CA_extensions Signature ok subject=/CN=Puppet CA: puppetmasterd.domain.com Getting Private key openssl x509 -in ca_crt.pem -noout -text|grep -A 3 Validity Validity Not Before: Apr 29 08:25:49 2019 GMT Not After : Apr 26 08:25:49 2029 GMT |
Puppetmasterd server
We have also to regen the CSR from the existing cert (assuming our fqdn for our cert is correctly also the currently set hostname)
1 2 3 4 |
cd /var/lib/puppet/ssl openssl x509 -x509toreq -in certs/$(hostname).pem -signkey private_keys/$(hostname).pem -out certificate_requests/$(hostname)_csr.pem Getting request Private Key Generating certificate request |
Now that we have CSR, we can sign with new CA
1 2 3 4 |
cp certs/$(hostname).pem certs/$(hostname).pem.old #Backing up openssl x509 -req -days 3650 -in certificate_requests/$(hostname)_csr.pem -CA ca/ca_crt.pem \ -CAkey ca/ca_key.pem -CAserial ca/serial -out certs/$(hostname).pem Signature ok |
Validating that puppetmasted key and new certs are matching (so crt and private keys are ok)
1 2 3 4 |
( openssl rsa -noout -modulus -in private_keys/$(hostname).pem 2> /dev/null | openssl md5 ; openssl x509 -noout -modulus -in certs/$(hostname).pem 2> /dev/null | openssl md5 ) (stdin)= 0ab385eb2c6e9e65a4ed929a2dd0dbe5 (stdin)= 0ab385eb2c6e9e65a4ed929a2dd0dbe5 |
It seems all good, so let’s restart puppetmasterd/httpd (foremand launches puppetmasterd for us)
1 |
systemctl restart puppet |
Puppet agents
From this point, puppet agents will not complain about the puppetmasterd cert, but still about the fact that CA itself will expire soon :
1 |
Warning: Certificate 'Puppet CA: puppetmasterd.domain.com' will expire on 2019-05-06T12:12:56GMT |
But as we have now the new ca_crt.pem at the puppetmasterd/foreman side, we can just distribute it on clients (through puppet or ansible or whatever) and then it will continue to work
1 2 |
cd /var/lib/puppet/ssl/certs mv ca.pem ca.pem.old |
And now distribute the new ca_crt.pem as ca.pem here
puppet snippet for this (in our puppet::agent class)
1 2 3 4 5 6 |
file { '/var/lib/puppet/ssl/certs/ca.pem': source => 'puppet:///puppet/ca_crt.pem', owner => 'puppet', group => 'puppet', require => Package['puppet'], } |
Next time you’ll “puppet agent -t” or that puppet will contact puppetmasterd, it will apply the new cert on and on next call, no warning, issue anymore
1 2 3 |
Info: Computing checksum on file /var/lib/puppet/ssl/certs/ca.pem Info: /Stage[main]/Puppet::Agent/File[/var/lib/puppet/ssl/certs/ca.pem]: Filebucketed /var/lib/puppet/ssl/certs/ca.pem to puppet with sum c63b1cc5a39489f5da7d272f00ec09fa Notice: /Stage[main]/Puppet::Agent/File[/var/lib/puppet/ssl/certs/ca.pem]/content: content changed '{md5}c63b1cc5a39489f5da7d272f00ec09fa' to '{md5}e3d2e55edbe1ad45570eef3c9ade051f' |
Hope it helps