File: //usr/share/scap-security-guide/bash/rhel7-script-rht-ccp.sh
#!/usr/bin/env bash
###############################################################################
#
# Bash Remediation Script for Red Hat Corporate Profile for Certified Cloud Providers (RH CCP)
#
# Profile Description:
# This profile contains the minimum security relevant
# configuration settings recommended by Red Hat, Inc for
# Red Hat Enterprise Linux 7 instances deployed by Red Hat Certified
# Cloud Providers.
#
# Profile ID: xccdf_org.ssgproject.content_profile_rht-ccp
# Benchmark ID: xccdf_org.ssgproject.content_benchmark_RHEL-7
# Benchmark Version: 0.1.72
# XCCDF Version: 1.2
#
# This file can be generated by OpenSCAP using:
# $ oscap xccdf generate fix --profile xccdf_org.ssgproject.content_profile_rht-ccp --fix-type bash ssg-rhel7-ds.xml
#
# This Bash Remediation Script is generated from an XCCDF profile without preliminary evaluation.
# It attempts to fix every selected rule, even if the system is already compliant.
#
# How to apply this Bash Remediation Script:
# $ sudo ./remediation-script.sh
#
###############################################################################
###############################################################################
# BEGIN fix (1 / 68) for 'xccdf_org.ssgproject.content_rule_package_aide_installed'
###############################################################################
(>&2 echo "Remediating rule 1/68: 'xccdf_org.ssgproject.content_rule_package_aide_installed'")
# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
if ! rpm -q --quiet "aide" ; then
yum install -y "aide"
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
# END fix for 'xccdf_org.ssgproject.content_rule_package_aide_installed'
###############################################################################
# BEGIN fix (2 / 68) for 'xccdf_org.ssgproject.content_rule_partition_for_tmp'
###############################################################################
(>&2 echo "Remediating rule 2/68: 'xccdf_org.ssgproject.content_rule_partition_for_tmp'")
(>&2 echo "FIX FOR THIS RULE 'xccdf_org.ssgproject.content_rule_partition_for_tmp' IS MISSING!")
# END fix for 'xccdf_org.ssgproject.content_rule_partition_for_tmp'
###############################################################################
# BEGIN fix (3 / 68) for 'xccdf_org.ssgproject.content_rule_partition_for_var'
###############################################################################
(>&2 echo "Remediating rule 3/68: 'xccdf_org.ssgproject.content_rule_partition_for_var'")
(>&2 echo "FIX FOR THIS RULE 'xccdf_org.ssgproject.content_rule_partition_for_var' IS MISSING!")
# END fix for 'xccdf_org.ssgproject.content_rule_partition_for_var'
###############################################################################
# BEGIN fix (4 / 68) for 'xccdf_org.ssgproject.content_rule_partition_for_var_log'
###############################################################################
(>&2 echo "Remediating rule 4/68: 'xccdf_org.ssgproject.content_rule_partition_for_var_log'")
(>&2 echo "FIX FOR THIS RULE 'xccdf_org.ssgproject.content_rule_partition_for_var_log' IS MISSING!")
# END fix for 'xccdf_org.ssgproject.content_rule_partition_for_var_log'
###############################################################################
# BEGIN fix (5 / 68) for 'xccdf_org.ssgproject.content_rule_partition_for_var_log_audit'
###############################################################################
(>&2 echo "Remediating rule 5/68: 'xccdf_org.ssgproject.content_rule_partition_for_var_log_audit'")
(>&2 echo "FIX FOR THIS RULE 'xccdf_org.ssgproject.content_rule_partition_for_var_log_audit' IS MISSING!")
# END fix for 'xccdf_org.ssgproject.content_rule_partition_for_var_log_audit'
###############################################################################
# BEGIN fix (6 / 68) for 'xccdf_org.ssgproject.content_rule_ensure_gpgcheck_globally_activated'
###############################################################################
(>&2 echo "Remediating rule 6/68: 'xccdf_org.ssgproject.content_rule_ensure_gpgcheck_globally_activated'")
# Remediation is applicable only in certain platforms
if rpm --quiet -q yum; then
# Strip any search characters in the key arg so that the key can be replaced without
# adding any search characters to the config file.
stripped_key=$(sed 's/[\^=\$,;+]*//g' <<< "^gpgcheck")
# shellcheck disable=SC2059
printf -v formatted_output "%s = %s" "$stripped_key" "1"
# If the key exists, change it. Otherwise, add it to the config_file.
# We search for the key string followed by a word boundary (matched by \>),
# so if we search for 'setting', 'setting2' won't match.
if LC_ALL=C grep -q -m 1 -i -e "^gpgcheck\\>" "/etc/yum.conf"; then
escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
LC_ALL=C sed -i --follow-symlinks "s/^gpgcheck\\>.*/$escaped_formatted_output/gi" "/etc/yum.conf"
else
if [[ -s "/etc/yum.conf" ]] && [[ -n "$(tail -c 1 -- "/etc/yum.conf" || true)" ]]; then
LC_ALL=C sed -i --follow-symlinks '$a'\\ "/etc/yum.conf"
fi
cce="CCE-26989-4"
printf '# Per %s: Set %s in %s\n' "${cce}" "${formatted_output}" "/etc/yum.conf" >> "/etc/yum.conf"
printf '%s\n' "$formatted_output" >> "/etc/yum.conf"
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
# END fix for 'xccdf_org.ssgproject.content_rule_ensure_gpgcheck_globally_activated'
###############################################################################
# BEGIN fix (7 / 68) for 'xccdf_org.ssgproject.content_rule_ensure_gpgcheck_never_disabled'
###############################################################################
(>&2 echo "Remediating rule 7/68: 'xccdf_org.ssgproject.content_rule_ensure_gpgcheck_never_disabled'")
sed -i 's/gpgcheck\s*=.*/gpgcheck=1/g' /etc/yum.repos.d/*
# END fix for 'xccdf_org.ssgproject.content_rule_ensure_gpgcheck_never_disabled'
###############################################################################
# BEGIN fix (8 / 68) for 'xccdf_org.ssgproject.content_rule_ensure_redhat_gpgkey_installed'
###############################################################################
(>&2 echo "Remediating rule 8/68: 'xccdf_org.ssgproject.content_rule_ensure_redhat_gpgkey_installed'")
# The two fingerprints below are retrieved from https://access.redhat.com/security/team/key
readonly REDHAT_RELEASE_FINGERPRINT="567E347AD0044ADE55BA8A5F199E2F91FD431D51"
readonly REDHAT_AUXILIARY_FINGERPRINT="43A6E49C4A38F4BE9ABF2A5345689C882FA658E0"
# Location of the key we would like to import (once it's integrity verified)
readonly REDHAT_RELEASE_KEY="/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release"
RPM_GPG_DIR_PERMS=$(stat -c %a "$(dirname "$REDHAT_RELEASE_KEY")")
# Verify /etc/pki/rpm-gpg directory permissions are safe
if [ "${RPM_GPG_DIR_PERMS}" -le "755" ]
then
# If they are safe, try to obtain fingerprints from the key file
# (to ensure there won't be e.g. CRC error).
readarray -t GPG_OUT < <(gpg --with-fingerprint --with-colons "$REDHAT_RELEASE_KEY" | grep "^fpr" | cut -d ":" -f 10)
GPG_RESULT=$?
# No CRC error, safe to proceed
if [ "${GPG_RESULT}" -eq "0" ]
then
echo "${GPG_OUT[*]}" | grep -vE "${REDHAT_RELEASE_FINGERPRINT}|${REDHAT_AUXILIARY_FINGERPRINT}" || {
# If $REDHAT_RELEASE_KEY file doesn't contain any keys with unknown fingerprint, import it
rpm --import "${REDHAT_RELEASE_KEY}"
}
fi
fi
# END fix for 'xccdf_org.ssgproject.content_rule_ensure_redhat_gpgkey_installed'
###############################################################################
# BEGIN fix (9 / 68) for 'xccdf_org.ssgproject.content_rule_security_patches_up_to_date'
###############################################################################
(>&2 echo "Remediating rule 9/68: 'xccdf_org.ssgproject.content_rule_security_patches_up_to_date'")
yum -y update
# END fix for 'xccdf_org.ssgproject.content_rule_security_patches_up_to_date'
###############################################################################
# BEGIN fix (10 / 68) for 'xccdf_org.ssgproject.content_rule_accounts_password_pam_unix_remember'
###############################################################################
(>&2 echo "Remediating rule 10/68: 'xccdf_org.ssgproject.content_rule_accounts_password_pam_unix_remember'")
# Remediation is applicable only in certain platforms
if rpm --quiet -q pam; then
var_password_pam_unix_remember='5'
if [ -f /usr/bin/authselect ]; then
if authselect list-features minimal | 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 }')
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 "/etc/pam.d/system-auth")
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.*)/\1'"requisite"' \2/' "$PAM_FILE_PATH"
else
LAST_MATCH_LINE=$(grep -nP "^password.*requisite.*pam_pwquality\.so" "$PAM_FILE_PATH" | tail -n 1 | cut -d: -f 1)
if [ ! -z $LAST_MATCH_LINE ]; then
sed -i --follow-symlinks $LAST_MATCH_LINE' a password '"requisite"' pam_pwhistory.so' "$PAM_FILE_PATH"
else
echo 'password '"requisite"' pam_pwhistory.so' >> "$PAM_FILE_PATH"
fi
fi
fi
fi
else
if ! grep -qP '^\s*password\s+'"requisite"'\s+pam_pwhistory.so\s*.*' "/etc/pam.d/system-auth"; then
# Line matching group + control + module was not found. Check group + module.
if [ "$(grep -cP '^\s*password\s+.*\s+pam_pwhistory.so\s*' "/etc/pam.d/system-auth")" -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.*)/\1'"requisite"' \2/' "/etc/pam.d/system-auth"
else
LAST_MATCH_LINE=$(grep -nP "^password.*requisite.*pam_pwquality\.so" "/etc/pam.d/system-auth" | tail -n 1 | cut -d: -f 1)
if [ ! -z $LAST_MATCH_LINE ]; then
sed -i --follow-symlinks $LAST_MATCH_LINE' a password '"requisite"' pam_pwhistory.so' "/etc/pam.d/system-auth"
else
echo 'password '"requisite"' pam_pwhistory.so' >> "/etc/pam.d/system-auth"
fi
fi
fi
fi
PWHISTORY_CONF="/etc/security/pwhistory.conf"
if [ -f $PWHISTORY_CONF ]; then
regex="^\s*remember\s*="
line="remember = $var_password_pam_unix_remember"
if ! grep -q $regex $PWHISTORY_CONF; then
echo $line >> $PWHISTORY_CONF
else
sed -i --follow-symlinks 's|^\s*\(remember\s*=\s*\)\(\S\+\)|\1'"$var_password_pam_unix_remember"'|g' $PWHISTORY_CONF
fi
if [ -e "/etc/pam.d/system-auth" ] ; then
PAM_FILE_PATH="/etc/pam.d/system-auth"
if [ -f /usr/bin/authselect ]; 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
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 }')
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 "/etc/pam.d/system-auth")
PAM_FILE_PATH="/etc/authselect/$CURRENT_PROFILE/$PAM_FILE_NAME"
authselect apply-changes -b
fi
if grep -qP '^\s*password\s.*\bpam_pwhistory.so\s.*\bremember\b' "$PAM_FILE_PATH"; then
sed -i -E --follow-symlinks 's/(.*password.*pam_pwhistory.so.*)\bremember\b=?[[:alnum:]]*(.*)/\1\2/g' "$PAM_FILE_PATH"
fi
if [ -f /usr/bin/authselect ]; then
authselect apply-changes -b
fi
else
echo "/etc/pam.d/system-auth was not found" >&2
fi
else
PAM_FILE_PATH="/etc/pam.d/system-auth"
if [ -f /usr/bin/authselect ]; 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
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 }')
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 "/etc/pam.d/system-auth")
PAM_FILE_PATH="/etc/authselect/$CURRENT_PROFILE/$PAM_FILE_NAME"
authselect apply-changes -b
fi
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.*)/\1'"requisite"' \2/' "$PAM_FILE_PATH"
else
echo 'password '"requisite"' pam_pwhistory.so' >> "$PAM_FILE_PATH"
fi
fi
# Check the option
if ! grep -qP '^\s*password\s+'"requisite"'\s+pam_pwhistory.so\s*.*\sremember\b' "$PAM_FILE_PATH"; then
sed -i -E --follow-symlinks '/\s*password\s+'"requisite"'\s+pam_pwhistory.so.*/ s/$/ remember='"$var_password_pam_unix_remember"'/' "$PAM_FILE_PATH"
else
sed -i -E --follow-symlinks 's/(\s*password\s+'"requisite"'\s+pam_pwhistory.so\s+.*)('"remember"'=)[[:alnum:]]+\s*(.*)/\1\2'"$var_password_pam_unix_remember"' \3/' "$PAM_FILE_PATH"
fi
if [ -f /usr/bin/authselect ]; then
authselect apply-changes -b
fi
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
# END fix for 'xccdf_org.ssgproject.content_rule_accounts_password_pam_unix_remember'
###############################################################################
# BEGIN fix (11 / 68) for 'xccdf_org.ssgproject.content_rule_accounts_passwords_pam_faillock_deny'
###############################################################################
(>&2 echo "Remediating rule 11/68: 'xccdf_org.ssgproject.content_rule_accounts_passwords_pam_faillock_deny'")
# Remediation is applicable only in certain platforms
if rpm --quiet -q pam; then
var_accounts_passwords_pam_faillock_deny='5'
if [ -f /usr/bin/authselect ]; 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-faillock
authselect apply-changes -b
else
AUTH_FILES=("/etc/pam.d/system-auth" "/etc/pam.d/password-auth")
for pam_file in "${AUTH_FILES[@]}"
do
if ! grep -qE '^\s*auth\s+required\s+pam_faillock\.so\s+(preauth silent|authfail).*$' "$pam_file" ; then
sed -i --follow-symlinks '/^auth.*sufficient.*pam_unix\.so.*/i auth required pam_faillock.so preauth silent' "$pam_file"
sed -i --follow-symlinks '/^auth.*required.*pam_deny\.so.*/i auth required pam_faillock.so authfail' "$pam_file"
sed -i --follow-symlinks '/^account.*required.*pam_unix\.so.*/i account required pam_faillock.so' "$pam_file"
fi
sed -Ei 's/(auth.*)(\[default=die\])(.*pam_faillock\.so)/\1required \3/g' "$pam_file"
done
fi
AUTH_FILES=("/etc/pam.d/system-auth" "/etc/pam.d/password-auth")
FAILLOCK_CONF="/etc/security/faillock.conf"
if [ -f $FAILLOCK_CONF ]; then
regex="^\s*deny\s*="
line="deny = $var_accounts_passwords_pam_faillock_deny"
if ! grep -q $regex $FAILLOCK_CONF; then
echo $line >> $FAILLOCK_CONF
else
sed -i --follow-symlinks 's|^\s*\(deny\s*=\s*\)\(\S\+\)|\1'"$var_accounts_passwords_pam_faillock_deny"'|g' $FAILLOCK_CONF
fi
for pam_file in "${AUTH_FILES[@]}"
do
if [ -e "$pam_file" ] ; then
PAM_FILE_PATH="$pam_file"
if [ -f /usr/bin/authselect ]; 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
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 }')
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 "$pam_file")
PAM_FILE_PATH="/etc/authselect/$CURRENT_PROFILE/$PAM_FILE_NAME"
authselect apply-changes -b
fi
if grep -qP '^\s*auth\s.*\bpam_faillock.so\s.*\bdeny\b' "$PAM_FILE_PATH"; then
sed -i -E --follow-symlinks 's/(.*auth.*pam_faillock.so.*)\bdeny\b=?[[:alnum:]]*(.*)/\1\2/g' "$PAM_FILE_PATH"
fi
if [ -f /usr/bin/authselect ]; then
authselect apply-changes -b
fi
else
echo "$pam_file was not found" >&2
fi
done
else
for pam_file in "${AUTH_FILES[@]}"
do
if ! grep -qE '^\s*auth.*pam_faillock\.so (preauth|authfail).*deny' "$pam_file"; then
sed -i --follow-symlinks '/^auth.*required.*pam_faillock\.so.*preauth.*silent.*/ s/$/ deny='"$var_accounts_passwords_pam_faillock_deny"'/' "$pam_file"
sed -i --follow-symlinks '/^auth.*required.*pam_faillock\.so.*authfail.*/ s/$/ deny='"$var_accounts_passwords_pam_faillock_deny"'/' "$pam_file"
else
sed -i --follow-symlinks 's/\(^auth.*required.*pam_faillock\.so.*preauth.*silent.*\)\('"deny"'=\)[0-9]\+\(.*\)/\1\2'"$var_accounts_passwords_pam_faillock_deny"'\3/' "$pam_file"
sed -i --follow-symlinks 's/\(^auth.*required.*pam_faillock\.so.*authfail.*\)\('"deny"'=\)[0-9]\+\(.*\)/\1\2'"$var_accounts_passwords_pam_faillock_deny"'\3/' "$pam_file"
fi
done
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
# END fix for 'xccdf_org.ssgproject.content_rule_accounts_passwords_pam_faillock_deny'
###############################################################################
# BEGIN fix (12 / 68) for 'xccdf_org.ssgproject.content_rule_accounts_password_pam_dcredit'
###############################################################################
(>&2 echo "Remediating rule 12/68: 'xccdf_org.ssgproject.content_rule_accounts_password_pam_dcredit'")
# Remediation is applicable only in certain platforms
if rpm --quiet -q pam; then
var_password_pam_dcredit='-1'
# Strip any search characters in the key arg so that the key can be replaced without
# adding any search characters to the config file.
stripped_key=$(sed 's/[\^=\$,;+]*//g' <<< "^dcredit")
# shellcheck disable=SC2059
printf -v formatted_output "%s = %s" "$stripped_key" "$var_password_pam_dcredit"
# If the key exists, change it. Otherwise, add it to the config_file.
# We search for the key string followed by a word boundary (matched by \>),
# so if we search for 'setting', 'setting2' won't match.
if LC_ALL=C grep -q -m 1 -i -e "^dcredit\\>" "/etc/security/pwquality.conf"; then
escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
LC_ALL=C sed -i --follow-symlinks "s/^dcredit\\>.*/$escaped_formatted_output/gi" "/etc/security/pwquality.conf"
else
if [[ -s "/etc/security/pwquality.conf" ]] && [[ -n "$(tail -c 1 -- "/etc/security/pwquality.conf" || true)" ]]; then
LC_ALL=C sed -i --follow-symlinks '$a'\\ "/etc/security/pwquality.conf"
fi
cce="CCE-27214-6"
printf '# Per %s: Set %s in %s\n' "${cce}" "${formatted_output}" "/etc/security/pwquality.conf" >> "/etc/security/pwquality.conf"
printf '%s\n' "$formatted_output" >> "/etc/security/pwquality.conf"
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
# END fix for 'xccdf_org.ssgproject.content_rule_accounts_password_pam_dcredit'
###############################################################################
# BEGIN fix (13 / 68) for 'xccdf_org.ssgproject.content_rule_accounts_password_pam_difok'
###############################################################################
(>&2 echo "Remediating rule 13/68: 'xccdf_org.ssgproject.content_rule_accounts_password_pam_difok'")
# Remediation is applicable only in certain platforms
if rpm --quiet -q pam; then
var_password_pam_difok='3'
# Strip any search characters in the key arg so that the key can be replaced without
# adding any search characters to the config file.
stripped_key=$(sed 's/[\^=\$,;+]*//g' <<< "^difok")
# shellcheck disable=SC2059
printf -v formatted_output "%s = %s" "$stripped_key" "$var_password_pam_difok"
# If the key exists, change it. Otherwise, add it to the config_file.
# We search for the key string followed by a word boundary (matched by \>),
# so if we search for 'setting', 'setting2' won't match.
if LC_ALL=C grep -q -m 1 -i -e "^difok\\>" "/etc/security/pwquality.conf"; then
escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
LC_ALL=C sed -i --follow-symlinks "s/^difok\\>.*/$escaped_formatted_output/gi" "/etc/security/pwquality.conf"
else
if [[ -s "/etc/security/pwquality.conf" ]] && [[ -n "$(tail -c 1 -- "/etc/security/pwquality.conf" || true)" ]]; then
LC_ALL=C sed -i --follow-symlinks '$a'\\ "/etc/security/pwquality.conf"
fi
cce="CCE-82020-9"
printf '# Per %s: Set %s in %s\n' "${cce}" "${formatted_output}" "/etc/security/pwquality.conf" >> "/etc/security/pwquality.conf"
printf '%s\n' "$formatted_output" >> "/etc/security/pwquality.conf"
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
# END fix for 'xccdf_org.ssgproject.content_rule_accounts_password_pam_difok'
###############################################################################
# BEGIN fix (14 / 68) for 'xccdf_org.ssgproject.content_rule_accounts_password_pam_lcredit'
###############################################################################
(>&2 echo "Remediating rule 14/68: 'xccdf_org.ssgproject.content_rule_accounts_password_pam_lcredit'")
# Remediation is applicable only in certain platforms
if rpm --quiet -q pam; then
var_password_pam_lcredit='-2'
# Strip any search characters in the key arg so that the key can be replaced without
# adding any search characters to the config file.
stripped_key=$(sed 's/[\^=\$,;+]*//g' <<< "^lcredit")
# shellcheck disable=SC2059
printf -v formatted_output "%s = %s" "$stripped_key" "$var_password_pam_lcredit"
# If the key exists, change it. Otherwise, add it to the config_file.
# We search for the key string followed by a word boundary (matched by \>),
# so if we search for 'setting', 'setting2' won't match.
if LC_ALL=C grep -q -m 1 -i -e "^lcredit\\>" "/etc/security/pwquality.conf"; then
escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
LC_ALL=C sed -i --follow-symlinks "s/^lcredit\\>.*/$escaped_formatted_output/gi" "/etc/security/pwquality.conf"
else
if [[ -s "/etc/security/pwquality.conf" ]] && [[ -n "$(tail -c 1 -- "/etc/security/pwquality.conf" || true)" ]]; then
LC_ALL=C sed -i --follow-symlinks '$a'\\ "/etc/security/pwquality.conf"
fi
cce="CCE-27345-8"
printf '# Per %s: Set %s in %s\n' "${cce}" "${formatted_output}" "/etc/security/pwquality.conf" >> "/etc/security/pwquality.conf"
printf '%s\n' "$formatted_output" >> "/etc/security/pwquality.conf"
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
# END fix for 'xccdf_org.ssgproject.content_rule_accounts_password_pam_lcredit'
###############################################################################
# BEGIN fix (15 / 68) for 'xccdf_org.ssgproject.content_rule_accounts_password_pam_ocredit'
###############################################################################
(>&2 echo "Remediating rule 15/68: 'xccdf_org.ssgproject.content_rule_accounts_password_pam_ocredit'")
# Remediation is applicable only in certain platforms
if rpm --quiet -q pam; then
var_password_pam_ocredit='-2'
# Strip any search characters in the key arg so that the key can be replaced without
# adding any search characters to the config file.
stripped_key=$(sed 's/[\^=\$,;+]*//g' <<< "^ocredit")
# shellcheck disable=SC2059
printf -v formatted_output "%s = %s" "$stripped_key" "$var_password_pam_ocredit"
# If the key exists, change it. Otherwise, add it to the config_file.
# We search for the key string followed by a word boundary (matched by \>),
# so if we search for 'setting', 'setting2' won't match.
if LC_ALL=C grep -q -m 1 -i -e "^ocredit\\>" "/etc/security/pwquality.conf"; then
escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
LC_ALL=C sed -i --follow-symlinks "s/^ocredit\\>.*/$escaped_formatted_output/gi" "/etc/security/pwquality.conf"
else
if [[ -s "/etc/security/pwquality.conf" ]] && [[ -n "$(tail -c 1 -- "/etc/security/pwquality.conf" || true)" ]]; then
LC_ALL=C sed -i --follow-symlinks '$a'\\ "/etc/security/pwquality.conf"
fi
cce="CCE-27360-7"
printf '# Per %s: Set %s in %s\n' "${cce}" "${formatted_output}" "/etc/security/pwquality.conf" >> "/etc/security/pwquality.conf"
printf '%s\n' "$formatted_output" >> "/etc/security/pwquality.conf"
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
# END fix for 'xccdf_org.ssgproject.content_rule_accounts_password_pam_ocredit'
###############################################################################
# BEGIN fix (16 / 68) for 'xccdf_org.ssgproject.content_rule_accounts_password_pam_retry'
###############################################################################
(>&2 echo "Remediating rule 16/68: 'xccdf_org.ssgproject.content_rule_accounts_password_pam_retry'")
# Remediation is applicable only in certain platforms
if rpm --quiet -q pam; then
var_password_pam_retry='3'
if [ -e "/etc/pam.d/system-auth" ] ; then
PAM_FILE_PATH="/etc/pam.d/system-auth"
if [ -f /usr/bin/authselect ]; 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
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 }')
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 "/etc/pam.d/system-auth")
PAM_FILE_PATH="/etc/authselect/$CURRENT_PROFILE/$PAM_FILE_NAME"
authselect apply-changes -b
fi
if ! grep -qP '^\s*password\s+'"requisite"'\s+pam_pwquality.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_pwquality.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_pwquality.so.*)/\1'"requisite"' \2/' "$PAM_FILE_PATH"
else
LAST_MATCH_LINE=$(grep -nP "^\s*account" "$PAM_FILE_PATH" | tail -n 1 | cut -d: -f 1)
if [ ! -z $LAST_MATCH_LINE ]; then
sed -i --follow-symlinks $LAST_MATCH_LINE' a password '"requisite"' pam_pwquality.so' "$PAM_FILE_PATH"
else
echo 'password '"requisite"' pam_pwquality.so' >> "$PAM_FILE_PATH"
fi
fi
fi
# Check the option
if ! grep -qP '^\s*password\s+'"requisite"'\s+pam_pwquality.so\s*.*\sretry\b' "$PAM_FILE_PATH"; then
sed -i -E --follow-symlinks '/\s*password\s+'"requisite"'\s+pam_pwquality.so.*/ s/$/ retry='"$var_password_pam_retry"'/' "$PAM_FILE_PATH"
else
sed -i -E --follow-symlinks 's/(\s*password\s+'"requisite"'\s+pam_pwquality.so\s+.*)('"retry"'=)[[:alnum:]]+\s*(.*)/\1\2'"$var_password_pam_retry"' \3/' "$PAM_FILE_PATH"
fi
if [ -f /usr/bin/authselect ]; then
authselect apply-changes -b
fi
else
echo "/etc/pam.d/system-auth was not found" >&2
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
# END fix for 'xccdf_org.ssgproject.content_rule_accounts_password_pam_retry'
###############################################################################
# BEGIN fix (17 / 68) for 'xccdf_org.ssgproject.content_rule_accounts_password_pam_ucredit'
###############################################################################
(>&2 echo "Remediating rule 17/68: 'xccdf_org.ssgproject.content_rule_accounts_password_pam_ucredit'")
# Remediation is applicable only in certain platforms
if rpm --quiet -q pam; then
var_password_pam_ucredit='-2'
# Strip any search characters in the key arg so that the key can be replaced without
# adding any search characters to the config file.
stripped_key=$(sed 's/[\^=\$,;+]*//g' <<< "^ucredit")
# shellcheck disable=SC2059
printf -v formatted_output "%s = %s" "$stripped_key" "$var_password_pam_ucredit"
# If the key exists, change it. Otherwise, add it to the config_file.
# We search for the key string followed by a word boundary (matched by \>),
# so if we search for 'setting', 'setting2' won't match.
if LC_ALL=C grep -q -m 1 -i -e "^ucredit\\>" "/etc/security/pwquality.conf"; then
escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
LC_ALL=C sed -i --follow-symlinks "s/^ucredit\\>.*/$escaped_formatted_output/gi" "/etc/security/pwquality.conf"
else
if [[ -s "/etc/security/pwquality.conf" ]] && [[ -n "$(tail -c 1 -- "/etc/security/pwquality.conf" || true)" ]]; then
LC_ALL=C sed -i --follow-symlinks '$a'\\ "/etc/security/pwquality.conf"
fi
cce="CCE-27200-5"
printf '# Per %s: Set %s in %s\n' "${cce}" "${formatted_output}" "/etc/security/pwquality.conf" >> "/etc/security/pwquality.conf"
printf '%s\n' "$formatted_output" >> "/etc/security/pwquality.conf"
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
# END fix for 'xccdf_org.ssgproject.content_rule_accounts_password_pam_ucredit'
###############################################################################
# BEGIN fix (18 / 68) for 'xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_libuserconf'
###############################################################################
(>&2 echo "Remediating rule 18/68: 'xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_libuserconf'")
# Remediation is applicable only in certain platforms
if rpm --quiet -q libuser; then
LIBUSER_CONF="/etc/libuser.conf"
CRYPT_STYLE_REGEX='[[:space:]]*\[defaults](.*(\n)+)+?[[:space:]]*crypt_style[[:space:]]*'
# Try find crypt_style in [defaults] section. If it is here, then change algorithm to sha512.
# If it isn't here, then add it to [defaults] section.
if grep -qzosP $CRYPT_STYLE_REGEX $LIBUSER_CONF ; then
sed -i "s/\(crypt_style[[:space:]]*=[[:space:]]*\).*/\1sha512/g" $LIBUSER_CONF
elif grep -qs "\[defaults]" $LIBUSER_CONF ; then
sed -i "/[[:space:]]*\[defaults]/a crypt_style = sha512" $LIBUSER_CONF
else
echo -e "[defaults]\ncrypt_style = sha512" >> $LIBUSER_CONF
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
# END fix for 'xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_libuserconf'
###############################################################################
# BEGIN fix (19 / 68) for 'xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_logindefs'
###############################################################################
(>&2 echo "Remediating rule 19/68: 'xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_logindefs'")
# Remediation is applicable only in certain platforms
if rpm --quiet -q shadow-utils; then
var_password_hashing_algorithm='SHA512'
# Strip any search characters in the key arg so that the key can be replaced without
# adding any search characters to the config file.
stripped_key=$(sed 's/[\^=\$,;+]*//g' <<< "^ENCRYPT_METHOD")
# shellcheck disable=SC2059
printf -v formatted_output "%s %s" "$stripped_key" "$var_password_hashing_algorithm"
# If the key exists, change it. Otherwise, add it to the config_file.
# We search for the key string followed by a word boundary (matched by \>),
# so if we search for 'setting', 'setting2' won't match.
if LC_ALL=C grep -q -m 1 -i -e "^ENCRYPT_METHOD\\>" "/etc/login.defs"; then
escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
LC_ALL=C sed -i --follow-symlinks "s/^ENCRYPT_METHOD\\>.*/$escaped_formatted_output/gi" "/etc/login.defs"
else
if [[ -s "/etc/login.defs" ]] && [[ -n "$(tail -c 1 -- "/etc/login.defs" || true)" ]]; then
LC_ALL=C sed -i --follow-symlinks '$a'\\ "/etc/login.defs"
fi
cce="CCE-82050-6"
printf '# Per %s: Set %s in %s\n' "${cce}" "${formatted_output}" "/etc/login.defs" >> "/etc/login.defs"
printf '%s\n' "$formatted_output" >> "/etc/login.defs"
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
# END fix for 'xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_logindefs'
###############################################################################
# BEGIN fix (20 / 68) for 'xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_systemauth'
###############################################################################
(>&2 echo "Remediating rule 20/68: 'xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_systemauth'")
# Remediation is applicable only in certain platforms
if rpm --quiet -q pam; then
if [ -e "/etc/pam.d/system-auth" ] ; then
PAM_FILE_PATH="/etc/pam.d/system-auth"
if [ -f /usr/bin/authselect ]; 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
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 }')
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 "/etc/pam.d/system-auth")
PAM_FILE_PATH="/etc/authselect/$CURRENT_PROFILE/$PAM_FILE_NAME"
authselect apply-changes -b
fi
if ! grep -qP '^\s*password\s+'"sufficient"'\s+pam_unix.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_unix.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_unix.so.*)/\1'"sufficient"' \2/' "$PAM_FILE_PATH"
else
echo 'password '"sufficient"' pam_unix.so' >> "$PAM_FILE_PATH"
fi
fi
# Check the option
if ! grep -qP '^\s*password\s+'"sufficient"'\s+pam_unix.so\s*.*\ssha512\b' "$PAM_FILE_PATH"; then
sed -i -E --follow-symlinks '/\s*password\s+'"sufficient"'\s+pam_unix.so.*/ s/$/ sha512/' "$PAM_FILE_PATH"
fi
if [ -f /usr/bin/authselect ]; then
authselect apply-changes -b
fi
else
echo "/etc/pam.d/system-auth was not found" >&2
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
# END fix for 'xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_systemauth'
###############################################################################
# BEGIN fix (21 / 68) for 'xccdf_org.ssgproject.content_rule_require_singleuser_auth'
###############################################################################
(>&2 echo "Remediating rule 21/68: 'xccdf_org.ssgproject.content_rule_require_singleuser_auth'")
# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
service_file="/usr/lib/systemd/system/rescue.service"
sulogin='/bin/sh -c "/usr/sbin/sulogin; /usr/bin/systemctl --fail --no-block default"'
if grep "^ExecStart=.*" "$service_file" ; then
sed -i "s%^ExecStart=.*%ExecStart=-$sulogin%" "$service_file"
else
echo "ExecStart=-$sulogin" >> "$service_file"
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
# END fix for 'xccdf_org.ssgproject.content_rule_require_singleuser_auth'
###############################################################################
# BEGIN fix (22 / 68) for 'xccdf_org.ssgproject.content_rule_accounts_minimum_age_login_defs'
###############################################################################
(>&2 echo "Remediating rule 22/68: 'xccdf_org.ssgproject.content_rule_accounts_minimum_age_login_defs'")
# Remediation is applicable only in certain platforms
if rpm --quiet -q shadow-utils; then
var_accounts_minimum_age_login_defs='7'
# Strip any search characters in the key arg so that the key can be replaced without
# adding any search characters to the config file.
stripped_key=$(sed 's/[\^=\$,;+]*//g' <<< "^PASS_MIN_DAYS")
# shellcheck disable=SC2059
printf -v formatted_output "%s %s" "$stripped_key" "$var_accounts_minimum_age_login_defs"
# If the key exists, change it. Otherwise, add it to the config_file.
# We search for the key string followed by a word boundary (matched by \>),
# so if we search for 'setting', 'setting2' won't match.
if LC_ALL=C grep -q -m 1 -i -e "^PASS_MIN_DAYS\\>" "/etc/login.defs"; then
escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
LC_ALL=C sed -i --follow-symlinks "s/^PASS_MIN_DAYS\\>.*/$escaped_formatted_output/gi" "/etc/login.defs"
else
if [[ -s "/etc/login.defs" ]] && [[ -n "$(tail -c 1 -- "/etc/login.defs" || true)" ]]; then
LC_ALL=C sed -i --follow-symlinks '$a'\\ "/etc/login.defs"
fi
cce="CCE-82036-5"
printf '# Per %s: Set %s in %s\n' "${cce}" "${formatted_output}" "/etc/login.defs" >> "/etc/login.defs"
printf '%s\n' "$formatted_output" >> "/etc/login.defs"
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
# END fix for 'xccdf_org.ssgproject.content_rule_accounts_minimum_age_login_defs'
###############################################################################
# BEGIN fix (23 / 68) for 'xccdf_org.ssgproject.content_rule_accounts_password_warn_age_login_defs'
###############################################################################
(>&2 echo "Remediating rule 23/68: 'xccdf_org.ssgproject.content_rule_accounts_password_warn_age_login_defs'")
# Remediation is applicable only in certain platforms
if rpm --quiet -q shadow-utils; then
var_accounts_password_warn_age_login_defs='7'
# Strip any search characters in the key arg so that the key can be replaced without
# adding any search characters to the config file.
stripped_key=$(sed 's/[\^=\$,;+]*//g' <<< "^PASS_WARN_AGE")
# shellcheck disable=SC2059
printf -v formatted_output "%s %s" "$stripped_key" "$var_accounts_password_warn_age_login_defs"
# If the key exists, change it. Otherwise, add it to the config_file.
# We search for the key string followed by a word boundary (matched by \>),
# so if we search for 'setting', 'setting2' won't match.
if LC_ALL=C grep -q -m 1 -i -e "^PASS_WARN_AGE\\>" "/etc/login.defs"; then
escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
LC_ALL=C sed -i --follow-symlinks "s/^PASS_WARN_AGE\\>.*/$escaped_formatted_output/gi" "/etc/login.defs"
else
if [[ -s "/etc/login.defs" ]] && [[ -n "$(tail -c 1 -- "/etc/login.defs" || true)" ]]; then
LC_ALL=C sed -i --follow-symlinks '$a'\\ "/etc/login.defs"
fi
cce="CCE-82016-7"
printf '# Per %s: Set %s in %s\n' "${cce}" "${formatted_output}" "/etc/login.defs" >> "/etc/login.defs"
printf '%s\n' "$formatted_output" >> "/etc/login.defs"
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
# END fix for 'xccdf_org.ssgproject.content_rule_accounts_password_warn_age_login_defs'
###############################################################################
# BEGIN fix (24 / 68) for 'xccdf_org.ssgproject.content_rule_accounts_password_all_shadowed'
###############################################################################
(>&2 echo "Remediating rule 24/68: 'xccdf_org.ssgproject.content_rule_accounts_password_all_shadowed'")
(>&2 echo "FIX FOR THIS RULE 'xccdf_org.ssgproject.content_rule_accounts_password_all_shadowed' IS MISSING!")
# END fix for 'xccdf_org.ssgproject.content_rule_accounts_password_all_shadowed'
###############################################################################
# BEGIN fix (25 / 68) for 'xccdf_org.ssgproject.content_rule_no_empty_passwords'
###############################################################################
(>&2 echo "Remediating rule 25/68: 'xccdf_org.ssgproject.content_rule_no_empty_passwords'")
# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
if [ -f /usr/bin/authselect ]; 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 without-nullok
authselect apply-changes -b
else
if grep -qP '^\s*auth\s+'"sufficient"'\s+pam_unix.so\s.*\bnullok\b' "/etc/pam.d/system-auth"; then
sed -i -E --follow-symlinks 's/(.*auth.*'"sufficient"'.*pam_unix.so.*)\snullok=?[[:alnum:]]*(.*)/\1\2/g' "/etc/pam.d/system-auth"
fi
if grep -qP '^\s*password\s+'"sufficient"'\s+pam_unix.so\s.*\bnullok\b' "/etc/pam.d/system-auth"; then
sed -i -E --follow-symlinks 's/(.*password.*'"sufficient"'.*pam_unix.so.*)\snullok=?[[:alnum:]]*(.*)/\1\2/g' "/etc/pam.d/system-auth"
fi
if grep -qP '^\s*auth\s+'"sufficient"'\s+pam_unix.so\s.*\bnullok\b' "/etc/pam.d/password-auth"; then
sed -i -E --follow-symlinks 's/(.*auth.*'"sufficient"'.*pam_unix.so.*)\snullok=?[[:alnum:]]*(.*)/\1\2/g' "/etc/pam.d/password-auth"
fi
if grep -qP '^\s*password\s+'"sufficient"'\s+pam_unix.so\s.*\bnullok\b' "/etc/pam.d/password-auth"; then
sed -i -E --follow-symlinks 's/(.*password.*'"sufficient"'.*pam_unix.so.*)\snullok=?[[:alnum:]]*(.*)/\1\2/g' "/etc/pam.d/password-auth"
fi
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
# END fix for 'xccdf_org.ssgproject.content_rule_no_empty_passwords'
###############################################################################
# BEGIN fix (26 / 68) for 'xccdf_org.ssgproject.content_rule_accounts_no_uid_except_zero'
###############################################################################
(>&2 echo "Remediating rule 26/68: 'xccdf_org.ssgproject.content_rule_accounts_no_uid_except_zero'")
awk -F: '$3 == 0 && $1 != "root" { print $1 }' /etc/passwd | xargs --no-run-if-empty --max-lines=1 passwd -l
# END fix for 'xccdf_org.ssgproject.content_rule_accounts_no_uid_except_zero'
###############################################################################
# BEGIN fix (27 / 68) for 'xccdf_org.ssgproject.content_rule_no_shelllogin_for_systemaccounts'
###############################################################################
(>&2 echo "Remediating rule 27/68: 'xccdf_org.ssgproject.content_rule_no_shelllogin_for_systemaccounts'")
readarray -t systemaccounts < <(awk -F: '($3 < 1000 && $3 != root \
&& $7 != "\/sbin\/shutdown" && $7 != "\/sbin\/halt" && $7 != "\/bin\/sync") \
{ print $1 }' /etc/passwd)
for systemaccount in "${systemaccounts[@]}"; do
usermod -s /sbin/nologin "$systemaccount"
done
# END fix for 'xccdf_org.ssgproject.content_rule_no_shelllogin_for_systemaccounts'
###############################################################################
# BEGIN fix (28 / 68) for 'xccdf_org.ssgproject.content_rule_file_permissions_var_log_audit'
###############################################################################
(>&2 echo "Remediating rule 28/68: 'xccdf_org.ssgproject.content_rule_file_permissions_var_log_audit'")
# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ] && rpm --quiet -q audit; then
if LC_ALL=C grep -iw ^log_file /etc/audit/auditd.conf; then
FILE=$(awk -F "=" '/^log_file/ {print $2}' /etc/audit/auditd.conf | tr -d ' ')
else
FILE="/var/log/audit/audit.log"
fi
chmod 0600 $FILE
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
# END fix for 'xccdf_org.ssgproject.content_rule_file_permissions_var_log_audit'
###############################################################################
# BEGIN fix (29 / 68) for 'xccdf_org.ssgproject.content_rule_file_groupowner_grub2_cfg'
###############################################################################
(>&2 echo "Remediating rule 29/68: 'xccdf_org.ssgproject.content_rule_file_groupowner_grub2_cfg'")
# Remediation is applicable only in certain platforms
if [ ! -d /sys/firmware/efi ] && rpm --quiet -q grub2-common && { [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; }; then
chgrp 0 /boot/grub2/grub.cfg
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
# END fix for 'xccdf_org.ssgproject.content_rule_file_groupowner_grub2_cfg'
###############################################################################
# BEGIN fix (30 / 68) for 'xccdf_org.ssgproject.content_rule_file_owner_grub2_cfg'
###############################################################################
(>&2 echo "Remediating rule 30/68: 'xccdf_org.ssgproject.content_rule_file_owner_grub2_cfg'")
# Remediation is applicable only in certain platforms
if [ ! -d /sys/firmware/efi ] && rpm --quiet -q grub2-common && { [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; }; then
chown 0 /boot/grub2/grub.cfg
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
# END fix for 'xccdf_org.ssgproject.content_rule_file_owner_grub2_cfg'
###############################################################################
# BEGIN fix (31 / 68) for 'xccdf_org.ssgproject.content_rule_file_permissions_grub2_cfg'
###############################################################################
(>&2 echo "Remediating rule 31/68: 'xccdf_org.ssgproject.content_rule_file_permissions_grub2_cfg'")
# Remediation is applicable only in certain platforms
if [ ! -d /sys/firmware/efi ] && rpm --quiet -q grub2-common && { [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; }; then
chmod u-xs,o-xwrt,g-xwrs /boot/grub2/grub.cfg
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
# END fix for 'xccdf_org.ssgproject.content_rule_file_permissions_grub2_cfg'
###############################################################################
# BEGIN fix (32 / 68) for 'xccdf_org.ssgproject.content_rule_grub2_password'
###############################################################################
(>&2 echo "Remediating rule 32/68: 'xccdf_org.ssgproject.content_rule_grub2_password'")
(>&2 echo "FIX FOR THIS RULE 'xccdf_org.ssgproject.content_rule_grub2_password' IS MISSING!")
# END fix for 'xccdf_org.ssgproject.content_rule_grub2_password'
###############################################################################
# BEGIN fix (33 / 68) for 'xccdf_org.ssgproject.content_rule_service_firewalld_enabled'
###############################################################################
(>&2 echo "Remediating rule 33/68: 'xccdf_org.ssgproject.content_rule_service_firewalld_enabled'")
# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ] && { rpm --quiet -q firewalld; }; then
SYSTEMCTL_EXEC='/usr/bin/systemctl'
"$SYSTEMCTL_EXEC" unmask 'firewalld.service'
"$SYSTEMCTL_EXEC" start 'firewalld.service'
"$SYSTEMCTL_EXEC" enable 'firewalld.service'
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
# END fix for 'xccdf_org.ssgproject.content_rule_service_firewalld_enabled'
###############################################################################
# BEGIN fix (34 / 68) for 'xccdf_org.ssgproject.content_rule_set_firewalld_default_zone'
###############################################################################
(>&2 echo "Remediating rule 34/68: 'xccdf_org.ssgproject.content_rule_set_firewalld_default_zone'")
(>&2 echo "FIX FOR THIS RULE 'xccdf_org.ssgproject.content_rule_set_firewalld_default_zone' IS MISSING!")
# END fix for 'xccdf_org.ssgproject.content_rule_set_firewalld_default_zone'
###############################################################################
# BEGIN fix (35 / 68) for 'xccdf_org.ssgproject.content_rule_kernel_module_dccp_disabled'
###############################################################################
(>&2 echo "Remediating rule 35/68: 'xccdf_org.ssgproject.content_rule_kernel_module_dccp_disabled'")
# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
if LC_ALL=C grep -q -m 1 "^install dccp" /etc/modprobe.d/dccp.conf ; then
sed -i 's#^install dccp.*#install dccp /bin/true#g' /etc/modprobe.d/dccp.conf
else
echo -e "\n# Disable per security requirements" >> /etc/modprobe.d/dccp.conf
echo "install dccp /bin/false" >> /etc/modprobe.d/dccp.conf
fi
if ! LC_ALL=C grep -q -m 1 "^blacklist dccp$" /etc/modprobe.d/dccp.conf ; then
echo "blacklist dccp" >> /etc/modprobe.d/dccp.conf
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
# END fix for 'xccdf_org.ssgproject.content_rule_kernel_module_dccp_disabled'
###############################################################################
# BEGIN fix (36 / 68) for 'xccdf_org.ssgproject.content_rule_kernel_module_sctp_disabled'
###############################################################################
(>&2 echo "Remediating rule 36/68: 'xccdf_org.ssgproject.content_rule_kernel_module_sctp_disabled'")
# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
if LC_ALL=C grep -q -m 1 "^install sctp" /etc/modprobe.d/sctp.conf ; then
sed -i 's#^install sctp.*#install sctp /bin/true#g' /etc/modprobe.d/sctp.conf
else
echo -e "\n# Disable per security requirements" >> /etc/modprobe.d/sctp.conf
echo "install sctp /bin/false" >> /etc/modprobe.d/sctp.conf
fi
if ! LC_ALL=C grep -q -m 1 "^blacklist sctp$" /etc/modprobe.d/sctp.conf ; then
echo "blacklist sctp" >> /etc/modprobe.d/sctp.conf
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
# END fix for 'xccdf_org.ssgproject.content_rule_kernel_module_sctp_disabled'
###############################################################################
# BEGIN fix (37 / 68) for 'xccdf_org.ssgproject.content_rule_file_groupowner_etc_group'
###############################################################################
(>&2 echo "Remediating rule 37/68: 'xccdf_org.ssgproject.content_rule_file_groupowner_etc_group'")
chgrp 0 /etc/group
# END fix for 'xccdf_org.ssgproject.content_rule_file_groupowner_etc_group'
###############################################################################
# BEGIN fix (38 / 68) for 'xccdf_org.ssgproject.content_rule_file_groupowner_etc_gshadow'
###############################################################################
(>&2 echo "Remediating rule 38/68: 'xccdf_org.ssgproject.content_rule_file_groupowner_etc_gshadow'")
chgrp 0 /etc/gshadow
# END fix for 'xccdf_org.ssgproject.content_rule_file_groupowner_etc_gshadow'
###############################################################################
# BEGIN fix (39 / 68) for 'xccdf_org.ssgproject.content_rule_file_groupowner_etc_passwd'
###############################################################################
(>&2 echo "Remediating rule 39/68: 'xccdf_org.ssgproject.content_rule_file_groupowner_etc_passwd'")
chgrp 0 /etc/passwd
# END fix for 'xccdf_org.ssgproject.content_rule_file_groupowner_etc_passwd'
###############################################################################
# BEGIN fix (40 / 68) for 'xccdf_org.ssgproject.content_rule_file_groupowner_etc_shadow'
###############################################################################
(>&2 echo "Remediating rule 40/68: 'xccdf_org.ssgproject.content_rule_file_groupowner_etc_shadow'")
chgrp 0 /etc/shadow
# END fix for 'xccdf_org.ssgproject.content_rule_file_groupowner_etc_shadow'
###############################################################################
# BEGIN fix (41 / 68) for 'xccdf_org.ssgproject.content_rule_file_owner_etc_group'
###############################################################################
(>&2 echo "Remediating rule 41/68: 'xccdf_org.ssgproject.content_rule_file_owner_etc_group'")
chown 0 /etc/group
# END fix for 'xccdf_org.ssgproject.content_rule_file_owner_etc_group'
###############################################################################
# BEGIN fix (42 / 68) for 'xccdf_org.ssgproject.content_rule_file_owner_etc_gshadow'
###############################################################################
(>&2 echo "Remediating rule 42/68: 'xccdf_org.ssgproject.content_rule_file_owner_etc_gshadow'")
chown 0 /etc/gshadow
# END fix for 'xccdf_org.ssgproject.content_rule_file_owner_etc_gshadow'
###############################################################################
# BEGIN fix (43 / 68) for 'xccdf_org.ssgproject.content_rule_file_owner_etc_passwd'
###############################################################################
(>&2 echo "Remediating rule 43/68: 'xccdf_org.ssgproject.content_rule_file_owner_etc_passwd'")
chown 0 /etc/passwd
# END fix for 'xccdf_org.ssgproject.content_rule_file_owner_etc_passwd'
###############################################################################
# BEGIN fix (44 / 68) for 'xccdf_org.ssgproject.content_rule_file_owner_etc_shadow'
###############################################################################
(>&2 echo "Remediating rule 44/68: 'xccdf_org.ssgproject.content_rule_file_owner_etc_shadow'")
chown 0 /etc/shadow
# END fix for 'xccdf_org.ssgproject.content_rule_file_owner_etc_shadow'
###############################################################################
# BEGIN fix (45 / 68) for 'xccdf_org.ssgproject.content_rule_file_permissions_etc_group'
###############################################################################
(>&2 echo "Remediating rule 45/68: 'xccdf_org.ssgproject.content_rule_file_permissions_etc_group'")
chmod u-xs,o-xwt,g-xws /etc/group
# END fix for 'xccdf_org.ssgproject.content_rule_file_permissions_etc_group'
###############################################################################
# BEGIN fix (46 / 68) for 'xccdf_org.ssgproject.content_rule_file_permissions_etc_gshadow'
###############################################################################
(>&2 echo "Remediating rule 46/68: 'xccdf_org.ssgproject.content_rule_file_permissions_etc_gshadow'")
chmod u-xwrs,o-xwrt,g-xwrs /etc/gshadow
# END fix for 'xccdf_org.ssgproject.content_rule_file_permissions_etc_gshadow'
###############################################################################
# BEGIN fix (47 / 68) for 'xccdf_org.ssgproject.content_rule_file_permissions_etc_passwd'
###############################################################################
(>&2 echo "Remediating rule 47/68: 'xccdf_org.ssgproject.content_rule_file_permissions_etc_passwd'")
chmod u-xs,o-xwt,g-xws /etc/passwd
# END fix for 'xccdf_org.ssgproject.content_rule_file_permissions_etc_passwd'
###############################################################################
# BEGIN fix (48 / 68) for 'xccdf_org.ssgproject.content_rule_file_permissions_etc_shadow'
###############################################################################
(>&2 echo "Remediating rule 48/68: 'xccdf_org.ssgproject.content_rule_file_permissions_etc_shadow'")
chmod u-xwrs,o-xwrt,g-xwrs /etc/shadow
# END fix for 'xccdf_org.ssgproject.content_rule_file_permissions_etc_shadow'
###############################################################################
# BEGIN fix (49 / 68) for 'xccdf_org.ssgproject.content_rule_file_ownership_binary_dirs'
###############################################################################
(>&2 echo "Remediating rule 49/68: 'xccdf_org.ssgproject.content_rule_file_ownership_binary_dirs'")
find /bin/ \
/usr/bin/ \
/usr/local/bin/ \
/sbin/ \
/usr/sbin/ \
/usr/local/sbin/ \
/usr/libexec \
\! -user root -execdir chown root {} \;
# END fix for 'xccdf_org.ssgproject.content_rule_file_ownership_binary_dirs'
###############################################################################
# BEGIN fix (50 / 68) for 'xccdf_org.ssgproject.content_rule_file_ownership_library_dirs'
###############################################################################
(>&2 echo "Remediating rule 50/68: 'xccdf_org.ssgproject.content_rule_file_ownership_library_dirs'")
find /lib/ -type f ! -uid 0 -regex '^.*$' -exec chown 0 {} \;
find /lib64/ -type f ! -uid 0 -regex '^.*$' -exec chown 0 {} \;
find /usr/lib/ -type f ! -uid 0 -regex '^.*$' -exec chown 0 {} \;
find /usr/lib64/ -type f ! -uid 0 -regex '^.*$' -exec chown 0 {} \;
# END fix for 'xccdf_org.ssgproject.content_rule_file_ownership_library_dirs'
###############################################################################
# BEGIN fix (51 / 68) for 'xccdf_org.ssgproject.content_rule_file_permissions_binary_dirs'
###############################################################################
(>&2 echo "Remediating rule 51/68: 'xccdf_org.ssgproject.content_rule_file_permissions_binary_dirs'")
DIRS="/bin /usr/bin /usr/local/bin /sbin /usr/sbin /usr/local/sbin /usr/libexec"
for dirPath in $DIRS; do
find "$dirPath" -perm /022 -exec chmod go-w '{}' \;
done
# END fix for 'xccdf_org.ssgproject.content_rule_file_permissions_binary_dirs'
###############################################################################
# BEGIN fix (52 / 68) for 'xccdf_org.ssgproject.content_rule_file_permissions_library_dirs'
###############################################################################
(>&2 echo "Remediating rule 52/68: 'xccdf_org.ssgproject.content_rule_file_permissions_library_dirs'")
find -H /lib/ -perm /o+w,g+w -type f -regex '^.*$' -exec chmod o-w,g-w {} \;
find -H /lib64/ -perm /o+w,g+w -type f -regex '^.*$' -exec chmod o-w,g-w {} \;
find -H /usr/lib/ -perm /o+w,g+w -type f -regex '^.*$' -exec chmod o-w,g-w {} \;
find -H /usr/lib64/ -perm /o+w,g+w -type f -regex '^.*$' -exec chmod o-w,g-w {} \;
# END fix for 'xccdf_org.ssgproject.content_rule_file_permissions_library_dirs'
###############################################################################
# BEGIN fix (53 / 68) for 'xccdf_org.ssgproject.content_rule_selinux_policytype'
###############################################################################
(>&2 echo "Remediating rule 53/68: 'xccdf_org.ssgproject.content_rule_selinux_policytype'")
# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
var_selinux_policy_name='targeted'
if [ -e "/etc/selinux/config" ] ; then
LC_ALL=C sed -i "/^SELINUXTYPE=/Id" "/etc/selinux/config"
else
touch "/etc/selinux/config"
fi
# make sure file has newline at the end
sed -i -e '$a\' "/etc/selinux/config"
cp "/etc/selinux/config" "/etc/selinux/config.bak"
# Insert at the end of the file
printf '%s\n' "SELINUXTYPE=$var_selinux_policy_name" >> "/etc/selinux/config"
# Clean up after ourselves.
rm "/etc/selinux/config.bak"
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
# END fix for 'xccdf_org.ssgproject.content_rule_selinux_policytype'
###############################################################################
# BEGIN fix (54 / 68) for 'xccdf_org.ssgproject.content_rule_selinux_state'
###############################################################################
(>&2 echo "Remediating rule 54/68: 'xccdf_org.ssgproject.content_rule_selinux_state'")
# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
var_selinux_state='enforcing'
if [ -e "/etc/selinux/config" ] ; then
LC_ALL=C sed -i "/^SELINUX=/Id" "/etc/selinux/config"
else
touch "/etc/selinux/config"
fi
# make sure file has newline at the end
sed -i -e '$a\' "/etc/selinux/config"
cp "/etc/selinux/config" "/etc/selinux/config.bak"
# Insert at the end of the file
printf '%s\n' "SELINUX=$var_selinux_state" >> "/etc/selinux/config"
# Clean up after ourselves.
rm "/etc/selinux/config.bak"
fixfiles onboot
fixfiles -f relabel
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
# END fix for 'xccdf_org.ssgproject.content_rule_selinux_state'
###############################################################################
# BEGIN fix (55 / 68) for 'xccdf_org.ssgproject.content_rule_service_abrtd_disabled'
###############################################################################
(>&2 echo "Remediating rule 55/68: 'xccdf_org.ssgproject.content_rule_service_abrtd_disabled'")
# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
SYSTEMCTL_EXEC='/usr/bin/systemctl'
"$SYSTEMCTL_EXEC" stop 'abrtd.service'
"$SYSTEMCTL_EXEC" disable 'abrtd.service'
"$SYSTEMCTL_EXEC" mask 'abrtd.service'
# Disable socket activation if we have a unit file for it
if "$SYSTEMCTL_EXEC" -q list-unit-files abrtd.socket; then
"$SYSTEMCTL_EXEC" stop 'abrtd.socket'
"$SYSTEMCTL_EXEC" mask 'abrtd.socket'
fi
# The service may not be running because it has been started and failed,
# so let's reset the state so OVAL checks pass.
# Service should be 'inactive', not 'failed' after reboot though.
"$SYSTEMCTL_EXEC" reset-failed 'abrtd.service' || true
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
# END fix for 'xccdf_org.ssgproject.content_rule_service_abrtd_disabled'
###############################################################################
# BEGIN fix (56 / 68) for 'xccdf_org.ssgproject.content_rule_package_telnet_removed'
###############################################################################
(>&2 echo "Remediating rule 56/68: 'xccdf_org.ssgproject.content_rule_package_telnet_removed'")
# CAUTION: This remediation script will remove telnet
# from the system, and may remove any packages
# that depend on telnet. Execute this
# remediation AFTER testing on a non-production
# system!
if rpm -q --quiet "telnet" ; then
yum remove -y "telnet"
fi
# END fix for 'xccdf_org.ssgproject.content_rule_package_telnet_removed'
###############################################################################
# BEGIN fix (57 / 68) for 'xccdf_org.ssgproject.content_rule_package_telnet-server_removed'
###############################################################################
(>&2 echo "Remediating rule 57/68: 'xccdf_org.ssgproject.content_rule_package_telnet-server_removed'")
# CAUTION: This remediation script will remove telnet-server
# from the system, and may remove any packages
# that depend on telnet-server. Execute this
# remediation AFTER testing on a non-production
# system!
if rpm -q --quiet "telnet-server" ; then
yum remove -y "telnet-server"
fi
# END fix for 'xccdf_org.ssgproject.content_rule_package_telnet-server_removed'
###############################################################################
# BEGIN fix (58 / 68) for 'xccdf_org.ssgproject.content_rule_service_telnet_disabled'
###############################################################################
(>&2 echo "Remediating rule 58/68: 'xccdf_org.ssgproject.content_rule_service_telnet_disabled'")
# Remediation is applicable only in certain platforms
if ( [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ] && rpm --quiet -q telnet-server ); then
SYSTEMCTL_EXEC='/usr/bin/systemctl'
"$SYSTEMCTL_EXEC" stop 'telnet.service'
"$SYSTEMCTL_EXEC" disable 'telnet.service'
"$SYSTEMCTL_EXEC" mask 'telnet.service'
# Disable socket activation if we have a unit file for it
if "$SYSTEMCTL_EXEC" -q list-unit-files telnet.socket; then
"$SYSTEMCTL_EXEC" stop 'telnet.socket'
"$SYSTEMCTL_EXEC" mask 'telnet.socket'
fi
# The service may not be running because it has been started and failed,
# so let's reset the state so OVAL checks pass.
# Service should be 'inactive', not 'failed' after reboot though.
"$SYSTEMCTL_EXEC" reset-failed 'telnet.service' || true
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
# END fix for 'xccdf_org.ssgproject.content_rule_service_telnet_disabled'
###############################################################################
# BEGIN fix (59 / 68) for 'xccdf_org.ssgproject.content_rule_sshd_set_keepalive_0'
###############################################################################
(>&2 echo "Remediating rule 59/68: 'xccdf_org.ssgproject.content_rule_sshd_set_keepalive_0'")
# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
if [ -e "/etc/ssh/sshd_config" ] ; then
LC_ALL=C sed -i "/^\s*ClientAliveCountMax\s\+/Id" "/etc/ssh/sshd_config"
else
touch "/etc/ssh/sshd_config"
fi
# make sure file has newline at the end
sed -i -e '$a\' "/etc/ssh/sshd_config"
cp "/etc/ssh/sshd_config" "/etc/ssh/sshd_config.bak"
# Insert at the beginning of the file
printf '%s\n' "ClientAliveCountMax 0" > "/etc/ssh/sshd_config"
cat "/etc/ssh/sshd_config.bak" >> "/etc/ssh/sshd_config"
# Clean up after ourselves.
rm "/etc/ssh/sshd_config.bak"
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
# END fix for 'xccdf_org.ssgproject.content_rule_sshd_set_keepalive_0'
###############################################################################
# BEGIN fix (60 / 68) for 'xccdf_org.ssgproject.content_rule_sshd_set_idle_timeout'
###############################################################################
(>&2 echo "Remediating rule 60/68: 'xccdf_org.ssgproject.content_rule_sshd_set_idle_timeout'")
# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ] && { grep -qP "^ID=[\"']?rhel[\"']?$" "/etc/os-release" && { real="$(grep -P "^VERSION_ID=[\"']?[\w.]+[\"']?$" /etc/os-release | sed "s/^VERSION_ID=[\"']\?\([^\"']\+\)[\"']\?$/\1/")"; expected="8.5"; printf "%s\n%s" "$real" "$expected" | sort -VC; }; }; then
sshd_idle_timeout_value='300'
if [ -e "/etc/ssh/sshd_config" ] ; then
LC_ALL=C sed -i "/^\s*ClientAliveInterval\s\+/Id" "/etc/ssh/sshd_config"
else
touch "/etc/ssh/sshd_config"
fi
# make sure file has newline at the end
sed -i -e '$a\' "/etc/ssh/sshd_config"
cp "/etc/ssh/sshd_config" "/etc/ssh/sshd_config.bak"
# Insert at the beginning of the file
printf '%s\n' "ClientAliveInterval $sshd_idle_timeout_value" > "/etc/ssh/sshd_config"
cat "/etc/ssh/sshd_config.bak" >> "/etc/ssh/sshd_config"
# Clean up after ourselves.
rm "/etc/ssh/sshd_config.bak"
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
# END fix for 'xccdf_org.ssgproject.content_rule_sshd_set_idle_timeout'
###############################################################################
# BEGIN fix (61 / 68) for 'xccdf_org.ssgproject.content_rule_disable_host_auth'
###############################################################################
(>&2 echo "Remediating rule 61/68: 'xccdf_org.ssgproject.content_rule_disable_host_auth'")
# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
if [ -e "/etc/ssh/sshd_config" ] ; then
LC_ALL=C sed -i "/^\s*HostbasedAuthentication\s\+/Id" "/etc/ssh/sshd_config"
else
touch "/etc/ssh/sshd_config"
fi
# make sure file has newline at the end
sed -i -e '$a\' "/etc/ssh/sshd_config"
cp "/etc/ssh/sshd_config" "/etc/ssh/sshd_config.bak"
# Insert at the beginning of the file
printf '%s\n' "HostbasedAuthentication no" > "/etc/ssh/sshd_config"
cat "/etc/ssh/sshd_config.bak" >> "/etc/ssh/sshd_config"
# Clean up after ourselves.
rm "/etc/ssh/sshd_config.bak"
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
# END fix for 'xccdf_org.ssgproject.content_rule_disable_host_auth'
###############################################################################
# BEGIN fix (62 / 68) for 'xccdf_org.ssgproject.content_rule_firewalld_sshd_port_enabled'
###############################################################################
(>&2 echo "Remediating rule 62/68: 'xccdf_org.ssgproject.content_rule_firewalld_sshd_port_enabled'")
# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
if ! rpm -q --quiet "firewalld" ; then
yum install -y "firewalld"
fi
if ! rpm -q --quiet "NetworkManager" ; then
yum install -y "NetworkManager"
fi
firewalld_sshd_zone='public'
if systemctl is-active NetworkManager && systemctl is-active firewalld; then
# First make sure the SSH service is enabled in run-time for the proper zone.
# This is to avoid connection issues when new interfaces are addeded to this zone.
firewall-cmd --zone="$firewalld_sshd_zone" --add-service=ssh
# This will collect all NetworkManager connections names
readarray -t nm_connections < <(nmcli -f UUID,TYPE con | grep ethernet | awk '{ print $1 }')
# If the connection is not yet assigned to a firewalld zone, assign it to the proper zone.
# This will not change connections which are already assigned to any firewalld zone.
for connection in "${nm_connections[@]}"; do
current_zone=$(nmcli -f connection.zone connection show "$connection" | awk '{ print $2}')
if [ $current_zone = "--" ]; then
nmcli connection modify "$connection" connection.zone $firewalld_sshd_zone
fi
done
systemctl restart NetworkManager
# Active zones are zones with at least one interface assigned to it.
# It is possible that traffic is comming by any active interface and consequently any
# active zone. So, this make sure all active zones are permanently allowing SSH service.
readarray -t firewalld_active_zones < <(firewall-cmd --get-active-zones | grep -v interfaces)
for zone in "${firewalld_active_zones[@]}"; do
firewall-cmd --permanent --zone="$zone" --add-service=ssh
done
firewall-cmd --reload
else
echo "
firewalld and NetworkManager services are not active. Remediation aborted!
This remediation could not be applied because it depends on firewalld and NetworkManager services running.
The service is not started by this remediation in order to prevent connection issues."
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
# END fix for 'xccdf_org.ssgproject.content_rule_firewalld_sshd_port_enabled'
###############################################################################
# BEGIN fix (63 / 68) for 'xccdf_org.ssgproject.content_rule_sshd_allow_only_protocol2'
###############################################################################
(>&2 echo "Remediating rule 63/68: 'xccdf_org.ssgproject.content_rule_sshd_allow_only_protocol2'")
# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
# Strip any search characters in the key arg so that the key can be replaced without
# adding any search characters to the config file.
stripped_key=$(sed 's/[\^=\$,;+]*//g' <<< "^Protocol")
# shellcheck disable=SC2059
printf -v formatted_output "%s %s" "$stripped_key" "2"
# If the key exists, change it. Otherwise, add it to the config_file.
# We search for the key string followed by a word boundary (matched by \>),
# so if we search for 'setting', 'setting2' won't match.
if LC_ALL=C grep -q -m 1 -i -e "^Protocol\\>" "/etc/ssh/sshd_config"; then
escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
LC_ALL=C sed -i --follow-symlinks "s/^Protocol\\>.*/$escaped_formatted_output/gi" "/etc/ssh/sshd_config"
else
if [[ -s "/etc/ssh/sshd_config" ]] && [[ -n "$(tail -c 1 -- "/etc/ssh/sshd_config" || true)" ]]; then
LC_ALL=C sed -i --follow-symlinks '$a'\\ "/etc/ssh/sshd_config"
fi
cce="CCE-27320-1"
printf '# Per %s: Set %s in %s\n' "${cce}" "${formatted_output}" "/etc/ssh/sshd_config" >> "/etc/ssh/sshd_config"
printf '%s\n' "$formatted_output" >> "/etc/ssh/sshd_config"
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
# END fix for 'xccdf_org.ssgproject.content_rule_sshd_allow_only_protocol2'
###############################################################################
# BEGIN fix (64 / 68) for 'xccdf_org.ssgproject.content_rule_sshd_disable_empty_passwords'
###############################################################################
(>&2 echo "Remediating rule 64/68: 'xccdf_org.ssgproject.content_rule_sshd_disable_empty_passwords'")
# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
if [ -e "/etc/ssh/sshd_config" ] ; then
LC_ALL=C sed -i "/^\s*PermitEmptyPasswords\s\+/Id" "/etc/ssh/sshd_config"
else
touch "/etc/ssh/sshd_config"
fi
# make sure file has newline at the end
sed -i -e '$a\' "/etc/ssh/sshd_config"
cp "/etc/ssh/sshd_config" "/etc/ssh/sshd_config.bak"
# Insert at the beginning of the file
printf '%s\n' "PermitEmptyPasswords no" > "/etc/ssh/sshd_config"
cat "/etc/ssh/sshd_config.bak" >> "/etc/ssh/sshd_config"
# Clean up after ourselves.
rm "/etc/ssh/sshd_config.bak"
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
# END fix for 'xccdf_org.ssgproject.content_rule_sshd_disable_empty_passwords'
###############################################################################
# BEGIN fix (65 / 68) for 'xccdf_org.ssgproject.content_rule_sshd_disable_root_login'
###############################################################################
(>&2 echo "Remediating rule 65/68: 'xccdf_org.ssgproject.content_rule_sshd_disable_root_login'")
# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
if [ -e "/etc/ssh/sshd_config" ] ; then
LC_ALL=C sed -i "/^\s*PermitRootLogin\s\+/Id" "/etc/ssh/sshd_config"
else
touch "/etc/ssh/sshd_config"
fi
# make sure file has newline at the end
sed -i -e '$a\' "/etc/ssh/sshd_config"
cp "/etc/ssh/sshd_config" "/etc/ssh/sshd_config.bak"
# Insert at the beginning of the file
printf '%s\n' "PermitRootLogin no" > "/etc/ssh/sshd_config"
cat "/etc/ssh/sshd_config.bak" >> "/etc/ssh/sshd_config"
# Clean up after ourselves.
rm "/etc/ssh/sshd_config.bak"
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
# END fix for 'xccdf_org.ssgproject.content_rule_sshd_disable_root_login'
###############################################################################
# BEGIN fix (66 / 68) for 'xccdf_org.ssgproject.content_rule_sshd_do_not_permit_user_env'
###############################################################################
(>&2 echo "Remediating rule 66/68: 'xccdf_org.ssgproject.content_rule_sshd_do_not_permit_user_env'")
# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
if [ -e "/etc/ssh/sshd_config" ] ; then
LC_ALL=C sed -i "/^\s*PermitUserEnvironment\s\+/Id" "/etc/ssh/sshd_config"
else
touch "/etc/ssh/sshd_config"
fi
# make sure file has newline at the end
sed -i -e '$a\' "/etc/ssh/sshd_config"
cp "/etc/ssh/sshd_config" "/etc/ssh/sshd_config.bak"
# Insert at the beginning of the file
printf '%s\n' "PermitUserEnvironment no" > "/etc/ssh/sshd_config"
cat "/etc/ssh/sshd_config.bak" >> "/etc/ssh/sshd_config"
# Clean up after ourselves.
rm "/etc/ssh/sshd_config.bak"
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
# END fix for 'xccdf_org.ssgproject.content_rule_sshd_do_not_permit_user_env'
###############################################################################
# BEGIN fix (67 / 68) for 'xccdf_org.ssgproject.content_rule_sshd_enable_warning_banner'
###############################################################################
(>&2 echo "Remediating rule 67/68: 'xccdf_org.ssgproject.content_rule_sshd_enable_warning_banner'")
# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
if [ -e "/etc/ssh/sshd_config" ] ; then
LC_ALL=C sed -i "/^\s*Banner\s\+/Id" "/etc/ssh/sshd_config"
else
touch "/etc/ssh/sshd_config"
fi
# make sure file has newline at the end
sed -i -e '$a\' "/etc/ssh/sshd_config"
cp "/etc/ssh/sshd_config" "/etc/ssh/sshd_config.bak"
# Insert at the beginning of the file
printf '%s\n' "Banner /etc/issue" > "/etc/ssh/sshd_config"
cat "/etc/ssh/sshd_config.bak" >> "/etc/ssh/sshd_config"
# Clean up after ourselves.
rm "/etc/ssh/sshd_config.bak"
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
# END fix for 'xccdf_org.ssgproject.content_rule_sshd_enable_warning_banner'
###############################################################################
# BEGIN fix (68 / 68) for 'xccdf_org.ssgproject.content_rule_sshd_use_approved_ciphers'
###############################################################################
(>&2 echo "Remediating rule 68/68: 'xccdf_org.ssgproject.content_rule_sshd_use_approved_ciphers'")
# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
sshd_approved_ciphers='aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,3des-cbc,aes192-cbc,aes256-cbc,[email protected]'
# Strip any search characters in the key arg so that the key can be replaced without
# adding any search characters to the config file.
stripped_key=$(sed 's/[\^=\$,;+]*//g' <<< "^Ciphers")
# shellcheck disable=SC2059
printf -v formatted_output "%s %s" "$stripped_key" "$sshd_approved_ciphers"
# If the key exists, change it. Otherwise, add it to the config_file.
# We search for the key string followed by a word boundary (matched by \>),
# so if we search for 'setting', 'setting2' won't match.
if LC_ALL=C grep -q -m 1 -i -e "^Ciphers\\>" "/etc/ssh/sshd_config"; then
escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
LC_ALL=C sed -i --follow-symlinks "s/^Ciphers\\>.*/$escaped_formatted_output/gi" "/etc/ssh/sshd_config"
else
if [[ -s "/etc/ssh/sshd_config" ]] && [[ -n "$(tail -c 1 -- "/etc/ssh/sshd_config" || true)" ]]; then
LC_ALL=C sed -i --follow-symlinks '$a'\\ "/etc/ssh/sshd_config"
fi
cce="CCE-27295-5"
printf '# Per %s: Set %s in %s\n' "${cce}" "${formatted_output}" "/etc/ssh/sshd_config" >> "/etc/ssh/sshd_config"
printf '%s\n' "$formatted_output" >> "/etc/ssh/sshd_config"
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
# END fix for 'xccdf_org.ssgproject.content_rule_sshd_use_approved_ciphers'