Guide to the Secure Configuration of Red Hat Enterprise Linux 8

with profile Protection Profile for General Purpose Operating Systems
This profile reflects mandatory configuration controls identified in the NIAP Configuration Annex to the Protection Profile for General Purpose Operating Systems (Protection Profile Version 4.2.1). This configuration profile is consistent with CNSSI-1253, which requires U.S. National Security Systems to adhere to certain configuration parameters. Accordingly, this configuration profile is suitable for use in U.S. National Security Systems.
This guide presents a catalog of security-relevant configuration settings for Red Hat Enterprise Linux 8. It is a rendering of content structured in the eXtensible Configuration Checklist Description Format (XCCDF) in order to support security automation. The SCAP content is is available in the scap-security-guide package which is developed at https://www.open-scap.org/security-policies/scap-security-guide.

Providing system administrators with such guidance informs them how to securely configure systems under their control in a variety of network roles. Policy makers and baseline creators can use this catalog of settings, with its associated references to higher-level security control catalogs, in order to assist them in security baseline creation. This guide is a catalog, not a checklist, and satisfaction of every item is not likely to be possible or sensible in many operational scenarios. However, the XCCDF format enables granular selection and adjustment of settings, and their association with OVAL and OCIL content provides an automated checking capability. Transformations of this document, and its associated automated checking content, are capable of providing baselines that meet a diverse set of policy objectives. Some example XCCDF Profiles, which are selections of items that form checklists and can be used as baselines, are available with this guide. They can be processed, in an automated fashion, with tools that support the Security Content Automation Protocol (SCAP). The DISA STIG, which provides required settings for US Department of Defense systems, is one example of a baseline created from this guidance.
Do not attempt to implement any of the settings in this guide without first testing them in a non-operational environment. The creators of this guidance assume no responsibility whatsoever for its use by other parties, and makes no guarantees, expressed or implied, about its quality, reliability, or any other characteristic.

Profile Information

Profile TitleProtection Profile for General Purpose Operating Systems
Profile IDxccdf_org.ssgproject.content_profile_ospp

CPE Platforms

  • cpe:/o:redhat:enterprise_linux:8
  • cpe:/o:redhat:enterprise_linux:8.0
  • cpe:/o:redhat:enterprise_linux:8.1
  • cpe:/o:redhat:enterprise_linux:8.2
  • cpe:/o:redhat:enterprise_linux:8.3
  • cpe:/o:redhat:enterprise_linux:8.4
  • cpe:/o:redhat:enterprise_linux:8.5
  • cpe:/o:redhat:enterprise_linux:8.6
  • cpe:/o:redhat:enterprise_linux:8.7
  • cpe:/o:redhat:enterprise_linux:8.8
  • cpe:/o:redhat:enterprise_linux:8.9
  • cpe:/o:redhat:enterprise_linux:8.10

Revision History

Current version: 0.1.62

  • draft (as of 2022-05-27)

Table of Contents

  1. System Settings
    1. Installing and Maintaining Software
    2. Account and Access Control
    3. System Accounting with auditd
    4. GRUB2 bootloader configuration
    5. zIPL bootloader configuration
    6. Configure Syslog
    7. Network Configuration and Firewalls
    8. File Permissions and Masks
    9. SELinux
  2. Services
    1. Base Services
    2. Application Whitelisting Daemon
    3. Kerberos
    4. Mail Server Software
    5. NFS and RPC
    6. Network Time Protocol
    7. SSH Server
    8. USBGuard daemon

Checklist

Group   Guide to the Secure Configuration of Red Hat Enterprise Linux 8   Group contains 63 groups and 211 rules
Group   System Settings   Group contains 51 groups and 181 rules
[ref]   Contains rules that check correct system settings.
Group   Installing and Maintaining Software   Group contains 9 groups and 40 rules
[ref]   The following sections contain information on security-relevant choices during the initial operating system installation process and the setup of software updates.
Group   System and Software Integrity   Group contains 4 groups and 11 rules
[ref]   System and software integrity can be gained by installing antivirus, increasing system encryption strength with FIPS, verifying installed software, enabling SELinux, installing an Intrusion Prevention System, etc. However, installing or enabling integrity checking tools cannot prevent intrusions, but they can detect that an intrusion may have occurred. Requirements for integrity checking may be highly dependent on the environment in which the system will be used. Snapshot-based approaches such as AIDE may induce considerable overhead in the presence of frequent software updates.
Group   Software Integrity Checking   Group contains 1 group and 1 rule
[ref]   Both the AIDE (Advanced Intrusion Detection Environment) software and the RPM package management system provide mechanisms for verifying the integrity of installed software. AIDE uses snapshots of file metadata (such as hashes) and compares these to current system files in order to detect changes.

The RPM package management system can conduct integrity checks by comparing information in its metadata database with files installed on the system.
Group   Verify Integrity with AIDE   Group contains 1 rule
[ref]   AIDE conducts integrity checks by comparing information about files with previously-gathered information. Ideally, the AIDE database is created immediately after initial system configuration, and then again after any software update. AIDE is highly configurable, with further configuration information located in /usr/share/doc/aide-VERSION.

Rule   Install AIDE   [ref]

The aide package can be installed with the following command:
$ sudo yum install aide
Rationale:
The AIDE package must be installed if it is to be available for integrity checking.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_package_aide_installed
Identifiers and References

Identifiers:  CCE-80844-4

References:  BP28(R51), 1, 11, 12, 13, 14, 15, 16, 2, 3, 5, 7, 8, 9, 5.10.1.3, APO01.06, BAI01.06, BAI02.01, BAI03.05, BAI06.01, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS01.03, DSS03.05, DSS04.07, DSS05.02, DSS05.03, DSS05.05, DSS05.07, DSS06.02, DSS06.06, CCI-002696, CCI-002699, CCI-001744, 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 4.1, SR 6.2, SR 7.6, 1034, 1288, 1341, 1417, A.11.2.4, A.12.1.2, A.12.2.1, A.12.4.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, A.14.2.7, A.15.2.1, A.8.2.3, CM-6(a), DE.CM-1, DE.CM-7, PR.DS-1, PR.DS-6, PR.DS-8, PR.IP-1, PR.IP-3, Req-11.5, SRG-OS-000363-GPOS-00150, SRG-OS-000445-GPOS-00199, RHEL-08-010359, 1.4.1, SV-251710r809354_rule


Complexity:low
Disruption:low
Strategy:enable

package --add=aide

Complexity:low
Disruption:low
Strategy:enable
- name: Ensure aide is installed
  package:
    name: aide
    state: present
  when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
  tags:
    - CCE-80844-4
    - CJIS-5.10.1.3
    - DISA-STIG-RHEL-08-010359
    - NIST-800-53-CM-6(a)
    - PCI-DSS-Req-11.5
    - enable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - package_aide_installed

Complexity:low
Disruption:low
Strategy:enable
# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then

if ! rpm -q --quiet "aide" ; then
    yum install -y "aide"
fi

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi


[[packages]]
name = "aide"
version = "*"

Complexity:low
Disruption:low
Strategy:enable
include install_aide

class install_aide {
  package { 'aide':
    ensure => 'installed',
  }
}
Group   Federal Information Processing Standard (FIPS)   Group contains 2 rules
[ref]   The Federal Information Processing Standard (FIPS) is a computer security standard which is developed by the U.S. Government and industry working groups to validate the quality of cryptographic modules. The FIPS standard provides four security levels to ensure adequate coverage of different industries, implementation of cryptographic modules, and organizational sizes and requirements.

FIPS 140-2 is the current standard for validating that mechanisms used to access cryptographic modules utilize authentication that meets industry and government requirements. For government systems, this allows Security Levels 1, 2, 3, or 4 for use on Red Hat Enterprise Linux 8.

See http://csrc.nist.gov/publications/PubsFIPS.html for more information.

Rule   Enable Dracut FIPS Module   [ref]

To enable FIPS mode, run the following command:
fips-mode-setup --enable
To enable FIPS, the system requires that the fips module is added in dracut configuration. Check if /etc/dracut.conf.d/40-fips.conf contain add_dracutmodules+=" fips "
Warning:  The system needs to be rebooted for these changes to take effect.
Warning:  System Crypto Modules must be provided by a vendor that undergoes FIPS-140 certifications. FIPS-140 is applicable to all Federal agencies that use cryptographic-based security systems to protect sensitive information in computer and telecommunication systems (including voice systems) as defined in Section 5131 of the Information Technology Management Reform Act of 1996, Public Law 104-106. This standard shall be used in designing and implementing cryptographic modules that Federal departments and agencies operate or are operated for them under contract. See https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.140-2.pdf To meet this, the system has to have cryptographic software provided by a vendor that has undergone this certification. This means providing documentation, test results, design information, and independent third party review by an accredited lab. While open source software is capable of meeting this, it does not meet FIPS-140 unless the vendor submits to this process.
Rationale:
Use of weak or untested encryption algorithms undermines the purposes of utilizing encryption to protect data. The operating system must implement cryptographic modules adhering to the higher standards approved by the federal government since this provides assurance they have been tested and validated.
Severity: 
high
Rule ID:xccdf_org.ssgproject.content_rule_enable_dracut_fips_module
Identifiers and References

Identifiers:  CCE-82155-3

References:  CCI-000068, CCI-000803, CCI-002450, 1446, CIP-003-8 R4.2, CIP-007-3 R5.1, SC-12(2), SC-12(3), IA-7, SC-13, CM-6(a), SC-12, FCS_RBG_EXT.1, SRG-OS-000478-GPOS-00223, SRG-OS-000120-VMM-000600, SRG-OS-000478-VMM-001980, SRG-OS-000396-VMM-001590, RHEL-08-010020, SV-230223r792855_rule


Complexity:medium
Disruption:medium
Reboot:true
Strategy:restrict
- name: Check to see the current status of FIPS mode
  command: /usr/bin/fips-mode-setup --check
  register: is_fips_enabled
  changed_when: false
  failed_when: false
  when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
  tags:
    - CCE-82155-3
    - DISA-STIG-RHEL-08-010020
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IA-7
    - NIST-800-53-SC-12
    - NIST-800-53-SC-12(2)
    - NIST-800-53-SC-12(3)
    - NIST-800-53-SC-13
    - enable_dracut_fips_module
    - high_severity
    - medium_complexity
    - medium_disruption
    - reboot_required
    - restrict_strategy

- name: Enable FIPS mode
  command: /usr/bin/fips-mode-setup --enable
  when:
    - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
    - is_fips_enabled.stdout.find('FIPS mode is enabled.') == -1
  tags:
    - CCE-82155-3
    - DISA-STIG-RHEL-08-010020
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IA-7
    - NIST-800-53-SC-12
    - NIST-800-53-SC-12(2)
    - NIST-800-53-SC-12(3)
    - NIST-800-53-SC-13
    - enable_dracut_fips_module
    - high_severity
    - medium_complexity
    - medium_disruption
    - reboot_required
    - restrict_strategy

- name: Enable Dracut FIPS Module
  lineinfile:
    path: /etc/dracut.conf.d/40-fips.conf
    line: add_dracutmodules+=" fips "
  when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
  tags:
    - CCE-82155-3
    - DISA-STIG-RHEL-08-010020
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IA-7
    - NIST-800-53-SC-12
    - NIST-800-53-SC-12(2)
    - NIST-800-53-SC-12(3)
    - NIST-800-53-SC-13
    - enable_dracut_fips_module
    - high_severity
    - medium_complexity
    - medium_disruption
    - reboot_required
    - restrict_strategy

# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then

fips-mode-setup --enable
FIPS_CONF="/etc/dracut.conf.d/40-fips.conf"
if ! grep "^add_dracutmodules+=\" fips \"" $FIPS_CONF; then
    echo "add_dracutmodules+=\" fips \"" >> $FIPS_CONF
fi

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi

Rule   Enable FIPS Mode   [ref]

To enable FIPS mode, run the following command:
fips-mode-setup --enable

The fips-mode-setup command will configure the system in FIPS mode by automatically configuring the following:
  • Setting the kernel FIPS mode flag (/proc/sys/crypto/fips_enabled) to 1
  • Creating /etc/system-fips
  • Setting the system crypto policy in /etc/crypto-policies/config to FIPS:OSPP
  • Loading the Dracut fips module
Warning:  The system needs to be rebooted for these changes to take effect.
Warning:  This rule DOES NOT CHECK if the components of the operating system are FIPS certified. You can find the list of FIPS certified modules at https://csrc.nist.gov/projects/cryptographic-module-validation-program/validated-modules/search. This rule checks if the system is running in FIPS mode. See the rule description for more information about what it means.
Rationale:
Use of weak or untested encryption algorithms undermines the purposes of utilizing encryption to protect data. The operating system must implement cryptographic modules adhering to the higher standards approved by the federal government since this provides assurance they have been tested and validated.
Severity: 
high
Rule ID:xccdf_org.ssgproject.content_rule_enable_fips_mode
Identifiers and References

Identifiers:  CCE-80942-6

References:  CCI-000068, CCI-000803, CCI-002450, 1446, CIP-003-8 R4.2, CIP-007-3 R5.1, CM-3(6), SC-12(2), SC-12(3), IA-7, SC-13, CM-6(a), SC-12, FCS_COP.1(1), FCS_COP.1(2), FCS_COP.1(3), FCS_COP.1(4), FCS_CKM.1, FCS_CKM.2, FCS_TLSC_EXT.1, FCS_RBG_EXT.1, SRG-OS-000478-GPOS-00223, SRG-OS-000396-GPOS-00176, SRG-OS-000120-VMM-000600, SRG-OS-000478-VMM-001980, SRG-OS-000396-VMM-001590, RHEL-08-010020, SV-230223r792855_rule


Complexity:medium
Disruption:medium
Reboot:true
Strategy:restrict
- name: XCCDF Value var_system_crypto_policy # promote to variable
  set_fact:
    var_system_crypto_policy: !!str FIPS:OSPP
  tags:
    - always

- name: Check to see the current status of FIPS mode
  command: /usr/bin/fips-mode-setup --check
  register: is_fips_enabled
  changed_when: false
  when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
  tags:
    - CCE-80942-6
    - DISA-STIG-RHEL-08-010020
    - NIST-800-53-CM-3(6)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IA-7
    - NIST-800-53-SC-12
    - NIST-800-53-SC-12(2)
    - NIST-800-53-SC-12(3)
    - NIST-800-53-SC-13
    - enable_fips_mode
    - high_severity
    - medium_complexity
    - medium_disruption
    - reboot_required
    - restrict_strategy

- name: Enable FIPS mode
  command: /usr/bin/fips-mode-setup --enable
  when:
    - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
    - is_fips_enabled.stdout.find('FIPS mode is enabled.') == -1
  tags:
    - CCE-80942-6
    - DISA-STIG-RHEL-08-010020
    - NIST-800-53-CM-3(6)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IA-7
    - NIST-800-53-SC-12
    - NIST-800-53-SC-12(2)
    - NIST-800-53-SC-12(3)
    - NIST-800-53-SC-13
    - enable_fips_mode
    - high_severity
    - medium_complexity
    - medium_disruption
    - reboot_required
    - restrict_strategy

- name: Enable FIPS Mode
  lineinfile:
    path: /etc/crypto-policies/config
    regexp: ^(?!#)(\S+)$
    line: '{{ var_system_crypto_policy }}'
    create: true
  when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
  tags:
    - CCE-80942-6
    - DISA-STIG-RHEL-08-010020
    - NIST-800-53-CM-3(6)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IA-7
    - NIST-800-53-SC-12
    - NIST-800-53-SC-12(2)
    - NIST-800-53-SC-12(3)
    - NIST-800-53-SC-13
    - enable_fips_mode
    - high_severity
    - medium_complexity
    - medium_disruption
    - reboot_required
    - restrict_strategy

- name: Verify that Crypto Policy is Set (runtime)
  command: /usr/bin/update-crypto-policies --set {{ var_system_crypto_policy }}
  when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
  tags:
    - CCE-80942-6
    - DISA-STIG-RHEL-08-010020
    - NIST-800-53-CM-3(6)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IA-7
    - NIST-800-53-SC-12
    - NIST-800-53-SC-12(2)
    - NIST-800-53-SC-12(3)
    - NIST-800-53-SC-13
    - enable_fips_mode
    - high_severity
    - medium_complexity
    - medium_disruption
    - reboot_required
    - restrict_strategy

# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then

var_system_crypto_policy='FIPS:OSPP'


fips-mode-setup --enable

stderr_of_call=$(update-crypto-policies --set ${var_system_crypto_policy} 2>&1 > /dev/null)
rc=$?

if test "$rc" = 127; then
	echo "$stderr_of_call" >&2
	echo "Make sure that the script is installed on the remediated system." >&2
	echo "See output of the 'dnf provides update-crypto-policies' command" >&2
	echo "to see what package to (re)install" >&2

	false  # end with an error code
elif test "$rc" != 0; then
	echo "Error invoking the update-crypto-policies script: $stderr_of_call" >&2
	false  # end with an error code
fi

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi
Group   System Cryptographic Policies   Group contains 8 rules
[ref]   Linux has the capability to centrally configure cryptographic polices. The command update-crypto-policies is used to set the policy applicable for the various cryptographic back-ends, such as SSL/TLS libraries. The configured cryptographic policies will be the default policy used by these backends unless the application user configures them otherwise. When the system has been configured to use the centralized cryptographic policies, the administrator is assured that any application that utilizes the supported backends will follow a policy that adheres to the configured profile. Currently the supported backends are:
  • GnuTLS library
  • OpenSSL library
  • NSS library
  • OpenJDK
  • Libkrb5
  • BIND
  • OpenSSH
Applications and languages which rely on any of these backends will follow the system policies as well. Examples are apache httpd, nginx, php, and others.

Rule   Install crypto-policies package   [ref]

The crypto-policies package can be installed with the following command:
$ sudo yum install crypto-policies
Rationale:
Centralized cryptographic policies simplify applying secure ciphers across an operating system and the applications that run on that operating system. Use of weak or untested encryption algorithms undermines the purposes of utilizing encryption to protect data.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_package_crypto-policies_installed
Identifiers and References

Identifiers:  CCE-82723-8

References:  FCS_COP.1(1), FCS_COP.1(2), FCS_COP.1(3), FCS_COP.1(4), FCS_CKM.1, FCS_CKM.2, FCS_TLSC_EXT.1, SRG-OS-000396-GPOS-00176, SRG-OS-000393-GPOS-00173, SRG-OS-000394-GPOS-00174


Complexity:low
Disruption:low
Strategy:enable

package --add=crypto-policies

Complexity:low
Disruption:low
Strategy:enable
- name: Ensure crypto-policies is installed
  package:
    name: crypto-policies
    state: present
  tags:
    - CCE-82723-8
    - enable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - package_crypto-policies_installed

Complexity:low
Disruption:low
Strategy:enable

if ! rpm -q --quiet "crypto-policies" ; then
    yum install -y "crypto-policies"
fi


[[packages]]
name = "crypto-policies"
version = "*"

Complexity:low
Disruption:low
Strategy:enable
include install_crypto-policies

class install_crypto-policies {
  package { 'crypto-policies':
    ensure => 'installed',
  }
}

Rule   Configure BIND to use System Crypto Policy   [ref]

Crypto Policies provide a centralized control over crypto algorithms usage of many packages. BIND is supported by crypto policy, but the BIND configuration may be set up to ignore it. To check that Crypto Policies settings are configured correctly, ensure that the /etc/named.conf includes the appropriate configuration: In the options section of /etc/named.conf, make sure that the following line is not commented out or superseded by later includes: include "/etc/crypto-policies/back-ends/bind.config";
Rationale:
Overriding the system crypto policy makes the behavior of the BIND service violate expectations, and makes system configuration more fragmented.
Severity: 
high
Rule ID:xccdf_org.ssgproject.content_rule_configure_bind_crypto_policy
Identifiers and References

Identifiers:  CCE-80934-3

References:  CIP-003-8 R4.2, CIP-007-3 R5.1, SC-13, SC-12(2), SC-12(3), SRG-OS-000423-GPOS-00187, SRG-OS-000426-GPOS-00190, RHEL-08-010020, SV-230223r792855_rule



function remediate_bind_crypto_policy() {
	CONFIG_FILE="/etc/named.conf"
	if test -f "$CONFIG_FILE"; then
		sed -i 's|options {|&\n\tinclude "/etc/crypto-policies/back-ends/bind.config";|' "$CONFIG_FILE"
		return 0
	else
		echo "Aborting remediation as '$CONFIG_FILE' was not even found." >&2
		return 1
	fi
}

remediate_bind_crypto_policy

Rule   Configure System Cryptography Policy   [ref]

To configure the system cryptography policy to use ciphers only from the FIPS:OSPP policy, run the following command:
$ sudo update-crypto-policies --set FIPS:OSPP
The rule checks if settings for selected crypto policy are configured as expected. Configuration files in the /etc/crypto-policies/back-ends are either symlinks to correct files provided by Crypto-policies package or they are regular files in case crypto policy customizations are applied. Crypto policies may be customized by crypto policy modules, in which case it is delimited from the base policy using a colon.
Warning:  The system needs to be rebooted for these changes to take effect.
Warning:  System Crypto Modules must be provided by a vendor that undergoes FIPS-140 certifications. FIPS-140 is applicable to all Federal agencies that use cryptographic-based security systems to protect sensitive information in computer and telecommunication systems (including voice systems) as defined in Section 5131 of the Information Technology Management Reform Act of 1996, Public Law 104-106. This standard shall be used in designing and implementing cryptographic modules that Federal departments and agencies operate or are operated for them under contract. See https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.140-2.pdf To meet this, the system has to have cryptographic software provided by a vendor that has undergone this certification. This means providing documentation, test results, design information, and independent third party review by an accredited lab. While open source software is capable of meeting this, it does not meet FIPS-140 unless the vendor submits to this process.
Rationale:
Centralized cryptographic policies simplify applying secure ciphers across an operating system and the applications that run on that operating system. Use of weak or untested encryption algorithms undermines the purposes of utilizing encryption to protect data.
Severity: 
high
Rule ID:xccdf_org.ssgproject.content_rule_configure_crypto_policy
Identifiers and References

Identifiers:  CCE-80935-0

References:  164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.312(e)(1), 164.312(e)(2)(ii), 1446, CIP-003-8 R4.2, CIP-007-3 R5.1, CIP-007-3 R7.1, AC-17(a), AC-17(2), CM-6(a), MA-4(6), SC-13, SC-12(2), SC-12(3), FCS_COP.1(1), FCS_COP.1(2), FCS_COP.1(3), FCS_COP.1(4), FCS_CKM.1, FCS_CKM.2, FCS_TLSC_EXT.1, SRG-OS-000396-GPOS-00176, SRG-OS-000393-GPOS-00173, SRG-OS-000394-GPOS-00174, RHEL-08-010020, 1.10, 1.11, SV-230223r792855_rule


Complexity:low
Disruption:low
Strategy:restrict
- name: XCCDF Value var_system_crypto_policy # promote to variable
  set_fact:
    var_system_crypto_policy: !!str FIPS:OSPP
  tags:
    - always

- name: Configure System Cryptography Policy
  lineinfile:
    path: /etc/crypto-policies/config
    regexp: ^(?!#)(\S+)$
    line: '{{ var_system_crypto_policy }}'
    create: true
  tags:
    - CCE-80935-0
    - DISA-STIG-RHEL-08-010020
    - NIST-800-53-AC-17(2)
    - NIST-800-53-AC-17(a)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-MA-4(6)
    - NIST-800-53-SC-12(2)
    - NIST-800-53-SC-12(3)
    - NIST-800-53-SC-13
    - configure_crypto_policy
    - high_severity
    - low_complexity
    - low_disruption
    - no_reboot_needed
    - restrict_strategy

- name: Verify that Crypto Policy is Set (runtime)
  command: /usr/bin/update-crypto-policies --set {{ var_system_crypto_policy }}
  tags:
    - CCE-80935-0
    - DISA-STIG-RHEL-08-010020
    - NIST-800-53-AC-17(2)
    - NIST-800-53-AC-17(a)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-MA-4(6)
    - NIST-800-53-SC-12(2)
    - NIST-800-53-SC-12(3)
    - NIST-800-53-SC-13
    - configure_crypto_policy
    - high_severity
    - low_complexity
    - low_disruption
    - no_reboot_needed
    - restrict_strategy


var_system_crypto_policy='FIPS:OSPP'


stderr_of_call=$(update-crypto-policies --set ${var_system_crypto_policy} 2>&1 > /dev/null)
rc=$?

if test "$rc" = 127; then
	echo "$stderr_of_call" >&2
	echo "Make sure that the script is installed on the remediated system." >&2
	echo "See output of the 'dnf provides update-crypto-policies' command" >&2
	echo "to see what package to (re)install" >&2

	false  # end with an error code
elif test "$rc" != 0; then
	echo "Error invoking the update-crypto-policies script: $stderr_of_call" >&2
	false  # end with an error code
fi

Rule   Configure Kerberos to use System Crypto Policy   [ref]

Crypto Policies provide a centralized control over crypto algorithms usage of many packages. Kerberos is supported by crypto policy, but it's configuration may be set up to ignore it. To check that Crypto Policies settings for Kerberos are configured correctly, examine that there is a symlink at /etc/krb5.conf.d/crypto-policies targeting /etc/cypto-policies/back-ends/krb5.config. If the symlink exists, Kerberos is configured to use the system-wide crypto policy settings.
Rationale:
Overriding the system crypto policy makes the behavior of Kerberos violate expectations, and makes system configuration more fragmented.
Severity: 
high
Rule ID:xccdf_org.ssgproject.content_rule_configure_kerberos_crypto_policy
Identifiers and References

Identifiers:  CCE-80936-8

References:  0418, 1055, 1402, CIP-003-8 R4.2, CIP-007-3 R5.1, SC-13, SC-12(2), SC-12(3), SRG-OS-000120-GPOS-00061, RHEL-08-010020, SV-230223r792855_rule


Complexity:low
Disruption:low
Reboot:true
Strategy:configure
- name: Configure Kerberos to use System Crypto Policy
  file:
    src: /etc/crypto-policies/back-ends/krb5.config
    path: /etc/krb5.conf.d/crypto-policies
    state: link
  tags:
    - CCE-80936-8
    - DISA-STIG-RHEL-08-010020
    - NIST-800-53-SC-12(2)
    - NIST-800-53-SC-12(3)
    - NIST-800-53-SC-13
    - configure_kerberos_crypto_policy
    - configure_strategy
    - high_severity
    - low_complexity
    - low_disruption
    - reboot_required

Complexity:low
Disruption:low
Reboot:true
Strategy:configure

rm -f /etc/krb5.conf.d/crypto-policies
ln -s /etc/crypto-policies/back-ends/krb5.config /etc/krb5.conf.d/crypto-policies

Rule   Configure Libreswan to use System Crypto Policy   [ref]

Crypto Policies provide a centralized control over crypto algorithms usage of many packages. Libreswan is supported by system crypto policy, but the Libreswan configuration may be set up to ignore it. To check that Crypto Policies settings are configured correctly, ensure that the /etc/ipsec.conf includes the appropriate configuration file. In /etc/ipsec.conf, make sure that the following line is not commented out or superseded by later includes: include /etc/crypto-policies/back-ends/libreswan.config
Rationale:
Overriding the system crypto policy makes the behavior of the Libreswan service violate expectations, and makes system configuration more fragmented.
Severity: 
high
Rule ID:xccdf_org.ssgproject.content_rule_configure_libreswan_crypto_policy
Identifiers and References

Identifiers:  CCE-80937-6

References:  CIP-003-8 R4.2, CIP-007-3 R5.1, CM-6(a), MA-4(6), SC-13, SC-12(2), SC-12(3), FCS_IPSEC_EXT.1.4, FCS_IPSEC_EXT.1.6, SRG-OS-000033-GPOS-00014, RHEL-08-010020, SV-230223r792855_rule


Complexity:low
Disruption:low
Strategy:restrict
- name: Configure Libreswan to use System Crypto Policy
  lineinfile:
    path: /etc/ipsec.conf
    line: include /etc/crypto-policies/back-ends/libreswan.config
    create: true
  tags:
    - CCE-80937-6
    - DISA-STIG-RHEL-08-010020
    - NIST-800-53-CM-6(a)
    - NIST-800-53-MA-4(6)
    - NIST-800-53-SC-12(2)
    - NIST-800-53-SC-12(3)
    - NIST-800-53-SC-13
    - configure_libreswan_crypto_policy
    - high_severity
    - low_complexity
    - low_disruption
    - no_reboot_needed
    - restrict_strategy


function remediate_libreswan_crypto_policy() {
    CONFIG_FILE="/etc/ipsec.conf"
    if ! grep -qP "^\s*include\s+/etc/crypto-policies/back-ends/libreswan.config\s*(?:#.*)?$" "$CONFIG_FILE" ; then
        echo 'include /etc/crypto-policies/back-ends/libreswan.config' >> "$CONFIG_FILE"
    fi
    return 0
}

remediate_libreswan_crypto_policy

Rule   Configure OpenSSL library to use System Crypto Policy   [ref]

Crypto Policies provide a centralized control over crypto algorithms usage of many packages. OpenSSL is supported by crypto policy, but the OpenSSL configuration may be set up to ignore it. To check that Crypto Policies settings are configured correctly, you have to examine the OpenSSL config file available under /etc/pki/tls/openssl.cnf. This file has the ini format, and it enables crypto policy support if there is a [ crypto_policy ] section that contains the .include /etc/crypto-policies/back-ends/opensslcnf.config directive.
Rationale:
Overriding the system crypto policy makes the behavior of the Java runtime violates expectations, and makes system configuration more fragmented.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_configure_openssl_crypto_policy
Identifiers and References

Identifiers:  CCE-80938-4

References:  CCI-001453, CIP-003-8 R4.2, CIP-007-3 R5.1, CIP-007-3 R7.1, AC-17(a), AC-17(2), CM-6(a), MA-4(6), SC-13, SC-12(2), SC-12(3), SRG-OS-000250-GPOS-00093, RHEL-08-010293, SV-230254r627750_rule


Complexity:low
Disruption:medium
- name: Test for crypto_policy group
  command: grep '^\s*\[\s*crypto_policy\s*]' /etc/pki/tls/openssl.cnf
  register: test_crypto_policy_group
  ignore_errors: true
  changed_when: false
  check_mode: false
  tags:
    - CCE-80938-4
    - DISA-STIG-RHEL-08-010293
    - NIST-800-53-AC-17(2)
    - NIST-800-53-AC-17(a)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-MA-4(6)
    - NIST-800-53-SC-12(2)
    - NIST-800-53-SC-12(3)
    - NIST-800-53-SC-13
    - configure_openssl_crypto_policy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - unknown_strategy

- name: Add .include for opensslcnf.config to crypto_policy section
  lineinfile:
    create: true
    insertafter: ^\s*\[\s*crypto_policy\s*]\s*
    line: .include /etc/crypto-policies/back-ends/opensslcnf.config
    path: /etc/pki/tls/openssl.cnf
  when:
    - test_crypto_policy_group.stdout is defined
    - test_crypto_policy_group.stdout | length > 0
  tags:
    - CCE-80938-4
    - DISA-STIG-RHEL-08-010293
    - NIST-800-53-AC-17(2)
    - NIST-800-53-AC-17(a)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-MA-4(6)
    - NIST-800-53-SC-12(2)
    - NIST-800-53-SC-12(3)
    - NIST-800-53-SC-13
    - configure_openssl_crypto_policy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - unknown_strategy

- name: Add crypto_policy group and set include opensslcnf.config
  lineinfile:
    create: true
    line: |-
      [crypto_policy]
      .include /etc/crypto-policies/back-ends/opensslcnf.config
    path: /etc/pki/tls/openssl.cnf
  when:
    - test_crypto_policy_group.stdout is defined
    - test_crypto_policy_group.stdout | length < 1
  tags:
    - CCE-80938-4
    - DISA-STIG-RHEL-08-010293
    - NIST-800-53-AC-17(2)
    - NIST-800-53-AC-17(a)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-MA-4(6)
    - NIST-800-53-SC-12(2)
    - NIST-800-53-SC-12(3)
    - NIST-800-53-SC-13
    - configure_openssl_crypto_policy
    - low_complexity
    - medium_disruption
    - medium_severity
    - no_reboot_needed
    - unknown_strategy


OPENSSL_CRYPTO_POLICY_SECTION='[ crypto_policy ]'
OPENSSL_CRYPTO_POLICY_SECTION_REGEX='\[\s*crypto_policy\s*\]'
OPENSSL_CRYPTO_POLICY_INCLUSION='.include /etc/crypto-policies/back-ends/opensslcnf.config'
OPENSSL_CRYPTO_POLICY_INCLUSION_REGEX='^\s*\.include\s*/etc/crypto-policies/back-ends/opensslcnf.config$'


  


function remediate_openssl_crypto_policy() {
	CONFIG_FILE=/etc/pki/tls/openssl.cnf
	if test -f "$CONFIG_FILE"; then
		if ! grep -q "^\\s*$OPENSSL_CRYPTO_POLICY_SECTION_REGEX" "$CONFIG_FILE"; then
			printf '\n%s\n\n%s' "$OPENSSL_CRYPTO_POLICY_SECTION" "$OPENSSL_CRYPTO_POLICY_INCLUSION" >> "$CONFIG_FILE"
			return 0
		elif ! grep -q "^\\s*$OPENSSL_CRYPTO_POLICY_INCLUSION_REGEX" "$CONFIG_FILE"; then
			sed -i "s|$OPENSSL_CRYPTO_POLICY_SECTION_REGEX|&\\n\\n$OPENSSL_CRYPTO_POLICY_INCLUSION\\n|" "$CONFIG_FILE"
			return 0
		fi
	else
		echo "Aborting remediation as '$CONFIG_FILE' was not even found." >&2
		return 1
	fi
}

remediate_openssl_crypto_policy

Rule   Configure SSH to use System Crypto Policy   [ref]

Crypto Policies provide a centralized control over crypto algorithms usage of many packages. SSH is supported by crypto policy, but the SSH configuration may be set up to ignore it. To check that Crypto Policies settings are configured correctly, ensure that the CRYPTO_POLICY variable is either commented or not set at all in the /etc/sysconfig/sshd.
Rationale:
Overriding the system crypto policy makes the behavior of the SSH service violate expectations, and makes system configuration more fragmented.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_configure_ssh_crypto_policy
Identifiers and References

Identifiers:  CCE-80939-2

References:  164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.312(e)(1), 164.312(e)(2)(ii), CIP-003-8 R4.2, CIP-007-3 R5.1, CIP-007-3 R7.1, AC-17(a), AC-17(2), CM-6(a), MA-4(6), SC-13, SRG-OS-000250-GPOS-00093, RHEL-08-010287, 5.2.20, SV-244526r809334_rule


Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
- name: Configure SSH to use System Crypto Policy
  lineinfile:
    dest: /etc/sysconfig/sshd
    state: absent
    regexp: ^\s*(?i)CRYPTO_POLICY.*$
  tags:
    - CCE-80939-2
    - DISA-STIG-RHEL-08-010287
    - NIST-800-53-AC-17(2)
    - NIST-800-53-AC-17(a)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-MA-4(6)
    - NIST-800-53-SC-13
    - configure_ssh_crypto_policy
    - disable_strategy
    - low_complexity
    - medium_disruption
    - medium_severity
    - reboot_required


SSH_CONF="/etc/sysconfig/sshd"

sed -i "/^\s*CRYPTO_POLICY.*$/Id" $SSH_CONF

Rule   OpenSSL uses strong entropy source   [ref]

By default, OpenSSL doesn't always use a SP800-90A compliant random number generator. A way to configure OpenSSL to always use a strong source is to setup a wrapper that defines a shell function that shadows the actual openssl binary, and that ensures that the -rand /dev/random option is added to every openssl invocation. To do so, place the following shell snippet exactly as-is to /etc/profile.d/openssl-rand.sh:
# provide a default -rand /dev/random option to openssl commands that
# support it

# written inefficiently for maximum shell compatibility
openssl()
(
  openssl_bin=/usr/bin/openssl

  case "$*" in
    # if user specified -rand, honor it
    *\ -rand\ *|*\ -help*) exec $openssl_bin "$@" ;;
  esac

  cmds=`$openssl_bin list -digest-commands -cipher-commands | tr '\n' ' '`
  for i in `$openssl_bin list -commands`; do
    if $openssl_bin list -options "$i" | grep -q '^rand '; then
      cmds=" $i $cmds"
    fi
  done

  case "$cmds" in
    *\ "$1"\ *)
      cmd="$1"; shift
      exec $openssl_bin "$cmd" -rand /dev/random "$@" ;;
  esac

  exec $openssl_bin "$@"
)
Warning:  This setting can cause problems on computers without the hardware random generator, because insufficient entropy blocks the program until enough entropy is available.
Rationale:
This rule ensures that openssl invocations always uses SP800-90A compliant random number generator as a default behavior.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_openssl_use_strong_entropy
Identifiers and References

Identifiers:  CCE-82721-2

References:  1277, 1552, FCS_RBG_EXT.1.2, SRG-OS-000480-GPOS-00227


Complexity:low
Disruption:low
Strategy:restrict
- name: Put a file with shell wrapper to configure OpenSSL to always use strong entropy
  copy:
    dest: /etc/profile.d/openssl-rand.sh
    content: |
      # provide a default -rand /dev/random option to openssl commands that
      # support it

      # written inefficiently for maximum shell compatibility
      openssl()
      (
        openssl_bin=/usr/bin/openssl

        case "$*" in
          # if user specified -rand, honor it
          *\ -rand\ *|*\ -help*) exec $openssl_bin "$@" ;;
        esac

        cmds=`$openssl_bin list -digest-commands -cipher-commands | tr '\n' ' '`
        for i in `$openssl_bin list -commands`; do
          if $openssl_bin list -options "$i" | grep -q '^rand '; then
            cmds=" $i $cmds"
          fi
        done

        case "$cmds" in
          *\ "$1"\ *)
            cmd="$1"; shift
            exec $openssl_bin "$cmd" -rand /dev/random "$@" ;;
        esac

        exec $openssl_bin "$@"
      )
  tags:
    - CCE-82721-2
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - openssl_use_strong_entropy
    - restrict_strategy


cat > /etc/profile.d/openssl-rand.sh <<- 'EOM'
# provide a default -rand /dev/random option to openssl commands that
# support it

# written inefficiently for maximum shell compatibility
openssl()
(
  openssl_bin=/usr/bin/openssl

  case "$*" in
    # if user specified -rand, honor it
    *\ -rand\ *|*\ -help*) exec $openssl_bin "$@" ;;
  esac

  cmds=`$openssl_bin list -digest-commands -cipher-commands | tr '\n' ' '`
  for i in `$openssl_bin list -commands`; do
    if $openssl_bin list -options "$i" | grep -q '^rand '; then
      cmds=" $i $cmds"
    fi
  done

  case "$cmds" in
    *\ "$1"\ *)
      cmd="$1"; shift
      exec $openssl_bin "$cmd" -rand /dev/random "$@" ;;
  esac

  exec $openssl_bin "$@"
)
EOM
Group   Disk Partitioning   Group contains 5 rules
[ref]   To ensure separation and protection of data, there are top-level system directories which should be placed on their own physical partition or logical volume. The installer's default partitioning scheme creates separate logical volumes for /, /boot, and swap.
  • If starting with any of the default layouts, check the box to \"Review and modify partitioning.\" This allows for the easy creation of additional logical volumes inside the volume group already created, though it may require making /'s logical volume smaller to create space. In general, using logical volumes is preferable to using partitions because they can be more easily adjusted later.
  • If creating a custom layout, create the partitions mentioned in the previous paragraph (which the installer will require anyway), as well as separate ones described in the following sections.
If a system has already been installed, and the default partitioning scheme was used, it is possible but nontrivial to modify it to create separate logical volumes for the directories listed above. The Logical Volume Manager (LVM) makes this possible. See the LVM HOWTO at http://tldp.org/HOWTO/LVM-HOWTO/ for more detailed information on LVM.

Rule   Ensure /home Located On Separate Partition   [ref]

If user home directories will be stored locally, create a separate partition for /home at installation time (or migrate it later using LVM). If /home will be mounted from another system such as an NFS server, then creating a separate partition is not necessary at installation time, and the mountpoint can instead be configured later.
Rationale:
Ensuring that /home is mounted on its own partition enables the setting of more restrictive mount options, and also helps ensure that users cannot trivially fill partitions used for log or audit data storage.
Severity: 
low
Rule ID:xccdf_org.ssgproject.content_rule_partition_for_home
Identifiers and References

Identifiers:  CCE-81044-0

References:  BP28(R12), 12, 15, 8, APO13.01, DSS05.02, CCI-000366, CCI-001208, 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, A.13.1.1, A.13.2.1, A.14.1.3, CM-6(a), SC-5(2), PR.PT-4, SRG-OS-000480-GPOS-00227, RHEL-08-010800, 1.1.13, SV-230328r627750_rule


Complexity:low
Disruption:high
Strategy:enable

part /home


[[customizations.filesystem]]
mountpoint = "/home"
size = 1073741824

Rule   Ensure /var Located On Separate Partition   [ref]

The /var directory is used by daemons and other system services to store frequently-changing data. Ensure that /var has its own partition or logical volume at installation time, or migrate it using LVM.
Rationale:
Ensuring that /var is mounted on its own partition enables the setting of more restrictive mount options. This helps protect system services such as daemons or other programs which use it. It is not uncommon for the /var directory to contain world-writable directories installed by other software packages.
Severity: 
low
Rule ID:xccdf_org.ssgproject.content_rule_partition_for_var
Identifiers and References

Identifiers:  CCE-80852-7

References:  BP28(R12), 12, 15, 8, APO13.01, DSS05.02, CCI-000366, 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, A.13.1.1, A.13.2.1, A.14.1.3, CM-6(a), SC-5(2), PR.PT-4, SRG-OS-000480-GPOS-00227, SRG-OS-000341-VMM-001220, RHEL-08-010540, 1.1.6, SV-230292r627750_rule


Complexity:low
Disruption:high
Strategy:enable

part /var


[[customizations.filesystem]]
mountpoint = "/var"
size = 3221225472

Rule   Ensure /var/log Located On Separate Partition   [ref]

System logs are stored in the /var/log directory. Ensure that /var/log has its own partition or logical volume at installation time, or migrate it using LVM.
Rationale:
Placing /var/log in its own partition enables better separation between log files and other files in /var/.
Severity: 
low
Rule ID:xccdf_org.ssgproject.content_rule_partition_for_var_log
Identifiers and References

Identifiers:  CCE-80853-5

References:  BP28(R12), BP28(R47), 1, 12, 14, 15, 16, 3, 5, 6, 8, APO11.04, APO13.01, BAI03.05, DSS05.02, DSS05.04, DSS05.07, MEA02.01, CCI-000366, 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 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, A.12.4.1, A.12.4.2, A.12.4.3, A.12.4.4, A.12.7.1, A.13.1.1, A.13.2.1, A.14.1.3, CIP-007-3 R6.5, CM-6(a), AU-4, SC-5(2), PR.PT-1, PR.PT-4, SRG-OS-000480-GPOS-00227, RHEL-08-010541, 1.1.11, SV-230293r627750_rule


Complexity:low
Disruption:high
Strategy:enable

part /var/log


[[customizations.filesystem]]
mountpoint = "/var/log"
size = 5368709120

Rule   Ensure /var/log/audit Located On Separate Partition   [ref]

Audit logs are stored in the /var/log/audit directory. Ensure that /var/log/audit has its own partition or logical volume at installation time, or migrate it using LVM. Make absolutely certain that it is large enough to store all audit logs that will be created by the auditing daemon.
Rationale:
Placing /var/log/audit in its own partition enables better separation between audit files and other files, and helps ensure that auditing cannot be halted due to the partition running out of space.
Severity: 
low
Rule ID:xccdf_org.ssgproject.content_rule_partition_for_var_log_audit
Identifiers and References

Identifiers:  CCE-80854-3

References:  BP28(R43), 1, 12, 13, 14, 15, 16, 2, 3, 5, 6, 8, APO11.04, APO13.01, BAI03.05, BAI04.04, DSS05.02, DSS05.04, DSS05.07, MEA02.01, CCI-000366, CCI-001849, 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, 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.2, SR 7.6, 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.13.1.1, A.13.2.1, A.14.1.3, A.17.2.1, CIP-007-3 R6.5, CM-6(a), AU-4, SC-5(2), PR.DS-4, PR.PT-1, PR.PT-4, SRG-OS-000341-GPOS-00132, SRG-OS-000480-GPOS-00227, SRG-OS-000341-VMM-001220, RHEL-08-010542, 1.1.12, SV-230294r627750_rule


Complexity:low
Disruption:high
Strategy:enable

part /var/log/audit


[[customizations.filesystem]]
mountpoint = "/var/log/audit"
size = 10737418240

Rule   Ensure /var/tmp Located On Separate Partition   [ref]

The /var/tmp directory is a world-writable directory used for temporary file storage. Ensure it has its own partition or logical volume at installation time, or migrate it using LVM.
Rationale:
The /var/tmp partition is used as temporary storage by many programs. Placing /var/tmp in its own partition enables the setting of more restrictive mount options, which can help protect programs which use it.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_partition_for_var_tmp
Identifiers and References

Identifiers:  CCE-82730-3

References:  BP28(R12), SRG-OS-000480-GPOS-00227, RHEL-08-010544, 1.1.7, SV-244529r743836_rule


Complexity:low
Disruption:high
Strategy:enable

part /var/tmp


[[customizations.filesystem]]
mountpoint = "/var/tmp"
size = 1073741824
Group   Sudo   Group contains 1 rule
[ref]   Sudo, 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.

Rule   Install sudo Package   [ref]

The sudo package can be installed with the following command:
$ sudo yum install sudo
Rationale:
sudo is a program designed to allow a system administrator to give limited root privileges to users and log root activity. The basic philosophy is to give as few privileges as possible but still allow system users to get their work done.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_package_sudo_installed
Identifiers and References

Identifiers:  CCE-82214-8

References:  BP28(R19), 1382, 1384, 1386, CM-6(a), SRG-OS-000324-GPOS-00125, 1.3.1


Complexity:low
Disruption:low
Strategy:enable

package --add=sudo

Complexity:low
Disruption:low
Strategy:enable
- name: Ensure sudo is installed
  package:
    name: sudo
    state: present
  when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
  tags:
    - CCE-82214-8
    - NIST-800-53-CM-6(a)
    - enable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - package_sudo_installed

Complexity:low
Disruption:low
Strategy:enable
# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then

if ! rpm -q --quiet "sudo" ; then
    yum install -y "sudo"
fi

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi


[[packages]]
name = "sudo"
version = "*"

Complexity:low
Disruption:low
Strategy:enable
include install_sudo

class install_sudo {
  package { 'sudo':
    ensure => 'installed',
  }
}
Group   System Tooling / Utilities   Group contains 15 rules
[ref]   The following checks evaluate the system for recommended base packages -- both for installation and removal.

Rule   Install dnf-plugin-subscription-manager Package   [ref]

The dnf-plugin-subscription-manager package can be installed with the following command:
$ sudo yum install dnf-plugin-subscription-manager
Rationale:
This package provides plugins to interact with repositories and subscriptions from the Red Hat entitlement platform; contains subscription-manager and product-id plugins.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_package_dnf-plugin-subscription-manager_installed
Identifiers and References

Identifiers:  CCE-82315-3

References:  0940, 1144, 1467, 1472, 1483, 1493, 1494, 1495, FPT_TUD_EXT.1, FPT_TUD_EXT.2, SRG-OS-000366-GPOS-00153


Complexity:low
Disruption:low
Strategy:enable

package --add=dnf-plugin-subscription-manager

Complexity:low
Disruption:low
Strategy:enable
- name: Ensure dnf-plugin-subscription-manager is installed
  package:
    name: dnf-plugin-subscription-manager
    state: present
  tags:
    - CCE-82315-3
    - enable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - package_dnf-plugin-subscription-manager_installed

Complexity:low
Disruption:low
Strategy:enable

if ! rpm -q --quiet "dnf-plugin-subscription-manager" ; then
    yum install -y "dnf-plugin-subscription-manager"
fi


[[packages]]
name = "dnf-plugin-subscription-manager"
version = "*"

Complexity:low
Disruption:low
Strategy:enable
include install_dnf-plugin-subscription-manager

class install_dnf-plugin-subscription-manager {
  package { 'dnf-plugin-subscription-manager':
    ensure => 'installed',
  }
}

Rule   Ensure gnutls-utils is installed   [ref]

The gnutls-utils package can be installed with the following command:
$ sudo yum install gnutls-utils
Rationale:
GnuTLS is a secure communications library implementing the SSL, TLS and DTLS protocols and technologies around them. It provides a simple C language application programming interface (API) to access the secure communications protocols as well as APIs to parse and write X.509, PKCS #12, OpenPGP and other required structures. This package contains command line TLS client and server and certificate manipulation tools.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_package_gnutls-utils_installed
Identifiers and References

Identifiers:  CCE-82395-5

References:  FIA_X509_EXT, SRG-OS-000480-GPOS-00227


Complexity:low
Disruption:low
Strategy:enable

package --add=gnutls-utils

Complexity:low
Disruption:low
Strategy:enable
- name: Ensure gnutls-utils is installed
  package:
    name: gnutls-utils
    state: present
  tags:
    - CCE-82395-5
    - enable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - package_gnutls-utils_installed

Complexity:low
Disruption:low
Strategy:enable

if ! rpm -q --quiet "gnutls-utils" ; then
    yum install -y "gnutls-utils"
fi


[[packages]]
name = "gnutls-utils"
version = "*"

Complexity:low
Disruption:low
Strategy:enable
include install_gnutls-utils

class install_gnutls-utils {
  package { 'gnutls-utils':
    ensure => 'installed',
  }
}

Rule   Install openscap-scanner Package   [ref]

The openscap-scanner package can be installed with the following command:
$ sudo yum install openscap-scanner
Rationale:
openscap-scanner contains the oscap command line tool. This tool is a configuration and vulnerability scanner, capable of performing compliance checking using SCAP content.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_package_openscap-scanner_installed
Identifiers and References

Identifiers:  CCE-82220-5

References:  SRG-OS-000480-GPOS-00227, SRG-OS-000191-GPOS-00080


Complexity:low
Disruption:low
Strategy:enable

package --add=openscap-scanner

Complexity:low
Disruption:low
Strategy:enable
- name: Ensure openscap-scanner is installed
  package:
    name: openscap-scanner
    state: present
  tags:
    - CCE-82220-5
    - enable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - package_openscap-scanner_installed

Complexity:low
Disruption:low
Strategy:enable

if ! rpm -q --quiet "openscap-scanner" ; then
    yum install -y "openscap-scanner"
fi


[[packages]]
name = "openscap-scanner"
version = "*"

Complexity:low
Disruption:low
Strategy:enable
include install_openscap-scanner

class install_openscap-scanner {
  package { 'openscap-scanner':
    ensure => 'installed',
  }
}

Rule   Install scap-security-guide Package   [ref]

The scap-security-guide package can be installed with the following command:
$ sudo yum install scap-security-guide
Rationale:
The scap-security-guide package provides a guide for configuration of the system from the final system's security point of view. The guidance is specified in the Security Content Automation Protocol (SCAP) format and constitutes a catalog of practical hardening advice, linked to government requirements where applicable. The SCAP Security Guide project bridges the gap between generalized policy requirements and specific implementation guidelines. A system administrator can use the oscap CLI tool from the openscap-scanner package, or the SCAP Workbench GUI tool from the scap-workbench package, to verify that the system conforms to provided guidelines. Refer to the scap-security-guide(8) manual page for futher information.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_package_scap-security-guide_installed
Identifiers and References

Identifiers:  CCE-82949-9

References:  SRG-OS-000480-GPOS-00227


Complexity:low
Disruption:low
Strategy:enable

package --add=scap-security-guide

Complexity:low
Disruption:low
Strategy:enable
- name: Ensure scap-security-guide is installed
  package:
    name: scap-security-guide
    state: present
  tags:
    - CCE-82949-9
    - enable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - package_scap-security-guide_installed

Complexity:low
Disruption:low
Strategy:enable

if ! rpm -q --quiet "scap-security-guide" ; then
    yum install -y "scap-security-guide"
fi


[[packages]]
name = "scap-security-guide"
version = "*"

Complexity:low
Disruption:low
Strategy:enable
include install_scap-security-guide

class install_scap-security-guide {
  package { 'scap-security-guide':
    ensure => 'installed',
  }
}

Rule   Install subscription-manager Package   [ref]

The subscription-manager package can be installed with the following command:
$ sudo yum install subscription-manager
Rationale:
Red Hat Subscription Manager is a local service which tracks installed products and subscriptions on a local system to help manage subscription assignments. It communicates with the backend subscription service (the Customer Portal or an on-premise server such as Subscription Asset Manager) and works with content management tools such as .
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_package_subscription-manager_installed
Identifiers and References

Identifiers:  CCE-82316-1

References:  0940, 1144, 1467, 1472, 1483, 1493, 1494, 1495, FPT_TUD_EXT.1, FPT_TUD_EXT.2, SRG-OS-000366-GPOS-00153


Complexity:low
Disruption:low
Strategy:enable

package --add=subscription-manager

Complexity:low
Disruption:low
Strategy:enable
- name: Ensure subscription-manager is installed
  package:
    name: subscription-manager
    state: present
  tags:
    - CCE-82316-1
    - enable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - package_subscription-manager_installed

Complexity:low
Disruption:low
Strategy:enable

if ! rpm -q --quiet "subscription-manager" ; then
    yum install -y "subscription-manager"
fi


[[packages]]
name = "subscription-manager"
version = "*"

Complexity:low
Disruption:low
Strategy:enable
include install_subscription-manager

class install_subscription-manager {
  package { 'subscription-manager':
    ensure => 'installed',
  }
}

Rule   Uninstall abrt-addon-ccpp Package   [ref]

The abrt-addon-ccpp package can be removed with the following command:
$ sudo yum erase abrt-addon-ccpp
Rationale:
abrt-addon-ccpp contains hooks for C/C++ crashed programs and abrt's C/C++ analyzer plugin.
Severity: 
low
Rule ID:xccdf_org.ssgproject.content_rule_package_abrt-addon-ccpp_removed
Identifiers and References

Identifiers:  CCE-82919-2

References:  CCI-000381, SRG-OS-000095-GPOS-00049, RHEL-08-040001, SV-230488r627750_rule


Complexity:low
Disruption:low
Strategy:disable

package --remove=abrt-addon-ccpp

Complexity:low
Disruption:low
Strategy:disable
- name: Ensure abrt-addon-ccpp is removed
  package:
    name: abrt-addon-ccpp
    state: absent
  tags:
    - CCE-82919-2
    - DISA-STIG-RHEL-08-040001
    - disable_strategy
    - low_complexity
    - low_disruption
    - low_severity
    - no_reboot_needed
    - package_abrt-addon-ccpp_removed

Complexity:low
Disruption:low
Strategy:disable

# CAUTION: This remediation script will remove abrt-addon-ccpp
#	   from the system, and may remove any packages
#	   that depend on abrt-addon-ccpp. Execute this
#	   remediation AFTER testing on a non-production
#	   system!

if rpm -q --quiet "abrt-addon-ccpp" ; then

    yum remove -y "abrt-addon-ccpp"

fi

Complexity:low
Disruption:low
Strategy:disable
include remove_abrt-addon-ccpp

class remove_abrt-addon-ccpp {
  package { 'abrt-addon-ccpp':
    ensure => 'purged',
  }
}

Rule   Uninstall abrt-addon-kerneloops Package   [ref]

The abrt-addon-kerneloops package can be removed with the following command:
$ sudo yum erase abrt-addon-kerneloops
Rationale:
abrt-addon-kerneloops contains plugins for collecting kernel crash information and reporter plugin which sends this information to a specified server, usually to kerneloops.org.
Severity: 
low
Rule ID:xccdf_org.ssgproject.content_rule_package_abrt-addon-kerneloops_removed
Identifiers and References

Identifiers:  CCE-82926-7

References:  CCI-000381, SRG-OS-000095-GPOS-00049, RHEL-08-040001, SV-230488r627750_rule


Complexity:low
Disruption:low
Strategy:disable

package --remove=abrt-addon-kerneloops

Complexity:low
Disruption:low
Strategy:disable
- name: Ensure abrt-addon-kerneloops is removed
  package:
    name: abrt-addon-kerneloops
    state: absent
  tags:
    - CCE-82926-7
    - DISA-STIG-RHEL-08-040001
    - disable_strategy
    - low_complexity
    - low_disruption
    - low_severity
    - no_reboot_needed
    - package_abrt-addon-kerneloops_removed

Complexity:low
Disruption:low
Strategy:disable

# CAUTION: This remediation script will remove abrt-addon-kerneloops
#	   from the system, and may remove any packages
#	   that depend on abrt-addon-kerneloops. Execute this
#	   remediation AFTER testing on a non-production
#	   system!

if rpm -q --quiet "abrt-addon-kerneloops" ; then

    yum remove -y "abrt-addon-kerneloops"

fi

Complexity:low
Disruption:low
Strategy:disable
include remove_abrt-addon-kerneloops

class remove_abrt-addon-kerneloops {
  package { 'abrt-addon-kerneloops':
    ensure => 'purged',
  }
}

Rule   Uninstall abrt-cli Package   [ref]

The abrt-cli package can be removed with the following command:
$ sudo yum erase abrt-cli
Rationale:
abrt-cli contains a command line client for controlling abrt daemon over sockets.
Severity: 
low
Rule ID:xccdf_org.ssgproject.content_rule_package_abrt-cli_removed
Identifiers and References

Identifiers:  CCE-82907-7

References:  CCI-000381, SRG-OS-000095-GPOS-00049, RHEL-08-040001, SV-230488r627750_rule


Complexity:low
Disruption:low
Strategy:disable

package --remove=abrt-cli

Complexity:low
Disruption:low
Strategy:disable
- name: Ensure abrt-cli is removed
  package:
    name: abrt-cli
    state: absent
  tags:
    - CCE-82907-7
    - DISA-STIG-RHEL-08-040001
    - disable_strategy
    - low_complexity
    - low_disruption
    - low_severity
    - no_reboot_needed
    - package_abrt-cli_removed

Complexity:low
Disruption:low
Strategy:disable

# CAUTION: This remediation script will remove abrt-cli
#	   from the system, and may remove any packages
#	   that depend on abrt-cli. Execute this
#	   remediation AFTER testing on a non-production
#	   system!

if rpm -q --quiet "abrt-cli" ; then

    yum remove -y "abrt-cli"

fi

Complexity:low
Disruption:low
Strategy:disable
include remove_abrt-cli

class remove_abrt-cli {
  package { 'abrt-cli':
    ensure => 'purged',
  }
}

Rule   Uninstall abrt-plugin-sosreport Package   [ref]

The abrt-plugin-sosreport package can be removed with the following command:
$ sudo yum erase abrt-plugin-sosreport
Rationale:
abrt-plugin-sosreport provides a plugin to include an sosreport in an ABRT report.
Severity: 
low
Rule ID:xccdf_org.ssgproject.content_rule_package_abrt-plugin-sosreport_removed
Identifiers and References

Identifiers:  CCE-82910-1

References:  CCI-000381, SRG-OS-000095-GPOS-00049, RHEL-08-040001, SV-230488r627750_rule


Complexity:low
Disruption:low
Strategy:disable

package --remove=abrt-plugin-sosreport

Complexity:low
Disruption:low
Strategy:disable
- name: Ensure abrt-plugin-sosreport is removed
  package:
    name: abrt-plugin-sosreport
    state: absent
  tags:
    - CCE-82910-1
    - DISA-STIG-RHEL-08-040001
    - disable_strategy
    - low_complexity
    - low_disruption
    - low_severity
    - no_reboot_needed
    - package_abrt-plugin-sosreport_removed

Complexity:low
Disruption:low
Strategy:disable

# CAUTION: This remediation script will remove abrt-plugin-sosreport
#	   from the system, and may remove any packages
#	   that depend on abrt-plugin-sosreport. Execute this
#	   remediation AFTER testing on a non-production
#	   system!

if rpm -q --quiet "abrt-plugin-sosreport" ; then

    yum remove -y "abrt-plugin-sosreport"

fi

Complexity:low
Disruption:low
Strategy:disable
include remove_abrt-plugin-sosreport

class remove_abrt-plugin-sosreport {
  package { 'abrt-plugin-sosreport':
    ensure => 'purged',
  }
}

Rule   Uninstall gssproxy Package   [ref]

The gssproxy package can be removed with the following command:
$ sudo yum erase gssproxy
Warning:  This rule is disabled on Red Hat Virtualization Hosts and Managers, it will report not applicable. RHV uses NFS storage, which has dependency on gssproxy.
Rationale:
gssproxy is a proxy for GSS API credential handling.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_package_gssproxy_removed
Identifiers and References

Identifiers:  CCE-82943-2

References:  CCI-000381, CCI-000366, SRG-OS-000095-GPOS-00049, SRG-OS-000480-GPOS-00227, RHEL-08-040370, SV-230559r646887_rule


Complexity:low
Disruption:low
Strategy:disable
- name: Ensure gssproxy is removed
  package:
    name: gssproxy
    state: absent
  tags:
    - CCE-82943-2
    - DISA-STIG-RHEL-08-040370
    - disable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - package_gssproxy_removed

Complexity:low
Disruption:low
Strategy:disable

# CAUTION: This remediation script will remove gssproxy
#	   from the system, and may remove any packages
#	   that depend on gssproxy. Execute this
#	   remediation AFTER testing on a non-production
#	   system!

if rpm -q --quiet "gssproxy" ; then

    yum remove -y "gssproxy"

fi

Complexity:low
Disruption:low
Strategy:disable
include remove_gssproxy

class remove_gssproxy {
  package { 'gssproxy':
    ensure => 'purged',
  }
}

Rule   Uninstall iprutils Package   [ref]

The iprutils package can be removed with the following command:
$ sudo yum erase iprutils
Rationale:
iprutils provides a suite of utlilities to manage and configure SCSI devices supported by the ipr SCSI storage device driver.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_package_iprutils_removed
Identifiers and References

Identifiers:  CCE-82946-5

References:  CCI-000366, SRG-OS-000095-GPOS-00049, SRG-OS-000480-GPOS-00227, RHEL-08-040380, SV-230560r627750_rule


Complexity:low
Disruption:low
Strategy:disable

package --remove=iprutils

Complexity:low
Disruption:low
Strategy:disable
- name: Ensure iprutils is removed
  package:
    name: iprutils
    state: absent
  tags:
    - CCE-82946-5
    - DISA-STIG-RHEL-08-040380
    - disable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - package_iprutils_removed

Complexity:low
Disruption:low
Strategy:disable

# CAUTION: This remediation script will remove iprutils
#	   from the system, and may remove any packages
#	   that depend on iprutils. Execute this
#	   remediation AFTER testing on a non-production
#	   system!

if rpm -q --quiet "iprutils" ; then

    yum remove -y "iprutils"

fi

Complexity:low
Disruption:low
Strategy:disable
include remove_iprutils

class remove_iprutils {
  package { 'iprutils':
    ensure => 'purged',
  }
}

Rule   Uninstall krb5-workstation Package   [ref]

The krb5-workstation package can be removed with the following command:
$ sudo yum erase krb5-workstation
Warning:  This rule is disabled on Red Hat Virtualization Hosts and Managers, it will report not applicable. RHV hosts require ipa-client package, which has dependency on krb5-workstation.
Rationale:
Kerberos is a network authentication system. The krb5-workstation package contains the basic Kerberos programs (kinit, klist, kdestroy, kpasswd). Currently, Kerberos does not utilize FIPS 140-2 cryptography and is not permitted on Government networks, nor is it permitted in many regulatory environments such as HIPAA.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_package_krb5-workstation_removed
Identifiers and References

Identifiers:  CCE-82931-7

References:  CCI-000803, SRG-OS-000095-GPOS-00049, SRG-OS-000120-GPOS-00061, RHEL-08-010162, SV-230239r646864_rule


Complexity:low
Disruption:low
Strategy:disable

package --remove=krb5-workstation

Complexity:low
Disruption:low
Strategy:disable
- name: Ensure krb5-workstation is removed
  package:
    name: krb5-workstation
    state: absent
  tags:
    - CCE-82931-7
    - DISA-STIG-RHEL-08-010162
    - disable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - package_krb5-workstation_removed

Complexity:low
Disruption:low
Strategy:disable

# CAUTION: This remediation script will remove krb5-workstation
#	   from the system, and may remove any packages
#	   that depend on krb5-workstation. Execute this
#	   remediation AFTER testing on a non-production
#	   system!

if rpm -q --quiet "krb5-workstation" ; then

    yum remove -y "krb5-workstation"

fi

Complexity:low
Disruption:low
Strategy:disable
include remove_krb5-workstation

class remove_krb5-workstation {
  package { 'krb5-workstation':
    ensure => 'purged',
  }
}

Rule   Uninstall libreport-plugin-logger Package   [ref]

The libreport-plugin-logger package can be removed with the following command:
$ sudo yum erase libreport-plugin-logger
Rationale:
libreport-plugin-logger is a ABRT plugin to report bugs into the Red Hat Support system.
Severity: 
low
Rule ID:xccdf_org.ssgproject.content_rule_package_libreport-plugin-logger_removed
Identifiers and References

Identifiers:  CCE-89201-8

References:  CCI-000381, SRG-OS-000095-GPOS-00049, RHEL-08-040001, SV-230488r627750_rule


Complexity:low
Disruption:low
Strategy:disable

package --remove=libreport-plugin-logger

Complexity:low
Disruption:low
Strategy:disable
- name: Ensure libreport-plugin-logger is removed
  package:
    name: libreport-plugin-logger
    state: absent
  tags:
    - CCE-89201-8
    - DISA-STIG-RHEL-08-040001
    - disable_strategy
    - low_complexity
    - low_disruption
    - low_severity
    - no_reboot_needed
    - package_libreport-plugin-logger_removed

Complexity:low
Disruption:low
Strategy:disable

# CAUTION: This remediation script will remove libreport-plugin-logger
#	   from the system, and may remove any packages
#	   that depend on libreport-plugin-logger. Execute this
#	   remediation AFTER testing on a non-production
#	   system!

if rpm -q --quiet "libreport-plugin-logger" ; then

    yum remove -y "libreport-plugin-logger"

fi

Complexity:low
Disruption:low
Strategy:disable
include remove_libreport-plugin-logger

class remove_libreport-plugin-logger {
  package { 'libreport-plugin-logger':
    ensure => 'purged',
  }
}

Rule   Uninstall libreport-plugin-rhtsupport Package   [ref]

The libreport-plugin-rhtsupport package can be removed with the following command:
$ sudo yum erase libreport-plugin-rhtsupport
Rationale:
libreport-plugin-rhtsupport is a ABRT plugin to report bugs into the Red Hat Support system.
Severity: 
low
Rule ID:xccdf_org.ssgproject.content_rule_package_libreport-plugin-rhtsupport_removed
Identifiers and References

Identifiers:  CCE-88955-0

References:  CCI-000381, SRG-OS-000095-GPOS-00049, RHEL-08-040001, SV-230488r627750_rule


Complexity:low
Disruption:low
Strategy:disable

package --remove=libreport-plugin-rhtsupport

Complexity:low
Disruption:low
Strategy:disable
- name: Ensure libreport-plugin-rhtsupport is removed
  package:
    name: libreport-plugin-rhtsupport
    state: absent
  tags:
    - CCE-88955-0
    - DISA-STIG-RHEL-08-040001
    - disable_strategy
    - low_complexity
    - low_disruption
    - low_severity
    - no_reboot_needed
    - package_libreport-plugin-rhtsupport_removed

Complexity:low
Disruption:low
Strategy:disable

# CAUTION: This remediation script will remove libreport-plugin-rhtsupport
#	   from the system, and may remove any packages
#	   that depend on libreport-plugin-rhtsupport. Execute this
#	   remediation AFTER testing on a non-production
#	   system!

if rpm -q --quiet "libreport-plugin-rhtsupport" ; then

    yum remove -y "libreport-plugin-rhtsupport"

fi

Complexity:low
Disruption:low
Strategy:disable
include remove_libreport-plugin-rhtsupport

class remove_libreport-plugin-rhtsupport {
  package { 'libreport-plugin-rhtsupport':
    ensure => 'purged',
  }
}

Rule   Uninstall python3-abrt-addon Package   [ref]

The python3-abrt-addon package can be removed with the following command:
$ sudo yum erase python3-abrt-addon
Rationale:
python3-abrt-addon contains python hook and python analyzer plugin for handling uncaught exceptions in python programs.
Severity: 
low
Rule ID:xccdf_org.ssgproject.content_rule_package_python3-abrt-addon_removed
Identifiers and References

Identifiers:  CCE-86084-1

References:  CCI-000381, SRG-OS-000095-GPOS-00049, RHEL-08-040001, SV-230488r627750_rule


Complexity:low
Disruption:low
Strategy:disable

package --remove=python3-abrt-addon

Complexity:low
Disruption:low
Strategy:disable
- name: Ensure python3-abrt-addon is removed
  package:
    name: python3-abrt-addon
    state: absent
  tags:
    - CCE-86084-1
    - DISA-STIG-RHEL-08-040001
    - disable_strategy
    - low_complexity
    - low_disruption
    - low_severity
    - no_reboot_needed
    - package_python3-abrt-addon_removed

Complexity:low
Disruption:low
Strategy:disable

# CAUTION: This remediation script will remove python3-abrt-addon
#	   from the system, and may remove any packages
#	   that depend on python3-abrt-addon. Execute this
#	   remediation AFTER testing on a non-production
#	   system!

if rpm -q --quiet "python3-abrt-addon" ; then

    yum remove -y "python3-abrt-addon"

fi

Complexity:low
Disruption:low
Strategy:disable
include remove_python3-abrt-addon

class remove_python3-abrt-addon {
  package { 'python3-abrt-addon':
    ensure => 'purged',
  }
}
Group   Updating Software   Group contains 8 rules
[ref]   The 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.

Red Hat Enterprise 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.

Rule   Install dnf-automatic Package   [ref]

The 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.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_package_dnf-automatic_installed
Identifiers and References

Identifiers:  CCE-82985-3

References:  BP28(R8), SRG-OS-000191-GPOS-00080


Complexity:low
Disruption:low
Strategy:enable

package --add=dnf-automatic

Complexity:low
Disruption:low
Strategy:enable
- name: Ensure dnf-automatic is installed
  package:
    name: dnf-automatic
    state: present
  tags:
    - CCE-82985-3
    - enable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - package_dnf-automatic_installed

Complexity:low
Disruption:low
Strategy:enable

if ! rpm -q --quiet "dnf-automatic" ; then
    yum install -y "dnf-automatic"
fi


[[packages]]
name = "dnf-automatic"
version = "*"

Complexity:low
Disruption:low
Strategy:enable
include install_dnf-automatic

class install_dnf-automatic {
  package { 'dnf-automatic':
    ensure => 'installed',
  }
}

Rule   Configure dnf-automatic to Install Available Updates Automatically   [ref]

To 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.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_dnf-automatic_apply_updates
Identifiers and References

Identifiers:  CCE-82494-6

References:  BP28(R8), 0940, 1144, 1467, 1472, 1483, 1493, 1494, 1495, SI-2(5), CM-6(a), SI-2(c), FMT_SMF_EXT.1, SRG-OS-000191-GPOS-00080


Complexity:low
Disruption:medium
- 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:
    - CCE-82494-6
    - 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


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

Rule   Configure dnf-automatic to Install Only Security Updates   [ref]

To 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.
Severity: 
low
Rule ID:xccdf_org.ssgproject.content_rule_dnf-automatic_security_updates_only
Identifiers and References

Identifiers:  CCE-82267-6

References:  BP28(R8), SI-2(5), CM-6(a), SI-2(c), FMT_SMF_EXT.1, SRG-OS-000191-GPOS-00080


Complexity:low
Disruption:medium
- 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:
    - CCE-82267-6
    - 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


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

Rule   Ensure gpgcheck Enabled In Main yum Configuration   [ref]

The 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).
Severity: 
high
Rule ID:xccdf_org.ssgproject.content_rule_ensure_gpgcheck_globally_activated
Identifiers and References

Identifiers:  CCE-80790-9

References:  BP28(R15), 11, 2, 3, 9, 5.10.4.1, APO01.06, BAI03.05, BAI06.01, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS06.02, 3.4.8, CCI-001749, 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, 4.3.4.4.4, SR 3.1, SR 3.3, SR 3.4, SR 3.8, SR 7.6, 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, CM-5(3), SI-7, SC-12, SC-12(3), CM-6(a), SA-12, SA-12(10), CM-11(a), CM-11(b), PR.DS-6, PR.DS-8, PR.IP-1, FPT_TUD_EXT.1, FPT_TUD_EXT.2, Req-6.2, SRG-OS-000366-GPOS-00153, SRG-OS-000366-VMM-001430, SRG-OS-000370-VMM-001460, SRG-OS-000404-VMM-001650, RHEL-08-010370, 1.2.4, SV-230264r627750_rule


Complexity:low
Disruption:medium
Strategy:configure
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
    - CCE-80790-9
    - CJIS-5.10.4.1
    - DISA-STIG-RHEL-08-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:
    - CCE-80790-9
    - CJIS-5.10.4.1
    - DISA-STIG-RHEL-08-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

# 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
    cce="CCE-80790-9"
    printf '\n# Per %s: Set %s in %s\n' "$cce" "$formatted_output" "/etc/yum.conf" >> "/etc/yum.conf"
    printf '%s\n' "$formatted_output" >> "/etc/yum.conf"
fi

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi

Rule   Ensure gpgcheck Enabled for Local Packages   [ref]

yum 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.
Severity: 
high
Rule ID:xccdf_org.ssgproject.content_rule_ensure_gpgcheck_local_packages
Identifiers and References

Identifiers:  CCE-80791-7

References:  BP28(R15), 11, 3, 9, BAI10.01, BAI10.02, BAI10.03, BAI10.05, 3.4.8, CCI-001749, 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, A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, CM-11(a), CM-11(b), CM-6(a), CM-5(3), SA-12, SA-12(10), PR.IP-1, FPT_TUD_EXT.1, FPT_TUD_EXT.2, SRG-OS-000366-GPOS-00153, SRG-OS-000366-VMM-001430, SRG-OS-000370-VMM-001460, SRG-OS-000404-VMM-001650, RHEL-08-010371, SV-230265r627750_rule


Complexity:low
Disruption:medium
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
    - CCE-80791-7
    - DISA-STIG-RHEL-08-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:
    - CCE-80791-7
    - DISA-STIG-RHEL-08-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

# 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
    cce="CCE-80791-7"
    printf '\n# Per %s: Set %s in %s\n' "$cce" "$formatted_output" "/etc/yum.conf" >> "/etc/yum.conf"
    printf '%s\n' "$formatted_output" >> "/etc/yum.conf"
fi

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi

Rule   Ensure gpgcheck Enabled for All yum Package Repositories   [ref]

To 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)."
Severity: 
high
Rule ID:xccdf_org.ssgproject.content_rule_ensure_gpgcheck_never_disabled
Identifiers and References

Identifiers:  CCE-80792-5

References:  BP28(R15), 11, 2, 3, 9, 5.10.4.1, APO01.06, BAI03.05, BAI06.01, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS06.02, 3.4.8, CCI-001749, 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, 4.3.4.4.4, SR 3.1, SR 3.3, SR 3.4, SR 3.8, SR 7.6, 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, CM-5(3), SI-7, SC-12, SC-12(3), CM-6(a), SA-12, SA-12(10), CM-11(a), CM-11(b), PR.DS-6, PR.DS-8, PR.IP-1, FPT_TUD_EXT.1, FPT_TUD_EXT.2, Req-6.2, SRG-OS-000366-GPOS-00153, SRG-OS-000366-VMM-001430, SRG-OS-000370-VMM-001460, SRG-OS-000404-VMM-001650


Complexity:low
Disruption:medium
Strategy:enable
- 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:
    - CCE-80792-5
    - 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:
    - CCE-80792-5
    - 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

sed -i 's/gpgcheck\s*=.*/gpgcheck=1/g' /etc/yum.repos.d/*

Rule   Ensure Red Hat GPG Key Installed   [ref]

To ensure the system can cryptographically verify base software packages come from Red Hat (and to connect to the Red Hat Network to receive them), the Red Hat GPG key must properly be installed. To install the Red Hat GPG key, run:
$ sudo subscription-manager register
If the system is not connected to the Internet or an RHN Satellite, then install the Red Hat GPG key from trusted media such as the Red Hat 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
Alternatively, the key may be pre-loaded during the RHEL installation. In such cases, the key can be installed by running the following command:
sudo rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
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 Red Hat GPG key is necessary to cryptographically verify packages are from Red Hat.
Severity: 
high
Rule ID:xccdf_org.ssgproject.content_rule_ensure_redhat_gpgkey_installed
Identifiers and References

Identifiers:  CCE-80795-8

References:  BP28(R15), 11, 2, 3, 9, 5.10.4.1, APO01.06, BAI03.05, BAI06.01, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS06.02, 3.4.8, CCI-001749, 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, 4.3.4.4.4, SR 3.1, SR 3.3, SR 3.4, SR 3.8, SR 7.6, 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, CIP-003-8 R4.2, CIP-003-8 R6, CIP-007-3 R4, CIP-007-3 R4.1, CIP-007-3 R4.2, CIP-007-3 R5.1, CM-5(3), SI-7, SC-12, SC-12(3), CM-6(a), PR.DS-6, PR.DS-8, PR.IP-1, FPT_TUD_EXT.1, FPT_TUD_EXT.2, Req-6.2, SRG-OS-000366-GPOS-00153, SRG-OS-000366-VMM-001430, SRG-OS-000370-VMM-001460, SRG-OS-000404-VMM-001650, 1.2.3


Complexity:medium
Disruption:medium
Strategy:restrict
- name: Read permission of GPG key directory
  stat:
    path: /etc/pki/rpm-gpg/
  register: gpg_key_directory_permission
  check_mode: false
  tags:
    - CCE-80795-8
    - CJIS-5.10.4.1
    - NIST-800-171-3.4.8
    - NIST-800-53-CM-5(3)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-SC-12
    - NIST-800-53-SC-12(3)
    - NIST-800-53-SI-7
    - PCI-DSS-Req-6.2
    - ensure_redhat_gpgkey_installed
    - high_severity
    - medium_complexity
    - medium_disruption
    - no_reboot_needed
    - restrict_strategy

- name: Read signatures in GPG key
  command: gpg --show-keys --with-fingerprint --with-colons "/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release"
  args:
    warn: false
  changed_when: false
  register: gpg_fingerprints
  check_mode: false
  tags:
    - CCE-80795-8
    - CJIS-5.10.4.1
    - NIST-800-171-3.4.8
    - NIST-800-53-CM-5(3)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-SC-12
    - NIST-800-53-SC-12(3)
    - NIST-800-53-SI-7
    - PCI-DSS-Req-6.2
    - ensure_redhat_gpgkey_installed
    - high_severity
    - medium_complexity
    - medium_disruption
    - no_reboot_needed
    - restrict_strategy

- name: Set Fact - Installed GPG Fingerprints
  set_fact:
    gpg_installed_fingerprints: |-
      {{ gpg_fingerprints.stdout | regex_findall('^pub.*
      (?:^fpr[:]*)([0-9A-Fa-f]*)', '\1') | list }}
  tags:
    - CCE-80795-8
    - CJIS-5.10.4.1
    - NIST-800-171-3.4.8
    - NIST-800-53-CM-5(3)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-SC-12
    - NIST-800-53-SC-12(3)
    - NIST-800-53-SI-7
    - PCI-DSS-Req-6.2
    - ensure_redhat_gpgkey_installed
    - high_severity
    - medium_complexity
    - medium_disruption
    - no_reboot_needed
    - restrict_strategy

- name: Set Fact - Valid fingerprints
  set_fact:
    gpg_valid_fingerprints: ("567E347AD0044ADE55BA8A5F199E2F91FD431D51" "6A6AA7C97C8890AEC6AEBFE2F76F66C3D4082792")
  tags:
    - CCE-80795-8
    - CJIS-5.10.4.1
    - NIST-800-171-3.4.8
    - NIST-800-53-CM-5(3)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-SC-12
    - NIST-800-53-SC-12(3)
    - NIST-800-53-SI-7
    - PCI-DSS-Req-6.2
    - ensure_redhat_gpgkey_installed
    - high_severity
    - medium_complexity
    - medium_disruption
    - no_reboot_needed
    - restrict_strategy

- name: Import RedHat GPG key
  rpm_key:
    state: present
    key: /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
  when:
    - gpg_key_directory_permission.stat.mode <= '0755'
    - (gpg_installed_fingerprints | difference(gpg_valid_fingerprints)) | length ==
      0
    - gpg_installed_fingerprints | length > 0
    - ansible_distribution == "RedHat"
  tags:
    - CCE-80795-8
    - CJIS-5.10.4.1
    - NIST-800-171-3.4.8
    - NIST-800-53-CM-5(3)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-SC-12
    - NIST-800-53-SC-12(3)
    - NIST-800-53-SI-7
    - PCI-DSS-Req-6.2
    - ensure_redhat_gpgkey_installed
    - high_severity
    - medium_complexity
    - medium_disruption
    - no_reboot_needed
    - restrict_strategy

# The two fingerprints below are retrieved from https://access.redhat.com/security/team/key
readonly REDHAT_RELEASE_FINGERPRINT="567E347AD0044ADE55BA8A5F199E2F91FD431D51"
readonly REDHAT_AUXILIARY_FINGERPRINT="6A6AA7C97C8890AEC6AEBFE2F76F66C3D4082792"

# Location of the key we would like to import (once it's integrity verified)
readonly REDHAT_RELEASE_KEY="/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release"

RPM_GPG_DIR_PERMS=$(stat -c %a "$(dirname "$REDHAT_RELEASE_KEY")")

# Verify /etc/pki/rpm-gpg directory permissions are safe
if [ "${RPM_GPG_DIR_PERMS}" -le "755" ]
then
  # If they are safe, try to obtain fingerprints from the key file
  # (to ensure there won't be e.g. CRC error).

  readarray -t GPG_OUT < <(gpg --show-keys --with-fingerprint --with-colons "$REDHAT_RELEASE_KEY" | grep -A1 "^pub" | grep "^fpr" | cut -d ":" -f 10)

  GPG_RESULT=$?
  # No CRC error, safe to proceed
  if [ "${GPG_RESULT}" -eq "0" ]
  then
    echo "${GPG_OUT[*]}" | grep -vE "${REDHAT_RELEASE_FINGERPRINT}|${REDHAT_AUXILIARY_FINGERPRINT}" || {
      # If $REDHAT_RELEASE_KEY file doesn't contain any keys with unknown fingerprint, import it
      rpm --import "${REDHAT_RELEASE_KEY}"
    }
  fi
fi

Rule   Enable dnf-automatic Timer   [ref]

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.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_timer_dnf-automatic_enabled
Identifiers and References

Identifiers:  CCE-82360-9

References:  BP28(R8), SI-2(5), CM-6(a), SI-2(c), FMT_SMF_EXT.1, SRG-OS-000191-GPOS-00080


Complexity:low
Disruption:low
Strategy:enable
- 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:
    - CCE-82360-9
    - 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

Complexity:low
Disruption:low
Strategy:enable

SYSTEMCTL_EXEC='/usr/bin/systemctl'
"$SYSTEMCTL_EXEC" start 'dnf-automatic.timer'
"$SYSTEMCTL_EXEC" enable 'dnf-automatic.timer'
Group   Account and Access Control   Group contains 13 groups and 30 rules
[ref]   In 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 Red Hat Enterprise Linux 8.
Group   Protect Accounts by Configuring PAM   Group contains 3 groups and 12 rules
[ref]   PAM, 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.
Warning:  Running authconfig or system-config-authentication will re-write the PAM configuration files, destroying any manually made changes and replacing them with a series of system defaults. One reference to the configuration file syntax can be found at http://www.linux-pam.org/Linux-PAM-html/sag-configuration-file.html.
Group   Set Lockouts for Failed Password Attempts   Group contains 4 rules
[ref]   The 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.

Rule   Limit Password Reuse   [ref]

Do 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.
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.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_accounts_password_pam_unix_remember
Identifiers and References

Identifiers:  CCE-80666-1

References:  BP28(R18), 1, 12, 15, 16, 5, 5.6.2.1.1, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.10, 3.5.8, CCI-000200, 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, 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, IA-5(f), IA-5(1)(e), PR.AC-1, PR.AC-6, PR.AC-7, Req-8.2.5, SRG-OS-000077-GPOS-00045, SRG-OS-000077-VMM-000440, 5.4.3


Complexity:low
Disruption:medium
Strategy:configure
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
    - CCE-80666-1
    - 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 5
  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:
    - CCE-80666-1
    - 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:
    - CCE-80666-1
    - 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:
    - CCE-80666-1
    - 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:
    - CCE-80666-1
    - 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:
    - CCE-80666-1
    - 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:
    - CCE-80666-1
    - 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:
    - CCE-80666-1
    - 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:
    - CCE-80666-1
    - 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:
    - CCE-80666-1
    - 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:
    - CCE-80666-1
    - 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:
    - CCE-80666-1
    - 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:
    - CCE-80666-1
    - 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:
    - CCE-80666-1
    - 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:
    - CCE-80666-1
    - 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:
    - CCE-80666-1
    - 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:
    - CCE-80666-1
    - 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:
    - CCE-80666-1
    - 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:
    - CCE-80666-1
    - 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:
    - CCE-80666-1
    - 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

# Remediation is applicable only in certain platforms
if rpm --quiet -q pam; then

var_password_pam_unix_remember='5'


if [ -f /usr/bin/authselect ]; then
    if authselect 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

Rule   Lock Accounts After Failed Password Attempts   [ref]

This 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 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.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_accounts_passwords_pam_faillock_deny
Identifiers and References

Identifiers:  CCE-80667-9

References:  BP28(R18), 1, 12, 15, 16, 5.5.3, DSS05.04, DSS05.10, DSS06.10, 3.1.8, CCI-000044, CCI-002236, CCI-002237, CCI-002238, 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, A.18.1.4, A.9.2.1, A.9.2.4, A.9.3.1, A.9.4.2, A.9.4.3, CM-6(a), AC-7(a), PR.AC-7, FIA_AFL.1, Req-8.1.6, SRG-OS-000329-GPOS-00128, SRG-OS-000021-GPOS-00005, SRG-OS-000021-VMM-000050, RHEL-08-020010, 5.3.3, 5.4.2, SV-230332r627750_rule


Complexity:low
Disruption:low
Strategy:restrict
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
    - CCE-80667-9
    - CJIS-5.5.3
    - DISA-STIG-RHEL-08-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:
    - CCE-80667-9
    - CJIS-5.5.3
    - DISA-STIG-RHEL-08-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:
    - CCE-80667-9
    - CJIS-5.5.3
    - DISA-STIG-RHEL-08-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:
    - CCE-80667-9
    - CJIS-5.5.3
    - DISA-STIG-RHEL-08-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:
    - CCE-80667-9
    - CJIS-5.5.3
    - DISA-STIG-RHEL-08-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:
    - CCE-80667-9
    - CJIS-5.5.3
    - DISA-STIG-RHEL-08-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:
    - CCE-80667-9
    - CJIS-5.5.3
    - DISA-STIG-RHEL-08-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

# 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

Rule   Set Interval For Counting Failed Password Attempts   [ref]

Utilizing 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.
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.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_accounts_passwords_pam_faillock_interval
Identifiers and References

Identifiers:  CCE-80669-5

References:  BP28(R18), 1, 12, 15, 16, DSS05.04, DSS05.10, DSS06.10, CCI-000044, CCI-002236, CCI-002237, CCI-002238, 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, A.18.1.4, A.9.2.1, A.9.2.4, A.9.3.1, A.9.4.2, A.9.4.3, CM-6(a), AC-7(a), PR.AC-7, FIA_AFL.1, SRG-OS-000329-GPOS-00128, SRG-OS-000021-GPOS-00005, SRG-OS-000021-VMM-000050, RHEL-08-020012, SV-230334r627750_rule


Complexity:low
Disruption:low
Strategy:restrict
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
    - CCE-80669-5
    - DISA-STIG-RHEL-08-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:
    - CCE-80669-5
    - DISA-STIG-RHEL-08-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:
    - CCE-80669-5
    - DISA-STIG-RHEL-08-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:
    - CCE-80669-5
    - DISA-STIG-RHEL-08-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:
    - CCE-80669-5
    - DISA-STIG-RHEL-08-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:
    - CCE-80669-5
    - DISA-STIG-RHEL-08-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:
    - CCE-80669-5
    - DISA-STIG-RHEL-08-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

# 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

Rule   Set Lockout Time for Failed Password Attempts   [ref]

This 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 supports the new /etc/security/faillock.conf file but the pam_faillock.so parameters are defined directly in /etc/pam.d/system-auth and /etc/pam.d/password-auth, the remediation will migrate the unlock_time parameter to /etc/security/faillock.conf to ensure compatibility with authselect tool. The parameters deny and fail_interval, if used, also have to be migrated by their respective remediation.
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.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_accounts_passwords_pam_faillock_unlock_time
Identifiers and References

Identifiers:  CCE-80670-3

References:  BP28(R18), 1, 12, 15, 16, 5.5.3, DSS05.04, DSS05.10, DSS06.10, 3.1.8, CCI-000044, CCI-002236, CCI-002237, CCI-002238, 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, A.18.1.4, A.9.2.1, A.9.2.4, A.9.3.1, A.9.4.2, A.9.4.3, CM-6(a), AC-7(b), PR.AC-7, FIA_AFL.1, Req-8.1.7, SRG-OS-000329-GPOS-00128, SRG-OS-000021-GPOS-00005, SRG-OS-000329-VMM-001180, RHEL-08-020016, 5.4.2, SV-230338r627750_rule


Complexity:low
Disruption:low
Strategy:restrict
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
    - CCE-80670-3
    - CJIS-5.5.3
    - DISA-STIG-RHEL-08-020016
    - 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:
    - CCE-80670-3
    - CJIS-5.5.3
    - DISA-STIG-RHEL-08-020016
    - 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:
    - CCE-80670-3
    - CJIS-5.5.3
    - DISA-STIG-RHEL-08-020016
    - 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:
    - CCE-80670-3
    - CJIS-5.5.3
    - DISA-STIG-RHEL-08-020016
    - 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 0
  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:
    - CCE-80670-3
    - CJIS-5.5.3
    - DISA-STIG-RHEL-08-020016
    - 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:
    - CCE-80670-3
    - CJIS-5.5.3
    - DISA-STIG-RHEL-08-020016
    - 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:
    - CCE-80670-3
    - CJIS-5.5.3
    - DISA-STIG-RHEL-08-020016
    - 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

# Remediation is applicable only in certain platforms
if rpm --quiet -q pam; then

var_accounts_passwords_pam_faillock_unlock_time='0'


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
Group   Set Password Quality Requirements   Group contains 1 group and 8 rules
[ref]   The 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.
Group   Set Password Quality Requirements with pam_pwquality   Group contains 8 rules
[ref]   The 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.

Rule   Ensure PAM Enforces Password Requirements - Minimum Digit Characters   [ref]

The 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.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_accounts_password_pam_dcredit
Identifiers and References

Identifiers:  CCE-80653-9

References:  BP28(R18), 1, 12, 15, 16, 5, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.10, CCI-000194, 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, 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, IA-5(c), IA-5(1)(a), CM-6(a), IA-5(4), PR.AC-1, PR.AC-6, PR.AC-7, FMT_MOF_EXT.1, Req-8.2.3, SRG-OS-000071-GPOS-00039, SRG-OS-000071-VMM-000380, RHEL-08-020130, SV-230359r627750_rule


Complexity:low
Disruption:low
Strategy:restrict
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
    - CCE-80653-9
    - DISA-STIG-RHEL-08-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:
    - CCE-80653-9
    - DISA-STIG-RHEL-08-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

Complexity:low
Disruption:low
Strategy:restrict
# 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
    cce="CCE-80653-9"
    printf '\n# Per %s: Set %s in %s\n' "$cce" "$formatted_output" "/etc/security/pwquality.conf" >> "/etc/security/pwquality.conf"
    printf '%s\n' "$formatted_output" >> "/etc/security/pwquality.conf"
fi

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi

Rule   Ensure PAM Enforces Password Requirements - Minimum Different Characters   [ref]

The pam_pwquality module's difok parameter sets the number of characters in a password that must not be present in and old password during a password change.

Modify the difok setting in /etc/security/pwquality.conf to equal 4 to require differing characters when changing 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 a minimum number of different characters during password changes ensures that newly changed passwords should not resemble previously compromised ones. Note that passwords which are changed on compromised systems will still be compromised, however.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_accounts_password_pam_difok
Identifiers and References

Identifiers:  CCE-80654-7

References:  1, 12, 15, 16, 5, 5.6.2.1.1, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.10, CCI-000195, 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, 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, IA-5(c), IA-5(1)(b), CM-6(a), IA-5(4), PR.AC-1, PR.AC-6, PR.AC-7, SRG-OS-000072-GPOS-00040, SRG-OS-000072-VMM-000390, RHEL-08-020170, SV-230363r627750_rule


Complexity:low
Disruption:low
Strategy:restrict
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
    - CCE-80654-7
    - CJIS-5.6.2.1.1
    - DISA-STIG-RHEL-08-020170
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IA-5(1)(b)
    - NIST-800-53-IA-5(4)
    - NIST-800-53-IA-5(c)
    - accounts_password_pam_difok
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy
- name: XCCDF Value var_password_pam_difok # promote to variable
  set_fact:
    var_password_pam_difok: !!str 4
  tags:
    - always

- name: Ensure PAM variable difok is set accordingly
  lineinfile:
    create: true
    dest: /etc/security/pwquality.conf
    regexp: ^#?\s*difok
    line: difok = {{ var_password_pam_difok }}
  when: '"pam" in ansible_facts.packages'
  tags:
    - CCE-80654-7
    - CJIS-5.6.2.1.1
    - DISA-STIG-RHEL-08-020170
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IA-5(1)(b)
    - NIST-800-53-IA-5(4)
    - NIST-800-53-IA-5(c)
    - accounts_password_pam_difok
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

Complexity:low
Disruption:low
Strategy:restrict
# Remediation is applicable only in certain platforms
if rpm --quiet -q pam; then

var_password_pam_difok='4'


# 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' <<< "^difok")

# shellcheck disable=SC2059
printf -v formatted_output "%s = %s" "$stripped_key" "$var_password_pam_difok"

# If the key exists, change it. Otherwise, add it to the config_file.
# We search for the key string followed by a word boundary (matched by \>),
# so if we search for 'setting', 'setting2' won't match.
if LC_ALL=C grep -q -m 1 -i -e "^difok\\>" "/etc/security/pwquality.conf"; then
    "${sed_command[@]}" "s/^difok\\>.*/$formatted_output/gi" "/etc/security/pwquality.conf"
else
    # \n is precaution for case where file ends without trailing newline
    cce="CCE-80654-7"
    printf '\n# Per %s: Set %s in %s\n' "$cce" "$formatted_output" "/etc/security/pwquality.conf" >> "/etc/security/pwquality.conf"
    printf '%s\n' "$formatted_output" >> "/etc/security/pwquality.conf"
fi

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi

Rule   Ensure PAM Enforces Password Requirements - Minimum Lowercase Characters   [ref]

The 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.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_accounts_password_pam_lcredit
Identifiers and References

Identifiers:  CCE-80655-4

References:  BP28(R18), 1, 12, 15, 16, 5, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.10, CCI-000193, 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, 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, IA-5(c), IA-5(1)(a), CM-6(a), IA-5(4), PR.AC-1, PR.AC-6, PR.AC-7, FMT_MOF_EXT.1, Req-8.2.3, SRG-OS-000070-GPOS-00038, SRG-OS-000070-VMM-000370, RHEL-08-020120, SV-230358r627750_rule


Complexity:low
Disruption:low
Strategy:restrict
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
    - CCE-80655-4
    - DISA-STIG-RHEL-08-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:
    - CCE-80655-4
    - DISA-STIG-RHEL-08-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

Complexity:low
Disruption:low
Strategy:restrict
# 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
    cce="CCE-80655-4"
    printf '\n# Per %s: Set %s in %s\n' "$cce" "$formatted_output" "/etc/security/pwquality.conf" >> "/etc/security/pwquality.conf"
    printf '%s\n' "$formatted_output" >> "/etc/security/pwquality.conf"
fi

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi

Rule   Ensure PAM Enforces Password Requirements - Maximum Consecutive Repeating Characters from Same Character Class   [ref]

The pam_pwquality module's maxclassrepeat parameter controls requirements for consecutive repeating characters from the same character class. When set to a positive number, it will reject passwords which contain more than that number of consecutive characters from the same character class. Modify the maxclassrepeat setting in /etc/security/pwquality.conf to equal 4 to prevent a run of (4 + 1) or more identical characters.
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 a password, the greater the number of possible combinations that need to be tested before the password is compromised.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_accounts_password_pam_maxclassrepeat
Identifiers and References

Identifiers:  CCE-81034-1

References:  1, 12, 15, 16, 5, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.10, CCI-000195, 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, 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, IA-5(c), IA-5(1)(a), CM-6(a), IA-5(4), PR.AC-1, PR.AC-6, PR.AC-7, SRG-OS-000072-GPOS-00040, RHEL-08-020140, SV-230360r809289_rule


Complexity:low
Disruption:low
Strategy:restrict
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
    - CCE-81034-1
    - DISA-STIG-RHEL-08-020140
    - 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_maxclassrepeat
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy
- name: XCCDF Value var_password_pam_maxclassrepeat # promote to variable
  set_fact:
    var_password_pam_maxclassrepeat: !!str 4
  tags:
    - always

- name: Ensure PAM variable maxclassrepeat is set accordingly
  lineinfile:
    create: true
    dest: /etc/security/pwquality.conf
    regexp: ^#?\s*maxclassrepeat
    line: maxclassrepeat = {{ var_password_pam_maxclassrepeat }}
  when: '"pam" in ansible_facts.packages'
  tags:
    - CCE-81034-1
    - DISA-STIG-RHEL-08-020140
    - 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_maxclassrepeat
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

Complexity:low
Disruption:low
Strategy:restrict
# Remediation is applicable only in certain platforms
if rpm --quiet -q pam; then

var_password_pam_maxclassrepeat='4'


# 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' <<< "^maxclassrepeat")

# shellcheck disable=SC2059
printf -v formatted_output "%s = %s" "$stripped_key" "$var_password_pam_maxclassrepeat"

# 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 "^maxclassrepeat\\>" "/etc/security/pwquality.conf"; then
    "${sed_command[@]}" "s/^maxclassrepeat\\>.*/$formatted_output/gi" "/etc/security/pwquality.conf"
else
    # \n is precaution for case where file ends without trailing newline
    cce="CCE-81034-1"
    printf '\n# Per %s: Set %s in %s\n' "$cce" "$formatted_output" "/etc/security/pwquality.conf" >> "/etc/security/pwquality.conf"
    printf '%s\n' "$formatted_output" >> "/etc/security/pwquality.conf"
fi

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi

Rule   Set Password Maximum Consecutive Repeating Characters   [ref]

The pam_pwquality module's maxrepeat parameter controls requirements for consecutive repeating characters. When set to a positive number, it will reject passwords which contain more than that number of consecutive characters. Modify the maxrepeat setting in /etc/security/pwquality.conf to equal 3 to prevent a run of (3 + 1) or more identical characters.
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.

Passwords with excessive repeating characters may be more vulnerable to password-guessing attacks.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_accounts_password_pam_maxrepeat
Identifiers and References

Identifiers:  CCE-82066-2

References:  1, 12, 15, 16, 5, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.10, CCI-000195, 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, 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, IA-5(c), CM-6(a), IA-5(4), PR.AC-1, PR.AC-6, PR.AC-7, SRG-OS-000072-GPOS-00040, RHEL-08-020150, SV-230361r627750_rule


Complexity:low
Disruption:low
Strategy:restrict
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
    - CCE-82066-2
    - DISA-STIG-RHEL-08-020150
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IA-5(4)
    - NIST-800-53-IA-5(c)
    - accounts_password_pam_maxrepeat
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy
- name: XCCDF Value var_password_pam_maxrepeat # promote to variable
  set_fact:
    var_password_pam_maxrepeat: !!str 3
  tags:
    - always

- name: Ensure PAM variable maxrepeat is set accordingly
  lineinfile:
    create: true
    dest: /etc/security/pwquality.conf
    regexp: ^#?\s*maxrepeat
    line: maxrepeat = {{ var_password_pam_maxrepeat }}
  when: '"pam" in ansible_facts.packages'
  tags:
    - CCE-82066-2
    - DISA-STIG-RHEL-08-020150
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IA-5(4)
    - NIST-800-53-IA-5(c)
    - accounts_password_pam_maxrepeat
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

Complexity:low
Disruption:low
Strategy:restrict
# Remediation is applicable only in certain platforms
if rpm --quiet -q pam; then

var_password_pam_maxrepeat='3'


# 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' <<< "^maxrepeat")

# shellcheck disable=SC2059
printf -v formatted_output "%s = %s" "$stripped_key" "$var_password_pam_maxrepeat"

# 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 "^maxrepeat\\>" "/etc/security/pwquality.conf"; then
    "${sed_command[@]}" "s/^maxrepeat\\>.*/$formatted_output/gi" "/etc/security/pwquality.conf"
else
    # \n is precaution for case where file ends without trailing newline
    cce="CCE-82066-2"
    printf '\n# Per %s: Set %s in %s\n' "$cce" "$formatted_output" "/etc/security/pwquality.conf" >> "/etc/security/pwquality.conf"
    printf '%s\n' "$formatted_output" >> "/etc/security/pwquality.conf"
fi

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi

Rule   Ensure PAM Enforces Password Requirements - Minimum Length   [ref]

The pam_pwquality module's minlen parameter controls requirements for minimum characters required in a password. Add minlen=12 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.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_accounts_password_pam_minlen
Identifiers and References

Identifiers:  CCE-80656-2

References:  BP28(R18), 1, 12, 15, 16, 5, 5.6.2.1.1, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.10, CCI-000205, 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, 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, IA-5(c), IA-5(1)(a), CM-6(a), IA-5(4), PR.AC-1, PR.AC-6, PR.AC-7, FMT_MOF_EXT.1, Req-8.2.3, SRG-OS-000078-GPOS-00046, SRG-OS-000072-VMM-000390, SRG-OS-000078-VMM-000450, RHEL-08-020230, 5.4.1, SV-230369r627750_rule


Complexity:low
Disruption:low
Strategy:restrict
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
    - CCE-80656-2
    - CJIS-5.6.2.1.1
    - DISA-STIG-RHEL-08-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 12
  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:
    - CCE-80656-2
    - CJIS-5.6.2.1.1
    - DISA-STIG-RHEL-08-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

Complexity:low
Disruption:low
Strategy:restrict
# Remediation is applicable only in certain platforms
if rpm --quiet -q pam; then

var_password_pam_minlen='12'


# 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
    cce="CCE-80656-2"
    printf '\n# Per %s: Set %s in %s\n' "$cce" "$formatted_output" "/etc/security/pwquality.conf" >> "/etc/security/pwquality.conf"
    printf '%s\n' "$formatted_output" >> "/etc/security/pwquality.conf"
fi

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi

Rule   Ensure PAM Enforces Password Requirements - Minimum Special Characters   [ref]

The 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 possible 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.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_accounts_password_pam_ocredit
Identifiers and References

Identifiers:  CCE-80663-8

References:  BP28(R18), 1, 12, 15, 16, 5, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.10, CCI-001619, 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, 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, IA-5(c), IA-5(1)(a), CM-6(a), IA-5(4), PR.AC-1, PR.AC-6, PR.AC-7, FMT_MOF_EXT.1, SRG-OS-000266-GPOS-00101, SRG-OS-000266-VMM-000940, RHEL-08-020280, SV-230375r627750_rule


Complexity:low
Disruption:low
Strategy:restrict
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
    - CCE-80663-8
    - DISA-STIG-RHEL-08-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:
    - CCE-80663-8
    - DISA-STIG-RHEL-08-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

Complexity:low
Disruption:low
Strategy:restrict
# 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
    cce="CCE-80663-8"
    printf '\n# Per %s: Set %s in %s\n' "$cce" "$formatted_output" "/etc/security/pwquality.conf" >> "/etc/security/pwquality.conf"
    printf '%s\n' "$formatted_output" >> "/etc/security/pwquality.conf"
fi

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi

Rule   Ensure PAM Enforces Password Requirements - Minimum Uppercase Characters   [ref]

The 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 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.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_accounts_password_pam_ucredit
Identifiers and References

Identifiers:  CCE-80665-3

References:  BP28(R18), 1, 12, 15, 16, 5, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.10, CCI-000192, 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, 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, IA-5(c), IA-5(1)(a), CM-6(a), IA-5(4), PR.AC-1, PR.AC-6, PR.AC-7, FMT_MOF_EXT.1, Req-8.2.3, SRG-OS-000069-GPOS-00037, SRG-OS-000069-VMM-000360, RHEL-08-020110, SV-230357r627750_rule


Complexity:low
Disruption:low
Strategy:restrict
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
    - CCE-80665-3
    - DISA-STIG-RHEL-08-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:
    - CCE-80665-3
    - DISA-STIG-RHEL-08-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

Complexity:low
Disruption:low
Strategy:restrict
# 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
    cce="CCE-80665-3"
    printf '\n# Per %s: Set %s in %s\n' "$cce" "$formatted_output" "/etc/security/pwquality.conf" >> "/etc/security/pwquality.conf"
    printf '%s\n' "$formatted_output" >> "/etc/security/pwquality.conf"
fi

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi
Group   Protect Physical Console Access   Group contains 2 groups and 10 rules
[ref]   It is impossible to fully protect a system from an attacker with physical access, so securing the space in which the system is located should be considered a necessary step. However, there are some steps which, if taken, make it more difficult for an attacker to quickly or undetectably modify a system from its console.
Group   Configure Screen Locking   Group contains 1 group and 5 rules
[ref]   When a user must temporarily leave an account logged-in, screen locking should be employed to prevent passersby from abusing the account. User education and training is particularly important for screen locking to be effective, and policies can be implemented to reinforce this.

Automatic screen locking is only meant as a safeguard for those cases where a user forgot to lock the screen.
Group   Configure Console Screen Locking   Group contains 5 rules
[ref]   A console screen locking mechanism is a temporary action taken when a user stops work and moves away from the immediate physical vicinity of the information system but does not logout because of the temporary nature of the absence. Rather than relying on the user to manually lock their operation system session prior to vacating the vicinity, operating systems need to be able to identify when a user's session has idled and take action to initiate the session lock.

Rule   Install the tmux Package   [ref]

To enable console screen locking, install the tmux package. A session lock is a temporary action taken when a user stops work and moves away from the immediate physical vicinity of the information system but does not want to log out because of the temporary nature of the absence. The session lock is implemented at the point where session activity can be determined. Rather than be forced to wait for a period of time to expire before the user session can be locked, Red Hat Enterprise Linux 8 needs to provide users with the ability to manually invoke a session lock so users can secure their session if it is necessary to temporarily vacate the immediate physical vicinity. Instruct users to begin new terminal sessions with the following command:
$ tmux
The console can now be locked with the following key combination:
ctrl+b :lock-session
Rationale:
A session time-out lock is a temporary action taken when a user stops work and moves away from the immediate physical vicinity of the information system but does not logout because of the temporary nature of the absence. Rather than relying on the user to manually lock their operation system session prior to vacating the vicinity, operating systems need to be able to identify when a user's session has idled and take action to initiate the session lock.

The tmux package allows for a session lock to be implemented and configured.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_package_tmux_installed
Identifiers and References

Identifiers:  CCE-80644-8

References:  1, 12, 15, 16, DSS05.04, DSS05.10, DSS06.10, 3.1.10, CCI-000058, CCI-000056, 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, A.18.1.4, A.9.2.1, A.9.2.4, A.9.3.1, A.9.4.2, A.9.4.3, CM-6(a), PR.AC-7, FMT_MOF_EXT.1, SRG-OS-000030-GPOS-00011, SRG-OS-000028-GPOS-00009, SRG-OS-000030-VMM-000110, RHEL-08-020039, SV-244537r743860_rule


Complexity:low
Disruption:low
Strategy:enable

package --add=tmux

Complexity:low
Disruption:low
Strategy:enable
- name: Ensure tmux is installed
  package:
    name: tmux
    state: present
  when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
  tags:
    - CCE-80644-8
    - DISA-STIG-RHEL-08-020039
    - NIST-800-171-3.1.10
    - NIST-800-53-CM-6(a)
    - enable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - package_tmux_installed

Complexity:low
Disruption:low
Strategy:enable
# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then

if ! rpm -q --quiet "tmux" ; then
    yum install -y "tmux"
fi

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi


[[packages]]
name = "tmux"
version = "*"

Complexity:low
Disruption:low
Strategy:enable
include install_tmux

class install_tmux {
  package { 'tmux':
    ensure => 'installed',
  }
}

Rule   Support session locking with tmux   [ref]

The tmux terminal multiplexer is used to implement automatic session locking. It should be started from /etc/bashrc or drop-in files within /etc/profile.d/.
Rationale:
Unlike bash itself, the tmux terminal multiplexer provides a mechanism to lock sessions after period of inactivity. A session lock is a temporary action taken when a user stops work and moves away from the immediate physical vicinity of the information system but does not want to log out because of the temporary nature of the absence.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_configure_bashrc_exec_tmux
Identifiers and References

Identifiers:  CCE-82266-8

References:  CCI-000056, FMT_SMF_EXT.1, SRG-OS-000031-GPOS-00012, SRG-OS-000028-GPOS-00009, RHEL-08-020041, SV-230349r810020_rule


Complexity:low
Disruption:low
Reboot:true
Strategy:enable
# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then

if ! grep -x '  case "$name" in sshd|login) exec tmux ;; esac' /etc/bashrc; then
    cat >> /etc/profile.d/tmux.sh <<'EOF'
if [ "$PS1" ]; then
  parent=$(ps -o ppid= -p $$)
  name=$(ps -o comm= -p $parent)
  case "$name" in sshd|login) exec tmux ;; esac
fi
EOF
fi

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi

Rule   Configure tmux to lock session after inactivity   [ref]

To enable console screen locking in tmux terminal multiplexer after a period of inactivity, the lock-after-time option has to be set to nonzero value in /etc/tmux.conf.
Rationale:
Locking the session after a period of inactivity limits the potential exposure if the session is left unattended.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_configure_tmux_lock_after_time
Identifiers and References

Identifiers:  CCE-82199-1

References:  CCI-000057, FMT_SMF_EXT.1, SRG-OS-000029-GPOS-00010, SRG-OS-000031-GPOS-00012, RHEL-08-020070, SV-230353r627750_rule


Complexity:low
Disruption:low
Strategy:restrict
- name: Configure tmux to lock session after inactivity
  block:

    - name: Check for duplicate values
      lineinfile:
        path: /etc/tmux.conf
        create: false
        regexp: ^\s*set -g lock-after-time\s+
        state: absent
      check_mode: true
      changed_when: false
      register: dupes

    - name: Deduplicate values from /etc/tmux.conf
      lineinfile:
        path: /etc/tmux.conf
        create: false
        regexp: ^\s*set -g lock-after-time\s+
        state: absent
      when: dupes.found is defined and dupes.found > 1

    - name: Insert correct line to /etc/tmux.conf
      lineinfile:
        path: /etc/tmux.conf
        create: true
        regexp: ^\s*set -g lock-after-time\s+
        line: set -g lock-after-time 900
        state: present
  when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
  tags:
    - CCE-82199-1
    - DISA-STIG-RHEL-08-020070
    - configure_tmux_lock_after_time
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then

tmux_conf="/etc/tmux.conf"

if grep -qP '^\s*set\s+-g\s+lock-after-time' "$tmux_conf" ; then
    sed -i 's/^\s*set\s\+-g\s\+lock-after-time.*$/set -g lock-after-time 900/' "$tmux_conf"
else
    echo "set -g lock-after-time 900" >> "$tmux_conf"
fi

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi

Rule   Configure the tmux Lock Command   [ref]

To enable console screen locking in tmux terminal multiplexer, the vlock command must be configured to be used as a locking mechanism. Add the following line to /etc/tmux.conf:
set -g lock-command vlock
. The console can now be locked with the following key combination:
ctrl+b :lock-session
Rationale:
The tmux package allows for a session lock to be implemented and configured. However, the session lock is implemented by an external command. The tmux default configuration does not contain an effective session lock.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_configure_tmux_lock_command
Identifiers and References

Identifiers:  CCE-80940-0

References:  CCI-000056, CCI-000058, AC-11(a), AC-11(b), CM-6(a), SRG-OS-000028-GPOS-00009, SRG-OS-000028-VMM-000090, SRG-OS-000030-VMM-000110, RHEL-08-020040, SV-230348r743987_rule


Complexity:low
Disruption:low
Strategy:restrict
- name: Configure the tmux Lock Command
  block:

    - name: Check for duplicate values
      lineinfile:
        path: /etc/tmux.conf
        create: false
        regexp: ^\s*set -g lock-command\s+
        state: absent
      check_mode: true
      changed_when: false
      register: dupes

    - name: Deduplicate values from /etc/tmux.conf
      lineinfile:
        path: /etc/tmux.conf
        create: false
        regexp: ^\s*set -g lock-command\s+
        state: absent
      when: dupes.found is defined and dupes.found > 1

    - name: Insert correct line to /etc/tmux.conf
      lineinfile:
        path: /etc/tmux.conf
        create: true
        regexp: ^\s*set -g lock-command\s+
        line: set -g lock-command vlock
        state: present
  when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
  tags:
    - CCE-80940-0
    - DISA-STIG-RHEL-08-020040
    - NIST-800-53-AC-11(a)
    - NIST-800-53-AC-11(b)
    - NIST-800-53-CM-6(a)
    - configure_tmux_lock_command
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then

tmux_conf="/etc/tmux.conf"

if grep -qP '^\s*set\s+-g\s+lock-command' "$tmux_conf" ; then
    sed -i 's/^\s*set\s\+-g\s\+lock-command.*$/set -g lock-command vlock/' "$tmux_conf"
else
    echo "set -g lock-command vlock" >> "$tmux_conf"
fi

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi

Rule   Prevent user from disabling the screen lock   [ref]

The tmux terminal multiplexer is used to implement automatic session locking. It should not be listed in /etc/shells.
Rationale:
Not listing tmux among permitted shells prevents malicious program running as user from lowering security by disabling the screen lock.
Severity: 
low
Rule ID:xccdf_org.ssgproject.content_rule_no_tmux_in_shells
Identifiers and References

Identifiers:  CCE-82361-7

References:  CCI-000056, CM-6, FMT_SMF_EXT.1, SRG-OS-000324-GPOS-00125, SRG-OS-000028-GPOS-00009, RHEL-08-020042, SV-230350r627750_rule


---
apiVersion: machineconfiguration.openshift.io/v1
kind: MachineConfig
spec:
  config:
    ignition:
      version: 3.1.0
    storage:
      files:
      - contents:
          source: data:,/bin/sh%0A/bin/bash%0A/usr/bin/sh%0A/usr/bin/bash%0A
        mode: 0644
        path: /etc/shells
        overwrite: true

# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then

if grep -q 'tmux\s*$' /etc/shells ; then
	sed -i '/tmux\s*$/d' /etc/shells
fi

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi

Rule   Disable debug-shell SystemD Service   [ref]

SystemD's debug-shell service is intended to diagnose SystemD related boot issues with various systemctl commands. Once enabled and following a system reboot, the root shell will be available on tty9 which is access by pressing CTRL-ALT-F9. The debug-shell service should only be used for SystemD related issues and should otherwise be disabled.

By default, the debug-shell SystemD service is already disabled. The debug-shell service can be disabled with the following command:
$ sudo systemctl mask --now debug-shell.service
Rationale:
This prevents attackers with physical access from trivially bypassing security on the machine through valid troubleshooting configurations and gaining root access when the system is rebooted.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_service_debug-shell_disabled
Identifiers and References

Identifiers:  CCE-80876-6

References:  3.4.5, CCI-000366, 164.308(a)(1)(ii)(B), 164.308(a)(7)(i), 164.308(a)(7)(ii)(A), 164.310(a)(1), 164.310(a)(2)(i), 164.310(a)(2)(ii), 164.310(a)(2)(iii), 164.310(b), 164.310(c), 164.310(d)(1), 164.310(d)(2)(iii), CM-6, FIA_UAU.1, SRG-OS-000324-GPOS-00125, SRG-OS-000480-GPOS-00227, RHEL-08-040180, SV-230532r627750_rule


---
apiVersion: machineconfiguration.openshift.io/v1
kind: MachineConfig
spec:
  config:
    ignition:
      version: 3.1.0
    systemd:
      units:
      - enabled: false
        name: debug-shell.service

Complexity:low
Disruption:low
Strategy:disable
- name: Disable service debug-shell
  block:

    - name: Disable service debug-shell
      systemd:
        name: debug-shell.service
        enabled: 'no'
        state: stopped
        masked: 'yes'
      ignore_errors: 'yes'
  when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
  tags:
    - CCE-80876-6
    - DISA-STIG-RHEL-08-040180
    - NIST-800-171-3.4.5
    - NIST-800-53-CM-6
    - disable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - service_debug-shell_disabled

- name: Unit Socket Exists - debug-shell.socket
  command: systemctl list-unit-files debug-shell.socket
  args:
    warn: false
  register: socket_file_exists
  changed_when: false
  ignore_errors: true
  check_mode: false
  when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
  tags:
    - CCE-80876-6
    - DISA-STIG-RHEL-08-040180
    - NIST-800-171-3.4.5
    - NIST-800-53-CM-6
    - disable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - service_debug-shell_disabled

- name: Disable socket debug-shell
  systemd:
    name: debug-shell.socket
    enabled: 'no'
    state: stopped
    masked: 'yes'
  when:
    - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
    - '"debug-shell.socket" in socket_file_exists.stdout_lines[1]'
  tags:
    - CCE-80876-6
    - DISA-STIG-RHEL-08-040180
    - NIST-800-171-3.4.5
    - NIST-800-53-CM-6
    - disable_strategy
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - service_debug-shell_disabled

Complexity:low
Disruption:low
Strategy:disable
# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then

SYSTEMCTL_EXEC='/usr/bin/systemctl'
"$SYSTEMCTL_EXEC" stop 'debug-shell.service'
"$SYSTEMCTL_EXEC" disable 'debug-shell.service'
"$SYSTEMCTL_EXEC" mask 'debug-shell.service'
# Disable socket activation if we have a unit file for it
if "$SYSTEMCTL_EXEC" list-unit-files | grep -q '^debug-shell.socket'; then
    "$SYSTEMCTL_EXEC" stop 'debug-shell.socket'
    "$SYSTEMCTL_EXEC" mask 'debug-shell.socket'
fi
# The service may not be running because it has been started and failed,
# so let's reset the state so OVAL checks pass.
# Service should be 'inactive', not 'failed' after reboot though.
"$SYSTEMCTL_EXEC" reset-failed 'debug-shell.service' || true

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi


[customizations.services]
disabled = ["debug-shell"]

Complexity:low
Disruption:low
Strategy:enable
include disable_debug-shell

class disable_debug-shell {
  service {'debug-shell':
    enable => false,
    ensure => 'stopped',
  }
}

Rule   Disable Ctrl-Alt-Del Burst Action   [ref]

By default, SystemD will reboot the system if the Ctrl-Alt-Del key sequence is pressed Ctrl-Alt-Delete more than 7 times in 2 seconds.

To configure the system to ignore the CtrlAltDelBurstAction setting, add or modify the following to /etc/systemd/system.conf:
CtrlAltDelBurstAction=none
Warning:  Disabling the Ctrl-Alt-Del key sequence in /etc/init/control-alt-delete.conf DOES NOT disable the Ctrl-Alt-Del key sequence if running in runlevel 6 (e.g. in GNOME, KDE, etc.)! The Ctrl-Alt-Del key sequence will only be disabled if running in the non-graphical runlevel 3.
Rationale:
A locally logged-in user who presses Ctrl-Alt-Del, when at the console, can reboot the system. If accidentally pressed, as could happen in the case of mixed OS environment, this can create the risk of short-term loss of availability of systems due to unintentional reboot.
Severity: 
high
Rule ID:xccdf_org.ssgproject.content_rule_disable_ctrlaltdel_burstaction
Identifiers and References

Identifiers:  CCE-80784-2

References:  12, 13, 14, 15, 16, 18, 3, 5, APO01.06, DSS05.04, DSS05.07, DSS06.02, 3.4.5, CCI-000366, 164.308(a)(1)(ii)(B), 164.308(a)(7)(i), 164.308(a)(7)(ii)(A), 164.310(a)(1), 164.310(a)(2)(i), 164.310(a)(2)(ii), 164.310(a)(2)(iii), 164.310(b), 164.310(c), 164.310(d)(1), 164.310(d)(2)(iii), 4.3.3.7.3, SR 2.1, SR 5.2, 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, CIP-003-8 R5.1.1, CIP-003-8 R5.3, CIP-004-6 R2.3, CIP-007-3 R2.1, CIP-007-3 R2.2, CIP-007-3 R2.3, CIP-007-3 R5.1, CIP-007-3 R5.1.1, CIP-007-3 R5.1.2, CM-6(a), AC-6(1), CM-6(a), PR.AC-4, PR.DS-5, SRG-OS-000324-GPOS-00125, SRG-OS-000480-GPOS-00227, RHEL-08-040172, SV-230531r627750_rule


---
apiVersion: machineconfiguration.openshift.io/v1
kind: MachineConfig
spec:
  config:
    ignition:
      version: 3.1.0
    storage:
      files:
      - contents:
          source: data:,CtrlAltDelBurstAction%3Dnone
        mode: 0644
        path: /etc/systemd/system.conf.d/disable_ctrlaltdelete_burstaction.conf
        overwrite: true

Complexity:low
Disruption:low
Strategy:disable
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
    - CCE-80784-2
    - DISA-STIG-RHEL-08-040172
    - NIST-800-171-3.4.5
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-6(a)
    - disable_ctrlaltdel_burstaction
    - disable_strategy
    - high_severity
    - low_complexity
    - low_disruption
    - no_reboot_needed

- name: Disable Ctrl-Alt-Del Burst Action
  lineinfile:
    dest: /etc/systemd/system.conf
    state: present
    regexp: ^CtrlAltDelBurstAction
    line: CtrlAltDelBurstAction=none
    create: true
  when: '"systemd" in ansible_facts.packages'
  tags:
    - CCE-80784-2
    - DISA-STIG-RHEL-08-040172
    - NIST-800-171-3.4.5
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - NIST-800-53-CM-6(a)
    - disable_ctrlaltdel_burstaction
    - disable_strategy
    - high_severity
    - low_complexity
    - low_disruption
    - no_reboot_needed

# Remediation is applicable only in certain platforms
if rpm --quiet -q systemd; 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/systemd/system.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' <<< "^CtrlAltDelBurstAction=")

# shellcheck disable=SC2059
printf -v formatted_output "%s=%s" "$stripped_key" "none"

# 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 "^CtrlAltDelBurstAction=\\>" "/etc/systemd/system.conf"; then
    "${sed_command[@]}" "s/^CtrlAltDelBurstAction=\\>.*/$formatted_output/gi" "/etc/systemd/system.conf"
else
    # \n is precaution for case where file ends without trailing newline
    cce="CCE-80784-2"
    printf '\n# Per %s: Set %s in %s\n' "$cce" "$formatted_output" "/etc/systemd/system.conf" >> "/etc/systemd/system.conf"
    printf '%s\n' "$formatted_output" >> "/etc/systemd/system.conf"
fi

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi

Rule   Disable Ctrl-Alt-Del Reboot Activation   [ref]

By default, SystemD will reboot the system if the Ctrl-Alt-Del key sequence is pressed.

To configure the system to ignore the Ctrl-Alt-Del key sequence from the command line instead of rebooting the system, do either of the following:
ln -sf /dev/null /etc/systemd/system/ctrl-alt-del.target
or
systemctl mask ctrl-alt-del.target


Do not simply delete the /usr/lib/systemd/system/ctrl-alt-del.service file, as this file may be restored during future system updates.
Rationale:
A locally logged-in user who presses Ctrl-Alt-Del, when at the console, can reboot the system. If accidentally pressed, as could happen in the case of mixed OS environment, this can create the risk of short-term loss of availability of systems due to unintentional reboot.
Severity: 
high
Rule ID:xccdf_org.ssgproject.content_rule_disable_ctrlaltdel_reboot
Identifiers and References

Identifiers:  CCE-80785-9

References:  12, 13, 14, 15, 16, 18, 3, 5, APO01.06, DSS05.04, DSS05.07, DSS06.02, 3.4.5, CCI-000366, 164.308(a)(1)(ii)(B), 164.308(a)(7)(i), 164.308(a)(7)(ii)(A), 164.310(a)(1), 164.310(a)(2)(i), 164.310(a)(2)(ii), 164.310(a)(2)(iii), 164.310(b), 164.310(c), 164.310(d)(1), 164.310(d)(2)(iii), 4.3.3.7.3, SR 2.1, SR 5.2, 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, CIP-003-8 R5.1.1, CIP-003-8 R5.3, CIP-004-6 R2.3, CIP-007-3 R2.1, CIP-007-3 R2.2, CIP-007-3 R2.3, CIP-007-3 R5.1, CIP-007-3 R5.1.1, CIP-007-3 R5.1.2, CM-6(a), AC-6(1), PR.AC-4, PR.DS-5, SRG-OS-000324-GPOS-00125, SRG-OS-000480-GPOS-00227, RHEL-08-040170, SV-230529r627750_rule


Complexity:low
Disruption:low
Reboot:true
Strategy:restrict
---
apiVersion: machineconfiguration.openshift.io/v1
kind: MachineConfig
spec:
  config:
    ignition:
      version: 3.1.0
    systemd:
      units:
      - name: ctrl-alt-del.target
        mask: true

Complexity:low
Disruption:low
Strategy:disable
- name: Disable Ctrl-Alt-Del Reboot Activation
  systemd:
    name: ctrl-alt-del.target
    force: true
    masked: true
    state: stopped
  when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
  tags:
    - CCE-80785-9
    - DISA-STIG-RHEL-08-040170
    - NIST-800-171-3.4.5
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - disable_ctrlaltdel_reboot
    - disable_strategy
    - high_severity
    - low_complexity
    - low_disruption
    - no_reboot_needed

# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then

systemctl disable --now ctrl-alt-del.target
systemctl mask --now ctrl-alt-del.target

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi

Rule   Verify that Interactive Boot is Disabled   [ref]

Red Hat Enterprise Linux 8 systems support an "interactive boot" option that can be used to prevent services from being started. On a Red Hat Enterprise Linux 8 system, interactive boot can be enabled by providing a 1, yes, true, or on value to the systemd.confirm_spawn kernel argument in /etc/default/grub. Remove any instance of
systemd.confirm_spawn=(1|yes|true|on)
from the kernel arguments in that file to disable interactive boot. Recovery booting must also be disabled. Confirm that GRUB_DISABLE_RECOVERY=true is set in /etc/default/grub. It is also required to change the runtime configuration, run:
/sbin/grubby --update-kernel=ALL --remove-args="systemd.confirm_spawn"
grub2-mkconfig -o /boot/grub2/grub.cfg
Rationale:
Using interactive or recovery boot, the console user could disable auditing, firewalls, or other services, weakening system security.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_grub2_disable_interactive_boot
Identifiers and References

Identifiers:  CCE-80826-1

References:  11, 12, 14, 15, 16, 18, 3, 5, DSS05.02, DSS05.04, DSS05.05, DSS05.07, DSS06.03, DSS06.06, 3.1.2, 3.4.5, CCI-000213, 164.308(a)(1)(ii)(B), 164.308(a)(7)(i), 164.308(a)(7)(ii)(A), 164.310(a)(1), 164.310(a)(2)(i), 164.310(a)(2)(ii), 164.310(a)(2)(iii), 164.310(b), 164.310(c), 164.310(d)(1), 164.310(d)(2)(iii), 4.3.3.2.2, 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, 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, A.6.1.2, A.7.1.1, A.9.1.2, A.9.2.1, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5, SC-2(1), CM-6(a), PR.AC-4, PR.AC-6, PR.PT-3, FIA_UAU.1, SRG-OS-000480-GPOS-00227


Complexity:low
Disruption:low
Reboot:true
Strategy:restrict
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
    - CCE-80826-1
    - NIST-800-171-3.1.2
    - NIST-800-171-3.4.5
    - NIST-800-53-CM-6(a)
    - NIST-800-53-SC-2(1)
    - grub2_disable_interactive_boot
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

- name: Verify GRUB_DISABLE_RECOVERY=true
  lineinfile:
    path: /etc/default/grub
    regexp: ^GRUB_DISABLE_RECOVERY=.*
    line: GRUB_DISABLE_RECOVERY=true
    state: present
  when: '"grub2-common" in ansible_facts.packages'
  tags:
    - CCE-80826-1
    - NIST-800-171-3.1.2
    - NIST-800-171-3.4.5
    - NIST-800-53-CM-6(a)
    - NIST-800-53-SC-2(1)
    - grub2_disable_interactive_boot
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

- name: Verify that Interactive Boot is Disabled in /etc/default/grub
  replace:
    dest: /etc/default/grub
    regexp: systemd.confirm_spawn=(1|yes|true|on)
    replace: systemd.confirm_spawn=no
  when: '"grub2-common" in ansible_facts.packages'
  tags:
    - CCE-80826-1
    - NIST-800-171-3.1.2
    - NIST-800-171-3.4.5
    - NIST-800-53-CM-6(a)
    - NIST-800-53-SC-2(1)
    - grub2_disable_interactive_boot
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

- name: Verify that Interactive Boot is Disabled (runtime)
  command: /sbin/grubby --update-kernel=ALL --remove-args="systemd.confirm_spawn"
  when: '"grub2-common" in ansible_facts.packages'
  tags:
    - CCE-80826-1
    - NIST-800-171-3.1.2
    - NIST-800-171-3.4.5
    - NIST-800-53-CM-6(a)
    - NIST-800-53-SC-2(1)
    - grub2_disable_interactive_boot
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

- name: Regen grub.cfg handle updated GRUB_DISABLE_RECOVERY and confirm_spawn
  command: grub2-mkconfig -o  /boot/grub2/grub.cfg
  when: '"grub2-common" in ansible_facts.packages'
  tags:
    - CCE-80826-1
    - NIST-800-171-3.1.2
    - NIST-800-171-3.4.5
    - NIST-800-53-CM-6(a)
    - NIST-800-53-SC-2(1)
    - grub2_disable_interactive_boot
    - low_complexity
    - low_disruption
    - medium_severity
    - reboot_required
    - restrict_strategy

Complexity:low
Disruption:low
Reboot:true
Strategy:restrict
# Remediation is applicable only in certain platforms
if rpm --quiet -q grub2-common; then

# Verify that Interactive Boot is Disabled in /etc/default/grub
CONFIRM_SPAWN_YES="systemd.confirm_spawn=\(1\|yes\|true\|on\)"
CONFIRM_SPAWN_NO="systemd.confirm_spawn=no"

if grep -q "\(GRUB_CMDLINE_LINUX\|GRUB_CMDLINE_LINUX_DEFAULT\)" /etc/default/grub
then
	sed -i "s/${CONFIRM_SPAWN_YES}/${CONFIRM_SPAWN_NO}/" /etc/default/grub
fi

# make sure GRUB_DISABLE_RECOVERY=true
if grep -q '^GRUB_DISABLE_RECOVERY=.*'  '/etc/default/grub' ; then
       # modify the GRUB command-line if an GRUB_DISABLE_RECOVERY= arg already exists
       sed -i 's/GRUB_DISABLE_RECOVERY=.*/GRUB_DISABLE_RECOVERY=true/' /etc/default/grub
else
       # no GRUB_DISABLE_RECOVERY=arg is present, append it to file
       echo "GRUB_DISABLE_RECOVERY=true"  >> '/etc/default/grub'
fi



# Remove 'systemd.confirm_spawn' kernel argument also from runtime settings
/sbin/grubby --update-kernel=ALL --remove-args="systemd.confirm_spawn"


#Regen grub.cfg handle updated GRUB_DISABLE_RECOVERY and confirm_spawn
grub2-mkconfig -o /boot/grub2/grub.cfg

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi

Rule   Require Authentication for Single User Mode   [ref]

Single-user mode is intended as a system recovery method, providing a single user root access to the system by providing a boot option at startup. By default, no authentication is performed if single-user mode is selected.

By default, single-user mode is protected by requiring a password and is set in /usr/lib/systemd/system/rescue.service.
Rationale:
This prevents attackers with physical access from trivially bypassing security on the machine and gaining root access. Such accesses are further prevented by configuring the bootloader password.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_require_singleuser_auth
Identifiers and References

Identifiers:  CCE-80855-0

References:  1, 11, 12, 14, 15, 16, 18, 3, 5, DSS05.02, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.06, DSS06.10, 3.1.1, 3.4.5, CCI-000213, 164.308(a)(1)(ii)(B), 164.308(a)(7)(i), 164.308(a)(7)(ii)(A), 164.310(a)(1), 164.310(a)(2)(i), 164.310(a)(2)(ii), 164.310(a)(2)(iii), 164.310(b), 164.310(c), 164.310(d)(1), 164.310(d)(2)(iii), 4.3.3.2.2, 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, 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, 0421, 0422, 0431, 0974, 1173, 1401, 1504, 1505, 1546, 1557, 1558, 1559, 1560, 1561, A.18.1.4, A.6.1.2, A.7.1.1, A.9.1.2, 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.1, A.9.4.2, A.9.4.3, A.9.4.4, A.9.4.5, CIP-003-8 R5.1.1, CIP-003-8 R5.3, CIP-004-6 R2.2.3, CIP-004-6 R2.3, CIP-007-3 R5.1, CIP-007-3 R5.1.2, CIP-007-3 R5.2, CIP-007-3 R5.3.1, CIP-007-3 R5.3.2, CIP-007-3 R5.3.3, IA-2, AC-3, CM-6(a), PR.AC-1, PR.AC-4, PR.AC-6, PR.AC-7, PR.PT-3, FIA_UAU.1, SRG-OS-000080-GPOS-00048, RHEL-08-010151, 1.5.3, SV-230236r743928_rule


Complexity:low
Disruption:low
Strategy:restrict
- name: require single user mode password
  lineinfile:
    create: true
    dest: /usr/lib/systemd/system/rescue.service
    regexp: ^#?ExecStart=
    line: ExecStart=-/usr/lib/systemd/systemd-sulogin-shell rescue
  when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
  tags:
    - CCE-80855-0
    - DISA-STIG-RHEL-08-010151
    - NIST-800-171-3.1.1
    - NIST-800-171-3.4.5
    - NIST-800-53-AC-3
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IA-2
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - require_singleuser_auth
    - restrict_strategy

# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then

service_file="/usr/lib/systemd/system/rescue.service"

sulogin="/usr/lib/systemd/systemd-sulogin-shell rescue"

if grep "^ExecStart=.*" "$service_file" ; then
    sed -i "s%^ExecStart=.*%ExecStart=-$sulogin%" "$service_file"
else
    echo "ExecStart=-$sulogin" >> "$service_file"
fi

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi
Group   Protect Accounts by Restricting Password-Based Login   Group contains 3 groups and 4 rules
[ref]   Conventionally, 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.
Group   Set Password Expiration Parameters   Group contains 1 rule
[ref]   The 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
Group   Verify Proper Storage and Existence of Password Hashes   Group contains 1 rule
[ref]   By 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.

Rule   Prevent Login to Accounts With Empty Password   [ref]

If an account is configured for password authentication but does not have an assigned password, it may be possible to log into the account without authentication. Remove any instances of the nullok in /etc/pam.d/system-auth to prevent logins with empty 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. Note that this rule is not applicable for systems running within a container. Having user with empty password within a container is not considered a risk, because it should not be possible to directly login into a container anyway.
Rationale:
If an account has an empty password, anyone could log in and run commands with the privileges of that account. Accounts with empty passwords should never be used in operational environments.
Severity: 
high
Rule ID:xccdf_org.ssgproject.content_rule_no_empty_passwords
Identifiers and References

Identifiers:  CCE-80841-0

References:  1, 12, 13, 14, 15, 16, 18, 3, 5, 5.5.2, APO01.06, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.02, DSS06.03, DSS06.10, 3.1.1, 3.1.5, CCI-000366, 164.308(a)(1)(ii)(B), 164.308(a)(7)(i), 164.308(a)(7)(ii)(A), 164.310(a)(1), 164.310(a)(2)(i), 164.310(a)(2)(ii), 164.310(a)(2)(iii), 164.310(b), 164.310(c), 164.310(d)(1), 164.310(d)(2)(iii), 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.3, 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, SR 5.2, 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.18.1.4, 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.1, A.9.2.2, A.9.2.3, A.9.2.4, A.9.2.6, A.9.3.1, A.9.4.1, A.9.4.2, A.9.4.3, A.9.4.4, A.9.4.5, IA-5(1)(a), IA-5(c), CM-6(a), PR.AC-1, PR.AC-4, PR.AC-6, PR.AC-7, PR.DS-5, FIA_UAU.1, Req-8.2.3, SRG-OS-000480-GPOS-00227, RHEL-08-020331, SV-244540r743869_rule


---
apiVersion: machineconfiguration.openshift.io/v1
kind: MachineConfig
spec:
  config:
    ignition:
      version: 3.1.0
    storage:
      files:
      - contents:
          source: data:,%23%20Generated%20by%20authselect%20on%20Sat%20Oct%2027%2014%3A59%3A36%202018%0A%23%20Do%20not%20modify%20this%20file%20manually.%0A%0Aauth%20%20%20%20%20%20%20%20required%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pam_env.so%0Aauth%20%20%20%20%20%20%20%20required%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pam_faildelay.so%20delay%3D2000000%0Aauth%20%20%20%20%20%20%20%20sufficient%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pam_fprintd.so%0Aauth%20%20%20%20%20%20%20%20%5Bdefault%3D1%20ignore%3Dignore%20success%3Dok%5D%20%20%20%20%20%20%20%20%20pam_succeed_if.so%20uid%20%3E%3D%201000%20quiet%0Aauth%20%20%20%20%20%20%20%20%5Bdefault%3D1%20ignore%3Dignore%20success%3Dok%5D%20%20%20%20%20%20%20%20%20pam_localuser.so%0Aauth%20%20%20%20%20%20%20%20sufficient%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pam_unix.so%20try_first_pass%0Aauth%20%20%20%20%20%20%20%20requisite%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pam_succeed_if.so%20uid%20%3E%3D%201000%20quiet_success%0Aauth%20%20%20%20%20%20%20%20sufficient%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pam_sss.so%20forward_pass%0Aauth%20%20%20%20%20%20%20%20required%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pam_deny.so%0A%0Aaccount%20%20%20%20%20required%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pam_unix.so%0Aaccount%20%20%20%20%20sufficient%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pam_localuser.so%0Aaccount%20%20%20%20%20sufficient%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pam_succeed_if.so%20uid%20%3C%201000%20quiet%0Aaccount%20%20%20%20%20%5Bdefault%3Dbad%20success%3Dok%20user_unknown%3Dignore%5D%20pam_sss.so%0Aaccount%20%20%20%20%20required%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pam_permit.so%0A%0Apassword%20%20%20%20requisite%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pam_pwquality.so%20try_first_pass%20local_users_only%0Apassword%20%20%20%20sufficient%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pam_unix.so%20sha512%20shadow%20try_first_pass%20use_authtok%0Apassword%20%20%20%20sufficient%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pam_sss.so%20use_authtok%0Apassword%20%20%20%20required%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pam_deny.so%0A%0Asession%20%20%20%20%20optional%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pam_keyinit.so%20revoke%0Asession%20%20%20%20%20required%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pam_limits.so%0A-session%20%20%20%20optional%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pam_systemd.so%0Asession%20%20%20%20%20%5Bsuccess%3D1%20default%3Dignore%5D%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pam_succeed_if.so%20service%20in%20crond%20quiet%20use_uid%0Asession%20%20%20%20%20required%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pam_unix.so%0Asession%20%20%20%20%20optional%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pam_sss.so%0A
        mode: 0644
        path: /etc/pam.d/password-auth
        overwrite: true
      - contents:
          source: data:,%23%20Generated%20by%20authselect%20on%20Sat%20Oct%2027%2014%3A59%3A36%202018%0A%23%20Do%20not%20modify%20this%20file%20manually.%0A%0Aauth%20%20%20%20%20%20%20%20required%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pam_env.so%0Aauth%20%20%20%20%20%20%20%20required%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pam_faildelay.so%20delay%3D2000000%0Aauth%20%20%20%20%20%20%20%20sufficient%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pam_fprintd.so%0Aauth%20%20%20%20%20%20%20%20%5Bdefault%3D1%20ignore%3Dignore%20success%3Dok%5D%20%20%20%20%20%20%20%20%20pam_succeed_if.so%20uid%20%3E%3D%201000%20quiet%0Aauth%20%20%20%20%20%20%20%20%5Bdefault%3D1%20ignore%3Dignore%20success%3Dok%5D%20%20%20%20%20%20%20%20%20pam_localuser.so%0Aauth%20%20%20%20%20%20%20%20sufficient%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pam_unix.so%20try_first_pass%0Aauth%20%20%20%20%20%20%20%20requisite%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pam_succeed_if.so%20uid%20%3E%3D%201000%20quiet_success%0Aauth%20%20%20%20%20%20%20%20sufficient%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pam_sss.so%20forward_pass%0Aauth%20%20%20%20%20%20%20%20required%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pam_deny.so%0A%0Aaccount%20%20%20%20%20required%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pam_unix.so%0Aaccount%20%20%20%20%20sufficient%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pam_localuser.so%0Aaccount%20%20%20%20%20sufficient%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pam_succeed_if.so%20uid%20%3C%201000%20quiet%0Aaccount%20%20%20%20%20%5Bdefault%3Dbad%20success%3Dok%20user_unknown%3Dignore%5D%20pam_sss.so%0Aaccount%20%20%20%20%20required%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pam_permit.so%0A%0Apassword%20%20%20%20requisite%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pam_pwquality.so%20try_first_pass%20local_users_only%0Apassword%20%20%20%20sufficient%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pam_unix.so%20sha512%20shadow%20try_first_pass%20use_authtok%0Apassword%20%20%20%20sufficient%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pam_sss.so%20use_authtok%0Apassword%20%20%20%20required%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pam_deny.so%0A%0Asession%20%20%20%20%20optional%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pam_keyinit.so%20revoke%0Asession%20%20%20%20%20required%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pam_limits.so%0A-session%20%20%20%20optional%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pam_systemd.so%0Asession%20%20%20%20%20%5Bsuccess%3D1%20default%3Dignore%5D%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pam_succeed_if.so%20service%20in%20crond%20quiet%20use_uid%0Asession%20%20%20%20%20required%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pam_unix.so%0Asession%20%20%20%20%20optional%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pam_sss.so%0A
        mode: 0644
        path: /etc/pam.d/system-auth
        overwrite: true

Complexity:low
Disruption:medium
Strategy:configure
- name: Check if system relies on authselect
  ansible.builtin.stat:
    path: /usr/bin/authselect
  register: result_authselect_present
  when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
  tags:
    - CCE-80841-0
    - CJIS-5.5.2
    - DISA-STIG-RHEL-08-020331
    - NIST-800-171-3.1.1
    - NIST-800-171-3.1.5
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IA-5(1)(a)
    - NIST-800-53-IA-5(c)
    - PCI-DSS-Req-8.2.3
    - configure_strategy
    - high_severity
    - low_complexity
    - medium_disruption
    - no_empty_passwords
    - no_reboot_needed

- name: Check integrity of authselect current profile
  ansible.builtin.command:
    cmd: authselect check
  register: result_authselect_check_cmd
  changed_when: false
  ignore_errors: true
  when:
    - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
    - result_authselect_present.stat.exists
  tags:
    - CCE-80841-0
    - CJIS-5.5.2
    - DISA-STIG-RHEL-08-020331
    - NIST-800-171-3.1.1
    - NIST-800-171-3.1.5
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IA-5(1)(a)
    - NIST-800-53-IA-5(c)
    - PCI-DSS-Req-8.2.3
    - configure_strategy
    - high_severity
    - low_complexity
    - medium_disruption
    - no_empty_passwords
    - no_reboot_needed

- name: Get authselect current features
  ansible.builtin.shell:
    cmd: authselect current | tail -n+3 | awk '{ print $2 }'
  register: result_authselect_features
  changed_when: false
  when:
    - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
    - result_authselect_present.stat.exists
    - result_authselect_check_cmd is success
  tags:
    - CCE-80841-0
    - CJIS-5.5.2
    - DISA-STIG-RHEL-08-020331
    - NIST-800-171-3.1.1
    - NIST-800-171-3.1.5
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IA-5(1)(a)
    - NIST-800-53-IA-5(c)
    - PCI-DSS-Req-8.2.3
    - configure_strategy
    - high_severity
    - low_complexity
    - medium_disruption
    - no_empty_passwords
    - no_reboot_needed

- name: Ensure nullok property is absent via authselect tool
  ansible.builtin.command:
    cmd: authselect enable-feature without-nullok
  register: result_authselect_cmd
  when:
    - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
    - result_authselect_present.stat.exists
    - result_authselect_check_cmd is success
    - result_authselect_features.stdout is not search("without-nullok")
  tags:
    - CCE-80841-0
    - CJIS-5.5.2
    - DISA-STIG-RHEL-08-020331
    - NIST-800-171-3.1.1
    - NIST-800-171-3.1.5
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IA-5(1)(a)
    - NIST-800-53-IA-5(c)
    - PCI-DSS-Req-8.2.3
    - configure_strategy
    - high_severity
    - low_complexity
    - medium_disruption
    - no_empty_passwords
    - 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: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
  tags:
    - CCE-80841-0
    - CJIS-5.5.2
    - DISA-STIG-RHEL-08-020331
    - NIST-800-171-3.1.1
    - NIST-800-171-3.1.5
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IA-5(1)(a)
    - NIST-800-53-IA-5(c)
    - PCI-DSS-Req-8.2.3
    - configure_strategy
    - high_severity
    - low_complexity
    - medium_disruption
    - no_empty_passwords
    - no_reboot_needed

- name: Ensure nullok property is absent by directly editing pam files
  replace:
    dest: '{{ item }}'
    regexp: nullok
  loop:
    - /etc/pam.d/system-auth
    - /etc/pam.d/password-auth
  when:
    - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
    - not result_authselect_present.stat.exists
  tags:
    - CCE-80841-0
    - CJIS-5.5.2
    - DISA-STIG-RHEL-08-020331
    - NIST-800-171-3.1.1
    - NIST-800-171-3.1.5
    - NIST-800-53-CM-6(a)
    - NIST-800-53-IA-5(1)(a)
    - NIST-800-53-IA-5(c)
    - PCI-DSS-Req-8.2.3
    - configure_strategy
    - high_severity
    - low_complexity
    - medium_disruption
    - no_empty_passwords
    - no_reboot_needed

Complexity:low
Disruption:medium
Strategy:configure
# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then

SYSTEM_AUTH="/etc/pam.d/system-auth"
PASSWORD_AUTH="/etc/pam.d/password-auth"
if [ -f /usr/bin/authselect ]; then
    if authselect check; then
        authselect enable-feature without-nullok
        authselect apply-changes
    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
    sed --follow-symlinks -i 's/\<nullok\>//g' $SYSTEM_AUTH
    sed --follow-symlinks -i 's/\<nullok\>//g' $PASSWORD_AUTH
fi

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi
Group   Restrict Root Logins   Group contains 2 rules
[ref]   Direct root logins should be allowed only for emergency use. In normal situations, the administrator should access the system via a unique unprivileged account, and then use su or sudo to execute privileged commands. Discouraging administrators from accessing the root account directly ensures an audit trail in organizations with multiple administrators. Locking down the channels through which root can connect directly also reduces opportunities for password-guessing against the root account. The login program uses the file /etc/securetty to determine which interfaces should allow root logins. The virtual devices /dev/console and /dev/tty* represent the system consoles (accessible via the Ctrl-Alt-F1 through Ctrl-Alt-F6 keyboard sequences on a default installation). The default securetty file also contains /dev/vc/*. These are likely to be deprecated in most environments, but may be retained for compatibility. Root should also be prohibited from connecting via network protocols. Other sections of this document include guidance describing how to prevent root from logging in via SSH.

Rule   Enforce usage of pam_wheel for su authentication   [ref]

To ensure that only users who are members of the wheel group can run commands with altered privileges through the su command, make sure that the following line exists in the file /etc/pam.d/su:
auth             required        pam_wheel.so use_uid
Rationale:
The su program allows to run commands with a substitute user and group ID. It is commonly used to run commands as the root user. Limiting access to such command is considered a good security practice.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_use_pam_wheel_for_su
Identifiers and References

Identifiers:  CCE-83318-6

References:  FMT_SMF_EXT.1.1, SRG-OS-000373-GPOS-00156, SRG-OS-000312-GPOS-00123, 5.7


Complexity:low
Disruption:low
Strategy:restrict
- name: restrict usage of su command only to members of wheel group
  replace:
    path: /etc/pam.d/su
    regexp: ^[\s]*#[\s]*auth[\s]+required[\s]+pam_wheel\.so[\s]+use_uid$
    replace: auth             required        pam_wheel.so use_uid
  tags:
    - CCE-83318-6
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy
    - use_pam_wheel_for_su


# uncomment the option if commented
  sed '/^[[:space:]]*#[[:space:]]*auth[[:space:]]\+required[[:space:]]\+pam_wheel\.so[[:space:]]\+use_uid$/s/^[[:space:]]*#//' -i /etc/pam.d/su
Group   Secure Session Configuration Files for Login Accounts   Group contains 1 group and 4 rules
[ref]   When a user logs into a Unix account, the system configures the user's session by reading a number of files. Many of these files are located in the user's home directory, and may have weak permissions as a result of user error or misconfiguration. If an attacker can modify or even read certain types of account configuration information, they can often gain full access to the affected user's account. Therefore, it is important to test and correct configuration file permissions for interactive accounts, particularly those of privileged users such as root or system administrators.
Group   Ensure that Users Have Sensible Umask Values   Group contains 3 rules
[ref]   The umask setting controls the default permissions for the creation of new files. With a default umask setting of 077, files and directories created by users will not be readable by any other user on the system. Users who wish to make specific files group- or world-readable can accomplish this by using the chmod command. Additionally, users can make all their files readable to their group by default by setting a umask of 027 in their shell configuration files. If default per-user groups exist (that is, if every user has a default group whose name is the same as that user's username and whose only member is the user), then it may even be safe for users to select a umask of 007, making it very easy to intentionally share files with groups of which the user is a member.

Rule   Ensure the Default Bash Umask is Set Correctly   [ref]

To ensure the default umask for users of the Bash shell is set properly, add or correct the umask setting in /etc/bashrc to read as follows:
umask 027
Rationale:
The umask value influences the permissions assigned to files when they are created. A misconfigured umask value could result in files with excessive permissions that can be read or written to by unauthorized users.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_accounts_umask_etc_bashrc
Identifiers and References

Identifiers:  CCE-81036-6

References:  BP28(R35), 18, APO13.01, BAI03.01, BAI03.02, BAI03.03, CCI-000366, 4.3.4.3.3, A.14.1.1, A.14.2.1, A.14.2.5, A.6.1.5, CIP-003-8 R5.1.1, CIP-003-8 R5.3, CIP-004-6 R2.3, CIP-007-3 R2.1, CIP-007-3 R2.2, CIP-007-3 R2.3, CIP-007-3 R5.1, CIP-007-3 R5.1.1, CIP-007-3 R5.1.2, AC-6(1), CM-6(a), PR.IP-2, SRG-OS-000480-GPOS-00228, SRG-OS-000480-GPOS-00227, RHEL-08-020353, 5.5.4, SV-230385r792902_rule


Complexity:low
Disruption:low
Strategy:restrict
- name: XCCDF Value var_accounts_user_umask # promote to variable
  set_fact:
    var_accounts_user_umask: !!str 027
  tags:
    - always

- name: Replace user umask in /etc/bashrc
  replace:
    path: /etc/bashrc
    regexp: umask.*
    replace: umask {{ var_accounts_user_umask }}
  register: umask_replace
  tags:
    - CCE-81036-6
    - DISA-STIG-RHEL-08-020353
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - accounts_umask_etc_bashrc
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

- name: Append user umask in /etc/bashrc
  lineinfile:
    create: true
    path: /etc/bashrc
    line: umask {{ var_accounts_user_umask }}
  when: umask_replace is not changed
  tags:
    - CCE-81036-6
    - DISA-STIG-RHEL-08-020353
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - accounts_umask_etc_bashrc
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy


var_accounts_user_umask='027'






grep -q umask /etc/bashrc && \
  sed -i "s/umask.*/umask $var_accounts_user_umask/g" /etc/bashrc
if ! [ $? -eq 0 ]; then
    echo "umask $var_accounts_user_umask" >> /etc/bashrc
fi

Rule   Ensure the Default C Shell Umask is Set Correctly   [ref]

To ensure the default umask for users of the C shell is set properly, add or correct the umask setting in /etc/csh.cshrc to read as follows:
umask 027
Rationale:
The umask value influences the permissions assigned to files when they are created. A misconfigured umask value could result in files with excessive permissions that can be read or written to by unauthorized users.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_accounts_umask_etc_csh_cshrc
Identifiers and References

Identifiers:  CCE-81037-4

References:  18, APO13.01, BAI03.01, BAI03.02, BAI03.03, CCI-000366, 4.3.4.3.3, A.14.1.1, A.14.2.1, A.14.2.5, A.6.1.5, CIP-003-8 R5.1.1, CIP-003-8 R5.3, CIP-004-6 R2.3, CIP-007-3 R2.1, CIP-007-3 R2.2, CIP-007-3 R2.3, CIP-007-3 R5.1, CIP-007-3 R5.1.1, CIP-007-3 R5.1.2, AC-6(1), CM-6(a), PR.IP-2, SRG-OS-000480-GPOS-00228, SRG-OS-000480-GPOS-00227, RHEL-08-020353, SV-230385r792902_rule


Complexity:low
Disruption:low
Strategy:restrict
- name: XCCDF Value var_accounts_user_umask # promote to variable
  set_fact:
    var_accounts_user_umask: !!str 027
  tags:
    - always

- name: Replace user umask in /etc/csh.cshrc
  replace:
    path: /etc/csh.cshrc
    regexp: umask.*
    replace: umask {{ var_accounts_user_umask }}
  register: umask_replace
  tags:
    - CCE-81037-4
    - DISA-STIG-RHEL-08-020353
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - accounts_umask_etc_csh_cshrc
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

- name: Append user umask in /etc/csh.cshrc
  lineinfile:
    create: true
    path: /etc/csh.cshrc
    line: umask {{ var_accounts_user_umask }}
  when: umask_replace is not changed
  tags:
    - CCE-81037-4
    - DISA-STIG-RHEL-08-020353
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - accounts_umask_etc_csh_cshrc
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy


var_accounts_user_umask='027'


grep -q umask /etc/csh.cshrc && \
  sed -i "s/umask.*/umask $var_accounts_user_umask/g" /etc/csh.cshrc
if ! [ $? -eq 0 ]; then
    echo "umask $var_accounts_user_umask" >> /etc/csh.cshrc
fi

Rule   Ensure the Default Umask is Set Correctly in /etc/profile   [ref]

To ensure the default umask controlled by /etc/profile is set properly, add or correct the umask setting in /etc/profile to read as follows:
umask 027
Rationale:
The umask value influences the permissions assigned to files when they are created. A misconfigured umask value could result in files with excessive permissions that can be read or written to by unauthorized users.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_accounts_umask_etc_profile
Identifiers and References

Identifiers:  CCE-81035-8

References:  BP28(R35), 18, APO13.01, BAI03.01, BAI03.02, BAI03.03, CCI-000366, 4.3.4.3.3, A.14.1.1, A.14.2.1, A.14.2.5, A.6.1.5, CIP-003-8 R5.1.1, CIP-003-8 R5.3, CIP-004-6 R2.3, CIP-007-3 R2.1, CIP-007-3 R2.2, CIP-007-3 R2.3, CIP-007-3 R5.1, CIP-007-3 R5.1.1, CIP-007-3 R5.1.2, AC-6(1), CM-6(a), PR.IP-2, SRG-OS-000480-GPOS-00228, SRG-OS-000480-GPOS-00227, RHEL-08-020353, 5.5.4, SV-230385r792902_rule


Complexity:low
Disruption:low
Strategy:restrict
- name: XCCDF Value var_accounts_user_umask # promote to variable
  set_fact:
    var_accounts_user_umask: !!str 027
  tags:
    - always

- name: Replace user umask in /etc/profile
  replace:
    path: /etc/profile
    regexp: ^[^#]*umask
    replace: umask {{ var_accounts_user_umask }}
  register: umask_replace
  tags:
    - CCE-81035-8
    - DISA-STIG-RHEL-08-020353
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - accounts_umask_etc_profile
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

- name: Append user umask in /etc/profile
  lineinfile:
    create: true
    path: /etc/profile
    line: umask {{ var_accounts_user_umask }}
  when: umask_replace is not changed
  tags:
    - CCE-81035-8
    - DISA-STIG-RHEL-08-020353
    - NIST-800-53-AC-6(1)
    - NIST-800-53-CM-6(a)
    - accounts_umask_etc_profile
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy


var_accounts_user_umask='027'


grep -qE '^[^#]*umask' /etc/profile && \
  sed -i "s/umask.*/umask $var_accounts_user_umask/g" /etc/profile
if ! [ $? -eq 0 ]; then
    echo "umask $var_accounts_user_umask" >> /etc/profile
fi
Group   System Accounting with auditd   Group contains 2 groups and 26 rules
[ref]   The audit service provides substantial capabilities for recording system activities. By default, the service audits about SELinux AVC denials and certain types of security-relevant events such as system logins, account modifications, and authentication events performed by programs such as sudo. Under its default configuration, auditd has modest disk space requirements, and should not noticeably impact system performance.

NOTE: The Linux Audit daemon auditd can be configured to use the augenrules program to read audit rules files (*.rules) located in /etc/audit/rules.d location and compile them to create the resulting form of the /etc/audit/audit.rules configuration file during the daemon startup (default configuration). Alternatively, the auditd daemon can use the auditctl utility to read audit rules from the /etc/audit/audit.rules configuration file during daemon startup, and load them into the kernel. The expected behavior is configured via the appropriate ExecStartPost directive setting in the /usr/lib/systemd/system/auditd.service configuration file. To instruct the auditd daemon to use the augenrules program to read audit rules (default configuration), use the following setting:
ExecStartPost=-/sbin/augenrules --load
in the /usr/lib/systemd/system/auditd.service configuration file. In order to instruct the auditd daemon to use the auditctl utility to read audit rules, use the following setting:
ExecStartPost=-/sbin/auditctl -R /etc/audit/audit.rules
in the /usr/lib/systemd/system/auditd.service configuration file. Refer to [Service] section of the /usr/lib/systemd/system/auditd.service configuration file for further details.

Government networks often have substantial auditing requirements and auditd can be configured to meet these requirements. Examining some example audit records demonstrates how the Linux audit system satisfies common requirements. The following example from Red Hat Enterprise Linux 7 Documentation available at https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html-single/selinux_users_and_administrators_guide/index#sect-Security-Enhanced_Linux-Fixing_Problems-Raw_Audit_Messages shows the substantial amount of information captured in a two typical "raw" audit messages, followed by a breakdown of the most important fields. In this example the message is SELinux-related and reports an AVC denial (and the associated system call) that occurred when the Apache HTTP Server attempted to access the /var/www/html/file1 file (labeled with the samba_share_t type):
type=AVC msg=audit(1226874073.147:96): avc:  denied  { getattr } for pid=2465 comm="httpd"
path="/var/www/html/file1" dev=dm-0 ino=284133 scontext=unconfined_u:system_r:httpd_t:s0
tcontext=unconfined_u:object_r:samba_share_t:s0 tclass=file

type=SYSCALL msg=audit(1226874073.147:96): arch=40000003 syscall=196 success=no exit=-13
a0=b98df198 a1=bfec85dc a2=54dff4 a3=2008171 items=0 ppid=2463 pid=2465 auid=502 uid=48
gid=48 euid=48 suid=48 fsuid=48 egid=48 sgid=48 fsgid=48 tty=(none) ses=6 comm="httpd"
exe="/usr/sbin/httpd" subj=unconfined_u:system_r:httpd_t:s0 key=(null)
  • msg=audit(1226874073.147:96)
    • The number in parentheses is the unformatted time stamp (Epoch time) for the event, which can be converted to standard time by using the date command.
  • { getattr }
    • The item in braces indicates the permission that was denied. getattr indicates the source process was trying to read the target file's status information. This occurs before reading files. This action is denied due to the file being accessed having the wrong label. Commonly seen permissions include getattr, read, and write.
  • comm="httpd"
    • The executable that launched the process. The full path of the executable is found in the exe= section of the system call (SYSCALL) message, which in this case, is exe="/usr/sbin/httpd".
  • path="/var/www/html/file1"
    • The path to the object (target) the process attempted to access.
  • scontext="unconfined_u:system_r:httpd_t:s0"
    • The SELinux context of the process that attempted the denied action. In this case, it is the SELinux context of the Apache HTTP Server, which is running in the httpd_t domain.
  • tcontext="unconfined_u:object_r:samba_share_t:s0"
    • The SELinux context of the object (target) the process attempted to access. In this case, it is the SELinux context of file1. Note: the samba_share_t type is not accessible to processes running in the httpd_t domain.
  • From the system call (SYSCALL) message, two items are of interest:
    • success=no: indicates whether the denial (AVC) was enforced or not. success=no indicates the system call was not successful (SELinux denied access). success=yes indicates the system call was successful - this can be seen for permissive domains or unconfined domains, such as initrc_t and kernel_t.
    • exe="/usr/sbin/httpd": the full path to the executable that launched the process, which in this case, is exe="/usr/sbin/httpd".
Group   Configure auditd Data Retention   Group contains 6 rules
[ref]   The audit system writes data to /var/log/audit/audit.log. By default, auditd rotates 5 logs by size (6MB), retaining a maximum of 30MB of data in total, and refuses to write entries when the disk is too full. This minimizes the risk of audit data filling its partition and impacting other services. This also minimizes the risk of the audit daemon temporarily disabling the system if it cannot write audit log (which it can be configured to do). For a busy system or a system which is thoroughly auditing system activity, the default settings for data retention may be insufficient. The log file size needed will depend heavily on what types of events are being audited. First configure auditing to log all the events of interest. Then monitor the log size manually for awhile to determine what file size will allow you to keep the required data for the correct time period.

Using a dedicated partition for /var/log/audit prevents the auditd logs from disrupting system functionality if they fill, and, more importantly, prevents other activity in /var from filling the partition and stopping the audit trail. (The audit logs are size-limited and therefore unlikely to grow without bound unless configured to do so.) Some machines may have requirements that no actions occur which cannot be audited. If this is the case, then auditd can be configured to halt the machine if it runs out of space. Note: Since older logs are rotated, configuring auditd this way does not prevent older logs from being rotated away before they can be viewed. If your system is configured to halt when logging cannot be performed, make sure this can never happen under normal circumstances! Ensure that /var/log/audit is on its own partition, and that this partition is larger than the maximum amount of data auditd will retain normally.

Rule   Configure auditd flush priority   [ref]

The auditd service can be configured to synchronously write audit event data to disk. Add or correct the following line in /etc/audit/auditd.conf to ensure that audit event data is fully synchronized with the log files on the disk:
flush = incremental_async
Rationale:
Audit data should be synchronously written to disk to ensure log integrity. These parameters assure that all audit event data is fully synchronized with the log files on the disk.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_auditd_data_retention_flush
Identifiers and References

Identifiers:  CCE-80680-2

References:  1, 12, 13, 14, 15, 16, 2, 3, 5, 6, 7, 8, 9, APO10.01, APO10.03, APO10.04, APO10.05, APO11.04, BAI03.05, DSS01.03, DSS03.05, DSS05.02, DSS05.04, DSS05.05, DSS05.07, MEA01.01, MEA01.02, MEA01.03, MEA01.04, MEA01.05, MEA02.01, 3.3.1, CCI-001576, 164.308(a)(1)(ii)(D), 164.308(a)(3)(ii)(A), 164.308(a)(5)(ii)(C), 164.312(a)(2)(i), 164.312(b), 164.312(d), 164.312(e), 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, 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, CIP-004-6 R2.2.3, CIP-004-6 R3.3, CIP-007-3 R5.2, CIP-007-3 R5.3.1, CIP-007-3 R5.3.2, CIP-007-3 R5.3.3, CIP-007-3 R6.5, AU-11, CM-6(a), DE.CM-1, DE.CM-3, DE.CM-7, ID.SC-4, PR.PT-1, SRG-OS-000480-GPOS-00227


Complexity:low
Disruption:low
Reboot:true
Strategy:restrict
---
apiVersion: machineconfiguration.openshift.io/v1
kind: MachineConfig
spec:
  config:
    ignition:
      version: 3.1.0
    storage:
      files:
      - contents:
          source: data:,{{ %23%0A%23%20This%20file%20controls%20the%20configuration%20of%20the%20audit%20daemon%0A%23%0A%0Alocal_events%20%3D%20yes%0Awrite_logs%20%3D%20yes%0Alog_file%20%3D%20/var/log/audit/audit.log%0Alog_group%20%3D%20root%0Alog_format%20%3D%20ENRICHED%0Aflush%20%3D%20%7B%7B.var_auditd_flush%7D%7D%0Afreq%20%3D%2050%0Amax_log_file%20%3D%20%7B%7B.var_auditd_max_log_file%7D%7D%0Anum_logs%20%3D%20%7B%7B.var_auditd_num_logs%7D%7D%0Apriority_boost%20%3D%204%0Aname_format%20%3D%20hostname%0A%23%23name%20%3D%20mydomain%0Amax_log_file_action%20%3D%20%7B%7B.var_auditd_max_log_file_action%7D%7D%0Aspace_left%20%3D%20%7B%7B.var_auditd_space_left%7D%7D%0Aspace_left_action%20%3D%20%7B%7B.var_auditd_space_left_action%7D%7D%0Averify_email%20%3D%20yes%0Aaction_mail_acct%20%3D%20%7B%7B.var_auditd_action_mail_acct%7D%7D%0Aadmin_space_left%20%3D%2050%0Aadmin_space_left_action%20%3D%20syslog%0Adisk_full_action%20%3D%20%7B%7B.var_auditd_disk_full_action%7D%7D%0Adisk_error_action%20%3D%20%7B%7B.var_auditd_disk_error_action%7D%7D%0Ause_libwrap%20%3D%20yes%0A%23%23tcp_listen_port%20%3D%2060%0Atcp_listen_queue%20%3D%205%0Atcp_max_per_addr%20%3D%201%0A%23%23tcp_client_ports%20%3D%201024-65535%0Atcp_client_max_idle%20%3D%200%0Atransport%20%3D%20TCP%0Akrb5_principal%20%3D%20auditd%0A%23%23krb5_key_file%20%3D%20/etc/audit/audit.key%0Adistribute_network%20%3D%20no%0Aq_depth%20%3D%20400%0Aoverflow_action%20%3D%20syslog%0Amax_restarts%20%3D%2010%0Aplugin_dir%20%3D%20/etc/audit/plugins.d }}
        mode: 0640
        path: /etc/audit/auditd.conf
        overwrite: true

Complexity:low
Disruption:low
Strategy:restrict
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
    - CCE-80680-2
    - NIST-800-171-3.3.1
    - NIST-800-53-AU-11
    - NIST-800-53-CM-6(a)
    - auditd_data_retention_flush
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy
- name: XCCDF Value var_auditd_flush # promote to variable
  set_fact:
    var_auditd_flush: !!str incremental_async
  tags:
    - always

- name: Configure auditd Flush Priority
  lineinfile:
    dest: /etc/audit/auditd.conf
    regexp: ^\s*flush\s*=\s*.*$
    line: flush = {{ var_auditd_flush }}
    state: present
    create: true
  when: '"audit" in ansible_facts.packages'
  tags:
    - CCE-80680-2
    - NIST-800-171-3.3.1
    - NIST-800-53-AU-11
    - NIST-800-53-CM-6(a)
    - auditd_data_retention_flush
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

# Remediation is applicable only in certain platforms
if rpm --quiet -q audit; then

var_auditd_flush='incremental_async'


AUDITCONFIG=/etc/audit/auditd.conf

# if flush is present, flush param edited to var_auditd_flush
# else flush param is defined by var_auditd_flush
#
# the freq param is only used for values 'incremental' and 'incremental_async' and will be
# commented out if flush != incremental or flush != incremental_async
#
# if flush == incremental or flush == incremental_async && freq param is not defined, it 
# will be defined as the package-default value of 20

grep -q ^flush $AUDITCONFIG && \
  sed -i 's/^flush.*/flush = '"$var_auditd_flush"'/g' $AUDITCONFIG
if ! [ $? -eq 0 ]; then
  echo "flush = $var_auditd_flush" >> $AUDITCONFIG
fi

if ! [ "$var_auditd_flush" == "incremental" ] && ! [ "$var_auditd_flush" == "incremental_async" ]; then
  sed -i 's/^freq/##freq/g' $AUDITCONFIG
elif [ "$var_auditd_flush" == "incremental" ] || [ "$var_auditd_flush" == "incremental_async" ]; then
  grep -q freq $AUDITCONFIG && \
    sed -i 's/^#\+freq/freq/g' $AUDITCONFIG
  if ! [ $? -eq 0 ]; then
    echo "freq = 20" >> $AUDITCONFIG
  fi
fi

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi

Rule   Set number of records to cause an explicit flush to audit logs   [ref]

To configure Audit daemon to issue an explicit flush to disk command after writing 50 records, set freq to 50 in /etc/audit/auditd.conf.
Rationale:
If option freq isn't set to 50, the flush to disk may happen after higher number of records, increasing the danger of audit loss.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_auditd_freq
Identifiers and References

Identifiers:  CCE-82258-5

References:  CM-6, FAU_GEN.1, SRG-OS-000051-GPOS-00024


Complexity:low
Disruption:low
Reboot:true
Strategy:restrict
---
apiVersion: machineconfiguration.openshift.io/v1
kind: MachineConfig
spec:
  config:
    ignition:
      version: 3.1.0
    storage:
      files:
      - contents:
          source: data:,{{ %23%0A%23%20This%20file%20controls%20the%20configuration%20of%20the%20audit%20daemon%0A%23%0A%0Alocal_events%20%3D%20yes%0Awrite_logs%20%3D%20yes%0Alog_file%20%3D%20/var/log/audit/audit.log%0Alog_group%20%3D%20root%0Alog_format%20%3D%20ENRICHED%0Aflush%20%3D%20%7B%7B.var_auditd_flush%7D%7D%0Afreq%20%3D%2050%0Amax_log_file%20%3D%20%7B%7B.var_auditd_max_log_file%7D%7D%0Anum_logs%20%3D%20%7B%7B.var_auditd_num_logs%7D%7D%0Apriority_boost%20%3D%204%0Aname_format%20%3D%20hostname%0A%23%23name%20%3D%20mydomain%0Amax_log_file_action%20%3D%20%7B%7B.var_auditd_max_log_file_action%7D%7D%0Aspace_left%20%3D%20%7B%7B.var_auditd_space_left%7D%7D%0Aspace_left_action%20%3D%20%7B%7B.var_auditd_space_left_action%7D%7D%0Averify_email%20%3D%20yes%0Aaction_mail_acct%20%3D%20%7B%7B.var_auditd_action_mail_acct%7D%7D%0Aadmin_space_left%20%3D%2050%0Aadmin_space_left_action%20%3D%20syslog%0Adisk_full_action%20%3D%20%7B%7B.var_auditd_disk_full_action%7D%7D%0Adisk_error_action%20%3D%20%7B%7B.var_auditd_disk_error_action%7D%7D%0Ause_libwrap%20%3D%20yes%0A%23%23tcp_listen_port%20%3D%2060%0Atcp_listen_queue%20%3D%205%0Atcp_max_per_addr%20%3D%201%0A%23%23tcp_client_ports%20%3D%201024-65535%0Atcp_client_max_idle%20%3D%200%0Atransport%20%3D%20TCP%0Akrb5_principal%20%3D%20auditd%0A%23%23krb5_key_file%20%3D%20/etc/audit/audit.key%0Adistribute_network%20%3D%20no%0Aq_depth%20%3D%20400%0Aoverflow_action%20%3D%20syslog%0Amax_restarts%20%3D%2010%0Aplugin_dir%20%3D%20/etc/audit/plugins.d }}
        mode: 0640
        path: /etc/audit/auditd.conf
        overwrite: true

Complexity:low
Disruption:low
Strategy:restrict
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
    - CCE-82258-5
    - NIST-800-53-CM-6
    - auditd_freq
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

- name: Set number of records to cause an explicit flush to audit logs
  block:

    - name: Check for duplicate values
      lineinfile:
        path: /etc/audit/auditd.conf
        create: false
        regexp: (?i)^\s*freq\s*=\s*
        state: absent
      check_mode: true
      changed_when: false
      register: dupes

    - name: Deduplicate values from /etc/audit/auditd.conf
      lineinfile:
        path: /etc/audit/auditd.conf
        create: false
        regexp: (?i)^\s*freq\s*=\s*
        state: absent
      when: dupes.found is defined and dupes.found > 1

    - name: Insert correct line to /etc/audit/auditd.conf
      lineinfile:
        path: /etc/audit/auditd.conf
        create: true
        regexp: (?i)^\s*freq\s*=\s*
        line: freq = 50
        state: present
  when: '"audit" in ansible_facts.packages'
  tags:
    - CCE-82258-5
    - NIST-800-53-CM-6
    - auditd_freq
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

Complexity:low
Disruption:low
Strategy:restrict
# Remediation is applicable only in certain platforms
if rpm --quiet -q audit; then

if [ -e "/etc/audit/auditd.conf" ] ; then
    
    LC_ALL=C sed -i "/^\s*freq\s*=\s*/Id" "/etc/audit/auditd.conf"
else
    touch "/etc/audit/auditd.conf"
fi
# make sure file has newline at the end
sed -i -e '$a\' "/etc/audit/auditd.conf"

cp "/etc/audit/auditd.conf" "/etc/audit/auditd.conf.bak"
# Insert at the end of the file
printf '%s\n' "freq = 50" >> "/etc/audit/auditd.conf"
# Clean up after ourselves.
rm "/etc/audit/auditd.conf.bak"

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi

Rule   Include Local Events in Audit Logs   [ref]

To configure Audit daemon to include local events in Audit logs, set local_events to yes in /etc/audit/auditd.conf. This is the default setting.
Rationale:
If option local_events isn't set to yes only events from network will be aggregated.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_auditd_local_events
Identifiers and References

Identifiers:  CCE-82233-8

References:  CCI-000366, CM-6, FAU_GEN.1, SRG-OS-000062-GPOS-00031, SRG-OS-000480-GPOS-00227, RHEL-08-030061, SV-230393r627750_rule


Complexity:low
Disruption:low
Reboot:true
Strategy:restrict
---
apiVersion: machineconfiguration.openshift.io/v1
kind: MachineConfig
spec:
  config:
    ignition:
      version: 3.1.0
    storage:
      files:
      - contents:
          source: data:,{{ %23%0A%23%20This%20file%20controls%20the%20configuration%20of%20the%20audit%20daemon%0A%23%0A%0Alocal_events%20%3D%20yes%0Awrite_logs%20%3D%20yes%0Alog_file%20%3D%20/var/log/audit/audit.log%0Alog_group%20%3D%20root%0Alog_format%20%3D%20ENRICHED%0Aflush%20%3D%20%7B%7B.var_auditd_flush%7D%7D%0Afreq%20%3D%2050%0Amax_log_file%20%3D%20%7B%7B.var_auditd_max_log_file%7D%7D%0Anum_logs%20%3D%20%7B%7B.var_auditd_num_logs%7D%7D%0Apriority_boost%20%3D%204%0Aname_format%20%3D%20hostname%0A%23%23name%20%3D%20mydomain%0Amax_log_file_action%20%3D%20%7B%7B.var_auditd_max_log_file_action%7D%7D%0Aspace_left%20%3D%20%7B%7B.var_auditd_space_left%7D%7D%0Aspace_left_action%20%3D%20%7B%7B.var_auditd_space_left_action%7D%7D%0Averify_email%20%3D%20yes%0Aaction_mail_acct%20%3D%20%7B%7B.var_auditd_action_mail_acct%7D%7D%0Aadmin_space_left%20%3D%2050%0Aadmin_space_left_action%20%3D%20syslog%0Adisk_full_action%20%3D%20%7B%7B.var_auditd_disk_full_action%7D%7D%0Adisk_error_action%20%3D%20%7B%7B.var_auditd_disk_error_action%7D%7D%0Ause_libwrap%20%3D%20yes%0A%23%23tcp_listen_port%20%3D%2060%0Atcp_listen_queue%20%3D%205%0Atcp_max_per_addr%20%3D%201%0A%23%23tcp_client_ports%20%3D%201024-65535%0Atcp_client_max_idle%20%3D%200%0Atransport%20%3D%20TCP%0Akrb5_principal%20%3D%20auditd%0A%23%23krb5_key_file%20%3D%20/etc/audit/audit.key%0Adistribute_network%20%3D%20no%0Aq_depth%20%3D%20400%0Aoverflow_action%20%3D%20syslog%0Amax_restarts%20%3D%2010%0Aplugin_dir%20%3D%20/etc/audit/plugins.d }}
        mode: 0640
        path: /etc/audit/auditd.conf
        overwrite: true

Complexity:low
Disruption:low
Strategy:restrict
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
    - CCE-82233-8
    - DISA-STIG-RHEL-08-030061
    - NIST-800-53-CM-6
    - auditd_local_events
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

- name: Include Local Events in Audit Logs
  block:

    - name: Check for duplicate values
      lineinfile:
        path: /etc/audit/auditd.conf
        create: false
        regexp: (?i)^\s*local_events\s*=\s*
        state: absent
      check_mode: true
      changed_when: false
      register: dupes

    - name: Deduplicate values from /etc/audit/auditd.conf
      lineinfile:
        path: /etc/audit/auditd.conf
        create: false
        regexp: (?i)^\s*local_events\s*=\s*
        state: absent
      when: dupes.found is defined and dupes.found > 1

    - name: Insert correct line to /etc/audit/auditd.conf
      lineinfile:
        path: /etc/audit/auditd.conf
        create: true
        regexp: (?i)^\s*local_events\s*=\s*
        line: local_events = yes
        state: present
  when: '"audit" in ansible_facts.packages'
  tags:
    - CCE-82233-8
    - DISA-STIG-RHEL-08-030061
    - NIST-800-53-CM-6
    - auditd_local_events
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

Complexity:low
Disruption:low
Strategy:restrict
# Remediation is applicable only in certain platforms
if rpm --quiet -q audit; then

if [ -e "/etc/audit/auditd.conf" ] ; then
    
    LC_ALL=C sed -i "/^\s*local_events\s*=\s*/Id" "/etc/audit/auditd.conf"
else
    touch "/etc/audit/auditd.conf"
fi
# make sure file has newline at the end
sed -i -e '$a\' "/etc/audit/auditd.conf"

cp "/etc/audit/auditd.conf" "/etc/audit/auditd.conf.bak"
# Insert at the end of the file
printf '%s\n' "local_events = yes" >> "/etc/audit/auditd.conf"
# Clean up after ourselves.
rm "/etc/audit/auditd.conf.bak"

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi

Rule   Resolve information before writing to audit logs   [ref]

To configure Audit daemon to resolve all uid, gid, syscall, architecture, and socket address information before writing the events to disk, set log_format to ENRICHED in /etc/audit/auditd.conf.
Rationale:
If option log_format isn't set to ENRICHED, the audit records will be stored in a format exactly as the kernel sends them.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_auditd_log_format
Identifiers and References

Identifiers:  CCE-82201-5

References:  CCI-000366, CM-6, AU-3, FAU_GEN.1.2, SRG-OS-000255-GPOS-00096, SRG-OS-000480-GPOS-00227, RHEL-08-030063, SV-230395r627750_rule


Complexity:low
Disruption:low
Reboot:true
Strategy:restrict
---
apiVersion: machineconfiguration.openshift.io/v1
kind: MachineConfig
spec:
  config:
    ignition:
      version: 3.1.0
    storage:
      files:
      - contents:
          source: data:,{{ %23%0A%23%20This%20file%20controls%20the%20configuration%20of%20the%20audit%20daemon%0A%23%0A%0Alocal_events%20%3D%20yes%0Awrite_logs%20%3D%20yes%0Alog_file%20%3D%20/var/log/audit/audit.log%0Alog_group%20%3D%20root%0Alog_format%20%3D%20ENRICHED%0Aflush%20%3D%20%7B%7B.var_auditd_flush%7D%7D%0Afreq%20%3D%2050%0Amax_log_file%20%3D%20%7B%7B.var_auditd_max_log_file%7D%7D%0Anum_logs%20%3D%20%7B%7B.var_auditd_num_logs%7D%7D%0Apriority_boost%20%3D%204%0Aname_format%20%3D%20hostname%0A%23%23name%20%3D%20mydomain%0Amax_log_file_action%20%3D%20%7B%7B.var_auditd_max_log_file_action%7D%7D%0Aspace_left%20%3D%20%7B%7B.var_auditd_space_left%7D%7D%0Aspace_left_action%20%3D%20%7B%7B.var_auditd_space_left_action%7D%7D%0Averify_email%20%3D%20yes%0Aaction_mail_acct%20%3D%20%7B%7B.var_auditd_action_mail_acct%7D%7D%0Aadmin_space_left%20%3D%2050%0Aadmin_space_left_action%20%3D%20syslog%0Adisk_full_action%20%3D%20%7B%7B.var_auditd_disk_full_action%7D%7D%0Adisk_error_action%20%3D%20%7B%7B.var_auditd_disk_error_action%7D%7D%0Ause_libwrap%20%3D%20yes%0A%23%23tcp_listen_port%20%3D%2060%0Atcp_listen_queue%20%3D%205%0Atcp_max_per_addr%20%3D%201%0A%23%23tcp_client_ports%20%3D%201024-65535%0Atcp_client_max_idle%20%3D%200%0Atransport%20%3D%20TCP%0Akrb5_principal%20%3D%20auditd%0A%23%23krb5_key_file%20%3D%20/etc/audit/audit.key%0Adistribute_network%20%3D%20no%0Aq_depth%20%3D%20400%0Aoverflow_action%20%3D%20syslog%0Amax_restarts%20%3D%2010%0Aplugin_dir%20%3D%20/etc/audit/plugins.d }}
        mode: 0640
        path: /etc/audit/auditd.conf
        overwrite: true

Complexity:low
Disruption:low
Strategy:restrict
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
    - CCE-82201-5
    - DISA-STIG-RHEL-08-030063
    - NIST-800-53-AU-3
    - NIST-800-53-CM-6
    - auditd_log_format
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

- name: Resolve information before writing to audit logs
  block:

    - name: Check for duplicate values
      lineinfile:
        path: /etc/audit/auditd.conf
        create: false
        regexp: (?i)^\s*log_format\s*=\s*
        state: absent
      check_mode: true
      changed_when: false
      register: dupes

    - name: Deduplicate values from /etc/audit/auditd.conf
      lineinfile:
        path: /etc/audit/auditd.conf
        create: false
        regexp: (?i)^\s*log_format\s*=\s*
        state: absent
      when: dupes.found is defined and dupes.found > 1

    - name: Insert correct line to /etc/audit/auditd.conf
      lineinfile:
        path: /etc/audit/auditd.conf
        create: true
        regexp: (?i)^\s*log_format\s*=\s*
        line: log_format = ENRICHED
        state: present
  when: '"audit" in ansible_facts.packages'
  tags:
    - CCE-82201-5
    - DISA-STIG-RHEL-08-030063
    - NIST-800-53-AU-3
    - NIST-800-53-CM-6
    - auditd_log_format
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

Complexity:low
Disruption:low
Strategy:restrict
# Remediation is applicable only in certain platforms
if rpm --quiet -q audit; then

if [ -e "/etc/audit/auditd.conf" ] ; then
    
    LC_ALL=C sed -i "/^\s*log_format\s*=\s*/Id" "/etc/audit/auditd.conf"
else
    touch "/etc/audit/auditd.conf"
fi
# make sure file has newline at the end
sed -i -e '$a\' "/etc/audit/auditd.conf"

cp "/etc/audit/auditd.conf" "/etc/audit/auditd.conf.bak"
# Insert at the end of the file
printf '%s\n' "log_format = ENRICHED" >> "/etc/audit/auditd.conf"
# Clean up after ourselves.
rm "/etc/audit/auditd.conf.bak"

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi

Rule   Set hostname as computer node name in audit logs   [ref]

To configure Audit daemon to use value returned by gethostname syscall as computer node name in the audit events, set name_format to hostname in /etc/audit/auditd.conf.
Rationale:
If option name_format is left at its default value of none, audit events from different computers may be hard to distinguish.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_auditd_name_format
Identifiers and References

Identifiers:  CCE-82897-0

References:  CCI-001851, CM-6, AU-3, FAU_GEN.1.2, SRG-OS-000039-GPOS-00017, SRG-OS-000342-GPOS-00133, SRG-OS-000479-GPOS-00224, RHEL-08-030062, SV-230394r627750_rule


Complexity:low
Disruption:low
Reboot:true
Strategy:restrict
---
apiVersion: machineconfiguration.openshift.io/v1
kind: MachineConfig
spec:
  config:
    ignition:
      version: 3.1.0
    storage:
      files:
      - contents:
          source: data:,{{ %23%0A%23%20This%20file%20controls%20the%20configuration%20of%20the%20audit%20daemon%0A%23%0A%0Alocal_events%20%3D%20yes%0Awrite_logs%20%3D%20yes%0Alog_file%20%3D%20/var/log/audit/audit.log%0Alog_group%20%3D%20root%0Alog_format%20%3D%20ENRICHED%0Aflush%20%3D%20%7B%7B.var_auditd_flush%7D%7D%0Afreq%20%3D%2050%0Amax_log_file%20%3D%20%7B%7B.var_auditd_max_log_file%7D%7D%0Anum_logs%20%3D%20%7B%7B.var_auditd_num_logs%7D%7D%0Apriority_boost%20%3D%204%0Aname_format%20%3D%20hostname%0A%23%23name%20%3D%20mydomain%0Amax_log_file_action%20%3D%20%7B%7B.var_auditd_max_log_file_action%7D%7D%0Aspace_left%20%3D%20%7B%7B.var_auditd_space_left%7D%7D%0Aspace_left_action%20%3D%20%7B%7B.var_auditd_space_left_action%7D%7D%0Averify_email%20%3D%20yes%0Aaction_mail_acct%20%3D%20%7B%7B.var_auditd_action_mail_acct%7D%7D%0Aadmin_space_left%20%3D%2050%0Aadmin_space_left_action%20%3D%20syslog%0Adisk_full_action%20%3D%20%7B%7B.var_auditd_disk_full_action%7D%7D%0Adisk_error_action%20%3D%20%7B%7B.var_auditd_disk_error_action%7D%7D%0Ause_libwrap%20%3D%20yes%0A%23%23tcp_listen_port%20%3D%2060%0Atcp_listen_queue%20%3D%205%0Atcp_max_per_addr%20%3D%201%0A%23%23tcp_client_ports%20%3D%201024-65535%0Atcp_client_max_idle%20%3D%200%0Atransport%20%3D%20TCP%0Akrb5_principal%20%3D%20auditd%0A%23%23krb5_key_file%20%3D%20/etc/audit/audit.key%0Adistribute_network%20%3D%20no%0Aq_depth%20%3D%20400%0Aoverflow_action%20%3D%20syslog%0Amax_restarts%20%3D%2010%0Aplugin_dir%20%3D%20/etc/audit/plugins.d }}
        mode: 0640
        path: /etc/audit/auditd.conf
        overwrite: true

Complexity:low
Disruption:low
Strategy:restrict
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
    - CCE-82897-0
    - DISA-STIG-RHEL-08-030062
    - NIST-800-53-AU-3
    - NIST-800-53-CM-6
    - auditd_name_format
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

- name: Set hostname as computer node name in audit logs
  block:

    - name: Check for duplicate values
      lineinfile:
        path: /etc/audit/auditd.conf
        create: false
        regexp: (?i)^\s*name_format\s*=\s*
        state: absent
      check_mode: true
      changed_when: false
      register: dupes

    - name: Deduplicate values from /etc/audit/auditd.conf
      lineinfile:
        path: /etc/audit/auditd.conf
        create: false
        regexp: (?i)^\s*name_format\s*=\s*
        state: absent
      when: dupes.found is defined and dupes.found > 1

    - name: Insert correct line to /etc/audit/auditd.conf
      lineinfile:
        path: /etc/audit/auditd.conf
        create: true
        regexp: (?i)^\s*name_format\s*=\s*
        line: name_format = hostname
        state: present
  when: '"audit" in ansible_facts.packages'
  tags:
    - CCE-82897-0
    - DISA-STIG-RHEL-08-030062
    - NIST-800-53-AU-3
    - NIST-800-53-CM-6
    - auditd_name_format
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

Complexity:low
Disruption:low
Strategy:restrict
# Remediation is applicable only in certain platforms
if rpm --quiet -q audit; then

if [ -e "/etc/audit/auditd.conf" ] ; then
    
    LC_ALL=C sed -i "/^\s*name_format\s*=\s*/Id" "/etc/audit/auditd.conf"
else
    touch "/etc/audit/auditd.conf"
fi
# make sure file has newline at the end
sed -i -e '$a\' "/etc/audit/auditd.conf"

cp "/etc/audit/auditd.conf" "/etc/audit/auditd.conf.bak"
# Insert at the end of the file
printf '%s\n' "name_format = hostname" >> "/etc/audit/auditd.conf"
# Clean up after ourselves.
rm "/etc/audit/auditd.conf.bak"

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi

Rule   Write Audit Logs to the Disk   [ref]

To configure Audit daemon to write Audit logs to the disk, set write_logs to yes in /etc/audit/auditd.conf. This is the default setting.
Rationale:
If write_logs isn't set to yes, the Audit logs will not be written to the disk.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_auditd_write_logs
Identifiers and References

Identifiers:  CCE-82366-6

References:  CM-6, FAU_STG.1, SRG-OS-000480-GPOS-00227


Complexity:low
Disruption:low
Reboot:true
Strategy:restrict
---
apiVersion: machineconfiguration.openshift.io/v1
kind: MachineConfig
spec:
  config:
    ignition:
      version: 3.1.0
    storage:
      files:
      - contents:
          source: data:,{{ %23%0A%23%20This%20file%20controls%20the%20configuration%20of%20the%20audit%20daemon%0A%23%0A%0Alocal_events%20%3D%20yes%0Awrite_logs%20%3D%20yes%0Alog_file%20%3D%20/var/log/audit/audit.log%0Alog_group%20%3D%20root%0Alog_format%20%3D%20ENRICHED%0Aflush%20%3D%20%7B%7B.var_auditd_flush%7D%7D%0Afreq%20%3D%2050%0Amax_log_file%20%3D%20%7B%7B.var_auditd_max_log_file%7D%7D%0Anum_logs%20%3D%20%7B%7B.var_auditd_num_logs%7D%7D%0Apriority_boost%20%3D%204%0Aname_format%20%3D%20hostname%0A%23%23name%20%3D%20mydomain%0Amax_log_file_action%20%3D%20%7B%7B.var_auditd_max_log_file_action%7D%7D%0Aspace_left%20%3D%20%7B%7B.var_auditd_space_left%7D%7D%0Aspace_left_action%20%3D%20%7B%7B.var_auditd_space_left_action%7D%7D%0Averify_email%20%3D%20yes%0Aaction_mail_acct%20%3D%20%7B%7B.var_auditd_action_mail_acct%7D%7D%0Aadmin_space_left%20%3D%2050%0Aadmin_space_left_action%20%3D%20syslog%0Adisk_full_action%20%3D%20%7B%7B.var_auditd_disk_full_action%7D%7D%0Adisk_error_action%20%3D%20%7B%7B.var_auditd_disk_error_action%7D%7D%0Ause_libwrap%20%3D%20yes%0A%23%23tcp_listen_port%20%3D%2060%0Atcp_listen_queue%20%3D%205%0Atcp_max_per_addr%20%3D%201%0A%23%23tcp_client_ports%20%3D%201024-65535%0Atcp_client_max_idle%20%3D%200%0Atransport%20%3D%20TCP%0Akrb5_principal%20%3D%20auditd%0A%23%23krb5_key_file%20%3D%20/etc/audit/audit.key%0Adistribute_network%20%3D%20no%0Aq_depth%20%3D%20400%0Aoverflow_action%20%3D%20syslog%0Amax_restarts%20%3D%2010%0Aplugin_dir%20%3D%20/etc/audit/plugins.d }}
        mode: 0640
        path: /etc/audit/auditd.conf
        overwrite: true

Complexity:low
Disruption:low
Strategy:restrict
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
    - CCE-82366-6
    - NIST-800-53-CM-6
    - auditd_write_logs
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

- name: Write Audit Logs to the Disk
  block:

    - name: Check for duplicate values
      lineinfile:
        path: /etc/audit/auditd.conf
        create: false
        regexp: (?i)^\s*write_logs\s*=\s*
        state: absent
      check_mode: true
      changed_when: false
      register: dupes

    - name: Deduplicate values from /etc/audit/auditd.conf
      lineinfile:
        path: /etc/audit/auditd.conf
        create: false
        regexp: (?i)^\s*write_logs\s*=\s*
        state: absent
      when: dupes.found is defined and dupes.found > 1

    - name: Insert correct line to /etc/audit/auditd.conf
      lineinfile:
        path: /etc/audit/auditd.conf
        create: true
        regexp: (?i)^\s*write_logs\s*=\s*
        line: write_logs = yes
        state: present
  when: '"audit" in ansible_facts.packages'
  tags:
    - CCE-82366-6
    - NIST-800-53-CM-6
    - auditd_write_logs
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

Complexity:low
Disruption:low
Strategy:restrict
# Remediation is applicable only in certain platforms
if rpm --quiet -q audit; then

if [ -e "/etc/audit/auditd.conf" ] ; then
    
    LC_ALL=C sed -i "/^\s*write_logs\s*=\s*/Id" "/etc/audit/auditd.conf"
else
    touch "/etc/audit/auditd.conf"
fi
# make sure file has newline at the end
sed -i -e '$a\' "/etc/audit/auditd.conf"

cp "/etc/audit/auditd.conf" "/etc/audit/auditd.conf.bak"
# Insert at the end of the file
printf '%s\n' "write_logs = yes" >> "/etc/audit/auditd.conf"
# Clean up after ourselves.
rm "/etc/audit/auditd.conf.bak"

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi
Group   System Accounting with auditd   Group contains 16 rules
[ref]   The auditd program can perform comprehensive monitoring of system activity. This section makes use of recommended configuration settings for specific policies or use cases. The rules in this section make use of rules defined in /usr/share/doc/audit-VERSION/rules.

Rule   Configure auditing of unsuccessful file accesses   [ref]

Ensure that unsuccessful attempts to access a file are audited. The following rules configure audit as described above:
## Unsuccessful file access (any other opens) This has to go last.
-a always,exit -F arch=b32 -S open,openat,openat2,open_by_handle_at -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-access
-a always,exit -F arch=b64 -S open,openat,openat2,open_by_handle_at -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-access
-a always,exit -F arch=b32 -S open,openat,openat2,open_by_handle_at -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-access
-a always,exit -F arch=b64 -S open,openat,openat2,open_by_handle_at -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-access    
Load new Audit rules into kernel by running:
augenrules --load
Note: This rule utilizes a file provided by Audit package to comply with OSPP 4.2.1. You may reuse this rule in different profiles. If you decide to do so, it is recommended that you inspect contents of the file closely and make sure that they are alligned with your needs.
Rationale:
Unsuccessful attempts to access a file might be signs of malicious activity happening within the system. Auditing of such activities helps in their monitoring and investigation.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_audit_access_failed
Identifiers and References

Identifiers:  CCE-82833-5

References:  0582, 0584, 05885, 0586, 0846, 0957, AU-2(a), FAU_GEN.1.1.c, SRG-OS-000458-GPOS-00203, SRG-OS-000474-GPOS-00219, SRG-OS-000475-GPOS-00220, SRG-OS-000463-GPOS-00207, SRG-OS-000465-GPOS-00209, SRG-OS-000461-GPOS-00205


---
apiVersion: machineconfiguration.openshift.io/v1
kind: MachineConfig
spec:
  config:
    ignition:
      version: 3.1.0
    storage:
      files:
      - contents:
          source: data:,%23%23%20Unsuccessful%20file%20access%20%28any%20other%20opens%29%20This%20has%20to%20go%20last.%0A-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20open%2Copenat%2Copen_by_handle_at%20-F%20exit%3D-EACCES%20-F%20auid%26gt%3B%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-access%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20open%2Copenat%2Copen_by_handle_at%20-F%20exit%3D-EACCES%20-F%20auid%26gt%3B%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-access%0A-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20open%2Copenat%2Copen_by_handle_at%20-F%20exit%3D-EPERM%20-F%20auid%26gt%3B%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-access%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20open%2Copenat%2Copen_by_handle_at%20-F%20exit%3D-EPERM%20-F%20auid%26gt%3B%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-access
        mode: 0600
        path: /etc/audit/rules.d/30-ospp-v42-3-access-failed.rules
        overwrite: true

Complexity:low
Disruption:low
Strategy:restrict
- name: Put contents into /etc/audit/rules.d/30-ospp-v42-3-access-failed.rules according
    to policy
  copy:
    dest: /etc/audit/rules.d/30-ospp-v42-3-access-failed.rules
    content: |
      ## Unsuccessful file access (any other opens) This has to go last.
      -a always,exit -F arch=b32 -S open,openat,openat2,open_by_handle_at -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-access
      -a always,exit -F arch=b64 -S open,openat,openat2,open_by_handle_at -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-access
      -a always,exit -F arch=b32 -S open,openat,openat2,open_by_handle_at -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-access
      -a always,exit -F arch=b64 -S open,openat,openat2,open_by_handle_at -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-access
    force: true
  when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
  tags:
    - CCE-82833-5
    - NIST-800-53-AU-2(a)
    - audit_access_failed
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

- name: Remove any permissions from other group
  file:
    path: /etc/audit/rules.d/30-ospp-v42-3-access-failed.rules
    mode: o-rwx
  when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
  tags:
    - CCE-82833-5
    - NIST-800-53-AU-2(a)
    - audit_access_failed
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

Complexity:low
Disruption:low
Strategy:restrict
# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then

cat << 'EOF' > /etc/audit/rules.d/30-ospp-v42-3-access-failed.rules
## Unsuccessful file access (any other opens) This has to go last.
-a always,exit -F arch=b32 -S open,openat,openat2,open_by_handle_at -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-access
-a always,exit -F arch=b64 -S open,openat,openat2,open_by_handle_at -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-access
-a always,exit -F arch=b32 -S open,openat,openat2,open_by_handle_at -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-access
-a always,exit -F arch=b64 -S open,openat,openat2,open_by_handle_at -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-access
EOF

chmod o-rwx /etc/audit/rules.d/30-ospp-v42-3-access-failed.rules

augenrules --load

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi

Rule   Configure auditing of successful file accesses   [ref]

Ensure that successful attempts to access a file are audited. The following rules configure audit as described above:
## Successful file access (any other opens) This has to go last.
## These next two are likely to result in a whole lot of events
-a always,exit -F arch=b32 -S open,openat,openat2,open_by_handle_at -F success=1 -F auid>=1000 -F auid!=unset -F key=successful-access
-a always,exit -F arch=b64 -S open,openat,openat2,open_by_handle_at -F success=1 -F auid>=1000 -F auid!=unset -F key=successful-access    
The Audit package provides pre-configured rules in /usr/share/audit/sample-rules. The above content can be found in /usr/share/audit/sample-rules/30-ospp-v42-3-access-success.rules. To deploy this configuration, it is recommended to copy it over to the /etc/audit/rules.d/ directory:
cp /usr/share/audit/sample-rules/30-ospp-v42-3-access-success.rules /etc/audit/rules.d/
Load new Audit rules into kernel by running:
augenrules --load
Note: This rule utilizes a file provided by Audit package to comply with OSPP 4.2.1. You may reuse this rule in different profiles. If you decide to do so, it is recommended that you inspect contents of the file closely and make sure that they are alligned with your needs.
Rationale:
Auditing of successful attempts to access a file helps in investigation of activities performed on the system.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_audit_access_success
Identifiers and References

Identifiers:  CCE-82834-3

References:  0582, 0584, 05885, 0586, 0846, 0957, AU-2(a), FAU_GEN.1.1.c, SRG-OS-000458-GPOS-00203, SRG-OS-000474-GPOS-00219, SRG-OS-000475-GPOS-00220, SRG-OS-000463-GPOS-00207, SRG-OS-000465-GPOS-00209, SRG-OS-000461-GPOS-00205


---
apiVersion: machineconfiguration.openshift.io/v1
kind: MachineConfig
spec:
  config:
    ignition:
      version: 3.1.0
    storage:
      files:
      - contents:
          source: data:,%23%23%20Successful%20file%20access%20%28any%20other%20opens%29%20This%20has%20to%20go%20last.%0A%23%23%20These%20next%20two%20are%20likely%20to%20result%20in%20a%20whole%20lot%20of%20events%0A-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20open%2Copenat%2Copen_by_handle_at%20-F%20success%3D1%20-F%20auid%26gt%3B%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dsuccessful-access%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20open%2Copenat%2Copen_by_handle_at%20-F%20success%3D1%20-F%20auid%26gt%3B%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dsuccessful-access
        mode: 0600
        path: /etc/audit/rules.d/30-ospp-v42-3-access-success.rules
        overwrite: true

Complexity:low
Disruption:low
Strategy:restrict
- name: Put contents into /etc/audit/rules.d/30-ospp-v42-3-access-success.rules according
    to policy
  copy:
    dest: /etc/audit/rules.d/30-ospp-v42-3-access-success.rules
    content: |
      ## Successful file access (any other opens) This has to go last.
      ## These next two are likely to result in a whole lot of events
      -a always,exit -F arch=b32 -S open,openat,openat2,open_by_handle_at -F success=1 -F auid>=1000 -F auid!=unset -F key=successful-access
      -a always,exit -F arch=b64 -S open,openat,openat2,open_by_handle_at -F success=1 -F auid>=1000 -F auid!=unset -F key=successful-access
    force: true
  when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
  tags:
    - CCE-82834-3
    - NIST-800-53-AU-2(a)
    - audit_access_success
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

- name: Remove any permissions from other group
  file:
    path: /etc/audit/rules.d/30-ospp-v42-3-access-success.rules
    mode: o-rwx
  when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
  tags:
    - CCE-82834-3
    - NIST-800-53-AU-2(a)
    - audit_access_success
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

Complexity:low
Disruption:low
Strategy:restrict
# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then

cat << 'EOF' > /etc/audit/rules.d/30-ospp-v42-3-access-success.rules
## Successful file access (any other opens) This has to go last.
## These next two are likely to result in a whole lot of events
-a always,exit -F arch=b32 -S open,openat,openat2,open_by_handle_at -F success=1 -F auid>=1000 -F auid!=unset -F key=successful-access
-a always,exit -F arch=b64 -S open,openat,openat2,open_by_handle_at -F success=1 -F auid>=1000 -F auid!=unset -F key=successful-access
EOF

chmod o-rwx /etc/audit/rules.d/30-ospp-v42-3-access-success.rules

augenrules --load

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi

Rule   Configure basic parameters of Audit system   [ref]

Perform basic configuration of Audit system. Make sure that any previously defined rules are cleared, the auditing system is configured to handle sudden bursts of events, and in cases of failure, messages are configured to be directed to system log. The following rules configure audit as described above:
## First rule - delete all
-D

## Increase the buffers to survive stress events.
## Make this bigger for busy systems
-b 8192

## This determine how long to wait in burst of events
--backlog_wait_time 60000

## Set failure mode to syslog
-f 1    
The Audit package provides pre-configured rules in /usr/share/audit/sample-rules. The above content can be found in /usr/share/audit/sample-rules/10-base-config.rules. To deploy this configuration, it is recommended to copy it over to the /etc/audit/rules.d/ directory:
cp /usr/share/audit/sample-rules/10-base-config.rules /etc/audit/rules.d/
Load new Audit rules into kernel by running:
augenrules --load
Warning:  It might happen that Audit buffer configured by this rule is not large enough for certain use cases. If that is the case, the buffer size can be overridden by placing
-b larger_buffer_size
into a file within /etc/audit/rules.d directory, replacing larger_file_size with the desired value. The file name should start with a number higher than 10 and lower than 99.
Rationale:
Without basic configurations, audit may not perform as expected. It may not be able to correctly handle events under stressful conditions, or log events in case of failure.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_audit_basic_configuration
Identifiers and References

Identifiers:  CCE-82827-7

References:  AU-2(a), FAU_GEN.1, SRG-OS-000365-GPOS-00152, SRG-OS-000475-GPOS-00220


---
apiVersion: machineconfiguration.openshift.io/v1
kind: MachineConfig
spec:
  config:
    ignition:
      version: 3.1.0
    storage:
      files:
      - contents:
          source: data:,%23%23%20First%20rule%20-%20delete%20all%0A-D%0A%0A%23%23%20Increase%20the%20buffers%20to%20survive%20stress%20events.%0A%23%23%20Make%20this%20bigger%20for%20busy%20systems%0A-b%208192%0A%0A%23%23%20This%20determine%20how%20long%20to%20wait%20in%20burst%20of%20events%0A--backlog_wait_time%2060000%0A%0A%23%23%20Set%20failure%20mode%20to%20syslog%0A-f%201%0A
        mode: 0600
        path: /etc/audit/rules.d/10-base-config.rules
        overwrite: true

Complexity:low
Disruption:low
Strategy:restrict
- name: Put contents into /etc/audit/rules.d/10-base-config.rules according to policy
  copy:
    dest: /etc/audit/rules.d/10-base-config.rules
    content: |+
      ## First rule - delete all
      -D

      ## Increase the buffers to survive stress events.
      ## Make this bigger for busy systems
      -b 8192

      ## This determine how long to wait in burst of events
      --backlog_wait_time 60000

      ## Set failure mode to syslog
      -f 1

    force: true
  when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
  tags:
    - CCE-82827-7
    - NIST-800-53-AU-2(a)
    - audit_basic_configuration
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

- name: Remove any permissions from other group
  file:
    path: /etc/audit/rules.d/10-base-config.rules
    mode: o-rwx
  when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
  tags:
    - CCE-82827-7
    - NIST-800-53-AU-2(a)
    - audit_basic_configuration
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

Complexity:low
Disruption:low
Strategy:restrict
# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then

cat << 'EOF' > /etc/audit/rules.d/10-base-config.rules
## First rule - delete all
-D

## Increase the buffers to survive stress events.
## Make this bigger for busy systems
-b 8192

## This determine how long to wait in burst of events
--backlog_wait_time 60000

## Set failure mode to syslog
-f 1

EOF

chmod o-rwx /etc/audit/rules.d/10-base-config.rules

augenrules --load

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi

Rule   Configure auditing of unsuccessful file creations   [ref]

Ensure that unsuccessful attempts to create a file are audited. The following rules configure audit as described above:
## Unsuccessful file creation (open with O_CREAT)
-a always,exit -F arch=b32 -S openat,open_by_handle_at -F a2&0100 -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-create
-a always,exit -F arch=b64 -S openat,open_by_handle_at -F a2&0100 -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-create
-a always,exit -F arch=b32 -S open -F a1&0100 -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-create
-a always,exit -F arch=b64 -S open -F a1&0100 -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-create
-a always,exit -F arch=b32 -S creat -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-create
-a always,exit -F arch=b64 -S creat -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-create
-a always,exit -F arch=b32 -S openat,open_by_handle_at -F a2&0100 -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-create
-a always,exit -F arch=b64 -S openat,open_by_handle_at -F a2&0100 -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-create
-a always,exit -F arch=b32 -S open -F a1&0100 -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-create
-a always,exit -F arch=b64 -S open -F a1&0100 -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-create
-a always,exit -F arch=b32 -S creat -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-create
-a always,exit -F arch=b64 -S creat -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-create    
The Audit package provides pre-configured rules in /usr/share/audit/sample-rules. The above content can be found in /usr/share/audit/sample-rules/30-ospp-v42-1-create-failed.rules. To deploy this configuration, it is recommended to copy it over to the /etc/audit/rules.d/ directory:
cp /usr/share/audit/sample-rules/30-ospp-v42-1-create-failed.rules /etc/audit/rules.d/
Load new Audit rules into kernel by running:
augenrules --load
Note: This rule utilizes a file provided by Audit package to comply with OSPP 4.2.1. You may reuse this rule in different profiles. If you decide to do so, it is recommended that you inspect contents of the file closely and make sure that they are alligned with your needs.
Rationale:
Unsuccessful file creations might be a sign of a malicious action being performed on the system. Keeping log of such events helps in monitoring and investigation of such actions.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_audit_create_failed
Identifiers and References

Identifiers:  CCE-82374-0

References:  AU-2(a), FAU_GEN.1.1.c, SRG-OS-000458-GPOS-00203, SRG-OS-000474-GPOS-00219, SRG-OS-000475-GPOS-00220, SRG-OS-000463-GPOS-00207, SRG-OS-000465-GPOS-00209, SRG-OS-000461-GPOS-00205


---
apiVersion: machineconfiguration.openshift.io/v1
kind: MachineConfig
spec:
  config:
    ignition:
      version: 3.1.0
    storage:
      files:
      - contents:
          source: data:,%23%23%20Unsuccessful%20file%20creation%20%28open%20with%20O_CREAT%29%0A%23%23%20/etc/audit/rules.d/30-ospp-v42-1-create-failed.rules%0A-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20openat%2Copen_by_handle_at%20-F%20a2%26amp%3B0100%20-F%20exit%3D-EACCES%20-F%20auid%26gt%3B%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-create%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20openat%2Copen_by_handle_at%20-F%20a2%26amp%3B0100%20-F%20exit%3D-EACCES%20-F%20auid%26gt%3B%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-create%0A-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20open%20-F%20a1%26amp%3B0100%20-F%20exit%3D-EACCES%20-F%20auid%26gt%3B%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-create%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20open%20-F%20a1%26amp%3B0100%20-F%20exit%3D-EACCES%20-F%20auid%26gt%3B%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-create%0A-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20creat%20-F%20exit%3D-EACCES%20-F%20auid%26gt%3B%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-create%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20creat%20-F%20exit%3D-EACCES%20-F%20auid%26gt%3B%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-create%0A-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20openat%2Copen_by_handle_at%20-F%20a2%26amp%3B0100%20-F%20exit%3D-EPERM%20-F%20auid%26gt%3B%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-create%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20openat%2Copen_by_handle_at%20-F%20a2%26amp%3B0100%20-F%20exit%3D-EPERM%20-F%20auid%26gt%3B%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-create%0A-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20open%20-F%20a1%26amp%3B0100%20-F%20exit%3D-EPERM%20-F%20auid%26gt%3B%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-create%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20open%20-F%20a1%26amp%3B0100%20-F%20exit%3D-EPERM%20-F%20auid%26gt%3B%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-create%0A-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20creat%20-F%20exit%3D-EPERM%20-F%20auid%26gt%3B%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-create%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20creat%20-F%20exit%3D-EPERM%20-F%20auid%26gt%3B%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-create%0A
        mode: 0600
        path: /etc/audit/rules.d/30-ospp-v42-1-create-failed.rules 
        overwrite: true

Complexity:low
Disruption:low
Strategy:restrict
- name: Put contents into /etc/audit/rules.d/30-ospp-v42-1-create-failed.rules according
    to policy
  copy:
    dest: /etc/audit/rules.d/30-ospp-v42-1-create-failed.rules
    content: |
      ## Unsuccessful file creation (open with O_CREAT)
      -a always,exit -F arch=b32 -S openat,open_by_handle_at -F a2&0100 -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-create
      -a always,exit -F arch=b64 -S openat,open_by_handle_at -F a2&0100 -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-create
      -a always,exit -F arch=b32 -S open -F a1&0100 -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-create
      -a always,exit -F arch=b64 -S open -F a1&0100 -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-create
      -a always,exit -F arch=b32 -S creat -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-create
      -a always,exit -F arch=b64 -S creat -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-create
      -a always,exit -F arch=b32 -S openat,open_by_handle_at -F a2&0100 -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-create
      -a always,exit -F arch=b64 -S openat,open_by_handle_at -F a2&0100 -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-create
      -a always,exit -F arch=b32 -S open -F a1&0100 -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-create
      -a always,exit -F arch=b64 -S open -F a1&0100 -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-create
      -a always,exit -F arch=b32 -S creat -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-create
      -a always,exit -F arch=b64 -S creat -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-create
    force: true
  when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
  tags:
    - CCE-82374-0
    - NIST-800-53-AU-2(a)
    - audit_create_failed
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

- name: Remove any permissions from other group
  file:
    path: /etc/audit/rules.d/30-ospp-v42-1-create-failed.rules
    mode: o-rwx
  when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
  tags:
    - CCE-82374-0
    - NIST-800-53-AU-2(a)
    - audit_create_failed
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

Complexity:low
Disruption:low
Strategy:restrict
# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then

cat << 'EOF' > /etc/audit/rules.d/30-ospp-v42-1-create-failed.rules
## Unsuccessful file creation (open with O_CREAT)
-a always,exit -F arch=b32 -S openat,open_by_handle_at -F a2&0100 -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-create
-a always,exit -F arch=b64 -S openat,open_by_handle_at -F a2&0100 -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-create
-a always,exit -F arch=b32 -S open -F a1&0100 -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-create
-a always,exit -F arch=b64 -S open -F a1&0100 -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-create
-a always,exit -F arch=b32 -S creat -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-create
-a always,exit -F arch=b64 -S creat -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-create
-a always,exit -F arch=b32 -S openat,open_by_handle_at -F a2&0100 -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-create
-a always,exit -F arch=b64 -S openat,open_by_handle_at -F a2&0100 -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-create
-a always,exit -F arch=b32 -S open -F a1&0100 -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-create
-a always,exit -F arch=b64 -S open -F a1&0100 -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-create
-a always,exit -F arch=b32 -S creat -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-create
-a always,exit -F arch=b64 -S creat -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-create
EOF

chmod o-rwx /etc/audit/rules.d/30-ospp-v42-1-create-failed.rules

augenrules --load

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi

Rule   Configure auditing of successful file creations   [ref]

Ensure that successful attempts to create a file are audited. The following rules configure audit as described above:
## Successful file creation (open with O_CREAT)
-a always,exit -F arch=b32 -S openat,open_by_handle_at -F a2&0100 -F success=1 -F auid>=1000 -F auid!=unset -F key=successful-create
-a always,exit -F arch=b64 -S openat,open_by_handle_at -F a2&0100 -F success=1 -F auid>=1000 -F auid!=unset -F key=successful-create
-a always,exit -F arch=b32 -S open -F a1&0100 -F success=1 -F auid>=1000 -F auid!=unset -F key=successful-create
-a always,exit -F arch=b64 -S open -F a1&0100 -F success=1 -F auid>=1000 -F auid!=unset -F key=successful-create
-a always,exit -F arch=b32 -S creat -F success=1 -F auid>=1000 -F auid!=unset -F key=successful-create
-a always,exit -F arch=b64 -S creat -F success=1 -F auid>=1000 -F auid!=unset -F key=successful-create    
The Audit package provides pre-configured rules in /usr/share/audit/sample-rules. The above content can be found in /usr/share/audit/sample-rules/30-ospp-v42-1-create-success.rules. To deploy this configuration, it is recommended to copy it over to the /etc/audit/rules.d/ directory:
cp /usr/share/audit/sample-rules/30-ospp-v42-1-create-success.rules /etc/audit/rules.d/
Load new Audit rules into kernel by running:
augenrules --load
Rationale:
Auditing of successful attempts to create a file helps in investigation of actions which happened on the system.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_audit_create_success
Identifiers and References

Identifiers:  CCE-82829-3

References:  AU-2(a), FAU_GEN.1.1.c, SRG-OS-000458-GPOS-00203, SRG-OS-000474-GPOS-00219, SRG-OS-000475-GPOS-00220, SRG-OS-000463-GPOS-00207, SRG-OS-000465-GPOS-00209, SRG-OS-000461-GPOS-00205


Complexity:low
Disruption:low
Strategy:restrict
- name: Put contents into /etc/audit/rules.d/30-ospp-v42-1-create-success.rules according
    to policy
  copy:
    dest: /etc/audit/rules.d/30-ospp-v42-1-create-success.rules
    content: |
      ## Successful file creation (open with O_CREAT)
      -a always,exit -F arch=b32 -S openat,open_by_handle_at -F a2&0100 -F success=1 -F auid>=1000 -F auid!=unset -F key=successful-create
      -a always,exit -F arch=b64 -S openat,open_by_handle_at -F a2&0100 -F success=1 -F auid>=1000 -F auid!=unset -F key=successful-create
      -a always,exit -F arch=b32 -S open -F a1&0100 -F success=1 -F auid>=1000 -F auid!=unset -F key=successful-create
      -a always,exit -F arch=b64 -S open -F a1&0100 -F success=1 -F auid>=1000 -F auid!=unset -F key=successful-create
      -a always,exit -F arch=b32 -S creat -F success=1 -F auid>=1000 -F auid!=unset -F key=successful-create
      -a always,exit -F arch=b64 -S creat -F success=1 -F auid>=1000 -F auid!=unset -F key=successful-create
    force: true
  when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
  tags:
    - CCE-82829-3
    - NIST-800-53-AU-2(a)
    - audit_create_success
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

- name: Remove any permissions from other group
  file:
    path: /etc/audit/rules.d/30-ospp-v42-1-create-success.rules
    mode: o-rwx
  when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
  tags:
    - CCE-82829-3
    - NIST-800-53-AU-2(a)
    - audit_create_success
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

Complexity:low
Disruption:low
Strategy:restrict
# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then

cat << 'EOF' > /etc/audit/rules.d/30-ospp-v42-1-create-success.rules
## Successful file creation (open with O_CREAT)
-a always,exit -F arch=b32 -S openat,open_by_handle_at -F a2&0100 -F success=1 -F auid>=1000 -F auid!=unset -F key=successful-create
-a always,exit -F arch=b64 -S openat,open_by_handle_at -F a2&0100 -F success=1 -F auid>=1000 -F auid!=unset -F key=successful-create
-a always,exit -F arch=b32 -S open -F a1&0100 -F success=1 -F auid>=1000 -F auid!=unset -F key=successful-create
-a always,exit -F arch=b64 -S open -F a1&0100 -F success=1 -F auid>=1000 -F auid!=unset -F key=successful-create
-a always,exit -F arch=b32 -S creat -F success=1 -F auid>=1000 -F auid!=unset -F key=successful-create
-a always,exit -F arch=b64 -S creat -F success=1 -F auid>=1000 -F auid!=unset -F key=successful-create
EOF

chmod o-rwx /etc/audit/rules.d/30-ospp-v42-1-create-success.rules

augenrules --load

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi

Rule   Configure auditing of unsuccessful file deletions   [ref]

Ensure that unsuccessful attempts to delete a file are audited. The following rules configure audit as described above:
## Unsuccessful file delete
-a always,exit -F arch=b32 -S unlink,unlinkat,rename,renameat -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-delete
-a always,exit -F arch=b64 -S unlink,unlinkat,rename,renameat -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-delete
-a always,exit -F arch=b32 -S unlink,unlinkat,rename,renameat -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-delete
-a always,exit -F arch=b64 -S unlink,unlinkat,rename,renameat -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-delete    
The Audit package provides pre-configured rules in /usr/share/audit/sample-rules. The above content can be found in /usr/share/audit/sample-rules/30-ospp-v42-4-delete-failed.rules. To deploy this configuration, it is recommended to copy it over to the /etc/audit/rules.d/ directory:
cp /usr/share/audit/sample-rules/30-ospp-v42-4-delete-failed.rules /etc/audit/rules.d/
Load new Audit rules into kernel by running:
augenrules --load
Note: This rule utilizes a file provided by Audit package to comply with OSPP 4.2.1. You may reuse this rule in different profiles. If you decide to do so, it is recommended that you inspect contents of the file closely and make sure that they are alligned with your needs.
Rationale:
Unsuccessful attempts to delete a file might be signs of malicious activities. Auditing of such events help in monitoring and investigating of such activities.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_audit_delete_failed
Identifiers and References

Identifiers:  CCE-82835-0

References:  AU-2(a), FAU_GEN.1.1.c, SRG-OS-000458-GPOS-00203, SRG-OS-000474-GPOS-00219, SRG-OS-000475-GPOS-00220, SRG-OS-000463-GPOS-00207, SRG-OS-000465-GPOS-00209, SRG-OS-000461-GPOS-00205, SRG-OS-000468-GPOS-00212


---
apiVersion: machineconfiguration.openshift.io/v1
kind: MachineConfig
spec:
  config:
    ignition:
      version: 3.1.0
    storage:
      files:
      - contents:
          source: data:,%23%23%20Unsuccessful%20file%20delete%0A-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20unlink%2Cunlinkat%2Crename%2Crenameat%20-F%20exit%3D-EACCES%20-F%20auid%26gt%3B%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-delete%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20unlink%2Cunlinkat%2Crename%2Crenameat%20-F%20exit%3D-EACCES%20-F%20auid%26gt%3B%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-delete%0A-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20unlink%2Cunlinkat%2Crename%2Crenameat%20-F%20exit%3D-EPERM%20-F%20auid%26gt%3B%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-delete%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20unlink%2Cunlinkat%2Crename%2Crenameat%20-F%20exit%3D-EPERM%20-F%20auid%26gt%3B%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-delete
        mode: 0600
        path: /etc/audit/rules.d/30-ospp-v42-4-delete-failed.rules
        overwrite: true

Complexity:low
Disruption:low
Strategy:restrict
- name: Put contents into /etc/audit/rules.d/30-ospp-v42-4-delete-failed.rules according
    to policy
  copy:
    dest: /etc/audit/rules.d/30-ospp-v42-4-delete-failed.rules
    content: |
      ## Unsuccessful file delete
      -a always,exit -F arch=b32 -S unlink,unlinkat,rename,renameat -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-delete
      -a always,exit -F arch=b64 -S unlink,unlinkat,rename,renameat -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-delete
      -a always,exit -F arch=b32 -S unlink,unlinkat,rename,renameat -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-delete
      -a always,exit -F arch=b64 -S unlink,unlinkat,rename,renameat -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-delete
    force: true
  when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
  tags:
    - CCE-82835-0
    - NIST-800-53-AU-2(a)
    - audit_delete_failed
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

- name: Remove any permissions from other group
  file:
    path: /etc/audit/rules.d/30-ospp-v42-4-delete-failed.rules
    mode: o-rwx
  when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
  tags:
    - CCE-82835-0
    - NIST-800-53-AU-2(a)
    - audit_delete_failed
    - low_complexity
    - low_disruption
    - medium_severity
    - no_reboot_needed
    - restrict_strategy

Complexity:low
Disruption:low
Strategy:restrict
# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then

cat << 'EOF' > /etc/audit/rules.d/30-ospp-v42-4-delete-failed.rules
## Unsuccessful file delete
-a always,exit -F arch=b32 -S unlink,unlinkat,rename,renameat -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-delete
-a always,exit -F arch=b64 -S unlink,unlinkat,rename,renameat -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-delete
-a always,exit -F arch=b32 -S unlink,unlinkat,rename,renameat -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-delete
-a always,exit -F arch=b64 -S unlink,unlinkat,rename,renameat -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-delete
EOF

chmod o-rwx /etc/audit/rules.d/30-ospp-v42-4-delete-failed.rules

augenrules --load

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi

Rule   Configure auditing of successful file deletions   [ref]

Ensure that successful attempts to delete a file are audited. The following rules configure audit as described above:
## Successful file delete
-a always,exit -F arch=b32 -S unlink,unlinkat,rename,renameat -F success=1 -F auid>=1000 -F auid!=unset -F key=successful-delete
-a always,exit -F arch=b64 -S unlink,unlinkat,rename,renameat -F success=1 -F auid>=1000 -F auid!=unset -F key=successful-delete    
The Audit package provides pre-configured rules in /usr/share/audit/sample-rules. The above content can be found in /usr/share/audit/sample-rules/30-ospp-v42-4-delete-success.rules. To deploy this configuration, it is recommended to copy it over to the /etc/audit/rules.d/ directory:
cp /usr/share/audit/sample-rules/30-ospp-v42-4-delete-success.rules /etc/audit/rules.d/
Load new Audit rules into kernel by running:
augenrules --load
Note: This rule utilizes a file provided by Audit package to comply with OSPP 4.2.1. You may reuse this rule in different profiles. If you decide to do so, it is recommended that you inspect contents of the file closely and make sure that they are alligned with your needs.
Rationale:
Auditing of successful attempts to delete a file may help in monitoring and investigation of activities performed on the system.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_audit_delete_success
Identifiers and References

Identifiers:  CCE-82836-8

References:  AU-2(a), FAU_GEN.1.1.c, SRG-OS-000458-GPOS-00203, SRG-OS-000474-GPOS-00219, SRG-OS-000475-GPOS