Chef & Berkshelf – SSL Certificate Validation Error on Windows

When using Windows, Chef, Vagrant and Berkshelf, you may encounter an issue with certificate validation. The error you may encounter is as follows:

Faraday::SSLError: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed

The problem is Ruby is expecting the SSL_CERT_FILE environmental variable to be set. This should point to a CA bundle to use for SSL certificate validation. If this is not set, certificate validation will fail. You can adjust the Berkshelf configuration to not verify SSL certificates, but I have found this setting to be problematic and sporadically not work. The better option, is to actually set the environmental variable.

Luckily, Vagrant comes with a CA bundle. We can leverage Vagrant’s installation information in the registry to determine the installation location of Vagrant and use this to set the SSL_CERT_FILE variable appropriately. The following PowerShell script can be used to do this. It has a set and unset function. By default, running ./Set-SSLCert_Chef_Vagrant.ps1 set will set SSL_CERT_FILE as a user-specific environmental variable.

After running this script, close and re-open any open command prompts for the new variable to take effect. Vagrant is required for this script to work correctly.

# Filename: Set-SSLCert_Chef_Vagrant.ps1
# Brian Dwyer - 5/22/14

# ***USAGE***
# To Setup the SSL_CERT_FILE Variable
# ./Set-SSLCert_Chef_Vagrant.ps1 set

# To Remove the SLL_CERT_FILE Variable
# ./Set-SSLCert_Chef_Vagrant.ps1 unset

# System-Wide Environmental Variables
$System_Vars='HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment'

# User-Specific Environmental Variables
$User_Vars='HKCU:\Environment'

# Check if Vagrant is installed
If (!$env:Path.Contains('Vagrant'))
  {
    echo ""
    echo "/======| Error: Vagrant does not seem to be installed. |=====\"
    echo ""
    pause
    exit
    }

# Get Vagrant Installation Directory
$Vagrant_DIR = $env:Path.Split(';') -like "*vagrant*" | Out-String -Stream | Split-Path -Parent

# Registry Property Key/Value
$Reg_Key='SSL_CERT_FILE'
$Reg_Value="$Vagrant_DIR\embedded\cacert.pem"

# Setup
If ( $args[0] -eq 'set' )
  {
  echo "/======| Setting up Registry Key... |=====\"
  Set-ItemProperty $User_Vars -Name $Reg_Key -Value $Reg_Value
  pause
  exit
  }
Elseif ( $args[0] -eq 'unset' )
  {
  echo "/======| Removing Registry Key... |=====\"
  Remove-ItemProperty $User_Vars -Name $Reg_Key
  pause
  exit
  }
 Else
  {
  echo '------------------------------------------------'
  echo "|*|-Set SSL_CERT_FILE Environmental Variable-|*|"
  echo '------------------------------------------------'
  echo "|   Use 'set' or 'unset' to control script     |"
  echo '------------------------------------------------'
  pause
  exit
  }
Advertisements