How to update Chef test kitchen to ensure communication over winrm ssl in Azure. SSL is NOT the default configuration for communication. This post will discuss what the default configuration is and how to update it, making it more secure

Have you ever looked in the cert store after your test kitchen in Azure spins up (or is in the process of spinning up)? In the personal store for the computer, there will be a cert issued with the name of the vm.

Now you might think:

  • Where did this cert come from?
  • What is putting it here?
  • What is it used for?

Finding the cert created by test kitchen

If you aren’t sure or familiar with how to look at certificates in Windows, the easiest way is to log into the kitchen itself, hit the windows key, type mmc, then file, add/remove snap in from the upper left, select certificates from the available snap ins, then computer account, next, finish, ok. Back in the main tool, select certificates, then personal, then certificates again.

My test kitchen is VM-A1257843, the default is vm if you don’t specify it in the kitchen.yml:

cert-store-personal

Observing the test kitchen with verbose output

I am using the kitchen-azurerm driver since my test kitchen is deployed in Azure. My first step to understand if the cert was coming from the driver itself or Chef. I was able to accomplish this by running a kitchen create. If I wanted even more detail, I could run a kitchen create -l debug to see debug logs.

I noticed by just running the kitchen create the cert appeared, so I started to dig through the kitchen-azurerm code. I was able to find the code where the self-signed cert gets generated here …this file will get changed at some point so here is the actual code too:

def enable_winrm_powershell_script
  config[:winrm_powershell_script] ||
    <<-PS1
      $cert = New-SelfSignedCertificate -DnsName $env:COMPUTERNAME -CertStoreLocation Cert:\\LocalMachine\\My
      $config = '@{CertificateThumbprint="' + $cert.Thumbprint + '"}'
      winrm create winrm/config/listener?Address=*+Transport=HTTPS $config
      winrm set winrm/config/service/auth '@{Basic="true";Kerberos="false";Negotiate="true";Certificate="false";CredSSP="true"}'
      New-NetFirewallRule -DisplayName "Windows Remote Management (HTTPS-In)" -Name "Windows Remote Management (HTTPS-In)" -Profile Any -LocalPort 5986 -Protocol TCP
      winrm set winrm/config/service '@{AllowUnencrypted="true"}'
      New-NetFirewallRule -DisplayName "Windows Remote Management (HTTP-In)" -Name "Windows Remote Management (HTTP-In)" -Profile Any -LocalPort 5985 -Protocol TCP
    PS1
end

Now that we know the cert came from the kitchen-azurerm driver. On to what the heck is it being used for?

If I remove it, what happens?

If you delete the self-signed cert created by the kitchen-azurerm driver and run a kitchen converge, Chef still works. So really…what IS this cert being used for?

By default, this cert isn’t used for anything unless you’ve specified in your test kitchen transport section to use it.

Let’s jump into this for a minute…

If I look at the Chef documentation for the test kitchens winrm_transport settings the default is negotiate. If I go a step further by reviewing the winrm documentation, notice that negotiate uses HTTP :( This is why we can delete that self-signed cert created by the kitchen-azurerm driver and still have everything work.

If the transport section in your kitchen.yml looks like this:

transport:
  name: winrm
  elevated: true

Bad news buddy…you’re not using SSL!!

Have no fear, it is very easy to switch. After all, the self-signed cert is already created for us! :)

Just update the kitchen.yml

Switching to SSL

IMPORTANT NOTE: Ensure the below update to the transport section is on a new test kitchen, not an existing one.

transport:
  name: winrm
  elevated: true
  winrm_transport: ssl
  operation_timeout: 180

Now run a kitchen create or kitchen converge or kitchen verify.

ba-da-bing ba-da-boom, the test kitchen is now using that self-signed cert that it was creating by default. There are other connection options available for ssl mentioned here

What if I remove the cert with SSL enabled?

Now, if you delete the cert created by the kitchen-azurerm driver and re-run a kitchen converge (with ssl set in the transport section), you’ll get the following error:

>>>>>> ------Exception-------
>>>>>> Class: Kitchen::ActionFailed

>>>>>> Message: 1 actions failed.
>>>>>>     Failed to complete #converge action: [An existing connection was forcibly closed by the remote host. - SSL_connect] on default-windows2016
>>>>>> ----------------------
>>>>>> Please see .kitchen/logs/kitchen.log for more details

>>>>>> Also try running `kitchen diagnose --all` for configuration

Hence we are actually using that cert now!