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!