Sam Hooke

Using Kerberos from an Ansible playbook

To authenticate a Linux machine with Kerberos, you can run kinit <username>1 and it will then prompt for your password. However, when running kinit from an Ansible playbook it is desirable to do this without prompting.

Following are notes on how to automate calling kinit from an Ansible playbook, and some general debugging tips.

Solution overview §

Running kinit without prompting can be done using the Kerberos keytab. The process is as follows:

  1. Use ktutil to generate a *.keytab file.
  2. Copy the *.keytab file to the machine where you will run kinit.
  3. Run kinit <username> -k -t /path/to/ticket.keytab

Step-by-step with Ansible §

Following is how to do this with Ansible.

Generate the keytab file §

On an Ubuntu machine2, first install krb5-user3:

sudo apt-get install krb5-user

Then create a ticket.keytab file using ktutil:

addent -password -p username@YOUR.REALM.COM -k 0 -e rc4-hmac
<enter your password>
wkt ticket.keytab

Update Ansible playbook to copy ticket.keytab §

Update your Ansible playbook to:

  • Copy the ticket.keytab onto the node.
  • Run kinit using the ticket.keytab.
playbook.yml §
- name: Configure Kerberos
  become: true
    src: krb5.conf.j2
    dest: /etc/krb5.conf
    mode: '0644'

- name: Copy keytab
    src: ticket.keytab
    dest: "{{ ansible_env.HOME }}/ticket.keytab"
    mode: '0644'

- name: Init Kerberos
  ansible.builtin.command: "kinit {{ kerberos_username }} -k -t {{ ansible_env.HOME }}/ticket.keytab"

Note that we use the custom variable kerberos_username with kinit, so that needs to be defined somewhere.

Store your username §

One option for defining kerberos_username is to specify it in a my_username.yml which is added to .gitignore:

my_username.yml §
kerberos_username: sam

Then load this file in your playbook using include_vars4:

playbook.yml §
- name: Load username
    file: my_username.yml

This way, each user can have a custom my_username.yml file which they do not commit to version control.

Putting it all together §

First, ensure you have create a my_username.yml file like above, and put your Kerberos username in place.

Then, ensure that you have a ticket.keytab in your current working directory.

Now you can run ansible-playbook playbook.yml to provision your machine, and it will automatically run kinit without prompting.

Troubleshooting §

General debugging §

Using KRB5_TRACE allows you to get a lot more debug information out of kinit. For example, this will print to stdout:

KRB5_TRACE=/dev/stdout kinit <username>

Alternatively, you can capture the output in a file:

KRB5_TRACE=/home/sam/debug_kinit.txt kinit <username>

To debug why kinit with a *.keytab file is not working, it can be useful to compare the trace output of running kinit with a *.keytab file to running it inputting the password via the command line. This will show details such as which encryption scheme is being used.

Preauthentication failed §

If running kinit with your ticket.keytab gives this error:

kinit: Preauthentication failed while getting initial credentials

It may be that you need to use a different encryption scheme when running ktutil. Common options are rc4-hmac or aes256-cts.

If running kinit with your ticket.keytab gives one of the following errors:

  • kinit: Cannot find KDC for realm "YOUR.REALM.COM" while getting initial credentials
  • kinit: Cannot contact any KDC for realm 'YOUR.REALM.COM' while getting initial credentials
  • kinit: Cannot determine realm for host (principal host/localhost@)

It may indicate that you have input the realm incorrectly when using ktutil to generate the ticket.keytab. Consider using tools to debug, such as klist -k ticket.keytab. Also run kinit entering your password manually to ensure your /etc/krb5.conf file is correct.

  1. Assuming you have a correctly configured /etc/krb5.conf file. ↩︎

  2. Doesn’t have to be Ubuntu of course, but that’s what I’m using under WSL. ↩︎

  3. There is also a “Heimdal Kerberos”, which has slightly different command line usage. See here↩︎

  4. For more detail on Ansible variables, see here↩︎