Ansible WinRM Kerberos Authentication

Hi,

I am trying to run win_ping module using the adhoc command through ansible against domain controller through winrm and kerberos authentication. Issue is when I create an Environment Variable KRB5_CONFIG=/tmp/krb5.conf ansible is not picking up the Env and defaulting to whatever is in /etc/krb5.conf and hence failing to work as it’s not able to find the REALM in the database as it doesn’t exist in /etc/krb5.conf but in /tmp/krb5.conf. Is there any other way to supply the Environment Variable so that ansible knows where to find the kerberos config instead of just picking it up from default location. The environment variable works fine if I run the kinit user@REALM command and after supplying the password it gets the ticket.

The variable was setup correctly using
export KRB5_CONFIG=/tmp/krb5.conf
And the following was used for testing
ansible all -i “dc01,” -m win_ping -e ansible_user=domainadmin@REALM -e ansible_password=*** -e ansible_connection=winrm -e ansible_winrm_transport= kerberos -e ansible_winrm_cert_validation=ignore

Hey @Fragger_Lagger,

first of all welcome to the ansible community forum! Nice to have you onboard.

Have you set the variable kinit_env_vars? If I remember correctly I think that ansible isn’t forwarding ENV per default and the desired ENV that is getting parsed to kinit has to be specified via. this variable.

Hope this helps! Although I’m not a windows expert, I’m happy to help with windows related questions!

Hey @ nwerker

Thanks for the response.
I tried like this but it isn’t working.
ansible all -i “dc01,” -m win_ping -e ansible_user=diradmin@PROD -e ansible_password=**** -e ansible_connecti
on=winrm -e ansible_winrm_transport=kerberos -e ansible_winrm_cert_validation=ignore -e ansible_winrm_kinit_env_vars=[“KRB5_CONFIG=/home/anvil/krb5.conf”]

Have you tried only specifying the name of the environment variable, not the whole key + value?!

Like:

ansible all -i “dc01,” -m win_ping -e ansible_user=diradmin@PROD -e ansible_password=**** -e ansible_connection=winrm -e ansible_winrm_transport=kerberos -e ansible_winrm_cert_validation=ignore -e ansible_winrm_kinit_env_vars=[“KRB5_CONFIG”]

Thanks for the response @nwerker. Unfortunately it still didn’t work. It’s not picking up the Configuration from the environment variable.

Funny enough, I have been trying to achieve the same thing for the same exact reasons. I finally got something working based off of: BuildingTents | Giving the campers something to read while they guard the flag

have krb5.conf in ~/

make kinit.sh in ~/

#!/bin/bash

cd “$(dirname “$0”)”

export KRB5_CONFIG=./krb5.conf

kinit $1

make executable

chmod +x ~/kinit.sh

in your ansible-playbook line, add this extra var:

–extra-vars “ansible_winrm_kinit_cmd=/home/[USERNAME]/kinit.sh”

1 Like

Thanks @ITJoeSchmo for the response.

Your solution changed the error. Seems like it picked up the REALM but it’s not picking up the password supplied through ansible_password variable. I am getting this error


Kerberos auth failure for principal diradmin@PROD with subprocess: kinit: Pre-authentication failed: Cannot read password while getting initial credentials.

Update @ITJoeSchmo

It’s still not picking up the Correct REALM and correct configuration. If I remove the REALM from the user it doesn’t pick the proper configuration.

I think the only time you can exclude the REALM is if you have a default set in the krb5.conf file e.g.

# Default values used by the Kerberos V5 library
[libdefaults]
 default_realm = DOMAIN.TLD
 dns_lookup_realm = false
 dns_lookup_kdc = false
 ticket_lifetime = 24h
 renew_lifetime = 7d
 forwardable = true
 rdns = false

My ansible_* vars are being defined by a .yml in the ./inventory dir, but it seems to more or less match what you’re defining inline:

ansible_user: [ USING HASHIVAULT PLUGIN TO LOOKUP VALUE]
ansible_password: [ USING HASHIVAULT PLUGIN TO LOOKUP VALUE]
ansible_connection: winrm
ansible_winrm_transport: kerberos
ansible_winrm_server_cert_validation: ignore
ansible_port: 5985

Now that I think about it, does your password value have symbols?
I recall some issues where a password was not being parsed as expected because of symbols. Advanced playbook syntax — Ansible Community Documentation and

Some examples of how the extra var is processed using a simple play that just outputs the var:

    - name: Test string output
      ansible.builtin.debug:
        msg: "{{ testString }}"
ansible-playbook test.yml --extra-vars testString=test@#$!~%^&*()_-+=
[1] 3311782
bash: *()_-+=: command not found

TASK [Test string output] *******************************************************************************************************************************************************************
ok: [localhost] => 
  msg: test@#~%^

Notice it even caused a separate line of bash to execute by the first 2 lines of output

I cant seem to find a way to set an extra var as unsafe, AWX Tower does this by default but that is not really applicable here, only mentioning it in case you’re not familiar with AWX and see similar in search results.

I think you should try to set all your vars in a file where you can easily set !unsafe and see if that helps. Using Variables — Ansible Community Documentation

Make winrm_vars.yml

type or paste code hereansible_user: domainadmin@REALM 
ansible_password: !unsafe 234%234{435lkj{{lkjsdf
ansible_connection: winrm
ansible_winrm_transport: kerberos
ansible_winrm_cert_validation: ignore

Then run this to test:

ansible all -i "dc01"-m win_ping --extra-vars "@winrm_vars.yml"

Example of how tagging unsafe preserves the value as expected
test_vars.yml

unsafeString: !unsafe test@#$!~%^&*()_-+=
ansible-playbook test.yml --extra-vars @"test_vars.yml"
TASK [Test string output] *******************************************************************************************************************************************************************
ok: [localhost] => 
  msg: test@#$!~%^&*()_-+=