Puppet: Managing SSL certs in a multiple master, single CA setup

Puppet: Managing SSL certs in a multiple master, single CA setup

I just spent quite a bit of time figuring all of this out and gathering from
multiple blogs and sources, so thought I’d share w/ the Internets. What I need
is a single CA for multiple masters. There are many ways to do it; this is
simply what worked for me. The bits that took the most time to figure out
were that the pe-dashboard has its own certs that need to be recreated and
re-signed, and that the non-CA master needs to still have a copy of the ca.crt.


The following assumes Puppet Enterprise 2.8.1: a reasonably experienced user should be able to adapt it to Puppet Community w/o too much difficulty.

Because I’m using Vagrant for my dev/test environment, all the hostnames are going
to have a ‘vagrant-‘ prefix. So, for this example we will have the CA be on the
‘first’ master, vagrant-pupmaster. The other master will be vagrant-pupmaster2.
The node will be called vagrant-cent64-pupnode. You will need to put these
names into /etc/hosts on all three:

192.168.56.10 vagrant-pupmaster
192.168.56.11 vagrant-pupmaster2
192.168.56.20 vagrant-cent64-pupnode

Destroy all the existing certs (don’t do this on a production system). On
vagrant-pupmaster, vagrant-pupmaster2, and vagrant-cent64-pupnode do:

mv /etc/puppetlabs/puppet/ssl /etc/puppetlabs/puppet/ssl.pre_ca_regenerate

Next, generate a new certs on the CA. On vagrant-pupmaster aka puppetca do:

/opt/puppet/sbin/puppetca --generate --dns_alt_names puppetca,puppet vagrant-pupmaster
 
/opt/puppet/sbin/puppetca --generate vagrant-pupmaster2

On vagrant-pupmaster2 create an empty ssl dir and chmod/chown it appropriately:

mkdir -p /etc/puppetlabs/puppet/ssl
chown pe-puppet:root /etc/puppetlabs/puppet/ssl 
chmod 771 /etc/puppetlabs/puppet/ssl
mkdir -p /etc/puppetlabs/puppet/ssl/certs
chmod 755 /etc/puppetlabs/puppet/ssl/certs/
mkdir -p /etc/puppetlabs/puppet/ssl/private_keys 
chmod 750 /etc/puppetlabs/puppet/ssl/private_keys

Copy the ca crt and the vagrant-pupmaster2 cert over to vagrant-pupmaster2. On
vagrant-pupmaster, do:

scp /etc/puppetlabs/puppet/ssl/private_keys/vagrant-pupmaster2.pem root@vagrant-pupmaster2:/etc/puppetlabs/puppet/ssl/private_keys
scp /etc/puppetlabs/puppet/ssl/certs/vagrant-pupmaster2.pem root@vagrant-pupmaster2:/etc/puppetlabs/puppet/ssl/certs
scp /etc/puppetlabs/puppet/ssl/ca/ca_crl.pem root@vagrant-pupmaster2:/etc/puppetlabs/puppet/ssl/certs/ca_crl.pem

Recreate the puppet dashboard certs on the CA master. On vagrant-pupmaster, do:

su - puppet-dashboard
rake RAILS_ENV=production cert:create_key_pair
rake RAILS_ENV=production cert:request
rake RAILS_ENV=production cert:retrieve
exit
rsync -avz /opt/puppet/share/puppet-dashboard/certs root@vagrant-pupmaster2:/opt/puppet/share/puppet-dashboard/

On vagrant-pupmaster2 edit /etc/puppetlabs/httpd/conf.d/puppetmaster.conf
and make sure the CRL is commented out or deleted and the ProxyPass for
all certs to go to the CA is present and enabled:

#    SSLCARevocationFile     /etc/puppetlabs/puppet/ssl/ca/ca_crl.pem
SSLProxyEngine On
# Proxy all requests that start with things like /production/certificate to the CA
ProxyPassMatch ^/([^/]+/certificate.*)$ https://vagrant-pupmaster:8140/$1

On vagrant-pupmaster2 edit /etc/puppetlabs/puppet/puppet.conf. Make
sure ca = false:

[root@vagrant-pupmaster2 puppet]# grep 'ca =' /etc/puppetlabs/puppet/puppet.conf
    ca = false
[root@vagrant-pupmaster2 puppet]#

On vagrant-cent64-pupnode, edit /etc/puppetlabs/puppet/puppet.conf and set archive_file_server and
ca_server to vagrant-pupmaster, and set server to vagrant-pupmaster2:

[main]
    vardir = /var/opt/lib/pe-puppet
    logdir = /var/log/pe-puppet
    rundir = /var/run/pe-puppet
    modulepath = /etc/puppetlabs/puppet/modules:/opt/puppet/share/puppet/modules
    user  = pe-puppet
    group = pe-puppet
    archive_files = true
    archive_file_server = vagrant-pupmaster
 
[agent]
    certname = vagrant-cent64-pupnode
    server = vagrant-pupmaster2
    ca_server = vagrant-pupmaster
    report = true
    classfile = $vardir/classes.txt
    localconfig = $vardir/localconfig
    graph = true
    pluginsync = true

That should do it! Now restart puppet master and dashboard on both masters:

service pe-httpd restart;service pe-puppet-dashboard-workers restart

And run the agent on vagrant-cent64-pupnode:

puppet agent -t --debug --server vagrant-pupmaster2

Although the agent connects to vagrant-pupmaster2, the ProxyPass should
forward the CSR to vagrant-pupmaster (your CA). On vagrant-pupmaster do:

puppet cert --list

This should display the cert. The fact that it’s showing up on vagrant-pupmaster even
though you connected to vagrant-pupmaster2 as your server means the forwarding worked.
It should look something like below (the fingerprint will be different but it should have
the certname for the node):

[root@vagrant-pupmaster ssl]# puppet cert --list 
  "vagrant-cent64-pupnode" (F7:5C:EB:3D:D3:17:36:67:34:31:42:14:A0:4E:AC:DE)
[root@vagrant-pupmaster ssl]#

Now you need to sign it on the CA:

puppet cert --sign vagrant-cent64-pupnode

Once that’s done, run puppet agent on vagrant-cent64-pupnode:

puppet agent -t --debug --server vagrant-pupmaster


You should get a catalog and successful puppet run. If you get an error from
filebucket about getaddrinfo: Name or service not known, you probably need
to edit /etc/puppetlabs/puppet/manifests/site.pp to set filebucket to the
correct hostname:

    # Define filebucket 'main':
    filebucket { 'main':
      server => '<PUPPET MASTER'S DNS NAME>',
      path   => false,
    }

Leave a Reply

Your email address will not be published. Required fields are marked *