fix: EL10 PAM and crypto readiness via authselect profile and DEFAULT policy
This commit is contained in:
@@ -49,6 +49,15 @@
|
|||||||
bootstrap_var_key: "{{ 'bootstrap_' + (os | replace('-lts', '') | replace('-', '_')) }}"
|
bootstrap_var_key: "{{ 'bootstrap_' + (os | replace('-lts', '') | replace('-', '_')) }}"
|
||||||
ansible.builtin.include_tasks: "{{ bootstrap_os_task_map[os] }}"
|
ansible.builtin.include_tasks: "{{ bootstrap_os_task_map[os] }}"
|
||||||
|
|
||||||
|
# dnf --installroot never runs anaconda, so no authselect profile is selected and
|
||||||
|
# /etc/pam.d/system-auth is missing, leaving the system unable to authenticate.
|
||||||
|
# local is the right profile: local-auth only, no pam_sss.so, still CIS-capable.
|
||||||
|
- name: Select default authselect profile for the PAM stack
|
||||||
|
when: is_authselect | bool
|
||||||
|
ansible.builtin.command: "{{ chroot_command }} authselect select local --force"
|
||||||
|
register: bootstrap_authselect_result
|
||||||
|
changed_when: bootstrap_authselect_result.rc == 0
|
||||||
|
|
||||||
- name: Install hardware-matched firmware/microcode/GPU/peripheral packages
|
- name: Install hardware-matched firmware/microcode/GPU/peripheral packages
|
||||||
when: >-
|
when: >-
|
||||||
(system_cfg.features.firmware.enabled | bool)
|
(system_cfg.features.firmware.enabled | bool)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
# Feature-gated packages shared across all distros.
|
# Feature-gated packages shared across all distros. Arch strips nftables from
|
||||||
# Arch has special nftables handling and composes this differently.
|
# this and composes it differently.
|
||||||
bootstrap_common_conditional: >-
|
bootstrap_common_conditional: >-
|
||||||
{{
|
{{
|
||||||
(
|
(
|
||||||
@@ -15,12 +15,29 @@ bootstrap_common_conditional: >-
|
|||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# Native-installer parity backfill: anaconda and the d-i "standard" task leave
|
||||||
# Per-OS package definitions: base (rootfs/group install), extra (post-base),
|
# these, but install_weak_deps=False / Recommends-off minimal installs drop them.
|
||||||
# conditional (feature/version-gated, appended by task files).
|
bootstrap_el_runtime:
|
||||||
# DNF-based distros also carry repos (dnf --repo) and use base as group names.
|
- NetworkManager
|
||||||
# ---------------------------------------------------------------------------
|
- authselect
|
||||||
|
- authselect-libs
|
||||||
|
- chrony
|
||||||
|
- crypto-policies
|
||||||
|
- crypto-policies-scripts
|
||||||
|
- dbus
|
||||||
|
- polkit
|
||||||
|
|
||||||
|
bootstrap_deb_runtime:
|
||||||
|
- apparmor-utils
|
||||||
|
- chrony
|
||||||
|
- libpam-pwquality
|
||||||
|
- needrestart
|
||||||
|
- network-manager
|
||||||
|
- sudo
|
||||||
|
|
||||||
|
# Per-OS package definitions: base (rootfs/group install), extra (post-base),
|
||||||
|
# conditional (feature/version-gated, appended by task files). DNF distros also
|
||||||
|
# carry repos and use base as group names.
|
||||||
bootstrap_rhel:
|
bootstrap_rhel:
|
||||||
repos:
|
repos:
|
||||||
- "rhel{{ os_version_major }}-baseos"
|
- "rhel{{ os_version_major }}-baseos"
|
||||||
@@ -53,6 +70,7 @@ bootstrap_rhel:
|
|||||||
+ (['python39'] if os_version_major | default('') == '8' else ['python'])
|
+ (['python39'] if os_version_major | default('') == '8' else ['python'])
|
||||||
+ (['kernel'] if os_version_major | default('') == '10' else [])
|
+ (['kernel'] if os_version_major | default('') == '10' else [])
|
||||||
+ (['zram-generator'] if os_version_major | default('') in ['9', '10'] else [])
|
+ (['zram-generator'] if os_version_major | default('') in ['9', '10'] else [])
|
||||||
|
+ bootstrap_el_runtime
|
||||||
+ bootstrap_common_conditional
|
+ bootstrap_common_conditional
|
||||||
}}
|
}}
|
||||||
|
|
||||||
@@ -87,8 +105,8 @@ bootstrap_almalinux:
|
|||||||
- zstd
|
- zstd
|
||||||
conditional: >-
|
conditional: >-
|
||||||
{{
|
{{
|
||||||
(['dbus-daemon'] if (os_version_major | default('10') | int) >= 9 else [])
|
(['dhcp-client'] if (os_version_major | default('10') | int) < 10 else [])
|
||||||
+ (['dhcp-client'] if (os_version_major | default('10') | int) < 10 else [])
|
+ bootstrap_el_runtime
|
||||||
+ bootstrap_common_conditional
|
+ bootstrap_common_conditional
|
||||||
}}
|
}}
|
||||||
|
|
||||||
@@ -127,6 +145,7 @@ bootstrap_rocky:
|
|||||||
conditional: >-
|
conditional: >-
|
||||||
{{
|
{{
|
||||||
(['dhcp-client'] if (os_version_major | default('9') | int) < 10 else [])
|
(['dhcp-client'] if (os_version_major | default('9') | int) < 10 else [])
|
||||||
|
+ bootstrap_el_runtime
|
||||||
+ bootstrap_common_conditional
|
+ bootstrap_common_conditional
|
||||||
}}
|
}}
|
||||||
|
|
||||||
@@ -160,7 +179,6 @@ bootstrap_fedora:
|
|||||||
- nc
|
- nc
|
||||||
- nfs-utils
|
- nfs-utils
|
||||||
- nfsv4-client-utils
|
- nfsv4-client-utils
|
||||||
- polkit
|
|
||||||
- ppp
|
- ppp
|
||||||
- python3
|
- python3
|
||||||
- ripgrep
|
- ripgrep
|
||||||
@@ -171,7 +189,7 @@ bootstrap_fedora:
|
|||||||
- zoxide
|
- zoxide
|
||||||
- zram-generator
|
- zram-generator
|
||||||
- zstd
|
- zstd
|
||||||
conditional: "{{ bootstrap_common_conditional }}"
|
conditional: "{{ bootstrap_el_runtime + bootstrap_common_conditional }}"
|
||||||
|
|
||||||
bootstrap_debian:
|
bootstrap_debian:
|
||||||
base:
|
base:
|
||||||
@@ -189,28 +207,22 @@ bootstrap_debian:
|
|||||||
- python3
|
- python3
|
||||||
- xfsprogs
|
- xfsprogs
|
||||||
extra:
|
extra:
|
||||||
- apparmor-utils
|
|
||||||
- bat
|
- bat
|
||||||
- chrony
|
|
||||||
- curl
|
- curl
|
||||||
- entr
|
- entr
|
||||||
- fish
|
- fish
|
||||||
- fzf
|
- fzf
|
||||||
- htop
|
- htop
|
||||||
- jq
|
- jq
|
||||||
- libpam-pwquality
|
|
||||||
- linux-image-amd64
|
- linux-image-amd64
|
||||||
- lrzsz
|
- lrzsz
|
||||||
- mtr
|
- mtr
|
||||||
- ncdu
|
- ncdu
|
||||||
- needrestart
|
|
||||||
- net-tools
|
- net-tools
|
||||||
- network-manager
|
|
||||||
- python-is-python3
|
- python-is-python3
|
||||||
- ripgrep
|
- ripgrep
|
||||||
- rsync
|
- rsync
|
||||||
- screen
|
- screen
|
||||||
- sudo
|
|
||||||
- syslog-ng
|
- syslog-ng
|
||||||
- tcpd
|
- tcpd
|
||||||
- vim
|
- vim
|
||||||
@@ -225,6 +237,7 @@ bootstrap_debian:
|
|||||||
+ (['systemd-zram-generator'] if (os_version | string) not in ['10', '11'] else [])
|
+ (['systemd-zram-generator'] if (os_version | string) not in ['10', '11'] else [])
|
||||||
+ (['tldr'] if (os_version | string) not in ['13', 'unstable'] else [])
|
+ (['tldr'] if (os_version | string) not in ['13', 'unstable'] else [])
|
||||||
+ (['shim-signed'] if system_cfg.features.secure_boot.enabled | bool else [])
|
+ (['shim-signed'] if system_cfg.features.secure_boot.enabled | bool else [])
|
||||||
|
+ bootstrap_deb_runtime
|
||||||
+ bootstrap_common_conditional
|
+ bootstrap_common_conditional
|
||||||
}}
|
}}
|
||||||
|
|
||||||
@@ -246,10 +259,8 @@ bootstrap_ubuntu:
|
|||||||
- python3
|
- python3
|
||||||
- xfsprogs
|
- xfsprogs
|
||||||
extra:
|
extra:
|
||||||
- apparmor-utils
|
|
||||||
- bash-completion
|
- bash-completion
|
||||||
- bat
|
- bat
|
||||||
- chrony
|
|
||||||
- curl
|
- curl
|
||||||
- dnsutils
|
- dnsutils
|
||||||
- duf
|
- duf
|
||||||
@@ -261,20 +272,16 @@ bootstrap_ubuntu:
|
|||||||
- fzf
|
- fzf
|
||||||
- htop
|
- htop
|
||||||
- jq
|
- jq
|
||||||
- libpam-pwquality
|
|
||||||
- lrzsz
|
- lrzsz
|
||||||
- mtr
|
- mtr
|
||||||
- ncdu
|
- ncdu
|
||||||
- ncurses-term
|
- ncurses-term
|
||||||
- needrestart
|
|
||||||
- net-tools
|
- net-tools
|
||||||
- network-manager
|
|
||||||
- python-is-python3
|
- python-is-python3
|
||||||
- ripgrep
|
- ripgrep
|
||||||
- rsync
|
- rsync
|
||||||
- screen
|
- screen
|
||||||
- software-properties-common
|
- software-properties-common
|
||||||
- sudo
|
|
||||||
- syslog-ng
|
- syslog-ng
|
||||||
- systemd-zram-generator
|
- systemd-zram-generator
|
||||||
- tcpd
|
- tcpd
|
||||||
@@ -288,6 +295,7 @@ bootstrap_ubuntu:
|
|||||||
conditional: >-
|
conditional: >-
|
||||||
{{
|
{{
|
||||||
(['shim-signed'] if system_cfg.features.secure_boot.enabled | bool else [])
|
(['shim-signed'] if system_cfg.features.secure_boot.enabled | bool else [])
|
||||||
|
+ bootstrap_deb_runtime
|
||||||
+ bootstrap_common_conditional
|
+ bootstrap_common_conditional
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,9 @@
|
|||||||
|
|
||||||
# Non-RHEL/non-Debian distros: loop evaluates to [] (intentional skip)
|
# Non-RHEL/non-Debian distros: loop evaluates to [] (intentional skip)
|
||||||
- name: Prevent Login to Accounts With Empty Password
|
- name: Prevent Login to Accounts With Empty Password
|
||||||
when: cis_effective_rules.empty_password_login | default(false)
|
when:
|
||||||
|
- cis_effective_rules.empty_password_login | default(false)
|
||||||
|
- not is_authselect | bool
|
||||||
ansible.builtin.replace:
|
ansible.builtin.replace:
|
||||||
dest: "{{ item }}"
|
dest: "{{ item }}"
|
||||||
regexp: "\\s*nullok"
|
regexp: "\\s*nullok"
|
||||||
|
|||||||
@@ -1,11 +1,15 @@
|
|||||||
---
|
---
|
||||||
# Fedora ships its own crypto-policies preset and update-crypto-policies
|
# Fedora ships its own crypto-policies preset and update-crypto-policies
|
||||||
# behaves differently; applying DEFAULT:NO-SHA1 can break package signing.
|
# behaves differently; applying DEFAULT:NO-SHA1 can break package signing.
|
||||||
|
# EL10 dropped the NO-SHA1 subpolicy module (DEFAULT already disables SHA-1
|
||||||
|
# signatures), so the modifier is set only on EL9 and below.
|
||||||
- name: Configure System Cryptography Policy
|
- name: Configure System Cryptography Policy
|
||||||
|
vars:
|
||||||
|
_cis_crypto_policy: "{{ 'DEFAULT' if (os_version_major | int >= 10) else 'DEFAULT:NO-SHA1' }}"
|
||||||
when:
|
when:
|
||||||
- cis_effective_rules.crypto_policy | default(false)
|
- cis_effective_rules.crypto_policy | default(false)
|
||||||
- os in (os_family_rhel | difference(['fedora']))
|
- os in (os_family_rhel | difference(['fedora']))
|
||||||
ansible.builtin.command: "{{ chroot_command }} /usr/bin/update-crypto-policies --set DEFAULT:NO-SHA1"
|
ansible.builtin.command: "{{ chroot_command }} /usr/bin/update-crypto-policies --set {{ _cis_crypto_policy }}"
|
||||||
register: cis_crypto_policy_result
|
register: cis_crypto_policy_result
|
||||||
changed_when: "'Setting system-wide crypto-policies to' in cis_crypto_policy_result.stdout"
|
changed_when: "'Setting system-wide crypto-policies to' in cis_crypto_policy_result.stdout"
|
||||||
|
|
||||||
|
|||||||
@@ -126,32 +126,45 @@
|
|||||||
regexp: '^\s*#?\s*auth\s+required\s+pam_wheel\.so'
|
regexp: '^\s*#?\s*auth\s+required\s+pam_wheel\.so'
|
||||||
line: auth required pam_wheel.so
|
line: auth required pam_wheel.so
|
||||||
|
|
||||||
|
# authselect wires the pam_faillock stack via the feature; deny/unlock_time live
|
||||||
|
# in faillock.conf, the supported place (pam_faillock(8) deprecates module args).
|
||||||
|
- name: Configure account lockout (authselect)
|
||||||
|
when:
|
||||||
|
- cis_effective_rules.faillock | default(false)
|
||||||
|
- is_authselect | bool
|
||||||
|
block:
|
||||||
|
- name: Enable the authselect faillock feature
|
||||||
|
ansible.builtin.command: "{{ chroot_command }} authselect enable-feature with-faillock"
|
||||||
|
register: cis_faillock_result
|
||||||
|
changed_when: cis_faillock_result.rc == 0
|
||||||
|
|
||||||
|
- name: Set faillock thresholds
|
||||||
|
ansible.builtin.lineinfile:
|
||||||
|
path: /mnt/etc/security/faillock.conf
|
||||||
|
regexp: "{{ item.regexp }}"
|
||||||
|
line: "{{ item.line }}"
|
||||||
|
create: true
|
||||||
|
mode: "0644"
|
||||||
|
loop:
|
||||||
|
- {regexp: '^\s*#?\s*deny\s*=', line: "deny = {{ cis_cfg.faillock_deny }}"}
|
||||||
|
- {regexp: '^\s*#?\s*unlock_time\s*=', line: "unlock_time = {{ cis_cfg.faillock_unlock_time }}"}
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.line }}"
|
||||||
|
|
||||||
- name: Configure account lockout
|
- name: Configure account lockout
|
||||||
when: cis_effective_rules.faillock | default(false)
|
when:
|
||||||
|
- cis_effective_rules.faillock | default(false)
|
||||||
|
- not is_authselect | bool
|
||||||
ansible.builtin.lineinfile:
|
ansible.builtin.lineinfile:
|
||||||
path: "{{ item.path }}"
|
path: "{{ item.path }}"
|
||||||
regexp: "{{ item.regexp }}"
|
regexp: "{{ item.regexp }}"
|
||||||
line: "{{ item.line }}"
|
line: "{{ item.line }}"
|
||||||
loop:
|
loop:
|
||||||
- path: >-
|
- path: '/mnt/etc/{{ "pam.d/common-auth" if is_debian | bool else "pam.d/system-auth" }}'
|
||||||
/mnt/etc/{{
|
|
||||||
"pam.d/common-auth"
|
|
||||||
if is_debian | bool
|
|
||||||
else "authselect/system-auth"
|
|
||||||
if os == "fedora"
|
|
||||||
else "pam.d/system-auth"
|
|
||||||
}}
|
|
||||||
regexp: '^\s*auth\s+required\s+pam_faillock\.so'
|
regexp: '^\s*auth\s+required\s+pam_faillock\.so'
|
||||||
line: >-
|
line: >-
|
||||||
auth required pam_faillock.so onerr=fail audit silent deny={{ cis_cfg.faillock_deny }} unlock_time={{ cis_cfg.faillock_unlock_time }}
|
auth required pam_faillock.so onerr=fail audit silent deny={{ cis_cfg.faillock_deny }} unlock_time={{ cis_cfg.faillock_unlock_time }}
|
||||||
- path: >-
|
- path: '/mnt/etc/{{ "pam.d/common-account" if is_debian | bool else "pam.d/system-auth" }}'
|
||||||
/mnt/etc/{{
|
|
||||||
"pam.d/common-account"
|
|
||||||
if is_debian | bool
|
|
||||||
else "authselect/system-auth"
|
|
||||||
if os == "fedora"
|
|
||||||
else "pam.d/system-auth"
|
|
||||||
}}
|
|
||||||
regexp: '^\s*account\s+required\s+pam_faillock\.so'
|
regexp: '^\s*account\s+required\s+pam_faillock\.so'
|
||||||
line: account required pam_faillock.so
|
line: account required pam_faillock.so
|
||||||
loop_control:
|
loop_control:
|
||||||
|
|||||||
@@ -61,6 +61,12 @@
|
|||||||
ansible.builtin.set_fact:
|
ansible.builtin.set_fact:
|
||||||
os_version_major: "{{ (os_version | string).split('.')[0] }}"
|
os_version_major: "{{ (os_version | string).split('.')[0] }}"
|
||||||
|
|
||||||
|
# EL>=10 and Fedora dropped the static /etc/pam.d/system-auth shipped by pam;
|
||||||
|
# the PAM stack is generated by authselect and absent until a profile is selected.
|
||||||
|
- name: Flag authselect-managed PAM stacks
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
is_authselect: "{{ is_rhel | bool and (os_version_major | default('0') | int) >= 10 }}"
|
||||||
|
|
||||||
- name: Set chroot command wrapper
|
- name: Set chroot command wrapper
|
||||||
ansible.builtin.set_fact:
|
ansible.builtin.set_fact:
|
||||||
chroot_command: >-
|
chroot_command: >-
|
||||||
|
|||||||
Reference in New Issue
Block a user