From dac04304a409dc56c7d68e218ccf4d911be31366 Mon Sep 17 00:00:00 2001 From: Chris Zervakis Date: Mon, 10 Jan 2022 11:14:13 +0200 Subject: [PATCH] [Breaking] Drop support for PAM related config. The code for handling PAM stuff was not very robust. Since a small misconfiguration can lock the user out of their system, I've decided to drop support for PAM related configuration, other than disabling core dumps. --- README.md | 6 +-- defaults/main.yml | 6 --- docs/pam-limits.md | 24 +--------- tasks/limits.yml | 20 -------- tasks/main.yml | 6 +-- tasks/pam-Archlinux.yml | 88 ---------------------------------- tasks/pam-Debian.yml | 39 ---------------- tasks/pam-RedHat.yml | 101 ---------------------------------------- 8 files changed, 5 insertions(+), 285 deletions(-) delete mode 100644 tasks/pam-Archlinux.yml delete mode 100644 tasks/pam-Debian.yml delete mode 100644 tasks/pam-RedHat.yml diff --git a/README.md b/README.md index ac00534..e84752e 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,9 @@ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Ansible Role](https://img.shields.io/ansible/role/50034?color=dodgerblue)](https://galaxy.ansible.com/chzerv/security) +> **Important Changes**: +> As of v0.7, the role no longer supports the `security_enforce_strong_passwords`, `security_log_after_failed_logins` and `security_nproc_limit` options. Bad PAM configuration can lock you out of the system, so I'll have to find a better way to implement these. + **Remember, securing YOUR PC/server is YOUR OWN responsibility.** This is a very basic template and it should be used as a _template_, not a complete solution. This role performs some basic security configuration on RedHat/Debian/Archlinux based Linux systems, like: @@ -19,16 +22,13 @@ This role performs some basic security configuration on RedHat/Debian/Archlinux - Basic kernel-hardening. - Basic TCP/IP stack hardening. - Remove packages of your choice. -- Setup/configure PAM modules like `pam_tally2` and `pwquality`. - Disable core dumps, using `limits`. -- Set an `nproc` limit for protection against fork bombs, using `limits` (does not apply for the root user). ## Requirements - After running this role, SSH access will only be possible using public keys, therefore, your SSH keys must be already copied to the remote host. See [this ArchWiki entry](https://wiki.archlinux.org/title/SSH_keys#Copying_the_public_key_to_the_remote_server) on how to easily copy your SSH keys to the remote host. - Basic understanding of what each setting does. -- Not strictly a requirement, but if you decide to let the role configure PAM related stuff, make sure you have a root shell open on the remote host(s) before running the role. ## Role Variables diff --git a/defaults/main.yml b/defaults/main.yml index d22c5f7..d7d3482 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -60,10 +60,4 @@ security_autoupdates_blacklist: security_autoupdates_apply_updates: "yes" -security_secure_pam: true -security_enforce_strong_passwords: true -security_lock_after_failed_logins: true -security_lock_after_num_of_failed_logins: 4 security_disable_core_dumps: true -security_nproc_limit: true -security_nproc_limit_value: "2048" diff --git a/docs/pam-limits.md b/docs/pam-limits.md index c3e6f2c..61c83a3 100644 --- a/docs/pam-limits.md +++ b/docs/pam-limits.md @@ -1,29 +1,7 @@ -# PAM and limits configuration - -**NOTE:** Messing with PAM can be dangerous. Please, at least make sure you have a root shell open before running the role. - -```yaml -security_enforce_strong_passwords: true -security_lock_after_failed_logins: true -security_lock_after_num_of_failed_logins: 4 -``` - -> - Enforce users to use strong passwords (at least 12 characters, with digits, lowercase, uppercase and symbols). -> - Lock user accounts after number of consecutive failed login attempts. -> - How many consecutive login attempts are allowed. +# Set up limits using PAM ```yaml security_disable_core_dumps: true ``` > Whether to disable core dumps or not. - -```yaml -security_nproc_limit: true -security_nproc_limit_value: "2048" -``` - -> - Set a nproc limit to help against fork-bombs. -> - The value of the nproc limit. _This does NOT affect the root user!_ -> -> **Please note that having a very low limit can make your system unusable!** diff --git a/tasks/limits.yml b/tasks/limits.yml index fac60bb..6faae27 100644 --- a/tasks/limits.yml +++ b/tasks/limits.yml @@ -15,23 +15,3 @@ limit_item: core value: "0" comment: Disable core dumps for all users since they can contain sensitive information. - when: security_disable_core_dumps | bool - -- name: Enforce an 'nproc' limit. - block: - - name: Set the global nproc hardlimit. - pam_limits: - dest: /etc/security/limits.d/10-custom-limits.conf - domain: "*" - limit_type: hard - limit_item: nproc - value: "{{ security_nproc_limit_value }}" - - - name: Set the nproc hardlimit for the root user. - pam_limits: - dest: /etc/security/limits.d/10-custom-limits.conf - domain: root - limit_type: hard - limit_item: nproc - value: "65536" - when: security_nproc_limit | bool diff --git a/tasks/main.yml b/tasks/main.yml index ce03dad..fe11dc9 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -25,9 +25,5 @@ - security_autoupdates_enabled | bool - not ansible_os_family == "Archlinux" -- include_tasks: pam-{{ ansible_os_family }}.yml - when: security_secure_pam | bool - - include_tasks: limits.yml - when: - - security_secure_pam | bool + when: security_disable_core_dumps | bool diff --git a/tasks/pam-Archlinux.yml b/tasks/pam-Archlinux.yml deleted file mode 100644 index cf5fa38..0000000 --- a/tasks/pam-Archlinux.yml +++ /dev/null @@ -1,88 +0,0 @@ ---- -- name: Enforce users to use strong passwords (Archlinux systems) - block: - - name: Install cracklib - pacman: - name: cracklib - state: present - - - name: Enable pam_cracklib.so. - replace: - path: /etc/pam.d/passwd - regexp: '^#password\s*required\s*pam_cracklib\.so.*' - replace: > - password\trequired\tpam_cracklib.so - retry=3 - minlen=12 - difok=4 - lcredit=-1 - dcredit=-1 - ocredit=-1 - ucredit=-1 - backup: true - mode: "0644" - - - name: Replace nullok argument with use_authtok for pam_unix.so. - pamd: - name: passwd - type: password - control: required - module_path: pam_unix.so - module_arguments: "sha512 shadow use_authtok" - state: updated - backup: true - when: security_enforce_strong_passwords | bool - -- name: Check if pam_faillock.so is used. - shell: - cmd: 'grep -c "^auth\s*required\s*pam_faillock\.so.*" system-auth || true' - chdir: /etc/pam.d - changed_when: false - register: pam_faillock_exists - -- name: Check if pam_tally2.so is used. - shell: - cmd: 'grep -c "^auth\s*required\s*pam_tally2\.so.*" system-login || true' - chdir: /etc/pam.d - changed_when: false - register: pam_tally_exists - -- name: Lock user account after number of failed login attempts, using pam_faillock (Archlinux systems). - block: - - name: Update pam_faillock.so arguments, if it's being used - step 1 - pamd: - name: system-auth - type: auth - control: required - module_path: pam_faillock.so - module_arguments: "silent audit deny={{ security_lock_after_num_of_failed_logins }} unlock_time=1800" - state: args_present - backup: true - - - name: Update pam_faillock.so arguments, if it's being used - step 2 - pamd: - name: system-auth - type: auth - control: "[default=die]" - module_path: pam_faillock.so - module_arguments: "authfail audit deny={{ security_lock_after_num_of_failed_logins }} unlock_time=1800" - state: updated - backup: true - when: - - pam_faillock_exists.stdout != "0" - - pam_tally_exists.stdout == "0" - - security_lock_after_failed_logins | bool - -- name: Lock user account after number of failed login attempts, using pam_tally2 (Archlinux systems). - pamd: - name: system-login - type: auth - control: required - module_path: pam_tally2.so - module_arguments: "deny={{ security_lock_after_num_of_failed_logins }} unlock_time=1800 onerr=succeed file=/var/log/tallylog" - state: updated - backup: true - when: - - pam_tally_exists.stdout != "0" - - pam_faillock_exists.stdout == "0" - - security_lock_after_failed_logins | bool diff --git a/tasks/pam-Debian.yml b/tasks/pam-Debian.yml deleted file mode 100644 index a5fe04c..0000000 --- a/tasks/pam-Debian.yml +++ /dev/null @@ -1,39 +0,0 @@ ---- -- name: Enforce users to use strong passwords (Debian systems). - block: - - name: Install libpam-pwquality. - apt: - name: libpam-pwquality - update_cache: true - state: present - - - name: Update pwquality module arguments. - pamd: - name: common-password - type: password - control: "requisite" - module_path: pam_pwquality.so - module_arguments: " retry=3 - minlen=12 - lcredit=-1 - ucredit=-1 - dcredit=-1 - ocredit=-1 - enforce_for_root" - state: args_present - backup: true - when: security_enforce_strong_passwords | bool - -- name: Lock user account after number of failed login attempts (Debian systems). - pamd: - name: common-auth - type: auth - control: "[success=1 default=ignore]" - module_path: pam_unix.so - new_type: auth - new_control: required - new_module_path: pam_tally2.so - module_arguments: "onerr=fail deny={{ security_lock_after_num_of_failed_logins }} unlock_time=1800" - state: before - backup: true - when: security_lock_after_failed_logins | bool diff --git a/tasks/pam-RedHat.yml b/tasks/pam-RedHat.yml deleted file mode 100644 index 2dfbcd0..0000000 --- a/tasks/pam-RedHat.yml +++ /dev/null @@ -1,101 +0,0 @@ ---- -- name: Enforce users to use strong passwords (RedHat systems). - pamd: - name: system-auth - type: password - control: "requisite" - module_path: pam_pwquality.so - module_arguments: "try_first_pass - local_users_only - retry=3 - authok_type= - minlen=12 - lcredit=-1 - ucredit=-1 - dcredit=-1 - ocredit=-1 - enforce_for_root" - state: args_present - backup: true - when: security_enforce_strong_passwords | bool - -- name: Lock user account after number of failed login attempts (RedHat systems). - block: - - name: password-auth (auth required) - pamd: - name: password-auth - type: auth - control: required - module_path: pam_env.so - new_type: auth - new_control: required - new_module_path: pam_faillock.so - module_arguments: "preauth silent audit deny={{ security_lock_after_num_of_failed_logins }} unlock_time=1800" - state: after - backup: true - - - name: password-auth (auth [default=die]) - pamd: - name: password-auth - type: auth - control: sufficient - module_path: pam_unix.so - new_type: auth - new_control: "[default=die]" - new_module_path: pam_faillock.so - module_arguments: "authfail audit deny={{ security_lock_after_num_of_failed_logins }} unlock_time=1800" - state: after - backup: true - - - name: password-auth (account required) - pamd: - name: password-auth - type: account - control: required - module_path: pam_unix.so - new_type: account - new_control: required - new_module_path: pam_faillock.so - module_arguments: "authfail audit deny={{ security_lock_after_num_of_failed_logins }} unlock_time=1800" - state: before - backup: true - - - name: system-auth (auth required) - pamd: - name: system-auth - type: auth - control: required - module_path: pam_env.so - new_type: auth - new_control: required - new_module_path: pam_faillock.so - module_arguments: "preauth silent audit deny={{ security_lock_after_num_of_failed_logins }} unlock_time=1800" - state: after - backup: true - - - name: system-auth (auth [default=die]) - pamd: - name: system-auth - type: auth - control: sufficient - module_path: pam_unix.so - new_type: auth - new_control: "[default=die]" - new_module_path: pam_faillock.so - module_arguments: "authfail audit deny={{ security_lock_after_num_of_failed_logins }} unlock_time=1800" - state: after - backup: true - - - name: system-auth (account required) - pamd: - name: system-auth - type: account - control: required - module_path: pam_unix.so - new_type: account - new_control: required - new_module_path: pam_faillock.so - module_arguments: "authfail audit deny={{ security_lock_after_num_of_failed_logins }} unlock_time=1800" - state: before - backup: true - when: security_lock_after_failed_logins | bool