18

We do use an internal Certificate Authority to create server certificates in my company.

We also have to deal with a transparent proxy doing SSL interception (MITM).

I regularly encounter SSL validation errors due to Chef not knowing the CA certificate, and sometimes it's the tooling around chef itself (berkshelf, knife; even chef client itself when talking to the server for the first time since chef 12 enables SSL by default).

Question is: How do I make Chef aware of my CA certificate to get valid SSL exchanges ?

Tensibai
  • 11,416
  • 2
  • 37
  • 63

2 Answers2

15

There's a couple of way to achieve the result:

  1. Chef has a trusted_dir to allow adding certificate to the trusted list. the documentation has a lot of details about it. Adding your CA certificate to this directory would solve the problem. knife has it also in a slightly different path as per it's own documentation

  2. Chef use its own CA certiticate list in /opt/chef/embedded/ssl/certs/cacert.pem. You can add your CA certificate at end of this list to trust it.

The second option has an advantage of allowing you to export the environment variable SSL_CERT_FILE pointing to chef cacert.pem to allow most of the tools using openssl library to know your CA certificate.

For the case of a self signed certificate on the chef server (or another server used as target in a recipe), knife ssl_fetch would allow all knife commands to work.

To add the server certificate to the cacert.pem for the case 2. above, you can use the following command:

# For a self signed CA certiticate
openssl s_client -showcerts -connect <YOUR_CHEF_SERVER>:443 </dev/null 2>/dev/null|openssl x509 -outform PEM >> /opt/chefdk/embedded/ssl/certs/cacert.pem

# For an internal CA signed certificate:
openssl s_client -showcerts -verify 5 -connect <YOUR_CHEF_SERVER>:443 </dev/null 2>/dev/null | awk '/BEGIN/,/END/{if(/BEGIN/){a++}; certs[a]=(certs[a] "\n" $0)}; END {print certs[a]}' >> /opt/chefdk/embedded/ssl/certs/cacert.pem

export SSL_CERT_FILE=/opt/chefdk/embedded/ssl/certs/cacert.pem

The openssl command is included in chef-dk, so this can be done under windows also. Change the path to c:\opscode\ instead of /opt/. To export the environment variable use set SSL_CERT_FILE=... (with /P to add it permanently to your environment) in your command.

Tensibai
  • 11,416
  • 2
  • 37
  • 63
0

In my case, I was doing basically the same thing, because the internal certificate path was different than the typical certificate path, so I had to add my internal certificates. In my case, adding the SSL_CERT_FILE didn't work. I needed to copy my certificates, which I had exported as *.cer and then made *.pem versions using

. ./openssl x509 -inform der -in C:\dev\apps\certificates\org_root.cer -out C:\dev\apps\certificates\org_root.pem

I found the openssl tool here:

C:\opscode\chefdk\embedded\bin

Then I copied them to this location (which the location in the documentation above doesn't clarify very well) on the target machine:

C:\Users\[username]\.chef\trusted_certs

I had to create the "trusted_certs" folder on my target machine where I wanted to run the chef client. After copying the certificates there, it began working and trusting the internal certificate chain without SSL errors (in my case self-signed certificate error).

Also, on the ChefDK machine if you're using kitchen or something like that, I had to take the contents of my internal certificates' *.pem files and copy the contents of the content to the tail of the "C:\opscode\chefdk\embedded\ssl\certs\cacert.pem" file or the cacert.pem file referenced by the SSL_CERT_FILE environment variable. In my case, I was copying an internal intermediate cert as well as a internal root cert and I believe they recommend that order also (ending with the root in the chain). This requirement on the ChefDK machine is due to the ChefDK communicating with a client machine using "remote_file" and the solution I'm providing appears to relate to this Chef bug, which may be fixed in newer versions of Chef.

https://github.com/chef/chef/issues/5944