How to use ssl winrm for test kitchens running in Azure
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
:
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!