4

i am in process to set up a number of stateless nodes.

Each node is provided with the same OS image file. It fetches the hostname from the DHCP/DNS server during boot time.

Next step is to acquire the server configuration ... I am planning to use puppet for this part ....

BUT at this point the node does not have the correct certificate as it is a generic OS image. The first time a node is seen on the network this works fine because i can use autosign.conf to enable the cert to be signed and verfied

What do i need to do to solve the case where the node has already been seen on the network so the puppet master has a certificate for it... However the server certificate will NOT match to the newly created certificate on the node.

I tried inserting

allow_duplicate_certs = true

into puppet.conf

BUT it does not seem to work. Am i looking at the right settings? IS there a better/propper way to solve this?

2
  • 2
    So..you are also destroying these nodes? And then recreating them with the same names? Dec 10, 2013 at 23:43
  • Yes. That is effectively what i am doing. After first boot it is registering with puppet master and i can then give it a configuration, etc. Then on reboot it is destroyed. Along with the certificate the client holds. I would then like to be able to get the configuration back (via Puppet) automatically on boot. I was thinking this could be achieved by the system creating its new certificate on boot and then the puppet master auto-accepting this on boot as a new cert for the existing node name. And then automatically pulling the config down.
    – Ben
    Dec 18, 2013 at 10:00

3 Answers 3

3

The normal way to handle things like this (especially in EC2-like environments) is to use UUIDs for the client certificates instead of hostnames. I found a reasonable guide to the process on Puppetize Me's "Using UUIDs for agent certnames", but the gist of the process is this:

  1. Install uuidgen
  2. Run uuidgen to get a UUID.
  3. Edit puppet.conf and add certname = <UUID> to the [agent] section.
  4. Continue your Puppet deployment process as normal.

This process can be scripted without too much difficulty.

2
  • 1
    Good idea, but then how do you identify and get rid of old certificates which are no longer used? Dec 26, 2013 at 18:43
  • Well, you can just not worry about them, since an unused certificate doesn't really consume a lot of resources. Alternately, you can use the client reports (via Puppet Dashboard, if you're using it) to see who hasn't checked in for a while and use that information to clean up those nodes and their certificates. I've also seen mention of people having VM instances trigger a puppet node clean on the master when the instances shut down.
    – asciiphil
    Dec 26, 2013 at 20:35
0

I use the EC2 internal hostnames as the hostname(ie ip-X-X-X-X), and also as the certificate name.

And I use the Foreman to create EC2 instances. And with the foreman hooks plugin, I make sure that if a certificate with the same "ip-X-X-X-X" name exists on the master, it is deleted before the instance is created.

Before deleting, I also rename the host in foreman to "ip-X-X-X-X-", from whatever friendly name I gave it.

This also means I do not see friendly names in the host list, but I am ok with that since I use hostgroups, and can use the "column" plugin to see the comment field in foreman, where I keep friendly info.

Not an ideal situation, but works for me so far.

0

This might not be an ideal solution but this is what I was doing before moving to saltstack:

When rolling out a new EC2 box (I am using fabric to achieve this, this is all done on the puppetmaster):

1) On PuppetMaster(certificate and machine host name was already known; naming convention):

local('sudo puppetca -c {}' .format(cert_name));

local('sudo puppetca -g {}' .format(cert_name));

This would take care of the old certificate problem you mentioned.

After this copy over the following files to the new rolled out box using scp:

1) /var/lib/puppet/ssl/ca/signed/signed-cert_name.pem

2) /var/lib/puppet/ssl/private_keys/private-cert_name.pem

3) /var/lib/puppet/ssl/certs/ca.pem

Fabric Code for the above said:

local("sudo cp /var/lib/puppet/ssl/ca/signed/{}.pem /tmp/signed-{}.pem" .format(cert_name,cert_name))
local("sudo chown ubuntu:ubuntu /tmp/signed-{}.pem" .format(cert_name))
local("sudo cp /var/lib/puppet/ssl/private_keys/{}.pem /tmp/private-{}.pem" .format(cert_name,cert_name))
local("sudo chown ubuntu:ubuntu /tmp/private-{}.pem" .format(cert_name))
local("sudo cp /var/lib/puppet/ssl/certs/ca.pem /tmp/ca.pem")   
local("sudo chown ubuntu:ubuntu /tmp/ca.pem")
put("/tmp/signed-{}.pem" .format(cert_name),  "/home/ubuntu/signed-{}.pem" .format(cert_name))
put("/tmp/private-{}.pem" .format(cert_name) , "/home/ubuntu/private-{}.pem" .format(cert_name))
put("/tmp/ca.pem" , "/home/ubuntu/ca.pem")

Now on the new box run the following(I had a simple bash script doing this and fqdn was a param passed):

sudo chown root:root /home/ubuntu/ca.pem /home/ubuntu/signed-$fqdn.pem /home/ubuntu/private-$fqdn.pem
sudo chmod 600 /home/ubuntu/private-$fqdn.pem
sudo mkdir -p /var/lib/puppet/ssl/certs/ /var/lib/puppet/ssl/ca/signed/ /var/lib/puppet/ssl/private_keys/
sudo mv /home/ubuntu/ca.pem /var/lib/puppet/ssl/certs/ca.pem
sudo mv /home/ubuntu/signed-$fqdn.pem /var/lib/puppet/ssl/ca/signed/$fqdn.pem
sudo mv /home/ubuntu/private-$fqdn.pem /var/lib/puppet/ssl/private_keys/$fqdn.pem

I hope this was a little helpful.

note:local, and put are Fabric operations

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .