In many environments regulations require to intercept SSL traffic. This is necessary to enable firewalls or other devices to detect malicious activities. Puppet Enterprise in its default installation creates its own CA and maintains it. But this makes it impossible to intercept the SSL traffic between Puppet Enterprise and its agents without a man-in-the-middle attack is detected. To solve this problem, Puppet Enterprise can use your own Intermediate CA during installation.
The post will guide you through the process of creating your own Root CA. The next step will explain how to create an Intermediate CA from the newly created Root CA. I will attach my openssl.cnf files for my Root CA and my Intermediate CA to make it more easy to create these CAs.
Before we begin here’s the environment we will work in. The OS is a CentOS 7 server running the CAs. Puppet Enterprise will be installed on a Ubuntu 18.04 server. Out intermediate CA I will name „puppet“.
Environment on our CA server
On our server hosting our CA, we have to create some directories needed by our CA. Here’s an example directory layout I will use:
> cd /root
> mkdir -p ca/root_ca # our root ca
> mkdir -p ca/puppet # out intermediate ca
> cd root_ca
> mkdir certs crl newcerts private csr > chmod 700 private > touch index.txt > echo 1000 > serial
> echo 1000 > crlnumber
# setup of intermediate ca> cd ../puppet
> mkdir certs crl newcerts private csr
> chmod 700 private
> touch index.txt
> echo 1000 > serial
> echo 1000 > crlnumber
Next we will create a password file and encrypt that file. To keep things easy we will use the same password file for the Root CA and the Intermediate CA. In production environments you should have different files for each CA. Encryption of the password file needs a password for encryption. You have to enter this password twice.
cd /root/ca
# this secret we will use to protect private keys
> echo "your secret" > passfile
# You need to enter a encryption password twice
> openssl enc -aes-256-cfb8 -salt -in passfile -out passfile.enc
> chmod 0400 passfile passfile.enc
You can delete the file with the plaintext password. In our case the passfile file.
Now we are ready to create our CAs.
Creating a Root CA
If you already have your own Root CA please skip this step.
First we need to create an openssl.cnf file for our new Root CA. You can download the file root-openssl.cnf to make setup easier. But you can create an openssl.cnf file yourself as well.
The openssl.cnf file will be located in the /root/ca/root_ca directory.
Private key for Root CA
Now we are ready to create the private key for out new Root CA. I strongly recommend to use 4096 bits for the keys of your Root CA and your Intermediate CA.
> cd /root/ca/root_ca
> openssl genrsa -aes256 \
-passout file:/root/ca/passfile.enc \
-out private/cakey.pem 4096
> chmod 400 private/cakey.pem
The passphrase for this key will be taken from the encoded passfile.
Create certificate for Root CA
With our newly created private key we can create the public certificate of our Root CA. You have to fill several fields for your CA. I recommend, to put something like „My company Root CA“ into the Common Name field.
> cd /root/ca/root_ca
> openssl req -config openssl.cnf -new -x509 -days 3650 \
-extensions v3_ca \-passin file:/root/ca/passfile.enc \
-key private/cakey.pem \
-out certs/cacert.pem
Verify certificate for Root CA
Now we verify our new certificate.
> openssl x509 -noout -text -in certs/ca.cert.pem
You should see some informations about your certificate. If there are errors displayed something went wrong.
That’s it. You have your Root CA created. Let’s continue with creating our Intermediate CA.
Create CRL for Root CA
For our further use with Puppet Enterprise we need CRLs (Certificate revocation lists). We can create the one for our Root CA with the following commands:
> cd /root/ca/root/ca
> openssl ca -config openssl.cnf \
-passin file:/root/ca/passfile.enc \
-gencrl -out crl/crl.pem
The command will create a crl.pem file. We have no revoked certificates so far but we need this file later to install Puppet Enterprise.
Create an Intermediate CA
With our Root CA we are now able to create an Intermediate CA.
First we need to create an openssl.cnf file for our new Intermediate CA. You can download the file intermedite-openssl.cnf to make setup easier. But you can create an openssl.cnf file yourself as well.
The openssl.cnf file will be located in the /root/ca/puppet directory.
Create private key for Intermediate CA
To create the private key for the Intermediate CA do the following:
> cd /root/ca/puppet
> openssl genrsa -aes256 \
-passout file:/root/ca/passfile.enc \
-out private/puppet.cakey.pem 4096> chmod 400 private/puppet.cakey.pem
Create CSR for Intermediate CA
Now we have to create a Certificate Signing Request (CSR) for our Intermediate CA. I recommend, to put something like „My company Intermediate CA Puppet“ into the Common Name field. The „challenge password“ and the „optional company name“ fields you can leave empty.
> cd /root/ca/puppet
> openssl req -config openssl.cnf -new -sha256 \
-passin file:/root/ca/passfile.enc \
-key private/puppet.cakey.pem \
-out csr/puppet.csr.pem
Create certificate for intermediate CA
> cd /root/ca/root_ca # be careful here to do this in the directory of the root ca
> openssl ca -config openssl.cnf -extensions v3_intermediate_ca \
-days 2650 -notext -batch \
-passin file:/root/ca/passfile.enc \
-in ../puppet/csr/puppet.csr.pem \
-out ../puppet/certs/puppet.cacert.pem
Verify certificate for Intermediate CA
To verify the certificate do the following:
> cd /root/ca/puppet
> openssl x509 -noout -text \
-in certs/puppet.cacert.pem
You should see output similar to this: „intermediate.cert.pem: OK“
Create CRL for Intermediate CA
As we did for the Root CA we need to create a CRL for the Intermediate CA as well. To create the CRL for our Intermediate CA do the following:
> cd /root/ca/puppet
> openssl ca -config openssl.cnf \
-passin file:/root/ca/passfile.enc \
-gencrl -out crl/puppet.crl.pem
This CRL we need for the Puppet Enterprise installation later.
Installing Puppet Enterprise
There’s a documentation on how to install Puppet Enterprise with your own Intermediate CA. On how to install Puppet Enterprise with a self-signed Intermediate CA please refer to this documentation. Please read carefully about what you have to take care yourself when using you own Intermediate CA.
For the following I assume that you have a Ubuntu 18.04 server prepared. This server should comply to the system requirements for Puppet Enterprise. I will also assume that you have your Puppet Enterprise installer unpacked into the /var/tmp directory.
Preparations on our CA server
On our CA server we have to prepare some files for the Puppet Enterprise installation. We will copy these files into the /root/puppet_install directory.
The following steps have to be done ou your server hosting your newly created CAs.
Create a Cert Bundle
> mkdir -p /root/puppet_install
> cat /root/ca/puppet/certs/puppet.cacert.pem > /root/puppet_install/cert_bundle.pem
> echo >> /root/puppet_install/cert_bundle.pem
> cat /root/ca/root_ca/certs/cacert.pem >> /root/puppet_install/cert_bundle.pem
> echo >> /root/puppet_install/cert_bundle.pem
Create a CRL Bundle
> cat /root/ca/puppet/crl/puppet.crl.pem > /root/puppet_install/crl_bundle.pem
> echo >> /root/puppet_install/crl_bundle.pem
> cat /root/ca/root/ca/crl/crl.pem >> /root/puppet_install/crl_bundle.pem
> echo >> /root/puppet_install/crl_bundle.pem
Remove passphrase from Intermediate CA private key
Puppet Enterprise needs the private key without passphrase. We protected out private key with a passphrase. We copy the private key and remove the passphrase during copy.
> openssl rsa
-in /root/ca/puppet/private/puppet.cakey.pem \
-out /root/puppet_install/puppet-ca.key \
-passin file:/root/ca/passfile
Now we have all necessary files for the installation of Puppet Enterprise gathered. Copy the whole directory ro the server where Puppet Enterprise will be installed.
> scp -r /root/puppet_install <user>@<puppetserver>:/tmp/
Install Puppet Enterprise
On the puppet server move the directory to /root.
> mv /tmp/puppet_install /root/
> chmod 700
/root/puppet_install
Now we prepare our pe.conf file to use with the Puppet Enterprise installer.
Create a file /root/pe.conf with at least the following content. If you need some more settings in the pe.conf file please consult the Puppet Documentation.
{
"console_admin_password": "mypassword"
"puppet_enterprise::puppet_master_host": "<puppet server fqdn>""pe_install::signing_ca": {
"bundle": "/root/puppet_install/cert_bundle.pem"
"crl_chain": "/root/puppet_install/crl_bundle.pem"
"private_key": "/root/puppet_install/puppet-ca.key"
}}
The pe.conf file contains useful information for the Puppet Enterprise installer.
Change into the puppet enterprise installer directory and do the following:
> ./puppet-enterprise-installer -c /root/pe.conf
If everything is ok with your Intermediate CA the installer will work fine. If there are problems with the certificates you will see errors during the install process. Please look into the installer’s logfile to see what’s wrong.
Check auth.conf file
After Puppet Enterprise install is finished check the /etc/puppetlabs/puppetserver/conf.d/auth.conf file. Open the file and search for entries for the url /puppet-ca/v1/certificate_revocation_list. Currently in my installation I found this entry two times. Make sure that the type is set to regex. Here’s an example how that should look like:
"match-request": {
"method": "put",
"path": "^/puppet-ca/v1/certificate_revocation_list$",
"type": "regex"
},
"match-request": {
"method": [
"put"
],
"path": "^/puppet-ca/v1/certificate_revocation_list$",
"query-params": {},
"type": "regex"
},
"name": "puppetlabs certificate revocation list",
"sort-order": 500
If you change these entries restart your Puppet server.
Maintain CRLs in Puppet Enterprise
As you use your own Intermediate CA you have to take case to upload new CRLs to Puppet Enterprise. Here’s a short example script to upload CRLs to Puppet Enterprise.
#!/bin/bash
if [ $# -ne 1 ] ; then
prog=`basename $0`
echo "usage: $prog <crl file>"
exit 2
fi
type_header='Content-Type: text/plain'
cert="$(puppet config print hostcert)"
cacert="$(puppet config print localcacert)"
key="$(puppet config print hostprivkey)"
uri="https://$(puppet config print server):8140/puppet-ca/v1/certificate_revocation_list"
curl --insecure --cert "$cert" --cacert "$cacert" --key "$key" \
--header "Content-Type: text/plain" --header "Accept: text/plain" \
--request PUT --data "@$1" "$uri"
echo
exit 0
The best way is to create CRLs automatically, upload the new CRL to the Puppet Enterprise server and run the above script on that server.
Full script
I created a shell script with all the commands above to create a Root CA and an Intermediate CA. The script will also create the files needed for the Puppet Enterprise installer. You can download the zip file here but you are strongly advised to review it before you use it! I’m not responsible for whatever will happen.
Thank you so much for this article! After 5 days trying to solve this problem I couldnot without your article. So many many thansk 🙂
I found below mistakes or so 🙂
In: Create certificate for Root CA:
> openssl req -config openssl.cnf -new -x509 -days 3650 \
-extensions v3_ca \
-passin file:/root/ca/passfile.enc \
-key private/cakey.pem \
-out certs/cacert.pem
it should be root-openssl.cnf, it not so important but I think many people will save that also as root-openssl.cnf
In: Verify certificate for Root CA
openssl x509 -noout -text -in certs/ca.cert.pem
Should be:
openssl x509 -noout -text -in certs/cacert.pem
In: Remove passphrase from Intermediate CA private key
> openssl rsa -in /root/ca/puppet/private/puppet.cakey.pem \
-out /root/puppet_install/puppet-ca.key \
-passin file:/root/ca/passfile
it should be passfile.enc and not passfile, or -passin pass:“mypass“:
> openssl rsa -in /root/ca/puppet/private/puppet.cakey.pem \
-out /root/puppet_install/puppet-ca.key \
-passin file:/root/ca/passfile.enc
this is for new installation of puppetserver, if we have already one and want to use external CA we should also remove the crl.pem on clients.
Again thanks a lot you save my week so Im on friday and Im happy 🙂 Cheers