contains 42 rules |
System SettingsgroupContains rules that check correct system settings. |
contains 30 rules |
Installing and Maintaining SoftwaregroupThe following sections contain information on
security-relevant choices during the initial operating system
installation process and the setup of software
updates. |
contains 11 rules |
SudogroupSudo , which stands for "su 'do'", provides the ability to delegate authority
to certain users, groups of users, or system administrators. When configured for system
users and/or groups, Sudo can allow a user or group to execute privileged commands
that normally only root is allowed to execute.
For more information on Sudo and addition Sudo configuration options, see
https://www.sudo.ws.
|
contains 2 rules |
Ensure Users Re-Authenticate for Privilege Escalation - sudo !authenticateruleThe sudo !authenticate option, when specified, allows a user to execute commands using
sudo without having to authenticate. This should be disabled by making sure that the
!authenticate option does not exist in /etc/sudoers configuration file or
any sudo configuration snippets in /etc/sudoers.d/ . Rationale:Without re-authentication, users may access resources or perform tasks for which they
do not have authorization.
When operating systems provide the capability to escalate a functional capability, it
is critical that the user re-authenticate. references:
1, 12, 15, 16, 5, 4.3.3.5.1, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, SR 1.1, SR 1.10, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.7, SR 1.8, SR 1.9, SRG-OS-000373-VMM-001470, SRG-OS-000373-VMM-001480, SRG-OS-000373-VMM-001490, IA-11, CM-6(a), SRG-OS-000373-GPOS-00156, SRG-OS-000373-GPOS-00157, SRG-OS-000373-GPOS-00158, A.18.1.4, A.9.2.1, A.9.2.2, A.9.2.3, A.9.2.4, A.9.2.6, A.9.3.1, A.9.4.2, A.9.4.3, PR.AC-1, PR.AC-7, OL08-00-010381, SV-248582r779312_rule, CCI-002038, DSS05.04, DSS05.10, DSS06.03, DSS06.10, BP28(R5), BP28(R59) Remediation script:
for f in /etc/sudoers /etc/sudoers.d/* ; do
if [ ! -e "$f" ] ; then
continue
fi
matching_list=$(grep -P '^(?!#).*[\s]+\!authenticate.*$' $f | uniq )
if ! test -z "$matching_list"; then
while IFS= read -r entry; do
# comment out "!authenticate" matches to preserve user data
sed -i "s/^${entry}$/# &/g" $f
done <<< "$matching_list"
/usr/sbin/visudo -cf $f &> /dev/null || echo "Fail to validate $f with visudo"
fi
done
Remediation script:- name: Find /etc/sudoers.d/ files
find:
paths:
- /etc/sudoers.d/
register: sudoers
tags:
- DISA-STIG-OL08-00-010381
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-11
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- sudo_remove_no_authenticate
- name: Remove lines containing !authenticate from sudoers files
replace:
regexp: (^(?!#).*[\s]+\!authenticate.*$)
replace: '# \g<1>'
path: '{{ item.path }}'
validate: /usr/sbin/visudo -cf %s
with_items:
- path: /etc/sudoers
- '{{ sudoers.files }}'
tags:
- DISA-STIG-OL08-00-010381
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-11
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- sudo_remove_no_authenticate
|
Ensure Users Re-Authenticate for Privilege Escalation - sudo NOPASSWDruleThe sudo NOPASSWD tag, when specified, allows a user to execute
commands using sudo without having to authenticate. This should be disabled
by making sure that the NOPASSWD tag does not exist in
/etc/sudoers configuration file or any sudo configuration snippets
in /etc/sudoers.d/ . Rationale:Without re-authentication, users may access resources or perform tasks for which they
do not have authorization.
When operating systems provide the capability to escalate a functional capability, it
is critical that the user re-authenticate. references:
1, 12, 15, 16, 5, 4.3.3.5.1, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, SR 1.1, SR 1.10, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.7, SR 1.8, SR 1.9, SRG-OS-000373-VMM-001470, SRG-OS-000373-VMM-001480, SRG-OS-000373-VMM-001490, IA-11, CM-6(a), SRG-OS-000373-GPOS-00156, SRG-OS-000373-GPOS-00157, SRG-OS-000373-GPOS-00158, A.18.1.4, A.9.2.1, A.9.2.2, A.9.2.3, A.9.2.4, A.9.2.6, A.9.3.1, A.9.4.2, A.9.4.3, PR.AC-1, PR.AC-7, OL08-00-010380, SV-248581r779309_rule, CCI-002038, DSS05.04, DSS05.10, DSS06.03, DSS06.10, BP28(R5), BP28(R59) Remediation script:
for f in /etc/sudoers /etc/sudoers.d/* ; do
if [ ! -e "$f" ] ; then
continue
fi
matching_list=$(grep -P '^(?!#).*[\s]+NOPASSWD[\s]*\:.*$' $f | uniq )
if ! test -z "$matching_list"; then
while IFS= read -r entry; do
# comment out "NOPASSWD" matches to preserve user data
sed -i "s/^${entry}$/# &/g" $f
done <<< "$matching_list"
/usr/sbin/visudo -cf $f &> /dev/null || echo "Fail to validate $f with visudo"
fi
done
Remediation script:- name: Find /etc/sudoers.d/ files
find:
paths:
- /etc/sudoers.d/
register: sudoers
tags:
- DISA-STIG-OL08-00-010380
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-11
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- sudo_remove_nopasswd
- name: Remove lines containing NOPASSWD from sudoers files
replace:
regexp: (^(?!#).*[\s]+NOPASSWD[\s]*\:.*$)
replace: '# \g<1>'
path: '{{ item.path }}'
validate: /usr/sbin/visudo -cf %s
with_items:
- path: /etc/sudoers
- '{{ sudoers.files }}'
tags:
- DISA-STIG-OL08-00-010380
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-11
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- sudo_remove_nopasswd
|
Updating SoftwaregroupThe yum command line tool is used to install and
update software packages. The system also provides a graphical
software update tool in the System menu, in the Administration submenu,
called Software Update.
Oracle Linux 8 systems contain an installed software catalog called
the RPM database, which records metadata of installed packages. Consistently using
yum or the graphical Software Update for all software installation
allows for insight into the current inventory of installed software on the system.
|
contains 9 rules |
Install dnf-automatic PackageruleThe dnf-automatic package can be installed with the following command:
$ sudo yum install dnf-automatic Rationale:dnf-automatic is an alternative command line interface (CLI)
to dnf upgrade suitable for automatic, regular execution. Remediation script:
if ! rpm -q --quiet "dnf-automatic" ; then
yum install -y "dnf-automatic"
fi
Remediation script:- name: Ensure dnf-automatic is installed
package:
name: dnf-automatic
state: present
tags:
- enable_strategy
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- package_dnf-automatic_installed
Remediation script:include install_dnf-automatic
class install_dnf-automatic {
package { 'dnf-automatic':
ensure => 'installed',
}
}
Remediation script:
package --add=dnf-automatic
Remediation script:
[[packages]]
name = "dnf-automatic"
version = "*"
|
Configure dnf-automatic to Install Available Updates AutomaticallyruleTo ensure that the packages comprising the available updates will be automatically installed by dnf-automatic , set apply_updates to yes under [commands] section in /etc/dnf/automatic.conf . Rationale:Installing software updates is a fundamental mitigation against
the exploitation of publicly-known vulnerabilities. If the most
recent security patches and updates are not installed, unauthorized
users may take advantage of weaknesses in the unpatched software. The
lack of prompt attention to patching could result in a system compromise.
The automated installation of updates ensures that recent security patches
are applied in a timely manner. references:
FMT_SMF_EXT.1, SI-2(5), CM-6(a), SI-2(c), SRG-OS-000191-GPOS-00080, 0940, 1144, 1467, 1472, 1483, 1493, 1494, 1495, BP28(R8) Remediation script:
found=false
# set value in all files if they contain section or key
for f in $(echo -n "/etc/dnf/automatic.conf"); do
if [ ! -e "$f" ]; then
continue
fi
# find key in section and change value
if grep -qzosP "[[:space:]]*\[commands\]([^\n\[]*\n+)+?[[:space:]]*apply_updates" "$f"; then
sed -i "s/apply_updates[^(\n)]*/apply_updates = yes/" "$f"
found=true
# find section and add key = value to it
elif grep -qs "[[:space:]]*\[commands\]" "$f"; then
sed -i "/[[:space:]]*commands/a apply_updates = yes" "$f"
found=true
fi
done
# if section not in any file, append section with key = value to FIRST file in files parameter
if ! $found ; then
file=$(echo "/etc/dnf/automatic.conf" | cut -f1 -d' ')
mkdir -p "$(dirname "$file")"
echo -e "[commands]\napply_updates = yes" >> "$file"
fi
Remediation script:- name: Configure dnf-automatic to Install Available Updates Automatically
ini_file:
dest: /etc/dnf/automatic.conf
section: commands
option: apply_updates
value: 'yes'
create: true
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-SI-2(5)
- NIST-800-53-SI-2(c)
- dnf-automatic_apply_updates
- low_complexity
- medium_disruption
- medium_severity
- no_reboot_needed
- unknown_strategy
|
Configure dnf-automatic to Install Only Security UpdatesruleTo configure dnf-automatic to install only security updates
automatically, set upgrade_type to security under
[commands] section in /etc/dnf/automatic.conf . Rationale:By default, dnf-automatic installs all available updates.
Reducing the amount of updated packages only to updates that were
issued as a part of a security advisory increases the system stability. Remediation script:
found=false
# set value in all files if they contain section or key
for f in $(echo -n "/etc/dnf/automatic.conf"); do
if [ ! -e "$f" ]; then
continue
fi
# find key in section and change value
if grep -qzosP "[[:space:]]*\[commands\]([^\n\[]*\n+)+?[[:space:]]*upgrade_type" "$f"; then
sed -i "s/upgrade_type[^(\n)]*/upgrade_type = security/" "$f"
found=true
# find section and add key = value to it
elif grep -qs "[[:space:]]*\[commands\]" "$f"; then
sed -i "/[[:space:]]*commands/a upgrade_type = security" "$f"
found=true
fi
done
# if section not in any file, append section with key = value to FIRST file in files parameter
if ! $found ; then
file=$(echo "/etc/dnf/automatic.conf" | cut -f1 -d' ')
mkdir -p "$(dirname "$file")"
echo -e "[commands]\nupgrade_type = security" >> "$file"
fi
Remediation script:- name: Configure dnf-automatic to Install Only Security Updates
ini_file:
dest: /etc/dnf/automatic.conf
section: commands
option: upgrade_type
value: security
create: true
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-SI-2(5)
- NIST-800-53-SI-2(c)
- dnf-automatic_security_updates_only
- low_complexity
- low_severity
- medium_disruption
- no_reboot_needed
- unknown_strategy
|
Ensure gpgcheck Enabled In Main yum ConfigurationruleThe gpgcheck option controls whether
RPM packages' signatures are always checked prior to installation.
To configure yum to check package signatures before installing
them, ensure the following line appears in /etc/yum.conf in
the [main] section:
gpgcheck=1 Rationale:Changes to any software components can have significant effects on the
overall security of the operating system. This requirement ensures the
software has not been tampered with and that it has been provided by a
trusted vendor.
Accordingly, patches, service packs, device drivers, or operating system
components must be signed with a certificate recognized and approved by the
organization.
Verifying the authenticity of the software prior to installation
validates the integrity of the patch or upgrade received from a vendor.
This ensures the software has not been tampered with and that it has been
provided by a trusted vendor. Self-signed certificates are disallowed by
this requirement. Certificates used to verify the software must be from an
approved Certificate Authority (CA). references:
11, 2, 3, 9, 164.308(a)(1)(ii)(D), 164.312(b), 164.312(c)(1), 164.312(c)(2), 164.312(e)(2)(i), SR 3.1, SR 3.3, SR 3.4, SR 3.8, SR 7.6, 3.4.8, SRG-OS-000366-GPOS-00153, PR.DS-6, PR.DS-8, PR.IP-1, OL08-00-010370, SV-248574r779288_rule, BP28(R15), 4.3.4.3.2, 4.3.4.3.3, 4.3.4.4.4, CM-5(3), SI-7, SC-12, SC-12(3), CM-6(a), SA-12, SA-12(10), CM-11(a), CM-11(b), 5.10.4.1, SRG-OS-000366-VMM-001430, SRG-OS-000370-VMM-001460, SRG-OS-000404-VMM-001650, Req-6.2, A.11.2.4, A.12.1.2, A.12.2.1, A.12.5.1, A.12.6.2, A.14.1.2, A.14.1.3, A.14.2.2, A.14.2.3, A.14.2.4, FPT_TUD_EXT.1, FPT_TUD_EXT.2, CCI-001749, APO01.06, BAI03.05, BAI06.01, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS06.02 Remediation script:# Remediation is applicable only in certain platforms
if rpm --quiet -q yum; then
# Test if the config_file is a symbolic link. If so, use --follow-symlinks with sed.
# Otherwise, regular sed command will do.
sed_command=('sed' '-i')
if test -L "/etc/yum.conf"; then
sed_command+=('--follow-symlinks')
fi
# 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
"${sed_command[@]}" "s/^gpgcheck\\>.*/$formatted_output/gi" "/etc/yum.conf"
else
# \n is precaution for case where file ends without trailing newline
printf '%s\n' "$formatted_output" >> "/etc/yum.conf"
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
Remediation script:- name: Gather the package facts
package_facts:
manager: auto
tags:
- CJIS-5.10.4.1
- DISA-STIG-OL08-00-010370
- NIST-800-171-3.4.8
- NIST-800-53-CM-11(a)
- NIST-800-53-CM-11(b)
- NIST-800-53-CM-5(3)
- NIST-800-53-CM-6(a)
- NIST-800-53-SA-12
- NIST-800-53-SA-12(10)
- NIST-800-53-SC-12
- NIST-800-53-SC-12(3)
- NIST-800-53-SI-7
- PCI-DSS-Req-6.2
- configure_strategy
- ensure_gpgcheck_globally_activated
- high_severity
- low_complexity
- medium_disruption
- no_reboot_needed
- name: Ensure GPG check is globally activated
ini_file:
dest: /etc/yum.conf
section: main
option: gpgcheck
value: 1
no_extra_spaces: true
create: false
when: '"yum" in ansible_facts.packages'
tags:
- CJIS-5.10.4.1
- DISA-STIG-OL08-00-010370
- NIST-800-171-3.4.8
- NIST-800-53-CM-11(a)
- NIST-800-53-CM-11(b)
- NIST-800-53-CM-5(3)
- NIST-800-53-CM-6(a)
- NIST-800-53-SA-12
- NIST-800-53-SA-12(10)
- NIST-800-53-SC-12
- NIST-800-53-SC-12(3)
- NIST-800-53-SI-7
- PCI-DSS-Req-6.2
- configure_strategy
- ensure_gpgcheck_globally_activated
- high_severity
- low_complexity
- medium_disruption
- no_reboot_needed
|
Ensure gpgcheck Enabled for Local Packagesruleyum should be configured to verify the signature(s) of local packages
prior to installation. To configure yum to verify signatures of local
packages, set the localpkg_gpgcheck to 1 in /etc/yum.conf . Rationale:Changes to any software components can have significant effects to the overall security
of the operating system. This requirement ensures the software has not been tampered and
has been provided by a trusted vendor.
Accordingly, patches, service packs, device drivers, or operating system components must
be signed with a certificate recognized and approved by the organization. references:
11, 3, 9, 164.308(a)(1)(ii)(D), 164.312(b), 164.312(c)(1), 164.312(c)(2), 164.312(e)(2)(i), 4.3.4.3.2, 4.3.4.3.3, SR 7.6, SRG-OS-000366-VMM-001430, SRG-OS-000370-VMM-001460, SRG-OS-000404-VMM-001650, 3.4.8, SRG-OS-000366-GPOS-00153, A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, PR.IP-1, FPT_TUD_EXT.1, FPT_TUD_EXT.2, CM-11(a), CM-11(b), CM-6(a), CM-5(3), SA-12, SA-12(10), OL08-00-010371, SV-248575r779291_rule, CCI-001749, BAI10.01, BAI10.02, BAI10.03, BAI10.05, BP28(R15) Remediation script:# Remediation is applicable only in certain platforms
if rpm --quiet -q yum; then
# Test if the config_file is a symbolic link. If so, use --follow-symlinks with sed.
# Otherwise, regular sed command will do.
sed_command=('sed' '-i')
if test -L "/etc/yum.conf"; then
sed_command+=('--follow-symlinks')
fi
# 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' <<< "^localpkg_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 "^localpkg_gpgcheck\\>" "/etc/yum.conf"; then
"${sed_command[@]}" "s/^localpkg_gpgcheck\\>.*/$formatted_output/gi" "/etc/yum.conf"
else
# \n is precaution for case where file ends without trailing newline
printf '%s\n' "$formatted_output" >> "/etc/yum.conf"
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
Remediation script:- name: Gather the package facts
package_facts:
manager: auto
tags:
- DISA-STIG-OL08-00-010371
- NIST-800-171-3.4.8
- NIST-800-53-CM-11(a)
- NIST-800-53-CM-11(b)
- NIST-800-53-CM-5(3)
- NIST-800-53-CM-6(a)
- NIST-800-53-SA-12
- NIST-800-53-SA-12(10)
- ensure_gpgcheck_local_packages
- high_severity
- low_complexity
- medium_disruption
- no_reboot_needed
- unknown_strategy
- name: Ensure GPG check Enabled for Local Packages (Yum)
ini_file:
dest: /etc/yum.conf
section: main
option: localpkg_gpgcheck
value: 1
no_extra_spaces: true
create: true
when: '"yum" in ansible_facts.packages'
tags:
- DISA-STIG-OL08-00-010371
- NIST-800-171-3.4.8
- NIST-800-53-CM-11(a)
- NIST-800-53-CM-11(b)
- NIST-800-53-CM-5(3)
- NIST-800-53-CM-6(a)
- NIST-800-53-SA-12
- NIST-800-53-SA-12(10)
- ensure_gpgcheck_local_packages
- high_severity
- low_complexity
- medium_disruption
- no_reboot_needed
- unknown_strategy
|
Ensure gpgcheck Enabled for All yum Package RepositoriesruleTo ensure signature checking is not disabled for
any repos, remove any lines from files in /etc/yum.repos.d of the form:
gpgcheck=0 Rationale:Verifying the authenticity of the software prior to installation validates
the integrity of the patch or upgrade received from a vendor. This ensures
the software has not been tampered with and that it has been provided by a
trusted vendor. Self-signed certificates are disallowed by this
requirement. Certificates used to verify the software must be from an
approved Certificate Authority (CA)." references:
11, 2, 3, 9, 164.308(a)(1)(ii)(D), 164.312(b), 164.312(c)(1), 164.312(c)(2), 164.312(e)(2)(i), SR 3.1, SR 3.3, SR 3.4, SR 3.8, SR 7.6, 3.4.8, SRG-OS-000366-GPOS-00153, PR.DS-6, PR.DS-8, PR.IP-1, BP28(R15), 4.3.4.3.2, 4.3.4.3.3, 4.3.4.4.4, CM-5(3), SI-7, SC-12, SC-12(3), CM-6(a), SA-12, SA-12(10), CM-11(a), CM-11(b), 5.10.4.1, SRG-OS-000366-VMM-001430, SRG-OS-000370-VMM-001460, SRG-OS-000404-VMM-001650, Req-6.2, A.11.2.4, A.12.1.2, A.12.2.1, A.12.5.1, A.12.6.2, A.14.1.2, A.14.1.3, A.14.2.2, A.14.2.3, A.14.2.4, FPT_TUD_EXT.1, FPT_TUD_EXT.2, CCI-001749, APO01.06, BAI03.05, BAI06.01, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS06.02 Remediation script:sed -i 's/gpgcheck\s*=.*/gpgcheck=1/g' /etc/yum.repos.d/*
Remediation script:- name: Grep for yum repo section names
shell: |
set -o pipefail
grep -HEr '^\[.+\]' -r /etc/yum.repos.d/
register: repo_grep_results
ignore_errors: true
changed_when: false
tags:
- CJIS-5.10.4.1
- NIST-800-171-3.4.8
- NIST-800-53-CM-11(a)
- NIST-800-53-CM-11(b)
- NIST-800-53-CM-5(3)
- NIST-800-53-CM-6(a)
- NIST-800-53-SA-12
- NIST-800-53-SA-12(10)
- NIST-800-53-SC-12
- NIST-800-53-SC-12(3)
- NIST-800-53-SI-7
- PCI-DSS-Req-6.2
- enable_strategy
- ensure_gpgcheck_never_disabled
- high_severity
- low_complexity
- medium_disruption
- no_reboot_needed
- name: Set gpgcheck=1 for each yum repo
ini_file:
path: '{{ item[0] }}'
section: '{{ item[1] }}'
option: gpgcheck
value: '1'
no_extra_spaces: true
loop: '{{ repo_grep_results.stdout | regex_findall( ''(.+\.repo):\[(.+)\]\n?'' )
}}'
tags:
- CJIS-5.10.4.1
- NIST-800-171-3.4.8
- NIST-800-53-CM-11(a)
- NIST-800-53-CM-11(b)
- NIST-800-53-CM-5(3)
- NIST-800-53-CM-6(a)
- NIST-800-53-SA-12
- NIST-800-53-SA-12(10)
- NIST-800-53-SC-12
- NIST-800-53-SC-12(3)
- NIST-800-53-SI-7
- PCI-DSS-Req-6.2
- enable_strategy
- ensure_gpgcheck_never_disabled
- high_severity
- low_complexity
- medium_disruption
- no_reboot_needed
|
Ensure Oracle Linux GPG Key InstalledruleTo ensure the system can cryptographically verify base software
packages come from Oracle (and to connect to the Unbreakable Linux Network to
receive them), the Oracle GPG key must properly be installed.
To install the Oracle GPG key, run:
$ sudo uln_register
If the system is not connected to the Internet,
then install the Oracle GPG key from trusted media such as
the Oracle installation CD-ROM or DVD. Assuming the disc is mounted
in /media/cdrom , use the following command as the root user to import
it into the keyring:
$ sudo rpm --import /media/cdrom/RPM-GPG-KEY-oracle
Alternatively, the key may be pre-loaded during the Oracle installation. In
such cases, the key can be installed by running the following command:
sudo rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-oracle Rationale:Changes to software components can have significant effects on the
overall security of the operating system. This requirement ensures
the software has not been tampered with and that it has been provided
by a trusted vendor. The Oracle GPG key is necessary to
cryptographically verify packages are from Oracle. references:
11, 2, 3, 9, 4.3.4.3.2, 4.3.4.3.3, 4.3.4.4.4, SR 3.1, SR 3.3, SR 3.4, SR 3.8, SR 7.6, APO01.06, BAI03.05, BAI06.01, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS06.02, CM-5(3), SI-7, SC-12, SC-12(3), CM-6(a), CM-11(a), CM-11(b), Req-6.2, A.11.2.4, A.12.1.2, A.12.2.1, A.12.5.1, A.12.6.2, A.14.1.2, A.14.1.3, A.14.2.2, A.14.2.3, A.14.2.4, PR.DS-6, PR.DS-8, PR.IP-1, CCI-001749, 1.2.2 Remediation script:# OL fingerprints below retrieved from Oracle Linux Yum Server "Frequently Asked Questions"
# https://yum.oracle.com/faq.html#a10
readonly OL_RELEASE_FINGERPRINT="76FD3DB13AB67410B89DB10E82562EA9AD986DA3"
readonly OL_AUXILIARY_FINGERPRINT=""
FINGERPRINTS_REGEX="${OL_RELEASE_FINGERPRINT}"
if [[ -n "$OL_AUXILIARY_FINGERPRINT" ]]; then
FINGERPRINTS_REGEX+="|${OL_AUXILIARY_FINGERPRINT}"
fi
# Location of the key we would like to import (once it's integrity verified)
readonly OL_RELEASE_KEY="/etc/pki/rpm-gpg/RPM-GPG-KEY-oracle"
RPM_GPG_DIR_PERMS=$(stat -c %a "$(dirname "$OL_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 "$OL_RELEASE_KEY" | grep "^fpr" | cut -d ":" -f 10)
GPG_RESULT=$?
# No CRC error, safe to proceed
if [ "${GPG_RESULT}" -eq "0" ]
then
# Filter just hexadecimal fingerprints from gpg's output from
# processing of a key file
echo "${GPG_OUT[*]}" | grep -vE "$FINGERPRINTS_REGEX" || {
# If $ OL_RELEASE_KEY file doesn't contain any keys with unknown fingerprint, import it
rpm --import "${OL_RELEASE_KEY}"
}
fi
fi
|
Ensure Software Patches Installedrule
If the system is joined to the ULN
or a yum server, run the following command to install updates:
$ sudo yum update
If the system is not configured to use one of these sources, updates (in the form of RPM packages)
can be manually downloaded from the ULN and installed using rpm .
NOTE: U.S. Defense systems are required to be patched within 30 days or sooner as local policy
dictates.warning
The OVAL feed of Oracle Linux 8 is not a XML file, which may not be understood by all scanners. Rationale:Installing software updates is a fundamental mitigation against
the exploitation of publicly-known vulnerabilities. If the most
recent security patches and updates are not installed, unauthorized
users may take advantage of weaknesses in the unpatched software. The
lack of prompt attention to patching could result in a system compromise. references:
18, 20, 4, 4.2.3, 4.2.3.12, 4.2.3.7, 4.2.3.9, 5.10.4.1, Req-6.2, SRG-OS-000480-VMM-002000, SI-2(5), SI-2(c), CM-6(a), SRG-OS-000480-GPOS-00227, A.12.6.1, A.14.2.3, A.16.1.3, A.18.2.2, A.18.2.3, ID.RA-1, PR.IP-12, FMT_MOF_EXT.1, OL08-00-010010, SV-248523r779135_rule, CCI-000366, CCI-001227, APO12.01, APO12.02, APO12.03, APO12.04, BAI03.10, DSS05.01, DSS05.02, BP28(R08) Remediation script:
yum -y update
Remediation script:- name: Security patches are up to date
package:
name: '*'
state: latest
tags:
- CJIS-5.10.4.1
- DISA-STIG-OL08-00-010010
- NIST-800-53-CM-6(a)
- NIST-800-53-SI-2(5)
- NIST-800-53-SI-2(c)
- PCI-DSS-Req-6.2
- high_disruption
- low_complexity
- medium_severity
- patch_strategy
- reboot_required
- security_patches_up_to_date
- skip_ansible_lint
|
Enable dnf-automatic Timerrule
The dnf-automatic timer can be enabled with the following command:
$ sudo systemctl enable dnf-automatic.timer Rationale:The dnf-automatic is an alternative command line interface (CLI) to dnf upgrade with specific facilities to make it suitable to be executed automatically and regularly from systemd timers, cron jobs and similar.
The tool is controlled by dnf-automatic.timer SystemD timer. Remediation script:
SYSTEMCTL_EXEC='/usr/bin/systemctl'
"$SYSTEMCTL_EXEC" start 'dnf-automatic.timer'
"$SYSTEMCTL_EXEC" enable 'dnf-automatic.timer'
Remediation script:- name: Enable timer dnf-automatic
block:
- name: Gather the package facts
package_facts:
manager: auto
- name: Enable timer dnf-automatic
systemd:
name: dnf-automatic.timer
enabled: 'yes'
state: started
when:
- '"dnf-automatic" in ansible_facts.packages'
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-SI-2(5)
- NIST-800-53-SI-2(c)
- enable_strategy
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- timer_dnf-automatic_enabled
|
Account and Access ControlgroupIn traditional Unix security, if an attacker gains
shell access to a certain login account, they can perform any action
or access any file to which that account has access. Therefore,
making it more difficult for unauthorized people to gain shell
access to accounts, particularly to privileged accounts, is a
necessary part of securing a system. This section introduces
mechanisms for restricting access to accounts under
Oracle Linux 8. |
contains 15 rules |
Protect Accounts by Configuring PAMgroupPAM, or Pluggable Authentication Modules, is a system
which implements modular authentication for Linux programs. PAM provides
a flexible and configurable architecture for authentication, and it should be configured
to minimize exposure to unnecessary risk. This section contains
guidance on how to accomplish that.
PAM is implemented as a set of shared objects which are
loaded and invoked whenever an application wishes to authenticate a
user. Typically, the application must be running as root in order
to take advantage of PAM, because PAM's modules often need to be able
to access sensitive stores of account information, such as /etc/shadow.
Traditional privileged network listeners
(e.g. sshd) or SUID programs (e.g. sudo) already meet this
requirement. An SUID root application, userhelper, is provided so
that programs which are not SUID or privileged themselves can still
take advantage of PAM.
PAM looks in the directory /etc/pam.d for
application-specific configuration information. For instance, if
the program login attempts to authenticate a user, then PAM's
libraries follow the instructions in the file /etc/pam.d/login
to determine what actions should be taken.
One very important file in /etc/pam.d is
/etc/pam.d/system-auth . This file, which is included by
many other PAM configuration files, defines 'default' system authentication
measures. Modifying this file is a good way to make far-reaching
authentication changes, for instance when implementing a
centralized authentication service. warning
Be careful when making changes to PAM's configuration files.
The syntax for these files is complex, and modifications can
have unexpected consequences. The default configurations shipped
with applications should be sufficient for most users. |
contains 11 rules |
Set Lockouts for Failed Password AttemptsgroupThe pam_faillock PAM module provides the capability to
lock out user accounts after a number of failed login attempts. Its
documentation is available in
/usr/share/doc/pam-VERSION/txts/README.pam_faillock .
warning
Locking out user accounts presents the
risk of a denial-of-service attack. The lockout policy
must weigh whether the risk of such a
denial-of-service attack outweighs the benefits of thwarting
password guessing attacks. |
contains 5 rules |
Limit Password ReuseruleDo not allow users to reuse recent passwords. This can be
accomplished by using the remember option for the pam_unix
or pam_pwhistory PAM modules.
In the file /etc/pam.d/system-auth , append remember=2
to the line which refers to the pam_unix.so or pam_pwhistory.so module, as shown below:
The DoD STIG requirement is 5 passwords.warning
If the system relies on authselect tool to manage PAM settings, the remediation
will also use authselect tool. However, if any manual modification was made in
PAM files, the authselect integrity check will fail and the remediation will be
aborted in order to preserve intentional changes. In this case, an informative message will
be shown in the remediation report. Rationale:Preventing re-use of previous passwords helps ensure that a compromised password is not re-used by a user. references:
1, 12, 15, 16, 5, 4.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.2, 4.3.3.7.4, SR 1.1, SR 1.10, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.7, SR 1.8, SR 1.9, SR 2.1, 5.6.2.1.1, SRG-OS-000077-GPOS-00045, SRG-OS-000077-VMM-000440, 3.5.8, Req-8.2.5, A.18.1.4, A.7.1.1, A.9.2.1, A.9.2.2, A.9.2.3, A.9.2.4, A.9.2.6, A.9.3.1, A.9.4.2, A.9.4.3, PR.AC-1, PR.AC-6, PR.AC-7, IA-5(f), IA-5(1)(e), CCI-000200, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.10, BP28(R18) Remediation script:# Remediation is applicable only in certain platforms
if rpm --quiet -q pam; then
var_password_pam_unix_remember='2'
if [ -f /usr/bin/authselect ]; then
if authselect check; then
CURRENT_PROFILE=$(authselect current -r | awk '{ print $1 }')
# Standard profiles delivered with authselect should not be modified.
# 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"
# Ensure a backup before changing the profile
authselect apply-changes -b --backup=before-pwhistory-hardening.backup
authselect select $CURRENT_PROFILE
for feature in $ENABLED_FEATURES; do
authselect enable-feature $feature;
done
fi
# Include the desired configuration in the custom profile
CUSTOM_SYSTEM_AUTH="/etc/authselect/$CURRENT_PROFILE/system-auth"
CUSTOM_PASSWORD_AUTH="/etc/authselect/$CURRENT_PROFILE/password-auth"
for custom_pam_file in $CUSTOM_SYSTEM_AUTH $CUSTOM_PASSWORD_AUTH; do
if ! grep -q "^[^#].*pam_pwhistory.so.*remember=" $custom_pam_file; then
sed -i --follow-symlinks "/^password.*requisite.*pam_pwquality.so/a password requisite pam_pwhistory.so remember=$var_password_pam_unix_remember use_authtok" $custom_pam_file
else
sed -i --follow-symlinks "s/\(.*pam_pwhistory.so.*remember=\)[[:digit:]]\+\s\(.*\)/\1$var_password_pam_unix_remember \2/g" $custom_pam_file
fi
done
authselect apply-changes -b --backup=after-pwhistory-hardening.backup
else
echo "
authselect integrity check failed. Remediation aborted!
This remediation could not be applied because the authselect profile is not intact.
It is not recommended to manually edit the PAM files when authselect is available
In cases where the default authselect profile does not cover a specific demand, a custom authselect profile is recommended."
false
fi
else
AUTH_FILES[0]="/etc/pam.d/system-auth"
AUTH_FILES[1]="/etc/pam.d/password-auth"
for pamFile in "${AUTH_FILES[@]}"; do
if grep -q "pam_unix.so.*" $pamFile; then
if [ -e "$pamFile" ] ; then
valueRegex="$var_password_pam_unix_remember" defaultValue="$var_password_pam_unix_remember"
# 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+sufficient\\s+pam_unix.so(\\s.+)?\\s+remember(?"'!'"${valueRegex}(\\s|\$))" < "$pamFile" ; then
sed --follow-symlinks -i -E -e "s/^(\\s*password\\s+sufficient\\s+pam_unix.so(\\s.+)?\\s)remember=[^[:space:]]*/\\1remember${defaultValue}/" "$pamFile"
# add 'option=default' if option is not set
elif grep -q -E "^\\s*password\\s+sufficient\\s+pam_unix.so" < "$pamFile" &&
grep -E "^\\s*password\\s+sufficient\\s+pam_unix.so" < "$pamFile" | grep -q -E -v "\\sremember(=|\\s|\$)" ; then
sed --follow-symlinks -i -E -e "s/^(\\s*password\\s+sufficient\\s+pam_unix.so[^\\n]*)/\\1 remember${defaultValue}/" "$pamFile"
# add a new entry if none exists
elif ! grep -q -P "^\\s*password\\s+sufficient\\s+pam_unix.so(\\s.+)?\\s+remember${valueRegex}(\\s|\$)" < "$pamFile" ; then
echo "password sufficient pam_unix.so remember${defaultValue}" >> "$pamFile"
fi
else
echo "$pamFile doesn't exist" >&2
fi
fi
if grep -q "pam_pwhistory.so.*" $pamFile; then
if [ -e "$pamFile" ] ; then
valueRegex="$var_password_pam_unix_remember" defaultValue="$var_password_pam_unix_remember"
# 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+required\\s+pam_pwhistory.so(\\s.+)?\\s+remember(?"'!'"${valueRegex}(\\s|\$))" < "$pamFile" ; then
sed --follow-symlinks -i -E -e "s/^(\\s*password\\s+required\\s+pam_pwhistory.so(\\s.+)?\\s)remember=[^[:space:]]*/\\1remember${defaultValue}/" "$pamFile"
# add 'option=default' if option is not set
elif grep -q -E "^\\s*password\\s+required\\s+pam_pwhistory.so" < "$pamFile" &&
grep -E "^\\s*password\\s+required\\s+pam_pwhistory.so" < "$pamFile" | grep -q -E -v "\\sremember(=|\\s|\$)" ; then
sed --follow-symlinks -i -E -e "s/^(\\s*password\\s+required\\s+pam_pwhistory.so[^\\n]*)/\\1 remember${defaultValue}/" "$pamFile"
# add a new entry if none exists
elif ! grep -q -P "^\\s*password\\s+required\\s+pam_pwhistory.so(\\s.+)?\\s+remember${valueRegex}(\\s|\$)" < "$pamFile" ; then
echo "password required pam_pwhistory.so remember${defaultValue}" >> "$pamFile"
fi
else
echo "$pamFile doesn't exist" >&2
fi
fi
done
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
Remediation script:- name: Gather the package facts
package_facts:
manager: auto
tags:
- CJIS-5.6.2.1.1
- NIST-800-171-3.5.8
- NIST-800-53-IA-5(1)(e)
- NIST-800-53-IA-5(f)
- PCI-DSS-Req-8.2.5
- accounts_password_pam_unix_remember
- configure_strategy
- low_complexity
- medium_disruption
- medium_severity
- no_reboot_needed
- name: XCCDF Value var_password_pam_unix_remember # promote to variable
set_fact:
var_password_pam_unix_remember: !!str 2
tags:
- always
- name: Check if system relies on authselect
ansible.builtin.stat:
path: /usr/bin/authselect
register: result_authselect_present
when: '"pam" in ansible_facts.packages'
tags:
- CJIS-5.6.2.1.1
- NIST-800-171-3.5.8
- NIST-800-53-IA-5(1)(e)
- NIST-800-53-IA-5(f)
- PCI-DSS-Req-8.2.5
- accounts_password_pam_unix_remember
- configure_strategy
- low_complexity
- medium_disruption
- medium_severity
- no_reboot_needed
- name: Check the integrity of the current authselect profile
ansible.builtin.command:
cmd: authselect check
register: result_authselect_check_cmd
changed_when: false
ignore_errors: true
when:
- '"pam" in ansible_facts.packages'
- result_authselect_present.stat.exists
tags:
- CJIS-5.6.2.1.1
- NIST-800-171-3.5.8
- NIST-800-53-IA-5(1)(e)
- NIST-800-53-IA-5(f)
- PCI-DSS-Req-8.2.5
- accounts_password_pam_unix_remember
- configure_strategy
- low_complexity
- medium_disruption
- medium_severity
- no_reboot_needed
- name: Informative message based on the authselect integrity check result
ansible.builtin.assert:
that:
- result_authselect_check_cmd is success
fail_msg:
- authselect integrity check failed. Remediation aborted!
- This remediation could not be applied because the authselect profile is not
intact.
- It is not recommended to manually edit the PAM files when authselect is available
- In cases where the default authselect profile does not cover a specific demand,
a custom authselect profile is recommended.
success_msg:
- authselect integrity check passed
when: '"pam" in ansible_facts.packages'
tags:
- CJIS-5.6.2.1.1
- NIST-800-171-3.5.8
- NIST-800-53-IA-5(1)(e)
- NIST-800-53-IA-5(f)
- PCI-DSS-Req-8.2.5
- accounts_password_pam_unix_remember
- configure_strategy
- low_complexity
- medium_disruption
- medium_severity
- no_reboot_needed
- name: Get authselect current profile
ansible.builtin.shell:
cmd: authselect current -r | awk '{ print $1 }'
register: result_authselect_profile
changed_when: false
when:
- '"pam" in ansible_facts.packages'
- result_authselect_present.stat.exists
- result_authselect_check_cmd is success
tags:
- CJIS-5.6.2.1.1
- NIST-800-171-3.5.8
- NIST-800-53-IA-5(1)(e)
- NIST-800-53-IA-5(f)
- PCI-DSS-Req-8.2.5
- accounts_password_pam_unix_remember
- configure_strategy
- low_complexity
- medium_disruption
- medium_severity
- no_reboot_needed
- name: Define the current authselect profile as a local fact
ansible.builtin.set_fact:
authselect_current_profile: '{{ result_authselect_profile.stdout }}'
authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
when:
- '"pam" in ansible_facts.packages'
- result_authselect_profile is not skipped
- result_authselect_profile.stdout is match("custom/")
tags:
- CJIS-5.6.2.1.1
- NIST-800-171-3.5.8
- NIST-800-53-IA-5(1)(e)
- NIST-800-53-IA-5(f)
- PCI-DSS-Req-8.2.5
- accounts_password_pam_unix_remember
- configure_strategy
- low_complexity
- medium_disruption
- medium_severity
- no_reboot_needed
- name: Define the new authselect custom profile as a local fact
ansible.builtin.set_fact:
authselect_current_profile: '{{ result_authselect_profile.stdout }}'
authselect_custom_profile: custom/hardening
when:
- '"pam" in ansible_facts.packages'
- result_authselect_profile is not skipped
- result_authselect_profile.stdout is not match("custom/")
tags:
- CJIS-5.6.2.1.1
- NIST-800-171-3.5.8
- NIST-800-53-IA-5(1)(e)
- NIST-800-53-IA-5(f)
- PCI-DSS-Req-8.2.5
- accounts_password_pam_unix_remember
- configure_strategy
- low_complexity
- medium_disruption
- medium_severity
- no_reboot_needed
- name: Get authselect current features to also enable them in the custom profile
ansible.builtin.shell:
cmd: authselect current | tail -n+3 | awk '{ print $2 }'
register: result_authselect_features
changed_when: false
when:
- '"pam" in ansible_facts.packages'
- result_authselect_profile is not skipped
- authselect_current_profile is not match("custom/")
tags:
- CJIS-5.6.2.1.1
- NIST-800-171-3.5.8
- NIST-800-53-IA-5(1)(e)
- NIST-800-53-IA-5(f)
- PCI-DSS-Req-8.2.5
- accounts_password_pam_unix_remember
- configure_strategy
- low_complexity
- medium_disruption
- medium_severity
- no_reboot_needed
- name: Check if any custom profile with the same name was already created in the
past
ansible.builtin.stat:
path: /etc/authselect/{{ authselect_custom_profile }}
register: result_authselect_custom_profile_present
changed_when: false
when:
- '"pam" in ansible_facts.packages'
- result_authselect_present.stat.exists
- authselect_current_profile is not match("custom/")
tags:
- CJIS-5.6.2.1.1
- NIST-800-171-3.5.8
- NIST-800-53-IA-5(1)(e)
- NIST-800-53-IA-5(f)
- PCI-DSS-Req-8.2.5
- accounts_password_pam_unix_remember
- configure_strategy
- low_complexity
- medium_disruption
- medium_severity
- no_reboot_needed
- name: Create a custom profile based on the current profile
ansible.builtin.command:
cmd: authselect create-profile hardening -b sssd
register: result_authselect_create_profile
when:
- '"pam" in ansible_facts.packages'
- result_authselect_present.stat.exists
- result_authselect_check_cmd is success
- authselect_current_profile is not match("custom/")
- not result_authselect_custom_profile_present.stat.exists
tags:
- CJIS-5.6.2.1.1
- NIST-800-171-3.5.8
- NIST-800-53-IA-5(1)(e)
- NIST-800-53-IA-5(f)
- PCI-DSS-Req-8.2.5
- accounts_password_pam_unix_remember
- configure_strategy
- low_complexity
- medium_disruption
- medium_severity
- no_reboot_needed
- name: Ensure the desired configuration is updated in the custom profile
ansible.builtin.replace:
dest: '{{ item }}'
regexp: (.*pam_pwhistory.so.*remember=)(\S+)(.*)$
replace: \g<1>{{ var_password_pam_unix_remember }}\g<3>
loop:
- /etc/authselect/{{ authselect_custom_profile }}/system-auth
- /etc/authselect/{{ authselect_custom_profile }}/password-auth
when:
- '"pam" in ansible_facts.packages'
- result_authselect_profile is not skipped
- authselect_custom_profile is match("custom/")
tags:
- CJIS-5.6.2.1.1
- NIST-800-171-3.5.8
- NIST-800-53-IA-5(1)(e)
- NIST-800-53-IA-5(f)
- PCI-DSS-Req-8.2.5
- accounts_password_pam_unix_remember
- configure_strategy
- low_complexity
- medium_disruption
- medium_severity
- no_reboot_needed
- name: Ensure the desired configuration in present in the custom profile
ansible.builtin.lineinfile:
dest: '{{ item }}'
insertafter: ^password.*requisite.*pam_pwquality.so.*
line: password requisite pam_pwhistory.so remember={{ var_password_pam_unix_remember
}} use_authtok
loop:
- /etc/authselect/{{ authselect_custom_profile }}/system-auth
- /etc/authselect/{{ authselect_custom_profile }}/password-auth
when:
- '"pam" in ansible_facts.packages'
- result_authselect_profile is not skipped
- authselect_custom_profile is match("custom/")
tags:
- CJIS-5.6.2.1.1
- NIST-800-171-3.5.8
- NIST-800-53-IA-5(1)(e)
- NIST-800-53-IA-5(f)
- PCI-DSS-Req-8.2.5
- accounts_password_pam_unix_remember
- configure_strategy
- low_complexity
- medium_disruption
- medium_severity
- no_reboot_needed
- name: Ensure a backup of current authselect profile before select the custom profile
ansible.builtin.command:
cmd: authselect apply-changes -b --backup=before-pwhistory-hardening.backup
register: result_authselect_backup
when:
- '"pam" in ansible_facts.packages'
- result_authselect_check_cmd is success
- result_authselect_profile is not skipped
- authselect_current_profile is not match("custom/")
- authselect_custom_profile is not match(authselect_current_profile)
tags:
- CJIS-5.6.2.1.1
- NIST-800-171-3.5.8
- NIST-800-53-IA-5(1)(e)
- NIST-800-53-IA-5(f)
- PCI-DSS-Req-8.2.5
- accounts_password_pam_unix_remember
- configure_strategy
- low_complexity
- medium_disruption
- medium_severity
- no_reboot_needed
- name: Ensure the custom profile is selected
ansible.builtin.command:
cmd: authselect select {{ authselect_custom_profile }} --force
register: result_pam_authselect_select_profile
when:
- '"pam" in ansible_facts.packages'
- result_authselect_check_cmd is success
- result_authselect_profile is not skipped
- authselect_current_profile is not match("custom/")
- authselect_custom_profile is not match(authselect_current_profile)
tags:
- CJIS-5.6.2.1.1
- NIST-800-171-3.5.8
- NIST-800-53-IA-5(1)(e)
- NIST-800-53-IA-5(f)
- PCI-DSS-Req-8.2.5
- accounts_password_pam_unix_remember
- configure_strategy
- low_complexity
- medium_disruption
- medium_severity
- no_reboot_needed
- name: Restore the authselect features in the custom profile
ansible.builtin.command:
cmd: authselect enable-feature {{ item }}
register: result_pam_authselect_select_features
loop: '{{ result_authselect_features.stdout_lines }}'
when:
- '"pam" in ansible_facts.packages'
- result_authselect_profile is not skipped
- result_authselect_features is not skipped
- result_pam_authselect_select_profile is not skipped
tags:
- CJIS-5.6.2.1.1
- NIST-800-171-3.5.8
- NIST-800-53-IA-5(1)(e)
- NIST-800-53-IA-5(f)
- PCI-DSS-Req-8.2.5
- accounts_password_pam_unix_remember
- configure_strategy
- low_complexity
- medium_disruption
- medium_severity
- no_reboot_needed
- name: Ensure the custom profile changes are applied
ansible.builtin.command:
cmd: authselect apply-changes -b --backup=after-pwhistory-hardening.backup
when:
- '"pam" in ansible_facts.packages'
- result_authselect_check_cmd is success
- result_authselect_profile is not skipped
tags:
- CJIS-5.6.2.1.1
- NIST-800-171-3.5.8
- NIST-800-53-IA-5(1)(e)
- NIST-800-53-IA-5(f)
- PCI-DSS-Req-8.2.5
- accounts_password_pam_unix_remember
- configure_strategy
- low_complexity
- medium_disruption
- medium_severity
- no_reboot_needed
- name: Do not allow users to reuse recent passwords - system-auth (change)
replace:
dest: /etc/pam.d/system-auth
regexp: ^(password\s+sufficient\s+pam_unix\.so\s.*remember\s*=\s*)(\S+)(.*)$
replace: \g<1>{{ var_password_pam_unix_remember }}\g<3>
when:
- '"pam" in ansible_facts.packages'
- not result_authselect_present.stat.exists
tags:
- CJIS-5.6.2.1.1
- NIST-800-171-3.5.8
- NIST-800-53-IA-5(1)(e)
- NIST-800-53-IA-5(f)
- PCI-DSS-Req-8.2.5
- accounts_password_pam_unix_remember
- configure_strategy
- low_complexity
- medium_disruption
- medium_severity
- no_reboot_needed
- name: Do not allow users to reuse recent passwords - system-auth (add)
replace:
dest: /etc/pam.d/system-auth
regexp: ^password\s+sufficient\s+pam_unix\.so\s(?!.*remember\s*=\s*).*$
replace: \g<0> remember={{ var_password_pam_unix_remember }}
when:
- '"pam" in ansible_facts.packages'
- not result_authselect_present.stat.exists
tags:
- CJIS-5.6.2.1.1
- NIST-800-171-3.5.8
- NIST-800-53-IA-5(1)(e)
- NIST-800-53-IA-5(f)
- PCI-DSS-Req-8.2.5
- accounts_password_pam_unix_remember
- configure_strategy
- low_complexity
- medium_disruption
- medium_severity
- no_reboot_needed
- name: Do not allow users to reuse recent passwords - system-auth (change)
replace:
dest: /etc/pam.d/system-auth
regexp: ^(password\s+(?:(?:requisite)|(?:required))\s+pam_pwhistory\.so\s.*remember\s*=\s*)(\S+)(.*)$
replace: \g<1>{{ var_password_pam_unix_remember }}\g<3>
when:
- '"pam" in ansible_facts.packages'
- not result_authselect_present.stat.exists
tags:
- CJIS-5.6.2.1.1
- NIST-800-171-3.5.8
- NIST-800-53-IA-5(1)(e)
- NIST-800-53-IA-5(f)
- PCI-DSS-Req-8.2.5
- accounts_password_pam_unix_remember
- configure_strategy
- low_complexity
- medium_disruption
- medium_severity
- no_reboot_needed
- name: Do not allow users to reuse recent passwords - system-auth (add)
replace:
dest: /etc/pam.d/system-auth
regexp: ^password\s+(?:(?:requisite)|(?:required))\s+pam_pwhistory\.so\s(?!.*remember\s*=\s*).*$
replace: \g<0> remember={{ var_password_pam_unix_remember }}
when:
- '"pam" in ansible_facts.packages'
- not result_authselect_present.stat.exists
tags:
- CJIS-5.6.2.1.1
- NIST-800-171-3.5.8
- NIST-800-53-IA-5(1)(e)
- NIST-800-53-IA-5(f)
- PCI-DSS-Req-8.2.5
- accounts_password_pam_unix_remember
- configure_strategy
- low_complexity
- medium_disruption
- medium_severity
- no_reboot_needed
|
Lock Accounts After Failed Password AttemptsruleThis rule configures the system to lock out accounts after a number of incorrect login attempts
using pam_faillock.so .
pam_faillock.so module requires multiple entries in pam files. These entries must be carefully
defined to work as expected. In order to avoid any errors when manually editing these files,
it is recommended to use the appropriate tools, such as authselect or authconfig ,
depending on the OS version. warning
If the system relies on authselect tool to manage PAM settings, the remediation
will also use authselect tool. However, if any manual modification was made in
PAM files, the authselect integrity check will fail and the remediation will be
aborted in order to preserve intentional changes. In this case, an informative message will
be shown in the remediation report.
If the system supports the /etc/security/faillock.conf file, the pam_faillock
parameters should be defined in faillock.conf file. Rationale:Locking out user accounts after a number of incorrect attempts prevents direct password
guessing attacks. In combination with the silent option, user enumeration attacks
are also mitigated. references:
1, 12, 15, 16, SR 1.1, SR 1.10, SR 1.2, SR 1.5, SR 1.7, SR 1.8, SR 1.9, 3.1.8, SRG-OS-000329-GPOS-00128, SRG-OS-000021-GPOS-00005, PR.AC-7, OL08-00-020010, SV-248652r779522_rule, BP28(R18), 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, CM-6(a), AC-7(a), 0421, 0422, 0431, 0974, 1173, 1401, 1504, 1505, 1546, 1557, 1558, 1559, 1560, 1561, 5.5.3, SRG-OS-000021-VMM-000050, Req-8.1.6, A.18.1.4, A.9.2.1, A.9.2.4, A.9.3.1, A.9.4.2, A.9.4.3, FIA_AFL.1, CCI-000044, CCI-002236, CCI-002237, CCI-002238, DSS05.04, DSS05.10, DSS06.10 Remediation script:# Remediation is applicable only in certain platforms
if rpm --quiet -q pam; then
var_accounts_passwords_pam_faillock_deny='3'
if [ -f /usr/bin/authselect ]; then
if authselect check; then
authselect enable-feature with-faillock
authselect apply-changes
else
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."
false
fi
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.*sufficient.*pam_unix.so.*/a 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
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*\)\([0-9]\+\)/\1'"$var_accounts_passwords_pam_faillock_deny"'/g' $FAILLOCK_CONF
fi
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.*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
Remediation script:- name: Gather the package facts
package_facts:
manager: auto
tags:
- CJIS-5.5.3
- DISA-STIG-OL08-00-020010
- NIST-800-171-3.1.8
- NIST-800-53-AC-7(a)
- NIST-800-53-CM-6(a)
- PCI-DSS-Req-8.1.6
- accounts_passwords_pam_faillock_deny
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Lock Accounts After Failed Password Attempts - Check if system relies on authselect
tool
ansible.builtin.stat:
path: /usr/bin/authselect
register: result_authselect_present
when: '"pam" in ansible_facts.packages'
tags:
- CJIS-5.5.3
- DISA-STIG-OL08-00-020010
- NIST-800-171-3.1.8
- NIST-800-53-AC-7(a)
- NIST-800-53-CM-6(a)
- PCI-DSS-Req-8.1.6
- accounts_passwords_pam_faillock_deny
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Lock Accounts After Failed Password Attempts - Remediation where authselect
tool is present
block:
- name: Lock Accounts After Failed Password Attempts - Check integrity of authselect
current profile
ansible.builtin.command:
cmd: authselect check
register: result_authselect_check_cmd
changed_when: false
ignore_errors: true
- name: Lock Accounts After Failed Password Attempts - Informative message based
on the authselect integrity check result
ansible.builtin.assert:
that:
- result_authselect_check_cmd is success
fail_msg:
- 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.
success_msg:
- authselect integrity check passed
- name: Lock Accounts After Failed Password Attempts - Get authselect current
features
ansible.builtin.shell:
cmd: authselect current | tail -n+3 | awk '{ print $2 }'
register: result_authselect_features
changed_when: false
when:
- result_authselect_check_cmd is success
- name: Lock Accounts After Failed Password Attempts - Ensure with-faillock feature
is enabled using authselect tool
ansible.builtin.command:
cmd: authselect enable-feature with-faillock
register: result_authselect_cmd
when:
- result_authselect_check_cmd is success
- result_authselect_features.stdout is not search("with-faillock")
when:
- '"pam" in ansible_facts.packages'
- result_authselect_present.stat.exists
tags:
- CJIS-5.5.3
- DISA-STIG-OL08-00-020010
- NIST-800-171-3.1.8
- NIST-800-53-AC-7(a)
- NIST-800-53-CM-6(a)
- PCI-DSS-Req-8.1.6
- accounts_passwords_pam_faillock_deny
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Lock Accounts After Failed Password Attempts - Remediation where authselect
tool is not present
block:
- name: Lock Accounts After Failed Password Attempts - Check if pam_faillock.so
is already enabled
ansible.builtin.lineinfile:
path: /etc/pam.d/system-auth
regexp: .*auth.*pam_faillock.so (preauth|authfail)
state: absent
check_mode: true
changed_when: false
register: result_pam_faillock_is_enabled
- name: Lock Accounts After Failed Password Attempts - Enable pam_faillock.so
preauth editing PAM files
ansible.builtin.lineinfile:
path: '{{ item }}'
line: auth required pam_faillock.so preauth
insertbefore: ^auth.*sufficient.*pam_unix.so.*
state: present
loop:
- /etc/pam.d/system-auth
- /etc/pam.d/password-auth
when:
- result_pam_faillock_is_enabled.found == 0
- name: Lock Accounts After Failed Password Attempts - Enable pam_faillock.so
authfail editing PAM files
ansible.builtin.lineinfile:
path: '{{ item }}'
line: auth required pam_faillock.so authfail
insertafter: ^auth.*sufficient.*pam_unix.so.*
state: present
loop:
- /etc/pam.d/system-auth
- /etc/pam.d/password-auth
when:
- result_pam_faillock_is_enabled.found == 0
- name: Lock Accounts After Failed Password Attempts - Enable pam_faillock.so
account section editing PAM files
ansible.builtin.lineinfile:
path: '{{ item }}'
line: account required pam_faillock.so
insertbefore: ^account.*required.*pam_unix.so.*
state: present
loop:
- /etc/pam.d/system-auth
- /etc/pam.d/password-auth
when:
- result_pam_faillock_is_enabled.found == 0
when:
- '"pam" in ansible_facts.packages'
- not result_authselect_present.stat.exists
tags:
- CJIS-5.5.3
- DISA-STIG-OL08-00-020010
- NIST-800-171-3.1.8
- NIST-800-53-AC-7(a)
- NIST-800-53-CM-6(a)
- PCI-DSS-Req-8.1.6
- accounts_passwords_pam_faillock_deny
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: XCCDF Value var_accounts_passwords_pam_faillock_deny # promote to variable
set_fact:
var_accounts_passwords_pam_faillock_deny: !!str 3
tags:
- always
- name: Lock Accounts After Failed Password Attempts - Check the presence of /etc/security/faillock.conf
file
ansible.builtin.stat:
path: /etc/security/faillock.conf
register: result_faillock_conf_check
when: '"pam" in ansible_facts.packages'
tags:
- CJIS-5.5.3
- DISA-STIG-OL08-00-020010
- NIST-800-171-3.1.8
- NIST-800-53-AC-7(a)
- NIST-800-53-CM-6(a)
- PCI-DSS-Req-8.1.6
- accounts_passwords_pam_faillock_deny
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Lock Accounts After Failed Password Attempts - Ensure the pam_faillock.so
deny parameter in /etc/security/faillock.conf
ansible.builtin.lineinfile:
path: /etc/security/faillock.conf
regexp: ^\s*deny\s*=
line: deny = {{ var_accounts_passwords_pam_faillock_deny }}
state: present
when:
- '"pam" in ansible_facts.packages'
- result_faillock_conf_check.stat.exists
tags:
- CJIS-5.5.3
- DISA-STIG-OL08-00-020010
- NIST-800-171-3.1.8
- NIST-800-53-AC-7(a)
- NIST-800-53-CM-6(a)
- PCI-DSS-Req-8.1.6
- accounts_passwords_pam_faillock_deny
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Lock Accounts After Failed Password Attempts - Ensure the pam_faillock.so
deny parameter in PAM files
block:
- name: Lock Accounts After Failed Password Attempts - Check if pam_faillock.so
deny parameter is already enabled in pam files
ansible.builtin.lineinfile:
path: /etc/pam.d/system-auth
regexp: .*auth.*pam_faillock.so (preauth|authfail).*deny
state: absent
check_mode: true
changed_when: false
register: result_pam_faillock_deny_parameter_is_present
- name: Lock Accounts After Failed Password Attempts - Ensure the inclusion of
pam_faillock.so preauth deny parameter in auth section
ansible.builtin.lineinfile:
path: '{{ item }}'
backrefs: true
regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so preauth.*)
line: \1required\3 deny={{ var_accounts_passwords_pam_faillock_deny }}
state: present
loop:
- /etc/pam.d/system-auth
- /etc/pam.d/password-auth
when:
- result_pam_faillock_deny_parameter_is_present.found == 0
- name: Lock Accounts After Failed Password Attempts - Ensure the inclusion of
pam_faillock.so authfail deny parameter in auth section
ansible.builtin.lineinfile:
path: '{{ item }}'
backrefs: true
regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so authfail.*)
line: \1required\3 deny={{ var_accounts_passwords_pam_faillock_deny }}
state: present
loop:
- /etc/pam.d/system-auth
- /etc/pam.d/password-auth
when:
- result_pam_faillock_deny_parameter_is_present.found == 0
- name: Lock Accounts After Failed Password Attempts - Ensure the desired value
for pam_faillock.so preauth deny parameter in auth section
ansible.builtin.lineinfile:
path: '{{ item }}'
backrefs: true
regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so preauth.*)(deny)=[0-9]+(.*)
line: \1required\3\4={{ var_accounts_passwords_pam_faillock_deny }}\5
state: present
loop:
- /etc/pam.d/system-auth
- /etc/pam.d/password-auth
when:
- result_pam_faillock_deny_parameter_is_present.found > 0
- name: Lock Accounts After Failed Password Attempts - Ensure the desired value
for pam_faillock.so authfail deny parameter in auth section
ansible.builtin.lineinfile:
path: '{{ item }}'
backrefs: true
regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so authfail.*)(deny)=[0-9]+(.*)
line: \1required\3\4={{ var_accounts_passwords_pam_faillock_deny }}\5
state: present
loop:
- /etc/pam.d/system-auth
- /etc/pam.d/password-auth
when:
- result_pam_faillock_deny_parameter_is_present.found > 0
when:
- '"pam" in ansible_facts.packages'
- not result_faillock_conf_check.stat.exists
tags:
- CJIS-5.5.3
- DISA-STIG-OL08-00-020010
- NIST-800-171-3.1.8
- NIST-800-53-AC-7(a)
- NIST-800-53-CM-6(a)
- PCI-DSS-Req-8.1.6
- accounts_passwords_pam_faillock_deny
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
|
Configure the root Account for Failed Password AttemptsruleThis rule configures the system to lock out the root account after a number of
incorrect login attempts using pam_faillock.so .
pam_faillock.so module requires multiple entries in pam files. These entries must be carefully
defined to work as expected. In order to avoid any errors when manually editing these files,
it is recommended to use the appropriate tools, such as authselect or authconfig ,
depending on the OS version. warning
If the system relies on authselect tool to manage PAM settings, the remediation
will also use authselect tool. However, if any manual modification was made in
PAM files, the authselect integrity check will fail and the remediation will be
aborted in order to preserve intentional changes. In this case, an informative message will
be shown in the remediation report.
If the system supports the /etc/security/faillock.conf file, the pam_faillock
parameters should be defined in faillock.conf file. Rationale:By limiting the number of failed logon attempts, the risk of unauthorized system access via
user password guessing, also known as brute-forcing, is reduced. Limits are imposed by locking
the account. references:
1, 12, 15, 16, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, SR 1.1, SR 1.10, SR 1.2, SR 1.5, SR 1.7, SR 1.8, SR 1.9, 0421, 0422, 0431, 0974, 1173, 1401, 1504, 1505, 1546, 1557, 1558, 1559, 1560, 1561, CM-6(a), AC-7(b), IA-5(c), SRG-OS-000329-GPOS-00128, SRG-OS-000021-GPOS-00005, A.18.1.4, A.9.2.1, A.9.2.4, A.9.3.1, A.9.4.2, A.9.4.3, PR.AC-7, FMT_MOF_EXT.1, OL08-00-020022, SV-248664r779558_rule, CCI-002238, CCI-000044, DSS05.04, DSS05.10, DSS06.10, BP28(R18) Remediation script:# Remediation is applicable only in certain platforms
if rpm --quiet -q pam; then
if [ -f /usr/bin/authselect ]; then
if authselect check; then
authselect enable-feature with-faillock
authselect apply-changes
else
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."
false
fi
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.*sufficient.*pam_unix.so.*/a 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
FAILLOCK_CONF="/etc/security/faillock.conf"
if [ -f $FAILLOCK_CONF ]; then
regex="^\s*even_deny_root"
line="even_deny_root"
if ! grep -q $regex $FAILLOCK_CONF; then
echo $line >> $FAILLOCK_CONF
fi
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.*pam_faillock.so (preauth|authfail).*even_deny_root' "$pam_file"; then
sed -i --follow-symlinks '/^auth.*required.*pam_faillock.so.*preauth.*silent.*/ s/$/ even_deny_root/' "$pam_file"
sed -i --follow-symlinks '/^auth.*required.*pam_faillock.so.*authfail.*/ s/$/ even_deny_root/' "$pam_file"
fi
done
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
Remediation script:- name: Gather the package facts
package_facts:
manager: auto
tags:
- DISA-STIG-OL08-00-020022
- NIST-800-53-AC-7(b)
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-5(c)
- accounts_passwords_pam_faillock_deny_root
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Configure the root Account for Failed Password Attempts - Check if system
relies on authselect tool
ansible.builtin.stat:
path: /usr/bin/authselect
register: result_authselect_present
when: '"pam" in ansible_facts.packages'
tags:
- DISA-STIG-OL08-00-020022
- NIST-800-53-AC-7(b)
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-5(c)
- accounts_passwords_pam_faillock_deny_root
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Configure the root Account for Failed Password Attempts - Remediation where
authselect tool is present
block:
- name: Configure the root Account for Failed Password Attempts - Check integrity
of authselect current profile
ansible.builtin.command:
cmd: authselect check
register: result_authselect_check_cmd
changed_when: false
ignore_errors: true
- name: Configure the root Account for Failed Password Attempts - Informative
message based on the authselect integrity check result
ansible.builtin.assert:
that:
- result_authselect_check_cmd is success
fail_msg:
- 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.
success_msg:
- authselect integrity check passed
- name: Configure the root Account for Failed Password Attempts - Get authselect
current features
ansible.builtin.shell:
cmd: authselect current | tail -n+3 | awk '{ print $2 }'
register: result_authselect_features
changed_when: false
when:
- result_authselect_check_cmd is success
- name: Configure the root Account for Failed Password Attempts - Ensure with-faillock
feature is enabled using authselect tool
ansible.builtin.command:
cmd: authselect enable-feature with-faillock
register: result_authselect_cmd
when:
- result_authselect_check_cmd is success
- result_authselect_features.stdout is not search("with-faillock")
when:
- '"pam" in ansible_facts.packages'
- result_authselect_present.stat.exists
tags:
- DISA-STIG-OL08-00-020022
- NIST-800-53-AC-7(b)
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-5(c)
- accounts_passwords_pam_faillock_deny_root
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Configure the root Account for Failed Password Attempts - Remediation where
authselect tool is not present
block:
- name: Configure the root Account for Failed Password Attempts - Check if pam_faillock.so
is already enabled
ansible.builtin.lineinfile:
path: /etc/pam.d/system-auth
regexp: .*auth.*pam_faillock.so (preauth|authfail)
state: absent
check_mode: true
changed_when: false
register: result_pam_faillock_is_enabled
- name: Configure the root Account for Failed Password Attempts - Enable pam_faillock.so
preauth editing PAM files
ansible.builtin.lineinfile:
path: '{{ item }}'
line: auth required pam_faillock.so preauth
insertbefore: ^auth.*sufficient.*pam_unix.so.*
state: present
loop:
- /etc/pam.d/system-auth
- /etc/pam.d/password-auth
when:
- result_pam_faillock_is_enabled.found == 0
- name: Configure the root Account for Failed Password Attempts - Enable pam_faillock.so
authfail editing PAM files
ansible.builtin.lineinfile:
path: '{{ item }}'
line: auth required pam_faillock.so authfail
insertafter: ^auth.*sufficient.*pam_unix.so.*
state: present
loop:
- /etc/pam.d/system-auth
- /etc/pam.d/password-auth
when:
- result_pam_faillock_is_enabled.found == 0
- name: Configure the root Account for Failed Password Attempts - Enable pam_faillock.so
account section editing PAM files
ansible.builtin.lineinfile:
path: '{{ item }}'
line: account required pam_faillock.so
insertbefore: ^account.*required.*pam_unix.so.*
state: present
loop:
- /etc/pam.d/system-auth
- /etc/pam.d/password-auth
when:
- result_pam_faillock_is_enabled.found == 0
when:
- '"pam" in ansible_facts.packages'
- not result_authselect_present.stat.exists
tags:
- DISA-STIG-OL08-00-020022
- NIST-800-53-AC-7(b)
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-5(c)
- accounts_passwords_pam_faillock_deny_root
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Configure the root Account for Failed Password Attempts - Check the presence
of /etc/security/faillock.conf file
ansible.builtin.stat:
path: /etc/security/faillock.conf
register: result_faillock_conf_check
when: '"pam" in ansible_facts.packages'
tags:
- DISA-STIG-OL08-00-020022
- NIST-800-53-AC-7(b)
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-5(c)
- accounts_passwords_pam_faillock_deny_root
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Configure the root Account for Failed Password Attempts - Ensure the pam_faillock.so
even_deny_root parameter in /etc/security/faillock.conf
ansible.builtin.lineinfile:
path: /etc/security/faillock.conf
regexp: ^\s*even_deny_root
line: even_deny_root
state: present
when:
- '"pam" in ansible_facts.packages'
- result_faillock_conf_check.stat.exists
tags:
- DISA-STIG-OL08-00-020022
- NIST-800-53-AC-7(b)
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-5(c)
- accounts_passwords_pam_faillock_deny_root
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Configure the root Account for Failed Password Attempts - Ensure the pam_faillock.so
even_deny_root parameter in PAM files
block:
- name: Configure the root Account for Failed Password Attempts - Check if pam_faillock.so
even_deny_root parameter is already enabled in pam files
ansible.builtin.lineinfile:
path: /etc/pam.d/system-auth
regexp: .*auth.*pam_faillock.so (preauth|authfail).*even_deny_root
state: absent
check_mode: true
changed_when: false
register: result_pam_faillock_even_deny_root_parameter_is_present
- name: Configure the root Account for Failed Password Attempts - Ensure the inclusion
of pam_faillock.so preauth even_deny_root parameter in auth section
ansible.builtin.lineinfile:
path: '{{ item }}'
backrefs: true
regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so preauth.*)
line: \1required\3 even_deny_root
state: present
loop:
- /etc/pam.d/system-auth
- /etc/pam.d/password-auth
when:
- result_pam_faillock_even_deny_root_parameter_is_present.found == 0
- name: Configure the root Account for Failed Password Attempts - Ensure the inclusion
of pam_faillock.so authfail even_deny_root parameter in auth section
ansible.builtin.lineinfile:
path: '{{ item }}'
backrefs: true
regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so authfail.*)
line: \1required\3 even_deny_root
state: present
loop:
- /etc/pam.d/system-auth
- /etc/pam.d/password-auth
when:
- result_pam_faillock_even_deny_root_parameter_is_present.found == 0
when:
- '"pam" in ansible_facts.packages'
- not result_faillock_conf_check.stat.exists
tags:
- DISA-STIG-OL08-00-020022
- NIST-800-53-AC-7(b)
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-5(c)
- accounts_passwords_pam_faillock_deny_root
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
|
Set Interval For Counting Failed Password AttemptsruleUtilizing pam_faillock.so , the fail_interval directive configures the system
to lock out an account after a number of incorrect login attempts within a specified time
period. First make sure the feature is enabled using the following command:
Then edit the /etc/security/faillock.conf file as follows:
- add, uncomment or edit the following line:
fail_interval = 900 - add or uncomment the following line:
silent
warning
If the system relies on authselect tool to manage PAM settings, the remediation
will also use authselect tool. However, if any manual modification was made in
PAM files, the authselect integrity check will fail and the remediation will be
aborted in order to preserve intentional changes. In this case, an informative message will
be shown in the remediation report.
If the system supports the /etc/security/faillock.conf file, the pam_faillock
parameters should be defined in faillock.conf file. Rationale:By limiting the number of failed logon attempts the risk of unauthorized system
access via user password guessing, otherwise known as brute-forcing, is reduced.
Limits are imposed by locking the account. references:
1, 12, 15, 16, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, SR 1.1, SR 1.10, SR 1.2, SR 1.5, SR 1.7, SR 1.8, SR 1.9, 0421, 0422, 0431, 0974, 1173, 1401, 1504, 1505, 1546, 1557, 1558, 1559, 1560, 1561, SRG-OS-000021-VMM-000050, CM-6(a), AC-7(a), SRG-OS-000329-GPOS-00128, SRG-OS-000021-GPOS-00005, A.18.1.4, A.9.2.1, A.9.2.4, A.9.3.1, A.9.4.2, A.9.4.3, PR.AC-7, FIA_AFL.1, OL08-00-020012, SV-248654r779528_rule, CCI-000044, CCI-002236, CCI-002237, CCI-002238, DSS05.04, DSS05.10, DSS06.10, BP28(R18) Remediation script:# Remediation is applicable only in certain platforms
if rpm --quiet -q pam; then
var_accounts_passwords_pam_faillock_fail_interval='900'
if [ -f /usr/bin/authselect ]; then
if authselect check; then
authselect enable-feature with-faillock
authselect apply-changes
else
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."
false
fi
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.*sufficient.*pam_unix.so.*/a 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
FAILLOCK_CONF="/etc/security/faillock.conf"
if [ -f $FAILLOCK_CONF ]; then
regex="^\s*fail_interval\s*="
line="fail_interval = $var_accounts_passwords_pam_faillock_fail_interval"
if ! grep -q $regex $FAILLOCK_CONF; then
echo $line >> $FAILLOCK_CONF
else
sed -i --follow-symlinks 's/^\s*\(fail_interval\s*=\s*\)\([0-9]\+\)/\1'"$var_accounts_passwords_pam_faillock_fail_interval"'/g' $FAILLOCK_CONF
fi
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.*pam_faillock.so (preauth|authfail).*fail_interval' "$pam_file"; then
sed -i --follow-symlinks '/^auth.*required.*pam_faillock.so.*preauth.*silent.*/ s/$/ fail_interval='"$var_accounts_passwords_pam_faillock_fail_interval"'/' "$pam_file"
sed -i --follow-symlinks '/^auth.*required.*pam_faillock.so.*authfail.*/ s/$/ fail_interval='"$var_accounts_passwords_pam_faillock_fail_interval"'/' "$pam_file"
else
sed -i --follow-symlinks 's/\(^auth.*required.*pam_faillock.so.*preauth.*silent.*\)\('"fail_interval"'=\)[0-9]\+\(.*\)/\1\2'"$var_accounts_passwords_pam_faillock_fail_interval"'\3/' "$pam_file"
sed -i --follow-symlinks 's/\(^auth.*required.*pam_faillock.so.*authfail.*\)\('"fail_interval"'=\)[0-9]\+\(.*\)/\1\2'"$var_accounts_passwords_pam_faillock_fail_interval"'\3/' "$pam_file"
fi
done
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
Remediation script:- name: Gather the package facts
package_facts:
manager: auto
tags:
- DISA-STIG-OL08-00-020012
- NIST-800-53-AC-7(a)
- NIST-800-53-CM-6(a)
- accounts_passwords_pam_faillock_interval
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Set Interval For Counting Failed Password Attempts - Check if system relies
on authselect tool
ansible.builtin.stat:
path: /usr/bin/authselect
register: result_authselect_present
when: '"pam" in ansible_facts.packages'
tags:
- DISA-STIG-OL08-00-020012
- NIST-800-53-AC-7(a)
- NIST-800-53-CM-6(a)
- accounts_passwords_pam_faillock_interval
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Set Interval For Counting Failed Password Attempts - Remediation where authselect
tool is present
block:
- name: Set Interval For Counting Failed Password Attempts - Check integrity of
authselect current profile
ansible.builtin.command:
cmd: authselect check
register: result_authselect_check_cmd
changed_when: false
ignore_errors: true
- name: Set Interval For Counting Failed Password Attempts - Informative message
based on the authselect integrity check result
ansible.builtin.assert:
that:
- result_authselect_check_cmd is success
fail_msg:
- 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.
success_msg:
- authselect integrity check passed
- name: Set Interval For Counting Failed Password Attempts - Get authselect current
features
ansible.builtin.shell:
cmd: authselect current | tail -n+3 | awk '{ print $2 }'
register: result_authselect_features
changed_when: false
when:
- result_authselect_check_cmd is success
- name: Set Interval For Counting Failed Password Attempts - Ensure with-faillock
feature is enabled using authselect tool
ansible.builtin.command:
cmd: authselect enable-feature with-faillock
register: result_authselect_cmd
when:
- result_authselect_check_cmd is success
- result_authselect_features.stdout is not search("with-faillock")
when:
- '"pam" in ansible_facts.packages'
- result_authselect_present.stat.exists
tags:
- DISA-STIG-OL08-00-020012
- NIST-800-53-AC-7(a)
- NIST-800-53-CM-6(a)
- accounts_passwords_pam_faillock_interval
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Set Interval For Counting Failed Password Attempts - Remediation where authselect
tool is not present
block:
- name: Set Interval For Counting Failed Password Attempts - Check if pam_faillock.so
is already enabled
ansible.builtin.lineinfile:
path: /etc/pam.d/system-auth
regexp: .*auth.*pam_faillock.so (preauth|authfail)
state: absent
check_mode: true
changed_when: false
register: result_pam_faillock_is_enabled
- name: Set Interval For Counting Failed Password Attempts - Enable pam_faillock.so
preauth editing PAM files
ansible.builtin.lineinfile:
path: '{{ item }}'
line: auth required pam_faillock.so preauth
insertbefore: ^auth.*sufficient.*pam_unix.so.*
state: present
loop:
- /etc/pam.d/system-auth
- /etc/pam.d/password-auth
when:
- result_pam_faillock_is_enabled.found == 0
- name: Set Interval For Counting Failed Password Attempts - Enable pam_faillock.so
authfail editing PAM files
ansible.builtin.lineinfile:
path: '{{ item }}'
line: auth required pam_faillock.so authfail
insertafter: ^auth.*sufficient.*pam_unix.so.*
state: present
loop:
- /etc/pam.d/system-auth
- /etc/pam.d/password-auth
when:
- result_pam_faillock_is_enabled.found == 0
- name: Set Interval For Counting Failed Password Attempts - Enable pam_faillock.so
account section editing PAM files
ansible.builtin.lineinfile:
path: '{{ item }}'
line: account required pam_faillock.so
insertbefore: ^account.*required.*pam_unix.so.*
state: present
loop:
- /etc/pam.d/system-auth
- /etc/pam.d/password-auth
when:
- result_pam_faillock_is_enabled.found == 0
when:
- '"pam" in ansible_facts.packages'
- not result_authselect_present.stat.exists
tags:
- DISA-STIG-OL08-00-020012
- NIST-800-53-AC-7(a)
- NIST-800-53-CM-6(a)
- accounts_passwords_pam_faillock_interval
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: XCCDF Value var_accounts_passwords_pam_faillock_fail_interval # promote to variable
set_fact:
var_accounts_passwords_pam_faillock_fail_interval: !!str 900
tags:
- always
- name: Set Interval For Counting Failed Password Attempts - Check the presence of
/etc/security/faillock.conf file
ansible.builtin.stat:
path: /etc/security/faillock.conf
register: result_faillock_conf_check
when: '"pam" in ansible_facts.packages'
tags:
- DISA-STIG-OL08-00-020012
- NIST-800-53-AC-7(a)
- NIST-800-53-CM-6(a)
- accounts_passwords_pam_faillock_interval
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Set Interval For Counting Failed Password Attempts - Ensure the pam_faillock.so
fail_interval parameter in /etc/security/faillock.conf
ansible.builtin.lineinfile:
path: /etc/security/faillock.conf
regexp: ^\s*fail_interval\s*=
line: fail_interval = {{ var_accounts_passwords_pam_faillock_fail_interval }}
state: present
when:
- '"pam" in ansible_facts.packages'
- result_faillock_conf_check.stat.exists
tags:
- DISA-STIG-OL08-00-020012
- NIST-800-53-AC-7(a)
- NIST-800-53-CM-6(a)
- accounts_passwords_pam_faillock_interval
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Set Interval For Counting Failed Password Attempts - Ensure the pam_faillock.so
fail_interval parameter in PAM files
block:
- name: Set Interval For Counting Failed Password Attempts - Check if pam_faillock.so
fail_interval parameter is already enabled in pam files
ansible.builtin.lineinfile:
path: /etc/pam.d/system-auth
regexp: .*auth.*pam_faillock.so (preauth|authfail).*fail_interval
state: absent
check_mode: true
changed_when: false
register: result_pam_faillock_fail_interval_parameter_is_present
- name: Set Interval For Counting Failed Password Attempts - Ensure the inclusion
of pam_faillock.so preauth fail_interval parameter in auth section
ansible.builtin.lineinfile:
path: '{{ item }}'
backrefs: true
regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so preauth.*)
line: \1required\3 fail_interval={{ var_accounts_passwords_pam_faillock_fail_interval
}}
state: present
loop:
- /etc/pam.d/system-auth
- /etc/pam.d/password-auth
when:
- result_pam_faillock_fail_interval_parameter_is_present.found == 0
- name: Set Interval For Counting Failed Password Attempts - Ensure the inclusion
of pam_faillock.so authfail fail_interval parameter in auth section
ansible.builtin.lineinfile:
path: '{{ item }}'
backrefs: true
regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so authfail.*)
line: \1required\3 fail_interval={{ var_accounts_passwords_pam_faillock_fail_interval
}}
state: present
loop:
- /etc/pam.d/system-auth
- /etc/pam.d/password-auth
when:
- result_pam_faillock_fail_interval_parameter_is_present.found == 0
- name: Set Interval For Counting Failed Password Attempts - Ensure the desired
value for pam_faillock.so preauth fail_interval parameter in auth section
ansible.builtin.lineinfile:
path: '{{ item }}'
backrefs: true
regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so preauth.*)(fail_interval)=[0-9]+(.*)
line: \1required\3\4={{ var_accounts_passwords_pam_faillock_fail_interval
}}\5
state: present
loop:
- /etc/pam.d/system-auth
- /etc/pam.d/password-auth
when:
- result_pam_faillock_fail_interval_parameter_is_present.found > 0
- name: Set Interval For Counting Failed Password Attempts - Ensure the desired
value for pam_faillock.so authfail fail_interval parameter in auth section
ansible.builtin.lineinfile:
path: '{{ item }}'
backrefs: true
regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so authfail.*)(fail_interval)=[0-9]+(.*)
line: \1required\3\4={{ var_accounts_passwords_pam_faillock_fail_interval
}}\5
state: present
loop:
- /etc/pam.d/system-auth
- /etc/pam.d/password-auth
when:
- result_pam_faillock_fail_interval_parameter_is_present.found > 0
when:
- '"pam" in ansible_facts.packages'
- not result_faillock_conf_check.stat.exists
tags:
- DISA-STIG-OL08-00-020012
- NIST-800-53-AC-7(a)
- NIST-800-53-CM-6(a)
- accounts_passwords_pam_faillock_interval
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
|
Set Lockout Time for Failed Password AttemptsruleThis rule configures the system to lock out accounts during a specified time period after a
number of incorrect login attempts using pam_faillock.so .
pam_faillock.so module requires multiple entries in pam files. These entries must be carefully
defined to work as expected. In order to avoid any errors when manually editing these files,
it is recommended to use the appropriate tools, such as authselect or authconfig ,
depending on the OS version. warning
If the system relies on authselect tool to manage PAM settings, the remediation
will also use authselect tool. However, if any manual modification was made in
PAM files, the authselect integrity check will fail and the remediation will be
aborted in order to preserve intentional changes. In this case, an informative message will
be shown in the remediation report.
If the system supports the /etc/security/faillock.conf file, the pam_faillock
parameters should be defined in faillock.conf file. Rationale:Locking out user accounts after a number of incorrect attempts prevents direct password
guessing attacks. Ensuring that an administrator is involved in unlocking locked accounts
draws appropriate attention to such situations. references:
1, 12, 15, 16, SR 1.1, SR 1.10, SR 1.2, SR 1.5, SR 1.7, SR 1.8, SR 1.9, 3.1.8, SRG-OS-000329-GPOS-00128, SRG-OS-000021-GPOS-00005, PR.AC-7, OL08-00-020014, SV-248656r779534_rule, BP28(R18), 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, CM-6(a), AC-7(b), 0421, 0422, 0431, 0974, 1173, 1401, 1504, 1505, 1546, 1557, 1558, 1559, 1560, 1561, 5.5.3, SRG-OS-000329-VMM-001180, Req-8.1.7, A.18.1.4, A.9.2.1, A.9.2.4, A.9.3.1, A.9.4.2, A.9.4.3, FIA_AFL.1, CCI-000044, CCI-002236, CCI-002237, CCI-002238, DSS05.04, DSS05.10, DSS06.10 Remediation script:# Remediation is applicable only in certain platforms
if rpm --quiet -q pam; then
var_accounts_passwords_pam_faillock_unlock_time='900'
if [ -f /usr/bin/authselect ]; then
if authselect check; then
authselect enable-feature with-faillock
authselect apply-changes
else
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."
false
fi
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.*sufficient.*pam_unix.so.*/a 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
FAILLOCK_CONF="/etc/security/faillock.conf"
if [ -f $FAILLOCK_CONF ]; then
regex="^\s*unlock_time\s*="
line="unlock_time = $var_accounts_passwords_pam_faillock_unlock_time"
if ! grep -q $regex $FAILLOCK_CONF; then
echo $line >> $FAILLOCK_CONF
else
sed -i --follow-symlinks 's/^\s*\(unlock_time\s*=\s*\)\([0-9]\+\)/\1'"$var_accounts_passwords_pam_faillock_unlock_time"'/g' $FAILLOCK_CONF
fi
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.*pam_faillock.so (preauth|authfail).*unlock_time' "$pam_file"; then
sed -i --follow-symlinks '/^auth.*required.*pam_faillock.so.*preauth.*silent.*/ s/$/ unlock_time='"$var_accounts_passwords_pam_faillock_unlock_time"'/' "$pam_file"
sed -i --follow-symlinks '/^auth.*required.*pam_faillock.so.*authfail.*/ s/$/ unlock_time='"$var_accounts_passwords_pam_faillock_unlock_time"'/' "$pam_file"
else
sed -i --follow-symlinks 's/\(^auth.*required.*pam_faillock.so.*preauth.*silent.*\)\('"unlock_time"'=\)[0-9]\+\(.*\)/\1\2'"$var_accounts_passwords_pam_faillock_unlock_time"'\3/' "$pam_file"
sed -i --follow-symlinks 's/\(^auth.*required.*pam_faillock.so.*authfail.*\)\('"unlock_time"'=\)[0-9]\+\(.*\)/\1\2'"$var_accounts_passwords_pam_faillock_unlock_time"'\3/' "$pam_file"
fi
done
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
Remediation script:- name: Gather the package facts
package_facts:
manager: auto
tags:
- CJIS-5.5.3
- DISA-STIG-OL08-00-020014
- NIST-800-171-3.1.8
- NIST-800-53-AC-7(b)
- NIST-800-53-CM-6(a)
- PCI-DSS-Req-8.1.7
- accounts_passwords_pam_faillock_unlock_time
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Set Lockout Time for Failed Password Attempts - Check if system relies on
authselect tool
ansible.builtin.stat:
path: /usr/bin/authselect
register: result_authselect_present
when: '"pam" in ansible_facts.packages'
tags:
- CJIS-5.5.3
- DISA-STIG-OL08-00-020014
- NIST-800-171-3.1.8
- NIST-800-53-AC-7(b)
- NIST-800-53-CM-6(a)
- PCI-DSS-Req-8.1.7
- accounts_passwords_pam_faillock_unlock_time
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Set Lockout Time for Failed Password Attempts - Remediation where authselect
tool is present
block:
- name: Set Lockout Time for Failed Password Attempts - Check integrity of authselect
current profile
ansible.builtin.command:
cmd: authselect check
register: result_authselect_check_cmd
changed_when: false
ignore_errors: true
- name: Set Lockout Time for Failed Password Attempts - Informative message based
on the authselect integrity check result
ansible.builtin.assert:
that:
- result_authselect_check_cmd is success
fail_msg:
- 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.
success_msg:
- authselect integrity check passed
- name: Set Lockout Time for Failed Password Attempts - Get authselect current
features
ansible.builtin.shell:
cmd: authselect current | tail -n+3 | awk '{ print $2 }'
register: result_authselect_features
changed_when: false
when:
- result_authselect_check_cmd is success
- name: Set Lockout Time for Failed Password Attempts - Ensure with-faillock feature
is enabled using authselect tool
ansible.builtin.command:
cmd: authselect enable-feature with-faillock
register: result_authselect_cmd
when:
- result_authselect_check_cmd is success
- result_authselect_features.stdout is not search("with-faillock")
when:
- '"pam" in ansible_facts.packages'
- result_authselect_present.stat.exists
tags:
- CJIS-5.5.3
- DISA-STIG-OL08-00-020014
- NIST-800-171-3.1.8
- NIST-800-53-AC-7(b)
- NIST-800-53-CM-6(a)
- PCI-DSS-Req-8.1.7
- accounts_passwords_pam_faillock_unlock_time
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Set Lockout Time for Failed Password Attempts - Remediation where authselect
tool is not present
block:
- name: Set Lockout Time for Failed Password Attempts - Check if pam_faillock.so
is already enabled
ansible.builtin.lineinfile:
path: /etc/pam.d/system-auth
regexp: .*auth.*pam_faillock.so (preauth|authfail)
state: absent
check_mode: true
changed_when: false
register: result_pam_faillock_is_enabled
- name: Set Lockout Time for Failed Password Attempts - Enable pam_faillock.so
preauth editing PAM files
ansible.builtin.lineinfile:
path: '{{ item }}'
line: auth required pam_faillock.so preauth
insertbefore: ^auth.*sufficient.*pam_unix.so.*
state: present
loop:
- /etc/pam.d/system-auth
- /etc/pam.d/password-auth
when:
- result_pam_faillock_is_enabled.found == 0
- name: Set Lockout Time for Failed Password Attempts - Enable pam_faillock.so
authfail editing PAM files
ansible.builtin.lineinfile:
path: '{{ item }}'
line: auth required pam_faillock.so authfail
insertafter: ^auth.*sufficient.*pam_unix.so.*
state: present
loop:
- /etc/pam.d/system-auth
- /etc/pam.d/password-auth
when:
- result_pam_faillock_is_enabled.found == 0
- name: Set Lockout Time for Failed Password Attempts - Enable pam_faillock.so
account section editing PAM files
ansible.builtin.lineinfile:
path: '{{ item }}'
line: account required pam_faillock.so
insertbefore: ^account.*required.*pam_unix.so.*
state: present
loop:
- /etc/pam.d/system-auth
- /etc/pam.d/password-auth
when:
- result_pam_faillock_is_enabled.found == 0
when:
- '"pam" in ansible_facts.packages'
- not result_authselect_present.stat.exists
tags:
- CJIS-5.5.3
- DISA-STIG-OL08-00-020014
- NIST-800-171-3.1.8
- NIST-800-53-AC-7(b)
- NIST-800-53-CM-6(a)
- PCI-DSS-Req-8.1.7
- accounts_passwords_pam_faillock_unlock_time
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: XCCDF Value var_accounts_passwords_pam_faillock_unlock_time # promote to variable
set_fact:
var_accounts_passwords_pam_faillock_unlock_time: !!str 900
tags:
- always
- name: Set Lockout Time for Failed Password Attempts - Check the presence of /etc/security/faillock.conf
file
ansible.builtin.stat:
path: /etc/security/faillock.conf
register: result_faillock_conf_check
when: '"pam" in ansible_facts.packages'
tags:
- CJIS-5.5.3
- DISA-STIG-OL08-00-020014
- NIST-800-171-3.1.8
- NIST-800-53-AC-7(b)
- NIST-800-53-CM-6(a)
- PCI-DSS-Req-8.1.7
- accounts_passwords_pam_faillock_unlock_time
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Set Lockout Time for Failed Password Attempts - Ensure the pam_faillock.so
unlock_time parameter in /etc/security/faillock.conf
ansible.builtin.lineinfile:
path: /etc/security/faillock.conf
regexp: ^\s*unlock_time\s*=
line: unlock_time = {{ var_accounts_passwords_pam_faillock_unlock_time }}
state: present
when:
- '"pam" in ansible_facts.packages'
- result_faillock_conf_check.stat.exists
tags:
- CJIS-5.5.3
- DISA-STIG-OL08-00-020014
- NIST-800-171-3.1.8
- NIST-800-53-AC-7(b)
- NIST-800-53-CM-6(a)
- PCI-DSS-Req-8.1.7
- accounts_passwords_pam_faillock_unlock_time
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Set Lockout Time for Failed Password Attempts - Ensure the pam_faillock.so
unlock_time parameter in PAM files
block:
- name: Set Lockout Time for Failed Password Attempts - Check if pam_faillock.so
unlock_time parameter is already enabled in pam files
ansible.builtin.lineinfile:
path: /etc/pam.d/system-auth
regexp: .*auth.*pam_faillock.so (preauth|authfail).*unlock_time
state: absent
check_mode: true
changed_when: false
register: result_pam_faillock_unlock_time_parameter_is_present
- name: Set Lockout Time for Failed Password Attempts - Ensure the inclusion of
pam_faillock.so preauth unlock_time parameter in auth section
ansible.builtin.lineinfile:
path: '{{ item }}'
backrefs: true
regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so preauth.*)
line: \1required\3 unlock_time={{ var_accounts_passwords_pam_faillock_unlock_time
}}
state: present
loop:
- /etc/pam.d/system-auth
- /etc/pam.d/password-auth
when:
- result_pam_faillock_unlock_time_parameter_is_present.found == 0
- name: Set Lockout Time for Failed Password Attempts - Ensure the inclusion of
pam_faillock.so authfail unlock_time parameter in auth section
ansible.builtin.lineinfile:
path: '{{ item }}'
backrefs: true
regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so authfail.*)
line: \1required\3 unlock_time={{ var_accounts_passwords_pam_faillock_unlock_time
}}
state: present
loop:
- /etc/pam.d/system-auth
- /etc/pam.d/password-auth
when:
- result_pam_faillock_unlock_time_parameter_is_present.found == 0
- name: Set Lockout Time for Failed Password Attempts - Ensure the desired value
for pam_faillock.so preauth unlock_time parameter in auth section
ansible.builtin.lineinfile:
path: '{{ item }}'
backrefs: true
regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so preauth.*)(unlock_time)=[0-9]+(.*)
line: \1required\3\4={{ var_accounts_passwords_pam_faillock_unlock_time }}\5
state: present
loop:
- /etc/pam.d/system-auth
- /etc/pam.d/password-auth
when:
- result_pam_faillock_unlock_time_parameter_is_present.found > 0
- name: Set Lockout Time for Failed Password Attempts - Ensure the desired value
for pam_faillock.so authfail unlock_time parameter in auth section
ansible.builtin.lineinfile:
path: '{{ item }}'
backrefs: true
regexp: (^\s*auth\s+)([\w\[].*\b)(\s+pam_faillock.so authfail.*)(unlock_time)=[0-9]+(.*)
line: \1required\3\4={{ var_accounts_passwords_pam_faillock_unlock_time }}\5
state: present
loop:
- /etc/pam.d/system-auth
- /etc/pam.d/password-auth
when:
- result_pam_faillock_unlock_time_parameter_is_present.found > 0
when:
- '"pam" in ansible_facts.packages'
- not result_faillock_conf_check.stat.exists
tags:
- CJIS-5.5.3
- DISA-STIG-OL08-00-020014
- NIST-800-171-3.1.8
- NIST-800-53-AC-7(b)
- NIST-800-53-CM-6(a)
- PCI-DSS-Req-8.1.7
- accounts_passwords_pam_faillock_unlock_time
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
|
Set Password Quality RequirementsgroupThe default pam_pwquality PAM module provides strength
checking for passwords. It performs a number of checks, such as
making sure passwords are not similar to dictionary words, are of
at least a certain length, are not the previous password reversed,
and are not simply a change of case from the previous password. It
can also require passwords to be in certain character classes. The
pam_pwquality module is the preferred way of configuring
password requirements.
The man pages pam_pwquality(8)
provide information on the capabilities and configuration of
each. |
contains 5 rules |
Set Password Quality Requirements with pam_pwqualitygroupThe pam_pwquality PAM module can be configured to meet
requirements for a variety of policies.
For example, to configure pam_pwquality to require at least one uppercase
character, lowercase character, digit, and other (special)
character, make sure that pam_pwquality exists in /etc/pam.d/system-auth :
password requisite pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type=
If no such line exists, add one as the first line of the password section in /etc/pam.d/system-auth .
Next, modify the settings in /etc/security/pwquality.conf to match the following:
difok = 4
minlen = 14
dcredit = -1
ucredit = -1
lcredit = -1
ocredit = -1
maxrepeat = 3
The arguments can be modified to ensure compliance with
your organization's security policy. Discussion of each parameter follows. |
contains 5 rules |
Ensure PAM Enforces Password Requirements - Minimum Digit CharactersruleThe pam_pwquality module's dcredit parameter controls requirements for
usage of digits in a password. When set to a negative number, any password will be required to
contain that many digits. When set to a positive number, pam_pwquality will grant +1 additional
length credit for each digit. Modify the dcredit setting in
/etc/security/pwquality.conf to require the use of a digit in passwords. Rationale:Use of a complex password helps to increase the time and resources required
to compromise the password. Password complexity, or strength, is a measure of
the effectiveness of a password in resisting attempts at guessing and brute-force
attacks.
Password complexity is one factor of several that determines how long it takes
to crack a password. The more complex the password, the greater the number of
possible combinations that need to be tested before the password is compromised.
Requiring digits makes password guessing attacks more difficult by ensuring a larger
search space. references:
1, 12, 15, 16, 5, 4.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.2, 4.3.3.7.4, SR 1.1, SR 1.10, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.7, SR 1.8, SR 1.9, SR 2.1, 0421, 0422, 0431, 0974, 1173, 1401, 1504, 1505, 1546, 1557, 1558, 1559, 1560, 1561, Req-8.2.3, SRG-OS-000071-VMM-000380, IA-5(c), IA-5(1)(a), CM-6(a), IA-5(4), SRG-OS-000071-GPOS-00039, A.18.1.4, A.7.1.1, A.9.2.1, A.9.2.2, A.9.2.3, A.9.2.4, A.9.2.6, A.9.3.1, A.9.4.2, A.9.4.3, PR.AC-1, PR.AC-6, PR.AC-7, FMT_MOF_EXT.1, OL08-00-020130, SV-248689r779633_rule, CCI-000194, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.10, BP28(R18) Remediation script:# Remediation is applicable only in certain platforms
if rpm --quiet -q pam; then
var_password_pam_dcredit='1'
# Test if the config_file is a symbolic link. If so, use --follow-symlinks with sed.
# Otherwise, regular sed command will do.
sed_command=('sed' '-i')
if test -L "/etc/security/pwquality.conf"; then
sed_command+=('--follow-symlinks')
fi
# 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
"${sed_command[@]}" "s/^dcredit\\>.*/$formatted_output/gi" "/etc/security/pwquality.conf"
else
# \n is precaution for case where file ends without trailing newline
printf '%s\n' "$formatted_output" >> "/etc/security/pwquality.conf"
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
Remediation script:- name: Gather the package facts
package_facts:
manager: auto
tags:
- DISA-STIG-OL08-00-020130
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-5(1)(a)
- NIST-800-53-IA-5(4)
- NIST-800-53-IA-5(c)
- PCI-DSS-Req-8.2.3
- accounts_password_pam_dcredit
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: XCCDF Value var_password_pam_dcredit # promote to variable
set_fact:
var_password_pam_dcredit: !!str 1
tags:
- always
- name: Ensure PAM variable dcredit is set accordingly
lineinfile:
create: true
dest: /etc/security/pwquality.conf
regexp: ^#?\s*dcredit
line: dcredit = {{ var_password_pam_dcredit }}
when: '"pam" in ansible_facts.packages'
tags:
- DISA-STIG-OL08-00-020130
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-5(1)(a)
- NIST-800-53-IA-5(4)
- NIST-800-53-IA-5(c)
- PCI-DSS-Req-8.2.3
- accounts_password_pam_dcredit
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
|
Ensure PAM Enforces Password Requirements - Minimum Lowercase CharactersruleThe pam_pwquality module's lcredit parameter controls requirements for
usage of lowercase letters in a password. When set to a negative number, any password will be required to
contain that many lowercase characters. When set to a positive number, pam_pwquality will grant +1 additional
length credit for each lowercase character. Modify the lcredit setting in
/etc/security/pwquality.conf to require the use of a lowercase character in passwords. Rationale:Use of a complex password helps to increase the time and resources required
to compromise the password. Password complexity, or strength, is a measure of
the effectiveness of a password in resisting attempts at guessing and brute-force
attacks.
Password complexity is one factor of several that determines how long it takes
to crack a password. The more complex the password, the greater the number of
possble combinations that need to be tested before the password is compromised.
Requiring a minimum number of lowercase characters makes password guessing attacks
more difficult by ensuring a larger search space. references:
1, 12, 15, 16, 5, 4.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.2, 4.3.3.7.4, SR 1.1, SR 1.10, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.7, SR 1.8, SR 1.9, SR 2.1, 0421, 0422, 0431, 0974, 1173, 1401, 1504, 1505, 1546, 1557, 1558, 1559, 1560, 1561, Req-8.2.3, SRG-OS-000070-VMM-000370, IA-5(c), IA-5(1)(a), CM-6(a), IA-5(4), SRG-OS-000070-GPOS-00038, A.18.1.4, A.7.1.1, A.9.2.1, A.9.2.2, A.9.2.3, A.9.2.4, A.9.2.6, A.9.3.1, A.9.4.2, A.9.4.3, PR.AC-1, PR.AC-6, PR.AC-7, FMT_MOF_EXT.1, OL08-00-020120, SV-248688r779630_rule, CCI-000193, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.10, BP28(R18) Remediation script:# Remediation is applicable only in certain platforms
if rpm --quiet -q pam; then
var_password_pam_lcredit='1'
# Test if the config_file is a symbolic link. If so, use --follow-symlinks with sed.
# Otherwise, regular sed command will do.
sed_command=('sed' '-i')
if test -L "/etc/security/pwquality.conf"; then
sed_command+=('--follow-symlinks')
fi
# 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
"${sed_command[@]}" "s/^lcredit\\>.*/$formatted_output/gi" "/etc/security/pwquality.conf"
else
# \n is precaution for case where file ends without trailing newline
printf '%s\n' "$formatted_output" >> "/etc/security/pwquality.conf"
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
Remediation script:- name: Gather the package facts
package_facts:
manager: auto
tags:
- DISA-STIG-OL08-00-020120
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-5(1)(a)
- NIST-800-53-IA-5(4)
- NIST-800-53-IA-5(c)
- PCI-DSS-Req-8.2.3
- accounts_password_pam_lcredit
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: XCCDF Value var_password_pam_lcredit # promote to variable
set_fact:
var_password_pam_lcredit: !!str 1
tags:
- always
- name: Ensure PAM variable lcredit is set accordingly
lineinfile:
create: true
dest: /etc/security/pwquality.conf
regexp: ^#?\s*lcredit
line: lcredit = {{ var_password_pam_lcredit }}
when: '"pam" in ansible_facts.packages'
tags:
- DISA-STIG-OL08-00-020120
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-5(1)(a)
- NIST-800-53-IA-5(4)
- NIST-800-53-IA-5(c)
- PCI-DSS-Req-8.2.3
- accounts_password_pam_lcredit
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
|
Ensure PAM Enforces Password Requirements - Minimum LengthruleThe pam_pwquality module's minlen parameter controls requirements for
minimum characters required in a password. Add minlen=18
after pam_pwquality to set minimum password length requirements. Rationale:The shorter the password, the lower the number of possible combinations
that need to be tested before the password is compromised.
Password complexity, or strength, is a measure of the effectiveness of a
password in resisting attempts at guessing and brute-force attacks.
Password length is one factor of several that helps to determine strength
and how long it takes to crack a password. Use of more characters in a password
helps to exponentially increase the time and/or resources required to
compromose the password. references:
1, 12, 15, 16, 5, SR 1.1, SR 1.10, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.7, SR 1.8, SR 1.9, SR 2.1, IA-5(c), IA-5(1)(a), CM-6(a), IA-5(4), SRG-OS-000078-GPOS-00046, PR.AC-1, PR.AC-6, PR.AC-7, OL08-00-020230, SV-248699r779663_rule, BP28(R18), 4.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.2, 4.3.3.7.4, 0421, 0422, 0431, 0974, 1173, 1401, 1504, 1505, 1546, 1557, 1558, 1559, 1560, 1561, 5.6.2.1.1, SRG-OS-000072-VMM-000390, SRG-OS-000078-VMM-000450, Req-8.2.3, A.18.1.4, A.7.1.1, A.9.2.1, A.9.2.2, A.9.2.3, A.9.2.4, A.9.2.6, A.9.3.1, A.9.4.2, A.9.4.3, FMT_MOF_EXT.1, CCI-000205, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.10 Remediation script:# Remediation is applicable only in certain platforms
if rpm --quiet -q pam; then
var_password_pam_minlen='18'
# Test if the config_file is a symbolic link. If so, use --follow-symlinks with sed.
# Otherwise, regular sed command will do.
sed_command=('sed' '-i')
if test -L "/etc/security/pwquality.conf"; then
sed_command+=('--follow-symlinks')
fi
# 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' <<< "^minlen")
# shellcheck disable=SC2059
printf -v formatted_output "%s = %s" "$stripped_key" "$var_password_pam_minlen"
# 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 "^minlen\\>" "/etc/security/pwquality.conf"; then
"${sed_command[@]}" "s/^minlen\\>.*/$formatted_output/gi" "/etc/security/pwquality.conf"
else
# \n is precaution for case where file ends without trailing newline
printf '%s\n' "$formatted_output" >> "/etc/security/pwquality.conf"
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
Remediation script:- name: Gather the package facts
package_facts:
manager: auto
tags:
- CJIS-5.6.2.1.1
- DISA-STIG-OL08-00-020230
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-5(1)(a)
- NIST-800-53-IA-5(4)
- NIST-800-53-IA-5(c)
- PCI-DSS-Req-8.2.3
- accounts_password_pam_minlen
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: XCCDF Value var_password_pam_minlen # promote to variable
set_fact:
var_password_pam_minlen: !!str 18
tags:
- always
- name: Ensure PAM variable minlen is set accordingly
lineinfile:
create: true
dest: /etc/security/pwquality.conf
regexp: ^#?\s*minlen
line: minlen = {{ var_password_pam_minlen }}
when: '"pam" in ansible_facts.packages'
tags:
- CJIS-5.6.2.1.1
- DISA-STIG-OL08-00-020230
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-5(1)(a)
- NIST-800-53-IA-5(4)
- NIST-800-53-IA-5(c)
- PCI-DSS-Req-8.2.3
- accounts_password_pam_minlen
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
|
Ensure PAM Enforces Password Requirements - Minimum Special CharactersruleThe pam_pwquality module's ocredit= parameter controls requirements for
usage of special (or "other") characters in a password. When set to a negative number,
any password will be required to contain that many special characters.
When set to a positive number, pam_pwquality will grant +1
additional length credit for each special character. Modify the ocredit setting
in /etc/security/pwquality.conf to equal 1
to require use of a special character in passwords. Rationale:Use of a complex password helps to increase the time and resources required
to compromise the password. Password complexity, or strength, is a measure of
the effectiveness of a password in resisting attempts at guessing and brute-force
attacks.
Password complexity is one factor of several that determines how long it takes
to crack a password. The more complex the password, the greater the number of
possble combinations that need to be tested before the password is compromised.
Requiring a minimum number of special characters makes password guessing attacks
more difficult by ensuring a larger search space. references:
1, 12, 15, 16, 5, 4.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.2, 4.3.3.7.4, SR 1.1, SR 1.10, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.7, SR 1.8, SR 1.9, SR 2.1, 0421, 0422, 0431, 0974, 1173, 1401, 1504, 1505, 1546, 1557, 1558, 1559, 1560, 1561, SRG-OS-000266-VMM-000940, IA-5(c), IA-5(1)(a), CM-6(a), IA-5(4), SRG-OS-000266-GPOS-00101, A.18.1.4, A.7.1.1, A.9.2.1, A.9.2.2, A.9.2.3, A.9.2.4, A.9.2.6, A.9.3.1, A.9.4.2, A.9.4.3, PR.AC-1, PR.AC-6, PR.AC-7, FMT_MOF_EXT.1, OL08-00-020280, SV-248709r779693_rule, CCI-001619, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.10, BP28(R18) Remediation script:# Remediation is applicable only in certain platforms
if rpm --quiet -q pam; then
var_password_pam_ocredit='1'
# Test if the config_file is a symbolic link. If so, use --follow-symlinks with sed.
# Otherwise, regular sed command will do.
sed_command=('sed' '-i')
if test -L "/etc/security/pwquality.conf"; then
sed_command+=('--follow-symlinks')
fi
# 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
"${sed_command[@]}" "s/^ocredit\\>.*/$formatted_output/gi" "/etc/security/pwquality.conf"
else
# \n is precaution for case where file ends without trailing newline
printf '%s\n' "$formatted_output" >> "/etc/security/pwquality.conf"
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
Remediation script:- name: Gather the package facts
package_facts:
manager: auto
tags:
- DISA-STIG-OL08-00-020280
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-5(1)(a)
- NIST-800-53-IA-5(4)
- NIST-800-53-IA-5(c)
- accounts_password_pam_ocredit
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: XCCDF Value var_password_pam_ocredit # promote to variable
set_fact:
var_password_pam_ocredit: !!str 1
tags:
- always
- name: Ensure PAM variable ocredit is set accordingly
lineinfile:
create: true
dest: /etc/security/pwquality.conf
regexp: ^#?\s*ocredit
line: ocredit = {{ var_password_pam_ocredit }}
when: '"pam" in ansible_facts.packages'
tags:
- DISA-STIG-OL08-00-020280
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-5(1)(a)
- NIST-800-53-IA-5(4)
- NIST-800-53-IA-5(c)
- accounts_password_pam_ocredit
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
|
Ensure PAM Enforces Password Requirements - Minimum Uppercase CharactersruleThe pam_pwquality module's ucredit= parameter controls requirements for
usage of uppercase letters in a password. When set to a negative number, any password will be required to
contain that many uppercase characters. When set to a positive number, pam_pwquality will grant +1 additional
length credit for each uppercase character. Modify the ucredit setting in
/etc/security/pwquality.conf to require the use of an uppercase character in passwords. Rationale:Use of a complex password helps to increase the time and resources reuiqred to compromise the password.
Password complexity, or strength, is a measure of the effectiveness of a password in resisting attempts
at guessing and brute-force attacks.
Password complexity is one factor of several that determines how long it takes to crack a password. The more
complex the password, the greater the number of possible combinations that need to be tested before
the password is compromised. references:
1, 12, 15, 16, 5, 4.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.2, 4.3.3.7.4, SR 1.1, SR 1.10, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.7, SR 1.8, SR 1.9, SR 2.1, 0421, 0422, 0431, 0974, 1173, 1401, 1504, 1505, 1546, 1557, 1558, 1559, 1560, 1561, Req-8.2.3, SRG-OS-000069-VMM-000360, IA-5(c), IA-5(1)(a), CM-6(a), IA-5(4), SRG-OS-000069-GPOS-00037, A.18.1.4, A.7.1.1, A.9.2.1, A.9.2.2, A.9.2.3, A.9.2.4, A.9.2.6, A.9.3.1, A.9.4.2, A.9.4.3, PR.AC-1, PR.AC-6, PR.AC-7, FMT_MOF_EXT.1, OL08-00-020110, SV-248687r779627_rule, CCI-000192, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.10, BP28(R18) Remediation script:# Remediation is applicable only in certain platforms
if rpm --quiet -q pam; then
var_password_pam_ucredit='1'
# Test if the config_file is a symbolic link. If so, use --follow-symlinks with sed.
# Otherwise, regular sed command will do.
sed_command=('sed' '-i')
if test -L "/etc/security/pwquality.conf"; then
sed_command+=('--follow-symlinks')
fi
# 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
"${sed_command[@]}" "s/^ucredit\\>.*/$formatted_output/gi" "/etc/security/pwquality.conf"
else
# \n is precaution for case where file ends without trailing newline
printf '%s\n' "$formatted_output" >> "/etc/security/pwquality.conf"
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
Remediation script:- name: Gather the package facts
package_facts:
manager: auto
tags:
- DISA-STIG-OL08-00-020110
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-5(1)(a)
- NIST-800-53-IA-5(4)
- NIST-800-53-IA-5(c)
- PCI-DSS-Req-8.2.3
- accounts_password_pam_ucredit
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: XCCDF Value var_password_pam_ucredit # promote to variable
set_fact:
var_password_pam_ucredit: !!str 1
tags:
- always
- name: Ensure PAM variable ucredit is set accordingly
lineinfile:
create: true
dest: /etc/security/pwquality.conf
regexp: ^#?\s*ucredit
line: ucredit = {{ var_password_pam_ucredit }}
when: '"pam" in ansible_facts.packages'
tags:
- DISA-STIG-OL08-00-020110
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-5(1)(a)
- NIST-800-53-IA-5(4)
- NIST-800-53-IA-5(c)
- PCI-DSS-Req-8.2.3
- accounts_password_pam_ucredit
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
|
Set Password Hashing AlgorithmgroupThe system's default algorithm for storing password hashes in
/etc/shadow is SHA-512. This can be configured in several
locations. |
contains 1 rule |
Set PAM's Password Hashing AlgorithmruleThe PAM system service can be configured to only store encrypted
representations of passwords. In
/etc/pam.d/system-auth ,
the
password section of the file controls which PAM modules execute
during a password change. Set the pam_unix.so module in the
password section to include the argument sha512 , as shown
below:
password sufficient pam_unix.so sha512 other arguments...
This will help ensure when local users change their passwords, hashes for
the new passwords will be generated using the SHA-512 algorithm. This is
the default.Rationale:Passwords need to be protected at all times, and encryption is the standard
method for protecting passwords. If passwords are not encrypted, they can
be plainly read (i.e., clear text) and easily compromised. Passwords that
are encrypted with a weak algorithm are no more protected than if they are
kepy in plain text.
This setting ensures user and group account administration utilities are
configured to store only encrypted representations of passwords.
Additionally, the crypt_style configuration option ensures the use
of a strong hashing algorithm that makes password cracking attacks more
difficult. references:
1, 12, 15, 16, 5, SR 1.1, SR 1.10, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.7, SR 1.8, SR 1.9, SR 2.1, 3.13.11, SRG-OS-000073-GPOS-00041, PR.AC-1, PR.AC-6, PR.AC-7, OL08-00-010160, SV-248544r779198_rule, BP28(R32), 4.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.2, 4.3.3.7.4, IA-5(c), IA-5(1)(c), CM-6(a), 0418, 1055, 1402, 5.6.2.2, SRG-OS-000480-VMM-002000, Req-8.2.1, A.18.1.4, A.7.1.1, A.9.2.1, A.9.2.2, A.9.2.3, A.9.2.4, A.9.2.6, A.9.3.1, A.9.4.2, A.9.4.3, CCI-000196, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.10 Remediation script:# Remediation is applicable only in certain platforms
if rpm --quiet -q pam; then
AUTH_FILES[0]="/etc/pam.d/system-auth"
for pamFile in "${AUTH_FILES[@]}"
do
if ! grep -q "^password.*sufficient.*pam_unix.so.*sha512" $pamFile; then
sed -i --follow-symlinks "/^password.*sufficient.*pam_unix.so/ s/$/ sha512/" $pamFile
fi
done
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Protect Accounts by Restricting Password-Based LogingroupConventionally, Unix shell accounts are accessed by
providing a username and password to a login program, which tests
these values for correctness using the /etc/passwd and
/etc/shadow files. Password-based login is vulnerable to
guessing of weak passwords, and to sniffing and man-in-the-middle
attacks against passwords entered over a network or at an insecure
console. Therefore, mechanisms for accessing accounts by entering
usernames and passwords should be restricted to those which are
operationally necessary. |
contains 4 rules |
Set Password Expiration ParametersgroupThe file /etc/login.defs controls several
password-related settings. Programs such as passwd ,
su , and
login consult /etc/login.defs to determine
behavior with regard to password aging, expiration warnings,
and length. See the man page login.defs(5) for more information.
Users should be forced to change their passwords, in order to
decrease the utility of compromised passwords. However, the need to
change passwords often should be balanced against the risk that
users will reuse or write down passwords if forced to change them
too often. Forcing password changes every 90-360 days, depending on
the environment, is recommended. Set the appropriate value as
PASS_MAX_DAYS and apply it to existing accounts with the
-M flag.
The PASS_MIN_DAYS (-m ) setting prevents password
changes for 7 days after the first change, to discourage password
cycling. If you use this setting, train users to contact an administrator
for an emergency password change in case a new password becomes
compromised. The PASS_WARN_AGE (-W ) setting gives
users 7 days of warnings at login time that their passwords are about to expire.
For example, for each existing human user USER, expiration parameters
could be adjusted to a 180 day maximum password age, 7 day minimum password
age, and 7 day warning period with the following command:
$ sudo chage -M 180 -m 7 -W 7 USER |
contains 2 rules |
Set Password Maximum AgeruleTo specify password maximum age for new accounts,
edit the file /etc/login.defs
and add or correct the following line:
PASS_MAX_DAYS 90
A value of 180 days is sufficient for many environments.
The DoD requirement is 60.
The profile requirement is 90 .Rationale:Any password, no matter how complex, can eventually be cracked. Therefore, passwords
need to be changed periodically. If the operating system does not limit the lifetime
of passwords and force users to change their passwords, there is the risk that the
operating system passwords could be compromised.
Setting the password maximum age ensures users are required to
periodically change their passwords. Requiring shorter password lifetimes
increases the risk of users writing down the password in a convenient
location subject to physical compromise. references:
1, 12, 15, 16, 5, 4.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.2, 4.3.3.7.4, SR 1.1, SR 1.10, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.7, SR 1.8, SR 1.9, SR 2.1, 0418, 1055, 1402, 5.6.2.1, Req-8.2.4, 3.5.6, SRG-OS-000076-GPOS-00044, A.18.1.4, A.7.1.1, A.9.2.1, A.9.2.2, A.9.2.3, A.9.2.4, A.9.2.6, A.9.3.1, A.9.4.2, A.9.4.3, PR.AC-1, PR.AC-6, PR.AC-7, IA-5(f), IA-5(1)(d), CM-6(a), OL08-00-020200, SV-248696r779654_rule, CCI-000199, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.10, BP28(R18) Remediation script:# Remediation is applicable only in certain platforms
if rpm --quiet -q shadow-utils; then
var_accounts_maximum_age_login_defs='90'
grep -q ^PASS_MAX_DAYS /etc/login.defs && \
sed -i "s/PASS_MAX_DAYS.*/PASS_MAX_DAYS $var_accounts_maximum_age_login_defs/g" /etc/login.defs
if ! [ $? -eq 0 ]; then
echo "PASS_MAX_DAYS $var_accounts_maximum_age_login_defs" >> /etc/login.defs
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
Remediation script:- name: Gather the package facts
package_facts:
manager: auto
tags:
- CJIS-5.6.2.1
- DISA-STIG-OL08-00-020200
- NIST-800-171-3.5.6
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-5(1)(d)
- NIST-800-53-IA-5(f)
- PCI-DSS-Req-8.2.4
- accounts_maximum_age_login_defs
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: XCCDF Value var_accounts_maximum_age_login_defs # promote to variable
set_fact:
var_accounts_maximum_age_login_defs: !!str 90
tags:
- always
- name: Set Password Maximum Age
lineinfile:
create: true
dest: /etc/login.defs
regexp: ^#?PASS_MAX_DAYS
line: PASS_MAX_DAYS {{ var_accounts_maximum_age_login_defs }}
when: '"shadow-utils" in ansible_facts.packages'
tags:
- CJIS-5.6.2.1
- DISA-STIG-OL08-00-020200
- NIST-800-171-3.5.6
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-5(1)(d)
- NIST-800-53-IA-5(f)
- PCI-DSS-Req-8.2.4
- accounts_maximum_age_login_defs
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
|
Set Password Minimum Length in login.defsruleTo specify password length requirements for new accounts, edit the file
/etc/login.defs and add or correct the following line:
PASS_MIN_LEN 18
The DoD requirement is 15 .
The FISMA requirement is 12 .
The profile requirement is
18 .
If a program consults /etc/login.defs and also another PAM module
(such as pam_pwquality ) during a password change operation, then
the most restrictive must be satisfied. See PAM section for more
information about enforcing password quality requirements.Rationale:Requiring a minimum password length makes password
cracking attacks more difficult by ensuring a larger
search space. However, any security benefit from an onerous requirement
must be carefully weighed against usability problems, support costs, or counterproductive
behavior that may result. references:
1, 12, 15, 16, 5, 4.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.2, 4.3.3.7.4, SR 1.1, SR 1.10, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.7, SR 1.8, SR 1.9, SR 2.1, 0421, 0422, 0431, 0974, 1173, 1401, 1504, 1505, 1546, 1557, 1558, 1559, 1560, 1561, 5.6.2.1, 3.5.7, SRG-OS-000078-GPOS-00046, A.18.1.4, A.7.1.1, A.9.2.1, A.9.2.2, A.9.2.3, A.9.2.4, A.9.2.6, A.9.3.1, A.9.4.2, A.9.4.3, PR.AC-1, PR.AC-6, PR.AC-7, FMT_MOF_EXT.1, IA-5(f), IA-5(1)(a), CM-6(a), OL08-00-020231, SV-248700r779666_rule, CCI-000205, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.10, BP28(R18) Remediation script:# Remediation is applicable only in certain platforms
if rpm --quiet -q shadow-utils; then
var_accounts_password_minlen_login_defs='18'
grep -q ^PASS_MIN_LEN /etc/login.defs && \
sed -i "s/PASS_MIN_LEN.*/PASS_MIN_LEN\t$var_accounts_password_minlen_login_defs/g" /etc/login.defs
if ! [ $? -eq 0 ]
then
echo -e "PASS_MIN_LEN\t$var_accounts_password_minlen_login_defs" >> /etc/login.defs
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
Remediation script:- name: Gather the package facts
package_facts:
manager: auto
tags:
- CJIS-5.6.2.1
- DISA-STIG-OL08-00-020231
- NIST-800-171-3.5.7
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-5(1)(a)
- NIST-800-53-IA-5(f)
- accounts_password_minlen_login_defs
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: XCCDF Value var_accounts_password_minlen_login_defs # promote to variable
set_fact:
var_accounts_password_minlen_login_defs: !!str 18
tags:
- always
- name: Set Password Minimum Length in login.defs
lineinfile:
dest: /etc/login.defs
regexp: ^PASS_MIN_LEN *[0-9]*
state: present
line: PASS_MIN_LEN {{ var_accounts_password_minlen_login_defs }}
create: true
when: '"shadow-utils" in ansible_facts.packages'
tags:
- CJIS-5.6.2.1
- DISA-STIG-OL08-00-020231
- NIST-800-171-3.5.7
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-5(1)(a)
- NIST-800-53-IA-5(f)
- accounts_password_minlen_login_defs
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
|
Verify Proper Storage and Existence of Password
HashesgroupBy default, password hashes for local accounts are stored
in the second field (colon-separated) in
/etc/shadow . This file should be readable only by
processes running with root credentials, preventing users from
casually accessing others' password hashes and attempting
to crack them.
However, it remains possible to misconfigure the system
and store password hashes
in world-readable files such as /etc/passwd , or
to even store passwords themselves in plaintext on the system.
Using system-provided tools for password change/creation
should allow administrators to avoid such misconfiguration. |
contains 2 rules |
Set number of Password Hashing Rounds - password-authruleConfigure the number or rounds for the password hashing algorithm. This can be
accomplished by using the rounds option for the pam_unix PAM module.
In file /etc/pam.d/password-auth append rounds=65536
to the pam_unix.so file, as shown below:
password sufficient pam_unix.so ...existing_options... rounds=65536
The system's default number of rounds is 5000.warning
Setting a high number of hashing rounds makes it more difficult to brute force the password,
but requires more CPU resources to authenticate users. Rationale:Using a higher number of rounds makes password cracking attacks more difficult. Remediation script:# Remediation is applicable only in certain platforms
if rpm --quiet -q pam; then
var_password_pam_unix_rounds='65536'
if [ -f /usr/bin/authselect ]; then
if authselect check; then
CURRENT_PROFILE=$(authselect current -r | awk '{ print $1 }')
# Standard profiles delivered with authselect should not be modified.
# 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"
# Ensure a backup before changing the profile
authselect apply-changes -b --backup=before-rounds-hardening.backup
authselect select $CURRENT_PROFILE
for feature in $ENABLED_FEATURES; do
authselect enable-feature $feature;
done
fi
# Include the desired configuration in the custom profile
CUSTOM_PASSWORD_AUTH="/etc/authselect/$CURRENT_PROFILE/password-auth"
if ! grep -q "^\s*password.*pam_unix.so.*rounds=" $CUSTOM_PASSWORD_AUTH; then
sed -i --follow-symlinks "/^\s*password.*pam_unix.so/ s/$/ rounds=$var_password_pam_unix_rounds/" $CUSTOM_PASSWORD_AUTH
else
sed -r -i --follow-symlinks "s/(^\s*password.*pam_unix.so.*)(rounds=[[:digit:]]+)(.*)/\1rounds=$var_password_pam_unix_rounds \3/g" $CUSTOM_PASSWORD_AUTH
fi
authselect apply-changes -b --backup=after-rounds-hardening.backup
else
echo "
authselect integrity check failed. Remediation aborted!
This remediation could not be applied because the authselect profile is not intact.
It is not recommended to manually edit the PAM files when authselect is available.
In cases where the default authselect profile does not cover a specific demand, a custom authselect profile is recommended."
false
fi
else
pamFile="/etc/pam.d/password-auth"
if grep -q "rounds=" $pamFile; then
sed -iP --follow-symlinks "/password[[:space:]]\+sufficient[[:space:]]\+pam_unix\.so/ \
s/rounds=[[:digit:]]\+/rounds=$var_password_pam_unix_rounds/" $pamFile
else
sed -iP --follow-symlinks "/password[[:space:]]\+sufficient[[:space:]]\+pam_unix\.so/ s/$/ rounds=$var_password_pam_unix_rounds/" $pamFile
fi
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
Remediation script:- name: Gather the package facts
package_facts:
manager: auto
tags:
- DISA-STIG-OL08-00-010130
- accounts_password_pam_unix_rounds_password_auth
- configure_strategy
- low_complexity
- medium_disruption
- medium_severity
- no_reboot_needed
- name: XCCDF Value var_password_pam_unix_rounds # promote to variable
set_fact:
var_password_pam_unix_rounds: !!str 65536
tags:
- always
- name: Check for existing rounds parameter
ansible.builtin.lineinfile:
path: /etc/pam.d/password-auth
create: false
regexp: ^password.*pam_unix.so.*rounds=
state: absent
check_mode: true
changed_when: false
register: result_pam_unix_rounds_present
when: '"pam" in ansible_facts.packages'
tags:
- DISA-STIG-OL08-00-010130
- accounts_password_pam_unix_rounds_password_auth
- configure_strategy
- low_complexity
- medium_disruption
- medium_severity
- no_reboot_needed
- name: Check if system relies on authselect
ansible.builtin.stat:
path: /usr/bin/authselect
register: result_authselect_present
when: '"pam" in ansible_facts.packages'
tags:
- DISA-STIG-OL08-00-010130
- accounts_password_pam_unix_rounds_password_auth
- configure_strategy
- low_complexity
- medium_disruption
- medium_severity
- no_reboot_needed
- name: Remediation where authselect tool is present
block:
- name: Check the integrity of the current authselect profile
ansible.builtin.command:
cmd: authselect check
register: result_authselect_check_cmd
changed_when: false
ignore_errors: true
- name: Informative message based on the authselect integrity check result
ansible.builtin.assert:
that:
- result_authselect_check_cmd is success
fail_msg:
- authselect integrity check failed. Remediation aborted!
- This remediation could not be applied because the authselect profile is
not intact.
- It is not recommended to manually edit the PAM files when authselect is
available.
- In cases where the default authselect profile does not cover a specific
demand, a custom authselect profile is recommended.
success_msg:
- authselect integrity check passed
- name: Get authselect current profile
ansible.builtin.shell:
cmd: authselect current -r | awk '{ print $1 }'
register: result_authselect_profile
changed_when: false
when:
- result_authselect_check_cmd is success
- name: Define the current authselect profile as a local fact
ansible.builtin.set_fact:
authselect_current_profile: '{{ result_authselect_profile.stdout }}'
authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
when:
- result_authselect_profile is not skipped
- result_authselect_profile.stdout is match("custom/")
- name: Define the new authselect custom profile as a local fact
ansible.builtin.set_fact:
authselect_current_profile: '{{ result_authselect_profile.stdout }}'
authselect_custom_profile: custom/hardening
when:
- result_authselect_profile is not skipped
- result_authselect_profile.stdout is not match("custom/")
- name: Get authselect current features to also enable them in the custom profile
ansible.builtin.shell:
cmd: authselect current | tail -n+3 | awk '{ print $2 }'
register: result_authselect_features
changed_when: false
when:
- result_authselect_profile is not skipped
- authselect_current_profile is not match("custom/")
- name: Check if any custom profile with the same name was already created in
the past
ansible.builtin.stat:
path: /etc/authselect/{{ authselect_custom_profile }}
register: result_authselect_custom_profile_present
changed_when: false
when:
- authselect_current_profile is not match("custom/")
- name: Create a custom profile based on the current profile
ansible.builtin.command:
cmd: authselect create-profile hardening -b sssd
when:
- result_authselect_check_cmd is success
- authselect_current_profile is not match("custom/")
- not result_authselect_custom_profile_present.stat.exists
- name: Ensure the desired rounds value is updated in the custom profile
ansible.builtin.replace:
dest: /etc/authselect/{{ authselect_custom_profile }}/password-auth
regexp: (^\s*password.*pam_unix.so.*rounds=)(\S+)(.*)$
replace: \g<1>{{ var_password_pam_unix_rounds }}\g<3>
when:
- result_authselect_profile is not skipped
- result_pam_unix_rounds_present.found == 1
- name: Ensure the rounds parameter is included in the custom profile
ansible.builtin.replace:
dest: /etc/authselect/{{ authselect_custom_profile }}/password-auth
regexp: (^\s*password.*pam_unix.so.*)(?! rounds=\S+)(.*)$
replace: \g<1> \g<2> rounds={{ var_password_pam_unix_rounds }}
when:
- result_authselect_profile is not skipped
- result_pam_unix_rounds_present.found == 0
- name: Ensure a backup of current authselect profile before selecting the custom
profile
ansible.builtin.command:
cmd: authselect apply-changes -b --backup=before-rounds-hardening.backup
when:
- result_authselect_check_cmd is success
- result_authselect_profile is not skipped
- authselect_current_profile is not match("custom/")
- authselect_custom_profile is not match(authselect_current_profile)
- name: Ensure the custom profile is selected
ansible.builtin.command:
cmd: authselect select {{ authselect_custom_profile }} --force
register: result_pam_authselect_select_profile
when:
- result_authselect_check_cmd is success
- result_authselect_profile is not skipped
- authselect_current_profile is not match("custom/")
- authselect_custom_profile is not match(authselect_current_profile)
- name: Restore the authselect features in the custom profile
ansible.builtin.command:
cmd: authselect enable-feature {{ item }}
loop: '{{ result_authselect_features.stdout_lines }}'
when:
- result_authselect_profile is not skipped
- result_authselect_features is not skipped
- result_pam_authselect_select_profile is not skipped
- name: Ensure the custom profile changes are applied
ansible.builtin.command:
cmd: authselect apply-changes -b --backup=after-rounds-hardening.backup
when:
- result_authselect_check_cmd is success
- result_authselect_profile is not skipped
when:
- '"pam" in ansible_facts.packages'
- result_authselect_present.stat.exists
tags:
- DISA-STIG-OL08-00-010130
- accounts_password_pam_unix_rounds_password_auth
- configure_strategy
- low_complexity
- medium_disruption
- medium_severity
- no_reboot_needed
- name: Remediation where authselect tool is not present and PAM files are directly
edited
block:
- name: Ensure the desired rounds value is updated in the custom profile
ansible.builtin.replace:
dest: /etc/pam.d/password-auth
regexp: (^\s*password.*pam_unix.so.*rounds=)(\S+)(.*)$
replace: \g<1>{{ var_password_pam_unix_rounds }}\g<3>
- name: Ensure the remember parameter is included in the custom profile
ansible.builtin.replace:
dest: /etc/pam.d/password-auth
regexp: (^\s*password.*pam_unix.so.*)(?! rounds=\S+)(.*)$
replace: \g<1> \g<2> rounds={{ var_password_pam_unix_rounds }}
when:
- result_pam_unix_rounds_present.found == 0
when:
- '"pam" in ansible_facts.packages'
- not result_authselect_present.stat.exists
tags:
- DISA-STIG-OL08-00-010130
- accounts_password_pam_unix_rounds_password_auth
- configure_strategy
- low_complexity
- medium_disruption
- medium_severity
- no_reboot_needed
|
Set number of Password Hashing Rounds - system-authruleConfigure the number or rounds for the password hashing algorithm. This can be
accomplished by using the rounds option for the pam_unix PAM module.
In file /etc/pam.d/system-auth append rounds=65536
to the pam_unix.so file, as shown below:
password sufficient pam_unix.so ...existing_options... rounds=65536
The system's default number of rounds is 5000.warning
Setting a high number of hashing rounds makes it more difficult to brute force the password,
but requires more CPU resources to authenticate users. Rationale:Using a higher number of rounds makes password cracking attacks more difficult. Remediation script:# Remediation is applicable only in certain platforms
if rpm --quiet -q pam; then
var_password_pam_unix_rounds='65536'
if [ -f /usr/bin/authselect ]; then
if authselect check; then
CURRENT_PROFILE=$(authselect current -r | awk '{ print $1 }')
# Standard profiles delivered with authselect should not be modified.
# 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"
# Ensure a backup before changing the profile
authselect apply-changes -b --backup=before-rounds-hardening.backup
authselect select $CURRENT_PROFILE
for feature in $ENABLED_FEATURES; do
authselect enable-feature $feature;
done
fi
# Include the desired configuration in the custom profile
CUSTOM_SYSTEM_AUTH="/etc/authselect/$CURRENT_PROFILE/system-auth"
if ! grep -q "^\s*password.*pam_unix.so.*rounds=" $CUSTOM_SYSTEM_AUTH; then
sed -i --follow-symlinks "/^\s*password.*pam_unix.so/ s/$/ rounds=$var_password_pam_unix_rounds/" $CUSTOM_SYSTEM_AUTH
else
sed -r -i --follow-symlinks "s/(^\s*password.*pam_unix.so.*)(rounds=[[:digit:]]+)(.*)/\1rounds=$var_password_pam_unix_rounds \3/g" $CUSTOM_SYSTEM_AUTH
fi
authselect apply-changes -b --backup=after-rounds-hardening.backup
else
echo "
authselect integrity check failed. Remediation aborted!
This remediation could not be applied because the authselect profile is not intact.
It is not recommended to manually edit the PAM files when authselect is available.
In cases where the default authselect profile does not cover a specific demand, a custom authselect profile is recommended."
false
fi
else
pamFile="/etc/pam.d/system-auth"
if grep -q "rounds=" $pamFile; then
sed -iP --follow-symlinks "/password[[:space:]]\+sufficient[[:space:]]\+pam_unix\.so/ \
s/rounds=[[:digit:]]\+/rounds=$var_password_pam_unix_rounds/" $pamFile
else
sed -iP --follow-symlinks "/password[[:space:]]\+sufficient[[:space:]]\+pam_unix\.so/ s/$/ rounds=$var_password_pam_unix_rounds/" $pamFile
fi
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
Remediation script:- name: Gather the package facts
package_facts:
manager: auto
tags:
- DISA-STIG-OL08-00-010131
- accounts_password_pam_unix_rounds_system_auth
- configure_strategy
- low_complexity
- medium_disruption
- medium_severity
- no_reboot_needed
- name: XCCDF Value var_password_pam_unix_rounds # promote to variable
set_fact:
var_password_pam_unix_rounds: !!str 65536
tags:
- always
- name: Check for existing rounds parameter
ansible.builtin.lineinfile:
path: /etc/pam.d/system-auth
create: false
regexp: ^password.*pam_unix.so.*rounds=
state: absent
check_mode: true
changed_when: false
register: result_pam_unix_rounds_present
when: '"pam" in ansible_facts.packages'
tags:
- DISA-STIG-OL08-00-010131
- accounts_password_pam_unix_rounds_system_auth
- configure_strategy
- low_complexity
- medium_disruption
- medium_severity
- no_reboot_needed
- name: Check if system relies on authselect
ansible.builtin.stat:
path: /usr/bin/authselect
register: result_authselect_present
when: '"pam" in ansible_facts.packages'
tags:
- DISA-STIG-OL08-00-010131
- accounts_password_pam_unix_rounds_system_auth
- configure_strategy
- low_complexity
- medium_disruption
- medium_severity
- no_reboot_needed
- name: Remediation where authselect tool is present
block:
- name: Check the integrity of the current authselect profile
ansible.builtin.command:
cmd: authselect check
register: result_authselect_check_cmd
changed_when: false
ignore_errors: true
- name: Informative message based on the authselect integrity check result
ansible.builtin.assert:
that:
- result_authselect_check_cmd is success
fail_msg:
- authselect integrity check failed. Remediation aborted!
- This remediation could not be applied because the authselect profile is
not intact.
- It is not recommended to manually edit the PAM files when authselect is
available.
- In cases where the default authselect profile does not cover a specific
demand, a custom authselect profile is recommended.
success_msg:
- authselect integrity check passed
- name: Get authselect current profile
ansible.builtin.shell:
cmd: authselect current -r | awk '{ print $1 }'
register: result_authselect_profile
changed_when: false
when:
- result_authselect_check_cmd is success
- name: Define the current authselect profile as a local fact
ansible.builtin.set_fact:
authselect_current_profile: '{{ result_authselect_profile.stdout }}'
authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
when:
- result_authselect_profile is not skipped
- result_authselect_profile.stdout is match("custom/")
- name: Define the new authselect custom profile as a local fact
ansible.builtin.set_fact:
authselect_current_profile: '{{ result_authselect_profile.stdout }}'
authselect_custom_profile: custom/hardening
when:
- result_authselect_profile is not skipped
- result_authselect_profile.stdout is not match("custom/")
- name: Get authselect current features to also enable them in the custom profile
ansible.builtin.shell:
cmd: authselect current | tail -n+3 | awk '{ print $2 }'
register: result_authselect_features
changed_when: false
when:
- result_authselect_profile is not skipped
- authselect_current_profile is not match("custom/")
- name: Check if any custom profile with the same name was already created in
the past
ansible.builtin.stat:
path: /etc/authselect/{{ authselect_custom_profile }}
register: result_authselect_custom_profile_present
changed_when: false
when:
- authselect_current_profile is not match("custom/")
- name: Create a custom profile based on the current profile
ansible.builtin.command:
cmd: authselect create-profile hardening -b sssd
when:
- result_authselect_check_cmd is success
- authselect_current_profile is not match("custom/")
- not result_authselect_custom_profile_present.stat.exists
- name: Ensure the desired rounds value is updated in the custom profile
ansible.builtin.replace:
dest: /etc/authselect/{{ authselect_custom_profile }}/system-auth
regexp: (^\s*password.*pam_unix.so.*rounds=)(\S+)(.*)$
replace: \g<1>{{ var_password_pam_unix_rounds }}\g<3>
when:
- result_authselect_profile is not skipped
- result_pam_unix_rounds_present.found == 1
- name: Ensure the rounds parameter is included in the custom profile
ansible.builtin.replace:
dest: /etc/authselect/{{ authselect_custom_profile }}/system-auth
regexp: (^\s*password.*pam_unix.so.*)(?! rounds=\S+)(.*)$
replace: \g<1> \g<2> rounds={{ var_password_pam_unix_rounds }}
when:
- result_authselect_profile is not skipped
- result_pam_unix_rounds_present.found == 0
- name: Ensure a backup of current authselect profile before selecting the custom
profile
ansible.builtin.command:
cmd: authselect apply-changes -b --backup=before-rounds-hardening.backup
when:
- result_authselect_check_cmd is success
- result_authselect_profile is not skipped
- authselect_current_profile is not match("custom/")
- authselect_custom_profile is not match(authselect_current_profile)
- name: Ensure the custom profile is selected
ansible.builtin.command:
cmd: authselect select {{ authselect_custom_profile }} --force
register: result_pam_authselect_select_profile
when:
- result_authselect_check_cmd is success
- result_authselect_profile is not skipped
- authselect_current_profile is not match("custom/")
- authselect_custom_profile is not match(authselect_current_profile)
- name: Restore the authselect features in the custom profile
ansible.builtin.command:
cmd: authselect enable-feature {{ item }}
loop: '{{ result_authselect_features.stdout_lines }}'
when:
- result_authselect_profile is not skipped
- result_authselect_features is not skipped
- result_pam_authselect_select_profile is not skipped
- name: Ensure the custom profile changes are applied
ansible.builtin.command:
cmd: authselect apply-changes -b --backup=after-rounds-hardening.backup
when:
- result_authselect_check_cmd is success
- result_authselect_profile is not skipped
when:
- '"pam" in ansible_facts.packages'
- result_authselect_present.stat.exists
tags:
- DISA-STIG-OL08-00-010131
- accounts_password_pam_unix_rounds_system_auth
- configure_strategy
- low_complexity
- medium_disruption
- medium_severity
- no_reboot_needed
- name: Remediation where authselect tool is not present and PAM files are directly
edited
block:
- name: Ensure the desired rounds value is updated in the custom profile
ansible.builtin.replace:
dest: /etc/pam.d/system-auth
regexp: (^\s*password.*pam_unix.so.*rounds=)(\S+)(.*)$
replace: \g<1>{{ var_password_pam_unix_rounds }}\g<3>
- name: Ensure the remember parameter is included in the custom profile
ansible.builtin.replace:
dest: /etc/pam.d/system-auth
regexp: (^\s*password.*pam_unix.so.*)(?! rounds=\S+)(.*)$
replace: \g<1> \g<2> rounds={{ var_password_pam_unix_rounds }}
when:
- result_pam_unix_rounds_present.found == 0
when:
- '"pam" in ansible_facts.packages'
- not result_authselect_present.stat.exists
tags:
- DISA-STIG-OL08-00-010131
- accounts_password_pam_unix_rounds_system_auth
- configure_strategy
- low_complexity
- medium_disruption
- medium_severity
- no_reboot_needed
|
Configure SysloggroupThe syslog service has been the default Unix logging mechanism for
many years. It has a number of downsides, including inconsistent log format,
lack of authentication for received messages, and lack of authentication,
encryption, or reliable transport for messages sent over a network. However,
due to its long history, syslog is a de facto standard which is supported by
almost all Unix applications.
In Oracle Linux 8, rsyslog has replaced ksyslogd as the
syslog daemon of choice, and it includes some additional security features
such as reliable, connection-oriented (i.e. TCP) transmission of logs, the
option to log to database formats, and the encryption of log data en route to
a central logging server.
This section discusses how to configure rsyslog for
best effect, and how to use tools provided with the system to maintain and
monitor logs. |
contains 2 rules |
Ensure rsyslog is InstalledruleRsyslog is installed by default. The rsyslog package can be installed with the following command: $ sudo yum install rsyslog Rationale:The rsyslog package provides the rsyslog daemon, which provides
system logging services. references:
1, 14, 15, 16, 3, 5, 6, 164.312(a)(2)(ii), 4.3.3.3.9, 4.3.3.5.8, 4.3.4.4.7, 4.4.2.1, 4.4.2.2, 4.4.2.4, SR 2.10, SR 2.11, SR 2.12, SR 2.8, SR 2.9, CM-6(a), SRG-OS-000479-GPOS-00224, SRG-OS-000051-GPOS-00024, SRG-OS-000480-GPOS-00227, A.12.4.1, A.12.4.2, A.12.4.3, A.12.4.4, A.12.7.1, PR.PT-1, FTP_ITC_EXT.1.1, OL08-00-030670, SV-248812r780002_rule, CCI-001311, CCI-001312, CCI-000366, APO11.04, BAI03.05, DSS05.04, DSS05.07, MEA02.01, BP28(R5), NT28(R46) Remediation script:# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
if ! rpm -q --quiet "rsyslog" ; then
yum install -y "rsyslog"
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
Remediation script:- name: Ensure rsyslog is installed
package:
name: rsyslog
state: present
when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
tags:
- DISA-STIG-OL08-00-030670
- NIST-800-53-CM-6(a)
- enable_strategy
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- package_rsyslog_installed
Remediation script:include install_rsyslog
class install_rsyslog {
package { 'rsyslog':
ensure => 'installed',
}
}
Remediation script:
package --add=rsyslog
Remediation script:
[[packages]]
name = "rsyslog"
version = "*"
|
Enable rsyslog ServiceruleThe rsyslog service provides syslog-style logging by default on Oracle Linux 8.
The rsyslog service can be enabled with the following command:
$ sudo systemctl enable rsyslog.service Rationale:The rsyslog service must be running in order to provide
logging services, which are essential to system administration. references:
1, 12, 13, 14, 15, 16, 2, 3, 5, 6, 7, 8, 9, 164.312(a)(2)(ii), 4.3.2.6.7, 4.3.3.3.9, 4.3.3.5.8, 4.3.4.4.7, 4.4.2.1, 4.4.2.2, 4.4.2.4, SR 2.10, SR 2.11, SR 2.12, SR 2.8, SR 2.9, SR 6.1, SR 6.2, SR 7.1, SR 7.2, CM-6(a), AU-4(1), SRG-OS-000480-GPOS-00227, A.12.1.3, A.12.4.1, A.12.4.2, A.12.4.3, A.12.4.4, A.12.7.1, A.14.2.7, A.15.2.1, A.15.2.2, A.17.2.1, DE.CM-1, DE.CM-3, DE.CM-7, ID.SC-4, PR.DS-4, PR.PT-1, OL08-00-010561, SV-248615r779411_rule, CCI-001311, CCI-001312, CCI-001557, CCI-001851, CCI-000366, APO10.01, APO10.03, APO10.04, APO10.05, APO11.04, APO13.01, BAI03.05, BAI04.04, DSS01.03, DSS03.05, DSS05.02, DSS05.04, DSS05.05, DSS05.07, MEA01.01, MEA01.02, MEA01.03, MEA01.04, MEA01.05, MEA02.01, BP28(R5), NT28(R46) Remediation script:# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
SYSTEMCTL_EXEC='/usr/bin/systemctl'
"$SYSTEMCTL_EXEC" unmask 'rsyslog.service'
"$SYSTEMCTL_EXEC" start 'rsyslog.service'
"$SYSTEMCTL_EXEC" enable 'rsyslog.service'
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
Remediation script:- name: Enable service rsyslog
block:
- name: Gather the package facts
package_facts:
manager: auto
- name: Enable service rsyslog
service:
name: rsyslog
enabled: 'yes'
state: started
masked: 'no'
when:
- '"rsyslog" in ansible_facts.packages'
when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
tags:
- DISA-STIG-OL08-00-010561
- NIST-800-53-AU-4(1)
- NIST-800-53-CM-6(a)
- enable_strategy
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- service_rsyslog_enabled
Remediation script:include enable_rsyslog
class enable_rsyslog {
service {'rsyslog':
enable => true,
ensure => 'running',
}
}
Remediation script:
[customizations.services]
enabled = ["rsyslog"]
|
File Permissions and MasksgroupTraditional Unix security relies heavily on file and
directory permissions to prevent unauthorized users from reading or
modifying files to which they should not have access.
Several of the commands in this section search filesystems
for files or directories with certain characteristics, and are
intended to be run on every local partition on a given system.
When the variable PART appears in one of the commands below,
it means that the command is intended to be run repeatedly, with the
name of each local partition substituted for PART in turn.
The following command prints a list of all xfs partitions on the local
system, which is the default filesystem for Oracle Linux 8
installations:
$ mount -t xfs | awk '{print $3}'
For any systems that use a different
local filesystem type, modify this command as appropriate. |
contains 2 rules |
Verify Permissions on Important Files and
DirectoriesgroupPermissions for many files on a system must be set
restrictively to ensure sensitive information is properly protected.
This section discusses important
permission restrictions which can be verified
to ensure that no harmful discrepancies have
arisen. |
contains 2 rules |
Ensure All SGID Executables Are AuthorizedruleThe SGID (set group id) bit should be set only on files that were
installed via authorized means. A straightforward means of identifying
unauthorized SGID files is determine if any were not installed as part of an
RPM package, which is cryptographically verified. Investigate the origin
of any unpackaged SGID files.
This configuration check considers authorized SGID files which were installed via RPM.
It is assumed that when an individual has sudo access to install an RPM
and all packages are signed with an organizationally-recognized GPG key,
the software should be considered an approved package on the system.
Any SGID file not deployed through an RPM will be flagged for further review. Rationale:Executable files with the SGID permission run with the privileges of
the owner of the file. SGID files of uncertain provenance could allow for
unprivileged users to elevate privileges. The presence of these files should be
strictly controlled on the system. references:
12, 13, 14, 15, 16, 18, 3, 5, 4.3.3.7.3, SR 2.1, SR 5.2, CM-6(a), AC-6(1), A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5, PR.AC-4, PR.DS-5, APO01.06, DSS05.04, DSS05.07, DSS06.02, BP28(R37), BP28(R38) |
Ensure All SUID Executables Are AuthorizedruleThe SUID (set user id) bit should be set only on files that were
installed via authorized means. A straightforward means of identifying
unauthorized SUID files is determine if any were not installed as part of an
RPM package, which is cryptographically verified. Investigate the origin
of any unpackaged SUID files.
This configuration check considers authorized SUID files which were installed via RPM.
It is assumed that when an individual has sudo access to install an RPM
and all packages are signed with an organizationally-recognized GPG key,
the software should be considered an approved package on the system.
Any SUID file not deployed through an RPM will be flagged for further review. Rationale:Executable files with the SUID permission run with the privileges of
the owner of the file. SUID files of uncertain provenance could allow for
unprivileged users to elevate privileges. The presence of these files should be
strictly controlled on the system. references:
12, 13, 14, 15, 16, 18, 3, 5, 4.3.3.7.3, SR 2.1, SR 5.2, CM-6(a), AC-6(1), A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5, PR.AC-4, PR.DS-5, APO01.06, DSS05.04, DSS05.07, DSS06.02, BP28(R37), BP28(R38) |
ServicesgroupThe best protection against vulnerable software is running less software. This section describes how to review
the software which Oracle Linux 8 installs on a system and disable software which is not needed. It
then enumerates the software packages installed on a default Oracle Linux 8 system and provides guidance about which
ones can be safely disabled.
Oracle Linux 8 provides a convenient minimal install option that essentially installs the bare necessities for a functional
system. When building Oracle Linux 8 systems, it is highly recommended to select the minimal packages and then build up
the system from there. |
contains 12 rules |
DHCPgroupThe Dynamic Host Configuration Protocol (DHCP) allows
systems to request and obtain an IP address and other configuration
parameters from a server.
This guide recommends configuring networking on clients by manually editing
the appropriate files under /etc/sysconfig . Use of DHCP can make client
systems vulnerable to compromise by rogue DHCP servers, and should be avoided
unless necessary. If using DHCP is necessary, however, there are best practices
that should be followed to minimize security risk. |
contains 1 rule |
Disable DHCP ServergroupThe DHCP server dhcpd is not installed or activated by
default. If the software was installed and activated, but the
system does not need to act as a DHCP server, it should be disabled
and removed. |
contains 1 rule |
Uninstall DHCP Server PackageruleIf the system does not need to act as a DHCP server,
the dhcp package can be uninstalled.
The dhcp package can be removed with the following command:
$ sudo yum erase dhcp Rationale:Removing the DHCP server ensures that it cannot be easily or
accidentally reactivated and disrupt network operation. references:
11, 14, 3, 9, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 7.6, CM-7(a), CM-7(b), CM-6(a), A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, A.9.1.2, PR.IP-1, PR.PT-3, CCI-000366, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.05, DSS06.06, BP28(R1) Remediation script:
# CAUTION: This remediation script will remove dhcp
# from the system, and may remove any packages
# that depend on dhcp. Execute this
# remediation AFTER testing on a non-production
# system!
if rpm -q --quiet "dhcp" ; then
yum remove -y "dhcp"
fi
Remediation script:- name: Ensure dhcp is removed
package:
name: dhcp
state: absent
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-CM-7(a)
- NIST-800-53-CM-7(b)
- disable_strategy
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- package_dhcp_removed
Remediation script:include remove_dhcp
class remove_dhcp {
package { 'dhcp':
ensure => 'purged',
}
}
Remediation script:
package --remove=dhcp
|
Mail Server SoftwaregroupMail servers are used to send and receive email over the network.
Mail is a very common service, and Mail Transfer Agents (MTAs) are obvious
targets of network attack.
Ensure that systems are not running MTAs unnecessarily,
and configure needed MTAs as defensively as possible.
Very few systems at any site should be configured to directly receive email over the
network. Users should instead use mail client programs to retrieve email
from a central server that supports protocols such as IMAP or POP3.
However, it is normal for most systems to be independently capable of sending email,
for instance so that cron jobs can report output to an administrator.
Most MTAs, including Postfix, support a submission-only mode in which mail can be sent from
the local system to a central site MTA (or directly delivered to a local account),
but the system still cannot receive mail directly over a network.
The alternatives program in Oracle Linux 8 permits selection of other mail server software
(such as Sendmail), but Postfix is the default and is preferred.
Postfix was coded with security in mind and can also be more effectively contained by
SELinux as its modular design has resulted in separate processes performing specific actions.
More information is available on its website,
http://www.postfix.org. |
contains 1 rule |
Uninstall Sendmail PackageruleSendmail is not the default mail transfer agent and is
not installed by default.
The sendmail package can be removed with the following command:
$ sudo yum erase sendmail Rationale:The sendmail software was not developed with security in mind and
its design prevents it from being effectively contained by SELinux. Postfix
should be used instead. references:
11, 14, 3, 9, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 7.6, CM-7(a), CM-7(b), CM-6(a), SRG-OS-000480-GPOS-00227, SRG-OS-000095-GPOS-00049, A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, A.9.1.2, PR.IP-1, PR.PT-3, OL08-00-040002, SV-248825r780041_rule, CCI-000381, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.05, DSS06.06, BP28(R1) Remediation script:# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
# CAUTION: This remediation script will remove sendmail
# from the system, and may remove any packages
# that depend on sendmail. Execute this
# remediation AFTER testing on a non-production
# system!
if rpm -q --quiet "sendmail" ; then
yum remove -y "sendmail"
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
Remediation script:- name: Ensure sendmail is removed
package:
name: sendmail
state: absent
when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
tags:
- DISA-STIG-OL08-00-040002
- NIST-800-53-CM-6(a)
- NIST-800-53-CM-7(a)
- NIST-800-53-CM-7(b)
- disable_strategy
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- package_sendmail_removed
Remediation script:include remove_sendmail
class remove_sendmail {
package { 'sendmail':
ensure => 'purged',
}
}
Remediation script:
package --remove=sendmail
|
Obsolete ServicesgroupThis section discusses a number of network-visible
services which have historically caused problems for system
security, and for which disabling or severely limiting the service
has been the best available guidance for some time. As a result of
this, many of these services are not installed as part of Oracle Linux 8
by default.
Organizations which are running these services should
switch to more secure equivalents as soon as possible.
If it remains absolutely necessary to run one of
these services for legacy reasons, care should be taken to restrict
the service as much as possible, for instance by configuring host
firewall software such as iptables to restrict access to the
vulnerable service to only those remote hosts which have a known
need to use it. |
contains 10 rules |
XinetdgroupThe xinetd service acts as a dedicated listener for some
network services (mostly, obsolete ones) and can be used to provide access
controls and perform some logging. It has been largely obsoleted by other
features, and it is not installed by default. The older Inetd service
is not even available as part of Oracle Linux 8. |
contains 1 rule |
Uninstall xinetd PackageruleThe xinetd package can be removed with the following command:
$ sudo yum erase xinetd Rationale:Removing the xinetd package decreases the risk of the
xinetd service's accidental (or intentional) activation. references:
11, 12, 14, 15, 3, 8, 9, 164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii), 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 7.1, SR 7.6, CM-7(a), CM-7(b), CM-6(a), A.11.2.6, A.12.1.2, A.12.5.1, A.12.6.2, A.13.1.1, A.13.2.1, A.14.1.3, A.14.2.2, A.14.2.3, A.14.2.4, A.6.2.1, A.6.2.2, A.9.1.2, PR.AC-3, PR.IP-1, PR.PT-3, PR.PT-4, CCI-000305, APO13.01, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS01.04, DSS05.02, DSS05.03, DSS05.05, DSS06.06, BP28(R1) Remediation script:# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
# CAUTION: This remediation script will remove xinetd
# from the system, and may remove any packages
# that depend on xinetd. Execute this
# remediation AFTER testing on a non-production
# system!
if rpm -q --quiet "xinetd" ; then
yum remove -y "xinetd"
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
Remediation script:- name: Ensure xinetd is removed
package:
name: xinetd
state: absent
when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-CM-7(a)
- NIST-800-53-CM-7(b)
- disable_strategy
- low_complexity
- low_disruption
- low_severity
- no_reboot_needed
- package_xinetd_removed
Remediation script:include remove_xinetd
class remove_xinetd {
package { 'xinetd':
ensure => 'purged',
}
}
Remediation script:
package --remove=xinetd
|
NISgroupThe Network Information Service (NIS), also known as 'Yellow
Pages' (YP), and its successor NIS+ have been made obsolete by
Kerberos, LDAP, and other modern centralized authentication
services. NIS should not be used because it suffers from security
problems inherent in its design, such as inadequate protection of
important authentication information. |
contains 2 rules |
Remove NIS ClientruleThe Network Information Service (NIS), formerly known as Yellow Pages,
is a client-server directory service protocol used to distribute system configuration
files. The NIS client (ypbind ) was used to bind a system to an NIS server
and receive the distributed configuration files. Rationale:The NIS service is inherently an insecure system that has been vulnerable
to DOS attacks, buffer overflows and has poor authentication for querying
NIS maps. NIS generally has been replaced by such protocols as Lightweight
Directory Access Protocol (LDAP). It is recommended that the service be
removed. Remediation script:
# CAUTION: This remediation script will remove ypbind
# from the system, and may remove any packages
# that depend on ypbind. Execute this
# remediation AFTER testing on a non-production
# system!
if rpm -q --quiet "ypbind" ; then
yum remove -y "ypbind"
fi
Remediation script:- name: Ensure ypbind is removed
package:
name: ypbind
state: absent
tags:
- disable_strategy
- low_complexity
- low_disruption
- no_reboot_needed
- package_ypbind_removed
- unknown_severity
Remediation script:include remove_ypbind
class remove_ypbind {
package { 'ypbind':
ensure => 'purged',
}
}
Remediation script:
package --remove=ypbind
|
Uninstall ypserv PackageruleThe ypserv package can be removed with the following command:
$ sudo yum erase ypserv Rationale:The NIS service provides an unencrypted authentication service which does
not provide for the confidentiality and integrity of user passwords or the
remote session.
Removing the ypserv package decreases the risk of the accidental
(or intentional) activation of NIS or NIS+ services. references:
11, 12, 14, 15, 3, 8, 9, 164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii), 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 7.1, SR 7.6, CM-7(a), CM-7(b), CM-6(a), IA-5(1)(c), SRG-OS-000095-GPOS-00049, A.11.2.6, A.12.1.2, A.12.5.1, A.12.6.2, A.13.1.1, A.13.2.1, A.14.1.3, A.14.2.2, A.14.2.3, A.14.2.4, A.6.2.1, A.6.2.2, A.9.1.2, PR.AC-3, PR.IP-1, PR.PT-3, PR.PT-4, CCI-000381, APO13.01, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS01.04, DSS05.02, DSS05.03, DSS05.05, DSS06.06, BP28(R1) Remediation script:
# CAUTION: This remediation script will remove ypserv
# from the system, and may remove any packages
# that depend on ypserv. Execute this
# remediation AFTER testing on a non-production
# system!
if rpm -q --quiet "ypserv" ; then
yum remove -y "ypserv"
fi
Remediation script:- name: Ensure ypserv is removed
package:
name: ypserv
state: absent
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-CM-7(a)
- NIST-800-53-CM-7(b)
- NIST-800-53-IA-5(1)(c)
- disable_strategy
- high_severity
- low_complexity
- low_disruption
- no_reboot_needed
- package_ypserv_removed
Remediation script:include remove_ypserv
class remove_ypserv {
package { 'ypserv':
ensure => 'purged',
}
}
Remediation script:
package --remove=ypserv
|
Rlogin, Rsh, and RexecgroupThe Berkeley r-commands are legacy services which
allow cleartext remote access and have an insecure trust
model. |
contains 2 rules |
Uninstall rsh-server PackageruleThe rsh-server package can be removed with the following command:
$ sudo yum erase rsh-server Rationale:The rsh-server service provides unencrypted remote access service which does not
provide for the confidentiality and integrity of user passwords or the remote session and has very weak
authentication. If a privileged user were to login using this service, the privileged user password
could be compromised. The rsh-server package provides several obsolete and insecure
network services. Removing it decreases the risk of those services' accidental (or intentional)
activation. references:
11, 12, 14, 15, 3, 8, 9, 164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii), 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 7.1, SR 7.6, CM-7(a), CM-7(b), CM-6(a), IA-5(1)(c), SRG-OS-000095-GPOS-00049, A.11.2.6, A.12.1.2, A.12.5.1, A.12.6.2, A.13.1.1, A.13.2.1, A.14.1.3, A.14.2.2, A.14.2.3, A.14.2.4, A.6.2.1, A.6.2.2, A.9.1.2, PR.AC-3, PR.IP-1, PR.PT-3, PR.PT-4, OL08-00-040010, SV-248827r780047_rule, CCI-000381, APO13.01, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS01.04, DSS05.02, DSS05.03, DSS05.05, DSS06.06, BP28(R1) Remediation script:
# CAUTION: This remediation script will remove rsh-server
# from the system, and may remove any packages
# that depend on rsh-server. Execute this
# remediation AFTER testing on a non-production
# system!
if rpm -q --quiet "rsh-server" ; then
yum remove -y "rsh-server"
fi
Remediation script:- name: Ensure rsh-server is removed
package:
name: rsh-server
state: absent
tags:
- DISA-STIG-OL08-00-040010
- NIST-800-53-CM-6(a)
- NIST-800-53-CM-7(a)
- NIST-800-53-CM-7(b)
- NIST-800-53-IA-5(1)(c)
- disable_strategy
- high_severity
- low_complexity
- low_disruption
- no_reboot_needed
- package_rsh-server_removed
Remediation script:include remove_rsh-server
class remove_rsh-server {
package { 'rsh-server':
ensure => 'purged',
}
}
Remediation script:
package --remove=rsh-server
|
Uninstall rsh Packagerule
The rsh package contains the client commands
for the rsh services Rationale:These legacy clients contain numerous security exposures and have
been replaced with the more secure SSH package. Even if the server is removed,
it is best to ensure the clients are also removed to prevent users from
inadvertently attempting to use these commands and therefore exposing
their credentials. Note that removing the rsh package removes
the clients for rsh ,rcp , and rlogin . references:
A.8.2.3, A.13.1.1, A.13.2.1, A.13.2.3, A.14.1.2, A.14.1.3, 164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii), BP28(R1), 3.1.13 Remediation script:
# CAUTION: This remediation script will remove rsh
# from the system, and may remove any packages
# that depend on rsh. Execute this
# remediation AFTER testing on a non-production
# system!
if rpm -q --quiet "rsh" ; then
yum remove -y "rsh"
fi
Remediation script:- name: Ensure rsh is removed
package:
name: rsh
state: absent
tags:
- NIST-800-171-3.1.13
- disable_strategy
- low_complexity
- low_disruption
- no_reboot_needed
- package_rsh_removed
- unknown_severity
Remediation script:include remove_rsh
class remove_rsh {
package { 'rsh':
ensure => 'purged',
}
}
Remediation script:
package --remove=rsh
|
Chat/Messaging ServicesgroupThe talk software makes it possible for users to send and receive messages
across systems through a terminal session. |
contains 2 rules |
Uninstall talk PackageruleThe talk package contains the client program for the
Internet talk protocol, which allows the user to chat with other users on
different systems. Talk is a communication program which copies lines from one
terminal to the terminal of another user.
The talk package can be removed with the following command:
$ sudo yum erase talk Rationale:The talk software presents a security risk as it uses unencrypted protocols
for communications. Removing the talk package decreases the
risk of the accidental (or intentional) activation of talk client program. Remediation script:
# CAUTION: This remediation script will remove talk
# from the system, and may remove any packages
# that depend on talk. Execute this
# remediation AFTER testing on a non-production
# system!
if rpm -q --quiet "talk" ; then
yum remove -y "talk"
fi
Remediation script:- name: Ensure talk is removed
package:
name: talk
state: absent
tags:
- disable_strategy
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- package_talk_removed
Remediation script:include remove_talk
class remove_talk {
package { 'talk':
ensure => 'purged',
}
}
Remediation script:
package --remove=talk
|
Uninstall talk-server PackageruleThe talk-server package can be removed with the following command: $ sudo yum erase talk-server Rationale:The talk software presents a security risk as it uses unencrypted protocols
for communications. Removing the talk-server package decreases the
risk of the accidental (or intentional) activation of talk services. Remediation script:
# CAUTION: This remediation script will remove talk-server
# from the system, and may remove any packages
# that depend on talk-server. Execute this
# remediation AFTER testing on a non-production
# system!
if rpm -q --quiet "talk-server" ; then
yum remove -y "talk-server"
fi
Remediation script:- name: Ensure talk-server is removed
package:
name: talk-server
state: absent
tags:
- disable_strategy
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- package_talk-server_removed
Remediation script:include remove_talk-server
class remove_talk-server {
package { 'talk-server':
ensure => 'purged',
}
}
Remediation script:
package --remove=talk-server
|
TelnetgroupThe telnet protocol does not provide confidentiality or integrity
for information transmitted on the network. This includes authentication
information such as passwords. Organizations which use telnet should be
actively working to migrate to a more secure protocol. |
contains 2 rules |
Uninstall telnet-server PackageruleThe telnet-server package can be removed with the following command:
$ sudo yum erase telnet-server Rationale:It is detrimental for operating systems to provide, or install by default,
functionality exceeding requirements or mission objectives. These
unnecessary capabilities are often overlooked and therefore may remain
unsecure. They increase the risk to the platform by providing additional
attack vectors.
The telnet service provides an unencrypted remote access service which does
not provide for the confidentiality and integrity of user passwords or the
remote session. If a privileged user were to login using this service, the
privileged user password could be compromised.
Removing the telnet-server package decreases the risk of the
telnet service's accidental (or intentional) activation. references:
11, 12, 14, 15, 3, 8, 9, 164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii), 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 7.1, SR 7.6, CM-7(a), CM-7(b), CM-6(a), SRG-OS-000095-GPOS-00049, A.11.2.6, A.12.1.2, A.12.5.1, A.12.6.2, A.13.1.1, A.13.2.1, A.14.1.3, A.14.2.2, A.14.2.3, A.14.2.4, A.6.2.1, A.6.2.2, A.9.1.2, PR.AC-3, PR.IP-1, PR.PT-3, PR.PT-4, OL08-00-040000, SV-248823r780035_rule, CCI-000381, APO13.01, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS01.04, DSS05.02, DSS05.03, DSS05.05, DSS06.06, BP28(R1) Remediation script:
# 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
Remediation script:- name: Ensure telnet-server is removed
package:
name: telnet-server
state: absent
tags:
- DISA-STIG-OL08-00-040000
- NIST-800-53-CM-6(a)
- NIST-800-53-CM-7(a)
- NIST-800-53-CM-7(b)
- disable_strategy
- high_severity
- low_complexity
- low_disruption
- no_reboot_needed
- package_telnet-server_removed
Remediation script:include remove_telnet-server
class remove_telnet-server {
package { 'telnet-server':
ensure => 'purged',
}
}
Remediation script:
package --remove=telnet-server
|
Remove telnet ClientsruleThe telnet client allows users to start connections to other systems via
the telnet protocol. Rationale:The telnet protocol is insecure and unencrypted. The use
of an unencrypted transmission medium could allow an unauthorized user
to steal credentials. The ssh package provides an
encrypted session and stronger security and is included in Oracle Linux 8. references:
A.8.2.3, A.13.1.1, A.13.2.1, A.13.2.3, A.14.1.2, A.14.1.3, 164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii), BP28(R1), 3.1.13 Remediation script:
# 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
Remediation script:- name: Ensure telnet is removed
package:
name: telnet
state: absent
tags:
- NIST-800-171-3.1.13
- disable_strategy
- low_complexity
- low_disruption
- low_severity
- no_reboot_needed
- package_telnet_removed
Remediation script:include remove_telnet
class remove_telnet {
package { 'telnet':
ensure => 'purged',
}
}
Remediation script:
package --remove=telnet
|
TFTP ServergroupTFTP is a lightweight version of the FTP protocol which has
traditionally been used to configure networking equipment. However,
TFTP provides little security, and modern versions of networking
operating systems frequently support configuration via SSH or other
more secure protocols. A TFTP server should be run only if no more
secure method of supporting existing equipment can be
found. |
contains 1 rule |
Uninstall tftp-server PackageruleThe tftp-server package can be removed with the following command: $ sudo yum erase tftp-server Rationale:Removing the tftp-server package decreases the risk of the accidental
(or intentional) activation of tftp services.
If TFTP is required for operational support (such as transmission of router
configurations), its use must be documented with the Information Systems
Securty Manager (ISSM), restricted to only authorized personnel, and have
access control rules established. references:
11, 12, 14, 15, 3, 8, 9, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 7.1, SR 7.6, CM-7(a), CM-7(b), CM-6(a), SRG-OS-000480-GPOS-00227, A.11.2.6, A.12.1.2, A.12.5.1, A.12.6.2, A.13.1.1, A.13.2.1, A.14.1.3, A.14.2.2, A.14.2.3, A.14.2.4, A.6.2.1, A.6.2.2, A.9.1.2, PR.AC-3, PR.IP-1, PR.PT-3, PR.PT-4, OL08-00-040190, SV-248873r780185_rule, CCI-000318, CCI-000366, CCI-000368, CCI-001812, CCI-001813, CCI-001814, APO13.01, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS01.04, DSS05.02, DSS05.03, DSS05.05, DSS06.06, BP28(R1) Remediation script:
# CAUTION: This remediation script will remove tftp-server
# from the system, and may remove any packages
# that depend on tftp-server. Execute this
# remediation AFTER testing on a non-production
# system!
if rpm -q --quiet "tftp-server" ; then
yum remove -y "tftp-server"
fi
Remediation script:- name: Ensure tftp-server is removed
package:
name: tftp-server
state: absent
tags:
- DISA-STIG-OL08-00-040190
- NIST-800-53-CM-6(a)
- NIST-800-53-CM-7(a)
- NIST-800-53-CM-7(b)
- disable_strategy
- high_severity
- low_complexity
- low_disruption
- no_reboot_needed
- package_tftp-server_removed
Remediation script:include remove_tftp-server
class remove_tftp-server {
package { 'tftp-server':
ensure => 'purged',
}
}
Remediation script:
package --remove=tftp-server
|