I previously described how I configured TOTP using Google’s PAM module as a second factor for sudo. As I have been working with Ansible, which can use sudo throughout the execution of a playbook taking longer than the TOTP is valid for this can be a problem. While I am still developing my new setup, I have found it necessary to disable and re-enable the TOTP (falling back to the default of using the user account password for sudo), and have made two short playbooks that remove and re-add the configuration described in my previous post from 2019.

totp-sudo-disable

If the TOTP is enabled, then this playbook needs to be given a current TOTP value to run - to minimise the chance of the TOTP timing out, it does not gather facts. On my systems, which are all Debian, the /etc/pam.d/sudo file only includes other files by default so all lines beginning auth can be removed to disable TOTP.

---
# Remove extra `auth` lines, just leaving the standard include
- name: TOTP is not present in sudo configuration
  hosts: all
  # Don't need facts and reduces risk of current TOTP token timing out
  gather_facts: false
  tasks:
    - name: No sudo specific `auth` lines are present
      become: true
      ansible.builtin.lineinfile:
        path: /etc/pam.d/sudo
        regex: ^auth
        state: absent
...

totp-sudo-enable

This playbook re-adds the lines to require TOTP for sudo authentication. If the lines are missing, it requires the current user password for the Ansible user to run.

---
# Add totp auth lines to sudo configuration
- name: TOTP is enabled in sudo configuration
  hosts: all
  gather_facts: false  # Don't need any facts
  tasks:
    - name: Google authenticator specific `auth` lines are present
      become: true
      ansible.builtin.blockinfile:
        path: /etc/pam.d/sudo
        block: |
          auth sufficient pam_google_authenticator.so secret=/var/lib/sudo-secrets/${USER}.google_authenticator user=sudo-auth
          auth requisite pam_deny.so
        insertbefore: '@include common-auth'
...