Add Debian 13 PAM support to existing rules#14781
Conversation
|
Hi @israel-villar. Thanks for your PR. I'm waiting for a ComplianceAsCode member to verify that this patch is reasonable to test. If it is, they should reply with Regular contributors should join the org to skip this step. Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
|
This datastream diff is auto generated by the check Click here to see the full diffNew data stream adds bash remediation for rule 'xccdf_org.ssgproject.content_rule_accounts_password_pam_unix_enabled'.
New data stream adds bash remediation for rule 'xccdf_org.ssgproject.content_rule_accounts_password_pam_pwhistory_enabled'.
OVAL for rule 'xccdf_org.ssgproject.content_rule_accounts_password_pam_pwhistory_remember' differs.
--- oval:ssg-accounts_password_pam_pwhistory_remember:def:1
+++ oval:ssg-accounts_password_pam_pwhistory_remember:def:1
@@ -1,3 +1,3 @@
criteria AND
-criterion oval:ssg-test_pam_password_pam_pwhistory_remember:tst:1
-criterion oval:ssg-test_pam_password_pam_pwhistory_use_authtok:tst:1
+criterion oval:ssg-test_accounts_password_pam_pwhistory_remember_enabled:tst:1
+criterion oval:ssg-test_accounts_password_pam_pwhistory_remember_parameter:tst:1
bash remediation for rule 'xccdf_org.ssgproject.content_rule_accounts_password_pam_pwhistory_remember' differs.
--- xccdf_org.ssgproject.content_rule_accounts_password_pam_pwhistory_remember
+++ xccdf_org.ssgproject.content_rule_accounts_password_pam_pwhistory_remember
@@ -1,66 +1,103 @@
# Remediation is applicable only in certain platforms
if dpkg-query --show --showformat='${db:Status-Status}' 'linux-base' 2>/dev/null | grep -q '^installed$' && { dpkg-query --show --showformat='${db:Status-Status}' 'libpam-runtime' 2>/dev/null | grep -q '^installed$'; }; then
-declare -a VALUES=()
-declare -a VALUE_NAMES=()
-declare -a ARGS=()
-declare -a NEW_ARGS=()
-declare -a DEL_ARGS=()
+if [ -f /usr/bin/authselect ]; then
+ if authselect list-features sssd | grep -q with-pwhistory; then
+ if ! authselect check; then
+ echo "
+ authselect integrity check failed. Remediation aborted!
+ This remediation could not be applied because an authselect profile was not selected or the selected profile is not intact.
+ It is not recommended to manually edit the PAM files when authselect tool is available.
+ In cases where the default authselect profile does not cover a specific demand, a custom authselect profile is recommended."
+ exit 1
+ fi
+ authselect enable-feature with-pwhistory
+ authselect apply-changes -b
+ else
+
+ if ! authselect check; then
+ echo "
+ authselect integrity check failed. Remediation aborted!
+ This remediation could not be applied because an authselect profile was not selected or the selected profile is not intact.
+ It is not recommended to manually edit the PAM files when authselect tool is available.
+ In cases where the default authselect profile does not cover a specific demand, a custom authselect profile is recommended."
+ exit 1
+ fi
+ CURRENT_PROFILE=$(authselect current -r | awk '{ print $1 }')
+ # If not already in use, a custom profile is created preserving the enabled features.
+ if [[ ! $CURRENT_PROFILE == custom/* ]]; then
+ ENABLED_FEATURES=$(authselect current | tail -n+3 | awk '{ print $2 }')
+ # The "local" profile does not contain essential security features required by multiple Benchmarks.
+ # If currently used, it is replaced by "sssd", which is the best option in this case.
+ if [[ $CURRENT_PROFILE == local ]]; then
+ CURRENT_PROFILE="sssd"
+ fi
+ authselect create-profile hardening -b $CURRENT_PROFILE
+ CURRENT_PROFILE="custom/hardening"
+
+ authselect apply-changes -b --backup=before-hardening-custom-profile
+ authselect select $CURRENT_PROFILE
+ for feature in $ENABLED_FEATURES; do
+ authselect enable-feature $feature;
+ done
+
+ authselect apply-changes -b --backup=after-hardening-custom-profile
+ fi
+ PAM_FILE_NAME=$(basename "cac_pwhistory")
+ PAM_FILE_PATH="/etc/authselect/$CURRENT_PROFILE/$PAM_FILE_NAME"
+ authselect apply-changes -b
+
+ if ! grep -qP "^\s*password\s+requisite\s+pam_pwhistory.so\s*.*" "$PAM_FILE_PATH"; then
+ # Line matching group + control + module was not found. Check group + module.
+ if [ "$(grep -cP '^\s*password\s+.*\s+pam_pwhistory.so\s*' "$PAM_FILE_PATH")" -eq 1 ]; then
+ # The control is updated only if one single line matches.
+ sed -i -E --follow-symlinks "s/^(\s*password\s+).*(\bpam_pwhistory.so.*)/\1requisite \2/" "$PAM_FILE_PATH"
+ else
+ echo "password requisite pam_pwhistory.so" >> "$PAM_FILE_PATH"
+ fi
+ fi
+ fi
+else
+conf_name=cac_pwhistory
+conf_path="/usr/share/pam-configs"
+if [ ! -f "$conf_path"/"$conf_name" ]; then
+ cat << EOF > "$conf_path"/"$conf_name"
+Name: pwhistory password history checking
+Default: yes
+Priority: 1024
+Password-Type: Primary
+Password: requisite pam_pwhistory.so remember=24 enforce_for_root try_first_pass use_authtok
+Password-Initial: requisite pam_pwhistory.so remember=24 enforce_for_root try_first_pass
+EOF
+fi
+
+DEBIAN_FRONTEND=noninteractive pam-auth-update
+
+fi
var_password_pam_remember=''
-VALUES+=("$var_password_pam_remember")
-VALUE_NAMES+=("remember")
-ARGS+=("")
-NEW_ARGS+=("")
-VALUES+=("")
-VALUE_NAMES+=("")
-ARGS+=("use_authtok")
-NEW_ARGS+=("use_authtok")
+sed -i -E '/^Password:/,/^[^[:space:]]/ {
+ /pam_pwhistory\.so/ {
+ s/\s*remember=[^[:space:]]*//g
+ s/$/ remember='"$var_password_pam_remember"'/g
+ }
+}' /usr/share/pam-configs/cac_pwhistory
+sed -i -E '/^Password-Initial:/,/^[^[:space:]]/ {
+ /pam_pwhistory\.so/ {
+ s/\s*remember=[^[:space:]]*//g
+ s/$/ remember='"$var_password_pam_remember"'/g
+ }
+}' /usr/share/pam-configs/cac_pwhistory
-for idx in "${!VALUES[@]}"
-do
- if [ -e "/etc/pam.d/common-password" ] ; then
- valueRegex="${VALUES[$idx]}" defaultValue="${VALUES[$idx]}"
- # non-empty values need to be preceded by an equals sign
- [ -n "${valueRegex}" ] && valueRegex="=${valueRegex}"
- # add an equals sign to non-empty values
- [ -n "${defaultValue}" ] && defaultValue="=${defaultValue}"
-
- # fix the value for 'option' if one exists but does not match 'valueRegex'
- if grep -q -P "^\\s*password\\s+requisite\\s+pam_pwhistory.so(\\s.+)?\\s+${VALUE_NAMES[$idx]}(?"'!'"${valueRegex}(\\s|\$))" < "/etc/pam.d/common-password" ; then
- sed --follow-symlinks -i -E -e "s/^(\\s*password\\s+requisite\\s+pam_pwhistory.so(\\s.+)?\\s)${VALUE_NAMES[$idx]}=[^[:space:]]*/\\1${VALUE_NAMES[$idx]}${defaultValue}/" "/etc/pam.d/common-password"
-
- # add 'option=default' if option is not set
- elif grep -q -E "^\\s*password\\s+requisite\\s+pam_pwhistory.so" < "/etc/pam.d/common-password" &&
- grep -E "^\\s*password\\s+requisite\\s+pam_pwhistory.so" < "/etc/pam.d/common-password" | grep -q -E -v "\\s${VALUE_NAMES[$idx]}(=|\\s|\$)" ; then
-
- sed --follow-symlinks -i -E -e "s/^(\\s*password\\s+requisite\\s+pam_pwhistory.so[^\\n]*)/\\1 ${VALUE_NAMES[$idx]}${defaultValue}/" "/etc/pam.d/common-password"
- # add a new entry if none exists
- elif ! grep -q -P "^\\s*password\\s+requisite\\s+pam_pwhistory.so(\\s.+)?\\s+${VALUE_NAMES[$idx]}${valueRegex}(\\s|\$)" < "/etc/pam.d/common-password" ; then
- echo "password requisite pam_pwhistory.so ${VALUE_NAMES[$idx]}${defaultValue}" >> "/etc/pam.d/common-password"
- fi
- else
- echo "/etc/pam.d/common-password doesn't exist" >&2
- fi
-done
-
-for idx in "${!ARGS[@]}"
-do
- if ! grep -q -P "^\s*password\s+requisite\s+pam_pwhistory.so.*\s+${ARGS[$idx]}\s*$" /etc/pam.d/common-password ; then
- sed --follow-symlinks -i -E -e "s/^\\s*password\\s+requisite\\s+pam_pwhistory.so.*\$/& ${NEW_ARGS[$idx]}/" /etc/pam.d/common-password
- if [ -n "${DEL_ARGS[$idx]}" ]; then
- sed --follow-symlinks -i -E -e "s/\s+${DEL_ARGS[$idx]}\S+\s+/ /g" /etc/pam.d/common-password
- fi
- fi
-done
+DEBIAN_FRONTEND=noninteractive pam-auth-update --enable cac_pwhistory
else
>&2 echo 'Remediation is not applicable, nothing was done'
New data stream adds bash remediation for rule 'xccdf_org.ssgproject.content_rule_accounts_password_pam_pwhistory_use_authtok'.
New data stream adds bash remediation for rule 'xccdf_org.ssgproject.content_rule_accounts_password_pam_unix_authtok'.
New data stream adds bash remediation for rule 'xccdf_org.ssgproject.content_rule_accounts_passwords_pam_faillock_enabled'.
New data stream adds OVAL for rule 'xccdf_org.ssgproject.content_rule_accounts_password_pam_pwquality_enabled'.
New data stream adds bash remediation for rule 'xccdf_org.ssgproject.content_rule_accounts_password_pam_unix_no_remember'.
bash remediation for rule 'xccdf_org.ssgproject.content_rule_no_empty_passwords_unix' differs.
--- xccdf_org.ssgproject.content_rule_no_empty_passwords_unix
+++ xccdf_org.ssgproject.content_rule_no_empty_passwords_unix
@@ -23,6 +23,14 @@
DEBIAN_FRONTEND=noninteractive pam-auth-update
+# Fallback: remove nullok directly in case pam-auth-update was blocked
+# by local modifications to /etc/pam.d/common-*
+for pam_file in /etc/pam.d/common-password /etc/pam.d/common-auth \
+ /etc/pam.d/common-account /etc/pam.d/common-session \
+ /etc/pam.d/common-session-noninteractive; do
+ [ -f "$pam_file" ] && sed -i '/pam_unix\.so/s/\bnullok\b//g' "$pam_file"
+done
+
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi |
| @@ -0,0 +1,58 @@ | |||
| {{% if "debian" in product %}} | |||
There was a problem hiding this comment.
This file is almost identical to linux_os/guide/system/accounts/accounts-pam/locking_out_password_attempts/accounts_password_pam_pwhistory_remember/oval/ubuntu.xml. It's a lot of duplicate code. Please consolidate both files into a single shared.xml file.
There was a problem hiding this comment.
My original intention was to avoid touching existing files for other distros, but you're right. It's a lot of duplicate code.
Done. Consolidated files
There was a problem hiding this comment.
While investigating the UBI8/RHEL8 CI failure, we found that the reason for having separate per-distro OVAL files was that RHEL does not use /etc/pam.d/common-password — it uses system-auth and password-auth instead. When we consolidated those files into shared.xml, the build system started picking it up for RHEL products too, causing undefined-variable error and, if it had built, an incorrect check against a file that does not exist on RHEL.
To avoid duplicating code back into separate files, we wrapped the inside the existing {{% if %}} guard so that shared.xml produces empty output for products that do not use common-password. This prevents both the build crash and an incorrect OVAL evaluation on RHEL systems.
After that fix, the build succeeds but two additional UBI8 test failures are visible. These are pre-existing issues, present in upstream/master with identical test scripts and OVAL:
- accounts_password_pam_pwhistory_use_authtok: rhel_correct.pass.sh and rhel_wrong.fail.sh call authselect create-profile, which is not available in the UBI8 CI container (exit code 127). The scripts are missing a # packages = authselect,pam directive.
- accounts_password_pam_unix_authtok: rhel_wrong.fail.sh only does sed 's/use_authtok/remember/', assuming pam_unix.so is already in a non-first position in the password stack. In a minimal UBI8 container it is the only password module (instance 1), which the OVAL excludes from the non-first-line check. The resulting empty object set causes check_existence="any_exist" to return notapplicable instead of fail.
| @@ -0,0 +1,37 @@ | |||
| {{% if 'debian' in product %}} | |||
There was a problem hiding this comment.
Similarly, this file is also almost identical with existing OVAL files. This time this would be a 3rd file with same content in the linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_enabled/oval/ directory. Please reduce code duplication by merging all 3 into a single file named shared.xml.
Add Debian-specific bash remediations and OVAL checks for PAM rules that previously lacked Debian support: - accounts_password_pam_pwhistory_remember: add bash/debian.sh and oval/debian.xml using /etc/pam.d/common-password directly. - accounts_password_pam_pwhistory_use_authtok: add bash/debian.sh. - accounts_password_pam_unix_authtok: add bash/debian.sh. - accounts_password_pam_pwquality_enabled: add oval/debian.xml checking pam_pwquality.so in /etc/pam.d/common-password. Extend existing shared remediations to cover Debian: - accounts_password_pam_unix_enabled/bash/shared.sh: add multi_platform_debian. - accounts_password_pam_pwhistory_enabled/bash/shared.sh: add multi_platform_debian. - accounts_passwords_pam_faillock_enabled/bash/shared.sh: add multi_platform_debian. - accounts_password_pam_unix_no_remember/bash/shared.sh: add multi_platform_debian. - no_empty_passwords_unix/bash/shared.sh: add fallback that removes nullok directly from /etc/pam.d/common-* files in case pam-auth-update is blocked by local modifications. Add CIS Debian 13 options to password hashing algorithm variables: - var_password_hashing_algorithm.var: add cis_debian13=YESCRYPT|SHA512 - var_password_hashing_algorithm_pam.var: add cis_debian13=yescrypt|sha512 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
accounts_password_pam_pwhistory_remember: merge debian.xml and ubuntu.xml into a single shared.xml covering sle12, debian, and ubuntu products. accounts_password_pam_pwquality_enabled: merge debian.xml, ubuntu.xml, and sle.xml into a single shared.xml covering debian, ubuntu, sle15, and sle16. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The sle12 condition was carried over from the original ubuntu.xml but was never reachable there (the build system only applies ubuntu.xml to ubuntu products). Keeping only debian and ubuntu which are the actual consumers. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Wrap <def-group> inside the existing {{% if %}} block in
pwhistory_remember and pwquality_enabled shared.xml files so that
products without /etc/pam.d/common-password (e.g. RHEL8/UBI8) produce
empty OVAL output instead of a Jinja2 undefined-variable error.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
23ffcf9 to
df71da3
Compare
Add Debian-specific bash remediations and OVAL checks for PAM rules that previously lacked Debian support:
Extend existing shared remediations to cover Debian:
Add CIS Debian 13 options to password hashing algorithm variables:
Description:
Add Debian-specific bash remediations and OVAL checks for PAM rules that
previously lacked Debian support:
accounts_password_pam_pwhistory_remember: addbash/debian.shandoval/debian.xmlusing/etc/pam.d/common-passworddirectly.accounts_password_pam_pwhistory_use_authtok: addbash/debian.sh.accounts_password_pam_unix_authtok: addbash/debian.sh.accounts_password_pam_pwquality_enabled: addoval/debian.xmlchecking
pam_pwquality.soin/etc/pam.d/common-password.Extend existing shared remediations to cover Debian:
accounts_password_pam_unix_enabled/bash/shared.sh: addmulti_platform_debian.accounts_password_pam_pwhistory_enabled/bash/shared.sh: addmulti_platform_debian.accounts_passwords_pam_faillock_enabled/bash/shared.sh: addmulti_platform_debian.accounts_password_pam_unix_no_remember/bash/shared.sh: addmulti_platform_debian.no_empty_passwords_unix/bash/shared.sh: add fallback that removesnullokdirectly from/etc/pam.d/common-*files whenpam-auth-updateis blocked by local modifications.
Add CIS Debian 13 options to password hashing algorithm variables:
var_password_hashing_algorithm.var: addcis_debian13=YESCRYPT|SHA512var_password_hashing_algorithm_pam.var: addcis_debian13=yescrypt|sha512Rationale:
Debian uses
/etc/pam.d/common-*files managed bypam-auth-update.Rules that previously only had RHEL/SLE remediations needed Debian-specific
implementations that edit these files directly. The
nullokfallback isneeded because
pam-auth-updatemay refuse to run when local modificationsare detected.
Review Hints:
fix/debian-pam-pwquality-remediation(already open), which fixes
accounts_password_pam_pwquality_enabled/bash/shared.shand
shared/templates/accounts_password/bash.template. No file overlap.yescryptas the default password hashing algorithm(Debian 13 default);
SHA512is the legacy fallback allowed by CIS.