Puppet currently keeps hold of it's CSR, which is nice, however if the master returns a certificate which does not match the CSR, e.g. a previously signed certificate, the client cannot use it because it's not tied to the new private key.
The problem arises on the second run of puppet, which thinks it already has a certificate, even though it's un-usable.
Currently, I work around this problem with this very ugly script:
#!/bin/bash
#
# Try really hard to get a signed cert.
#
# Note: the CERT, Private Key, and Public Key env
# variables must match those specified in puppetd.conf
# currently, we don't parse that configuration file, so
# this script must match what puppet is configured to do.
#
PUPPETCONF="/Library/Puppet/Versioned/Client/config/puppet.network"
SSLDIR="/Library/Puppet/Generated/Client/SSL"
CERT="${SSLDIR}/host_cert.pem"
PRIKEY="${SSLDIR}/host_key.pem"
PUBKEY="${SSLDIR}/host_pub.pem"
CSR="${SSLDIR}/csr_$(hostname).pem"
# This function takes a cert as ARG1 and a private key as ARG2
# It challenges the private key by encrypting data to it with the cert.
function ValidCert()
{
local CERT="$1"
local KEY="$2"
if [ ! -e "$CERT" -a ! -e "$KEY" ]; then
return 1
fi
local CHALLENGE_FILE="/tmp/challenge_data.$$"
# Sign some random data and verify it with the certificate
dd if=/dev/random of="$CHALLENGE_FILE" bs=1k count=4 2> /dev/null
openssl smime -sign -in "$CHALLENGE_FILE" -outform pem -text \
-inkey "$PRIKEY" -signer "$CERT" \
-out "$CHALLENGE_FILE".sig.pem >&2
return $?
}
function CleanPuppetCert()
{
[ -e "$CERT" ] && rm -f "$CERT"
}
function CleanPuppetKeys()
{
[ -e "$PRIKEY" ] && rm -f "$PRIKEY"
[ -e "$PUBKEY" ] && rm -f "$PUBKEY"
[ -e "$CSR" ] && rm -f "$CSR"
}
function RunPuppet()
{
echo "Requesting Certificate for $(hostname -s) ..."
echo "%40 CSR"
run_puppet_network.sh \
--waitforcert 10 --onetime \
--verbose --color=false \
--tags certonly >&2
}
RunPuppet
while ! ValidCert "$CERT" "$PRIKEY"
do
CleanPuppetCert
echo "WARNING: Puppet Master returned the wrong cert. Try cleaning!"
SECS=60; DELAY=5;
while [ $SECS -gt 0 ]; do
echo "%40 Retry in ${SECS}s"
sleep $DELAY
((SECS=$SECS - $DELAY))
done
RunPuppet
done
exit 0