December 28, 2017 · ansible winrm certificate pki

Validate CA certificate in Ansible connecting with WinRM

Introduction

This post will show you how to use your own CA certificates instead of mucking around with self-signed certificates and the horrible option of not validating the certificates in Ansible, also known as ansible_winrm_server_cert_validation=ignore.

I will be using a Ubuntu Server 16.04 as my Ansible control machine but this should work on RHEL/CentOS with some minor tweaks.

Prereqs

This example will not show how to set up your own CA server or how to enroll servers automatically so be sure to have that in place.

In this example I will assume that you already have configured WinRM. If not please do so by executing the following command on the Windows servers that you want to control with Ansible.
Enable-PSRemoting

As for the Ansible control machine I will assume that you have kerberos authentication up and running. Otherwise take a look at the official documentation.

Enable WinRM https listener on Windows server

You need to have a server authentication certificate on the machine in order to activate the https listener.

Open the local machine certificate store
certlm.msc

Verify that you have the appropriate certificate.

Activate the new listener.
winrm quickconfig -transport:https

Unfortunately I have not seen any better option to do this then to RDP to the Windows server and execute the command.

Verify that the new listener is enabled.
winrm enumerate winrm/config/listener

Don't forget to open the port (5986) in the firewall if necessary.
New-NetFirewallRule -DisplayName 'WinRM HTTPS Inbound' -Profile Domain -Direction Inbound -Action Allow -Protocol TCP -LocalPort 5986

Export root cert from Windows PKI

Open your favorite browser and head over to your CA server.
http://<your_ca_server>/certsrv

Click "Download a CA crtificate, certificate chain or CRL"

Make sure that the encoding method is set to Base 64
Click "Download CA certificate".

Copy the CA certificate to your Ansible control machine.

Create new directory in /usr/local/share/ca-certificates to put your certificate in:
sudo mkdir /usr/local/share/ca-certificates/safdal.se

Change extension on certificate:
mv certnew.cer certnew.crt

Copy certificate to new directory:
sudo cp certnew.crt /usr/local/share/ca-certificates/safdal.se

Update to take effect:
sudo update-ca-certificates

Example before adding CA trust

My Ansible hosts file:

[windows]
windows-server.safdal.se

[windows:vars]
ansible_user=administrator@SAFDAL.SE  
ansible_password="SecretPassword"  
ansible_port=5986  
ansible_connection=winrm  

I will use the basic win_ping module to test the connection.

ansible windows-server.safdal.se -m win_ping

This will end in a horrible error message.

windows-server.safdal.se | UNREACHABLE! => {  
    "changed": false, 
    "msg": "kerberos: HTTPSConnectionPool(host='windows-server.safdal.se', port=5986): Max retries exceeded with url: /wsman (Caused by SSLError(SSLError(1, u'[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:590)'),)), ssl: HTTPSConnectionPool(host='windows-server.safdal.se', port=5986): Max retries exceeded with url: /wsman (Caused by SSLError(SSLError(1, u'[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:590)'),))", 
    "unreachable": true
}

Let's fix that.

Modify Ansible hosts file

Edit the Ansible hosts file and add the following line:
ansible_winrm_ca_trust_path=/etc/ssl/certs

[windows]
windows-server.safdal.se

[windows:vars]
ansible_user=administrator@SAFDAL.SE  
ansible_password="SecretPassword"  
ansible_port=5986  
ansible_connection=winrm  
ansible_winrm_ca_trust_path=/etc/ssl/certs  

Example after adding CA trust

ansible windows-server.safdal.se -m win_ping

WIN WIN WIN!