I have been trying to get Kerberos auth working with WinRM to be the authentication for transport mechanism within Ansible. I want to configure a Window system, from the non-domain-joined Linux host that runs my automations. Getting these two hosts to talk over WinRM introduces a bunch of options and difficulties with each one. If you look at the table on Ansible’s website for Windows auth with WinRM, you see only a few options for a domain joined machine:

https://docs.ansible.com/ansible/latest/os_guide/windows_winrm.html#credssp
I specifically needed it for an Active Directory account part of my setup was creating lab machines and building domain controllers on the fly. Basic auth is out, Certificate is out, what is left is Kerberos, NTLM, or CredSSP. Then to throw another wrench in this, the Ansible host and server are in FIPS mode. At this point FIPS disables MD5. NTLMv2 uses MD5 internally, which means it does not want to work with an FIPS enabled machine. CredSSP is backed by NTLM hashes as well making Kerberos your only option.
I did not want to have to domain join my Ansible machine to my Windows Domain; this is a test environment. Through a bunch of tinkering I have found a way to run Ansible, and have Ansible use a local krb5.conf file, instead of your system one in /etc/krb5.conf.
- I am on Rocky and installed the following:
- dnf install krb5-devel krb5-libs krb5-workstation python3.12-devel
- pip3.12 install pykerberos gssapi krb5 pypsrp[kerberos]<=1.0.0
- (Note I am using python 3.12 for my Ansible)
- You do need the host you wish to connect to have its FQDN accessible from your Ansible system (we will assume Linux)
- This can be in the hosts file or DNS
- Then you need to set the inventory.yml similar to:
- my-host-post-domain:
ansible_host: host.example.com
ansible_user: Admin@EXAMPLE.COM
ansible_password: WindowsPassword123
ansible_connection: winrm
ansible_winrm_transport: kerberos
ansible_winrm_kinit_cmd: “./kinit.sh”
ansible_winrm_message_encryption: never
ansible_winrm_server_cert_validation: ignore
- my-host-post-domain:
- Create a file where you launch ansible from, kinit.sh:
- #!/bin/bash
cd “$(dirname “$0″)”
export KRB5_CONFIG=./krb5.conf
kinit $1
- #!/bin/bash
- Create your krb5.conf file
- [libdefaults]
default_realm = EXAMPLE.COM
dns_lookup_realm = false
dns_lookup_kdc = false
ticket_lifetime = 24h
renew_lifetime = 7d
forwardable = true
rdns = false
[realms]
EXAMPLE.COM = {
kdc = 192.168.100.2
admin_server = 192.168.100.2
}
[domain_realm]
.example.com = EXAMPLE.COM
example.com= EXAMPLE.COM
(I am purposefully disabling DNS lookup and using my IP addresses, that is up to you.)
- [libdefaults]
- Then I run my Ansible with the following:
- KRB5_CONFIG=./krb5.conf ansible-playbook -i inventory.yml site.yml
It seems if you do not have the kinit.sh file, then kinit does not see the config. And if you don’t have the environment variable before the Ansible command, when Ansible goes to use GSS to connect to the Windows system, Ansible will not see the config.
Troubleshooting
Some fun errors along the way:
- Server not found in Kerberos database
- This means the server you are CONNECTING TO cant be found, usually this means the ansible_host is not the FQDN. Then when kinit is done it tries to connect to AD via the IP and that fails.
- Kerberos auth failure for principal Admin@EXAMPLE.COM with subprocess: kinit: Cannot find KDC for realm \”EXAMPLE.COM\” while getting initial credentials
- It cant find the krb5.conf file, OR under [domain_realm], your mapping has an issue