From 91bcd2a6050936916b57fab632220c723c6b44b6 Mon Sep 17 00:00:00 2001 From: Ludovic Poujol Date: Thu, 25 May 2023 11:43:53 +0200 Subject: [PATCH] policy_pam: New role allowing to manage password policy with pam_pwquality & pam_pwhistory --- CHANGELOG.md | 1 + policy_pam/defaults/main.yml | 32 +++++++++++++ policy_pam/meta/main.yml | 25 ++++++++++ policy_pam/tasks/main.yml | 88 ++++++++++++++++++++++++++++++++++++ 4 files changed, 146 insertions(+) create mode 100644 policy_pam/defaults/main.yml create mode 100644 policy_pam/meta/main.yml create mode 100644 policy_pam/tasks/main.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index 6673906a..2664ba03 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ The **patch** part changes is incremented if multiple releases happen the same m * userlogrotate: rotate also php.log. * nagios-nrpe: add a NRPE check-local command with completion. +* policy_pam: New role allowing to manage password policy with pam_pwquality & pam_pwhistory ### Changed diff --git a/policy_pam/defaults/main.yml b/policy_pam/defaults/main.yml new file mode 100644 index 00000000..5a2f79d2 --- /dev/null +++ b/policy_pam/defaults/main.yml @@ -0,0 +1,32 @@ +--- + +# PAM -- pam_pwquality +# Ensure password meet a given quality/complexity requirement +policy_pam_pwquality: true + +# Configuration settings for pam_pwquality +# For more in depth info, see man pam_pwquality(8) + +# Minimum password lengh/credit +policy_pam_pwquality_minlen: 4 + +# Credits values for char types +# Value : Interger N with : +# N >= 0 - Maximum credit given for each char type in the password +# N < 0 - Minimum number of chars of given type in the password +# digit chars +policy_pam_pwquality_dcredit: 0 +# uppercase chars +policy_pam_pwquality_ucredit: 0 +# lowercase chars +policy_pam_pwquality_lcredit: 0 +# other chars +policy_pam_pwquality_ocredit: 0 + + +# PAM -- pam_pwhistory +# Prevent old password re-use +policy_pam_pwhistory: true + +# How many old passwords to retain +policy_pam_pwhistory_length: 5 \ No newline at end of file diff --git a/policy_pam/meta/main.yml b/policy_pam/meta/main.yml new file mode 100644 index 00000000..85198ada --- /dev/null +++ b/policy_pam/meta/main.yml @@ -0,0 +1,25 @@ +--- +galaxy_info: + author: Evolix + company: Evolix + description: Add repositories to APT sources list. + + issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues + + license: GPLv2 + + min_ansible_version: "2.10" + + platforms: + - name: Debian + versions: + - bullseye + + galaxy_tags: [] + # Be sure to remove the '[]' above if you add dependencies + # to this list. + +dependencies: [] + # List your role dependencies here, one per line. + # Be sure to remove the '[]' above if you add dependencies + # to this list. diff --git a/policy_pam/tasks/main.yml b/policy_pam/tasks/main.yml new file mode 100644 index 00000000..e5c7bb9a --- /dev/null +++ b/policy_pam/tasks/main.yml @@ -0,0 +1,88 @@ +--- +# +# -password [success=1 default=ignore] pam_unix.so obscure yescrypt +# +password requisite pam_pwquality.so retry=3 +# +password [success=1 default=ignore] pam_unix.so obscure use_authtok try_first_pass yescrypt + + + +# PAM -- pam_pwquality + +- name: libpam-pwquality is installed + apt: + state: present + name: + - libpam-pwquality + - cracklib-runtime + when: policy_pam_pwquality + +- name: Enable pam_pwquality + ansible.builtin.lineinfile: + dest: /etc/pam.d/common-password + regexp: '^password\s+requisite\s+pam_pwquality.so' + line: "password requisite pam_pwquality.so retry=3" + insertafter: '(the "Primary" block)' + when: policy_pam_pwquality + +- name: Disable pam_pwquality + ansible.builtin.lineinfile: + dest: /etc/pam.d/common-password + regexp: '^password\s+requisite\s+pam_pwquality.so' + state: absent + when: policy_pam_pwquality is false + +- name: Configure pam_pwquality + replace: + dest: /etc/security/pwquality.conf + regexp: "^#? ?{{ item.name }} = .*" + replace: "{{ item.name }} = {{ item.value }}" + with_items: + - { name: minlen, value: "{{ policy_pam_pwquality_minlen }}" } + - { name: dcredit, value: "{{ policy_pam_pwquality_dcredit }}" } + - { name: ucredit, value: "{{ policy_pam_pwquality_ucredit }}" } + - { name: lcredit, value: "{{ policy_pam_pwquality_lcredit }}" } + - { name: ocredit, value: "{{ policy_pam_pwquality_ocredit }}" } + when: policy_pam_pwquality + + + +# PAM -- pam_pwhistory + +- name: Enable pam_pwhistory + ansible.builtin.lineinfile: + dest: /etc/pam.d/common-password + regexp: '^password\s+required\s+pam_pwhistory.so' + line: "password required pam_pwhistory.so remember={{ policy_pam_pwhistory_length }} {{ 'use_authtok' if policy_pam_pwquality}}" + insertbefore: 'pam_unix.so' + when: policy_pam_pwhistory + +# LATER : Enforce a password min age +# - name: Change PASS_MIN_DAYS +# replace: +# dest: /etc/login.defs +# replace: "PASS_MIN_DAYS 7" +# regexp: '^PASS_MIN_DAYS.*' + +- name: Disable pam_pwhistory + ansible.builtin.lineinfile: + dest: /etc/pam.d/common-password + regexp: '^password\s+required\s+pam_pwhistory.so' + state: absent + when: policy_pam_pwhistory is false + + + +# PAM -- pam_unix +- name: Update pam_unix if previous modules were enabled + ansible.builtin.lineinfile: + dest: /etc/pam.d/common-password + regexp: 'pam_unix.so obscure' + line: "password [success=1 default=ignore] pam_unix.so obscure use_authtok try_first_pass yescrypt" + when: policy_pam_pwhistory or policy_pam_pwquality + +- name: Update pam_unix if previous modules are all disabled + ansible.builtin.lineinfile: + dest: /etc/pam.d/common-password + regexp: 'pam_unix.so obscure' + line: "password [success=1 default=ignore] pam_unix.so obscure yescrypt" + when: policy_pam_pwhistory is false and policy_pam_pwquality is false \ No newline at end of file