How can I pre-sign puppet certificates?

Puppet requires certificates between the client (puppet) being managed and the server (puppetmaster). You can run manually on the client and then go onto the server to sign the certificate, but how do you automate this process for clusters / cloud machines?


On the server (puppetmaster) run:

puppetca --generate <NAME>

Then copy the following from the server onto the client:

/var/lib/puppet/ssl/certs/<NAME>.pem
/var/lib/puppet/ssl/certs/ca.pem
/var/lib/puppet/ssl/private_keys/<NAME>.pem

If you wish to sign <NAME> as something other than the hostname use:

puppetd --fqdn=<NAME>

And add to /etc/puppet/puppet.conf if running the daemon

[puppetd]
certname=<NAME>

If you have a host database, you can use the autosign feature. In your puppet.conf file, in the [puppetmasterd], add:

autosign = /path/to/autosign.conf

Then use a crontab to generate this file. The autosign file is just a list of hosts to autosign when they first connect to the puppetmaster. I use LDAP to configure my puppet hosts, so my cron looks like:

* * * * * root /usr/bin/ldapsearch -x '(objectClass=puppetClient)' cn | /bin/grep ^cn | /bin/sed 's!^cn: !!' > /etc/puppet/autosign.conf

I'm sure people who use iClassify would be able to write a query to do the same.

Of course, you need to have some trust in the network. I use this on EC2. My puppetmaster server is in a group that only allows connections from other trusted groups. I wouldn't recommend doing this if your puppetmaster is open to the internet.


Simple answer: automatically sign new requests. This of course is dangerous because you're blindly trusting any system that connects to your puppetmaster, which is the purpose for requiring manual signing.

[puppetmasterd]
autosign = true

You can specify false and a file to use to determine which keys to sign, too.

See the configuration reference on the Puppet wiki.

Another option is to use a tool like Capistrano, where you specify the puppetmaster node and create the client instance nodes, and in the task:

  • Create the instance node, say with EC2's API with Ruby.
  • Run puppetd on the instance, connecting to the server.
  • Run puppetca --sign for the instance's request (since we know the instance name as it was given in the creation bit above).
  • Run puppetd again on the instance, this time successfully connecting as the certificate is signed.

On the server (puppetmaster) run:

puppetca --generate <NAME>

Then copy the following from the server onto the client:

/var/lib/puppet/ssl/certs/<NAME>.pem
/var/lib/puppet/ssl/certs/ca.pem
/var/lib/puppet/ssl/private_keys/<NAME>.pem

If you wish to has as something other than the hostname use:

puppetd --fqdn=<NAME>

And add to /etc/puppet/puppet.conf if running the daemon

[puppetd]
certname=<NAME>