Guide to the Secure Configuration of OpenEmbedded

with profile Sample Security Profile for OpenEmbedded Distros
This profile is an sample for use in documentation and example content. The selected rules are standard and should pass quickly on most systems.
This guide presents a catalog of security-relevant configuration settings for OpenEmbedded. 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 TitleSample Security Profile for OpenEmbedded Distros
Profile IDxccdf_org.ssgproject.content_profile_standard

CPE Platforms

  • cpe:/o:openembedded:harden:
  • cpe:/o:openembedded:nodistro:
  • cpe:/o:openembedded:petalinux:
  • cpe:/o:openembedded:poky:

Revision History

Current version: 0.1.74

  • draft (as of 2024-06-20)

Table of Contents

  1. System Settings
    1. Installing and Maintaining Software
    2. Account and Access Control
    3. GRUB2 bootloader configuration
    4. Configure Syslog
    5. Network Configuration and Firewalls
    6. File Permissions and Masks
  2. Services
    1. Avahi Server
    2. Cron and At Daemons
    3. DHCP
    4. DNS Server
    5. FTP Server
    6. Web Server
    7. IMAP and POP3 Server
    8. LDAP
    9. NFS and RPC
    10. Obsolete Services
    11. Print Support
    12. Proxy Server
    13. Samba(SMB) Microsoft Windows File Sharing Server
    14. SNMP Server
    15. SSH Server
  3. System Accounting with auditd

    Checklist

    Group   Guide to the Secure Configuration of OpenEmbedded   Group contains 72 groups and 137 rules
    Group   System Settings   Group contains 36 groups and 72 rules
    [ref]   Contains rules that check correct system settings.
    Group   Installing and Maintaining Software   Group contains 4 groups and 3 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 2 groups and 2 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 2 rules
    [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 2 rules
    [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 dnf 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
    References:
    cis-csc1, 11, 12, 13, 14, 15, 16, 2, 3, 5, 7, 8, 9
    cjis5.10.1.3
    cobit5APO01.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
    disaCCI-002696, CCI-002699, CCI-001744
    isa-62443-20094.3.4.3.2, 4.3.4.3.3, 4.3.4.4.4
    isa-62443-2013SR 3.1, SR 3.3, SR 3.4, SR 3.8, SR 4.1, SR 6.2, SR 7.6
    ism1034, 1288, 1341, 1417
    iso27001-2013A.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
    nistCM-6(a)
    nist-csfDE.CM-1, DE.CM-7, PR.DS-1, PR.DS-6, PR.DS-8, PR.IP-1, PR.IP-3
    pcidssReq-11.5
    os-srgSRG-OS-000445-GPOS-00199
    anssiR76, R79
    pcidss411.5.2

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

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

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:enable
    include install_aide
    
    class install_aide {
      package { 'aide':
        ensure => 'installed',
      }
    }
    

    Rule   Configure Periodic Execution of AIDE   [ref]

    At a minimum, AIDE should be configured to run a weekly scan. To implement a daily execution of AIDE at 4:05am using cron, add the following line to /etc/crontab:
    05 4 * * * root /usr/sbin/aide --check
    To implement a weekly execution of AIDE at 4:05am using cron, add the following line to /etc/crontab:
    05 4 * * 0 root /usr/sbin/aide --check
    AIDE can be executed periodically through other means; this is merely one example. The usage of cron's special time codes, such as @daily and @weekly is acceptable.
    Rationale:
    By default, AIDE does not install itself for periodic execution. Periodically running AIDE is necessary to reveal unexpected changes in installed files.

    Unauthorized changes to the baseline configuration could make the system vulnerable to various attacks or allow unauthorized access to the operating system. Changes to operating system configurations can have unintended side effects, some of which may be relevant to security.

    Detecting such changes and providing an automated response can help avoid unintended, negative consequences that could ultimately affect the security state of the operating system. The operating system's Information Management Officer (IMO)/Information System Security Officer (ISSO) and System Administrators (SAs) must be notified via email and/or monitoring system trap when there is an unauthorized modification of a configuration item.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_aide_periodic_cron_checking
    References:
    cis-csc1, 11, 12, 13, 14, 15, 16, 2, 3, 5, 7, 8, 9
    cjis5.10.1.3
    cobit5APO01.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
    disaCCI-001744, CCI-002699, CCI-002702
    isa-62443-20094.3.4.3.2, 4.3.4.3.3, 4.3.4.4.4
    isa-62443-2013SR 3.1, SR 3.3, SR 3.4, SR 3.8, SR 4.1, SR 6.2, SR 7.6
    iso27001-2013A.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
    nistSI-7, SI-7(1), CM-6(a)
    nist-csfDE.CM-1, DE.CM-7, PR.DS-1, PR.DS-6, PR.DS-8, PR.IP-1, PR.IP-3
    pcidssReq-11.5
    os-srgSRG-OS-000363-GPOS-00150, SRG-OS-000446-GPOS-00200, SRG-OS-000447-GPOS-00201
    anssiR76
    pcidss411.5.2

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:restrict
    - name: Ensure AIDE is installed
      package:
        name: '{{ item }}'
        state: present
      with_items:
      - aide
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - CJIS-5.10.1.3
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SI-7
      - NIST-800-53-SI-7(1)
      - PCI-DSS-Req-11.5
      - PCI-DSSv4-11.5.2
      - aide_periodic_cron_checking
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
    
    - name: Set cron package name - RedHat
      set_fact:
        cron_pkg_name: cronie
      when:
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - ansible_os_family == "RedHat" or ansible_os_family == "Suse"
      tags:
      - CJIS-5.10.1.3
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SI-7
      - NIST-800-53-SI-7(1)
      - PCI-DSS-Req-11.5
      - PCI-DSSv4-11.5.2
      - aide_periodic_cron_checking
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
    
    - name: Set cron package name - Debian
      set_fact:
        cron_pkg_name: cron
      when:
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - ansible_os_family == "Debian"
      tags:
      - CJIS-5.10.1.3
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SI-7
      - NIST-800-53-SI-7(1)
      - PCI-DSS-Req-11.5
      - PCI-DSSv4-11.5.2
      - aide_periodic_cron_checking
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
    
    - name: Install cron
      package:
        name: '{{ cron_pkg_name }}'
        state: present
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - CJIS-5.10.1.3
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SI-7
      - NIST-800-53-SI-7(1)
      - PCI-DSS-Req-11.5
      - PCI-DSSv4-11.5.2
      - aide_periodic_cron_checking
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
    
    - name: Configure Periodic Execution of AIDE
      cron:
        name: run AIDE check
        minute: 5
        hour: 4
        weekday: 0
        user: root
        job: /usr/sbin/aide --check
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - CJIS-5.10.1.3
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SI-7
      - NIST-800-53-SI-7(1)
      - PCI-DSS-Req-11.5
      - PCI-DSSv4-11.5.2
      - aide_periodic_cron_checking
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
    
    Group   Updating Software   Group contains 1 rule
    [ref]   The dnf 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.

    OpenEmbedded systems contain an installed software catalog called the RPM database, which records metadata of installed packages. Consistently using dnf or the graphical Software Update for all software installation allows for insight into the current inventory of installed software on the system.

    Rule   Ensure gpgcheck Enabled In Main dnf Configuration   [ref]

    The gpgcheck option controls whether RPM packages' signatures are always checked prior to installation. To configure dnf to check package signatures before installing them, ensure the following line appears in /etc/dnf/dnf.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
    References:
    cis-csc11, 2, 3, 9
    cjis5.10.4.1
    cobit5APO01.06, BAI03.05, BAI06.01, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS06.02
    cui3.4.8
    disaCCI-001749
    hipaa164.308(a)(1)(ii)(D), 164.312(b), 164.312(c)(1), 164.312(c)(2), 164.312(e)(2)(i)
    isa-62443-20094.3.4.3.2, 4.3.4.3.3, 4.3.4.4.4
    isa-62443-2013SR 3.1, SR 3.3, SR 3.4, SR 3.8, SR 7.6
    iso27001-2013A.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
    nistCM-5(3), SI-7, SC-12, SC-12(3), CM-6(a), SA-12, SA-12(10), CM-11(a), CM-11(b)
    nist-csfPR.DS-6, PR.DS-8, PR.IP-1
    osppFPT_TUD_EXT.1, FPT_TUD_EXT.2
    pcidssReq-6.2
    os-srgSRG-OS-000366-GPOS-00153
    anssiR59
    pcidss46.3.3

    Complexity:low
    Disruption:medium
    Reboot:false
    Strategy:configure
    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.10.4.1
      - NIST-800-171-3.4.8
      - NIST-800-53-CM-11(a)
      - NIST-800-53-CM-11(b)
      - NIST-800-53-CM-5(3)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SA-12
      - NIST-800-53-SA-12(10)
      - NIST-800-53-SC-12
      - NIST-800-53-SC-12(3)
      - NIST-800-53-SI-7
      - PCI-DSS-Req-6.2
      - PCI-DSSv4-6.3.3
      - 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/dnf/dnf.conf
        section: main
        option: gpgcheck
        value: 1
        no_extra_spaces: true
        create: false
      when: '"dnf" in ansible_facts.packages'
      tags:
      - CJIS-5.10.4.1
      - NIST-800-171-3.4.8
      - NIST-800-53-CM-11(a)
      - NIST-800-53-CM-11(b)
      - NIST-800-53-CM-5(3)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SA-12
      - NIST-800-53-SA-12(10)
      - NIST-800-53-SC-12
      - NIST-800-53-SC-12(3)
      - NIST-800-53-SI-7
      - PCI-DSS-Req-6.2
      - PCI-DSSv4-6.3.3
      - configure_strategy
      - ensure_gpgcheck_globally_activated
      - high_severity
      - low_complexity
      - medium_disruption
      - no_reboot_needed
    
    Group   Account and Access Control   Group contains 15 groups and 33 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 OpenEmbedded.
    Group   Warning Banners for System Accesses   Group contains 8 rules
    [ref]   Each system should expose as little information about itself as possible.

    System banners, which are typically displayed just before a login prompt, give out information about the service or the host's operating system. This might include the distribution name and the system kernel version, and the particular version of a network service. This information can assist intruders in gaining access to the system as it can reveal whether the system is running vulnerable software. Most network services can be configured to limit what information is displayed.

    Many organizations implement security policies that require a system banner provide notice of the system's ownership, provide warning to unauthorized users, and remind authorized users of their consent to monitoring.

    Rule   Modify the System Login Banner   [ref]

    To configure the system login banner edit /etc/issue. Replace the default text with a message compliant with the local site policy or a legal disclaimer. The DoD required text is either:

    You are accessing a U.S. Government (USG) Information System (IS) that is provided for USG-authorized use only. By using this IS (which includes any device attached to this IS), you consent to the following conditions:
    -The USG routinely intercepts and monitors communications on this IS for purposes including, but not limited to, penetration testing, COMSEC monitoring, network operations and defense, personnel misconduct (PM), law enforcement (LE), and counterintelligence (CI) investigations.
    -At any time, the USG may inspect and seize data stored on this IS.
    -Communications using, or data stored on, this IS are not private, are subject to routine monitoring, interception, and search, and may be disclosed or used for any USG-authorized purpose.
    -This IS includes security measures (e.g., authentication and access controls) to protect USG interests -- not for your personal benefit or privacy.
    -Notwithstanding the above, using this IS does not constitute consent to PM, LE or CI investigative searching or monitoring of the content of privileged communications, or work product, related to personal representation or services by attorneys, psychotherapists, or clergy, and their assistants. Such communications and work product are private and confidential. See User Agreement for details.


    OR:

    I've read & consent to terms in IS user agreem't.
    Rationale:
    Display of a standardized and approved use notification before granting access to the operating system ensures privacy and security notification verbiage used is consistent with applicable federal laws, Executive Orders, directives, policies, regulations, standards, and guidance.

    System use notifications are required only for access via login interfaces with human users and are not required when such human interfaces do not exist.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_banner_etc_issue
    References:
    cis-csc1, 12, 15, 16
    cobit5DSS05.04, DSS05.10, DSS06.10
    cui3.1.9
    disaCCI-000048, CCI-000050, CCI-001384, CCI-001385, CCI-001386, CCI-001387, CCI-001388
    isa-62443-20094.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
    isa-62443-2013SR 1.1, SR 1.10, SR 1.2, SR 1.5, SR 1.7, SR 1.8, SR 1.9
    iso27001-2013A.18.1.4, A.9.2.1, A.9.2.4, A.9.3.1, A.9.4.2, A.9.4.3
    nistAC-8(a), AC-8(c)
    nist-csfPR.AC-7
    osppFMT_MOF_EXT.1
    os-srgSRG-OS-000023-GPOS-00006, SRG-OS-000228-GPOS-00088

    Rule   Modify the System Message of the Day Banner   [ref]

    To configure the system message banner edit /etc/motd. Replace the default text with a message compliant with the local site policy or a legal disclaimer. The DoD required text is either:

    You are accessing a U.S. Government (USG) Information System (IS) that is provided for USG-authorized use only. By using this IS (which includes any device attached to this IS), you consent to the following conditions:
    -The USG routinely intercepts and monitors communications on this IS for purposes including, but not limited to, penetration testing, COMSEC monitoring, network operations and defense, personnel misconduct (PM), law enforcement (LE), and counterintelligence (CI) investigations.
    -At any time, the USG may inspect and seize data stored on this IS.
    -Communications using, or data stored on, this IS are not private, are subject to routine monitoring, interception, and search, and may be disclosed or used for any USG-authorized purpose.
    -This IS includes security measures (e.g., authentication and access controls) to protect USG interests -- not for your personal benefit or privacy.
    -Notwithstanding the above, using this IS does not constitute consent to PM, LE or CI investigative searching or monitoring of the content of privileged communications, or work product, related to personal representation or services by attorneys, psychotherapists, or clergy, and their assistants. Such communications and work product are private and confidential. See User Agreement for details.


    OR:

    I've read & consent to terms in IS user agreem't.
    Rationale:
    Display of a standardized and approved use notification before granting access to the operating system ensures privacy and security notification verbiage used is consistent with applicable federal laws, Executive Orders, directives, policies, regulations, standards, and guidance.

    System use notifications are required only for access via login interfaces with human users and are not required when such human interfaces do not exist.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_banner_etc_motd

    Rule   Verify Group Ownership of System Login Banner   [ref]

    To properly set the group owner of /etc/issue, run the command:
    $ sudo chgrp root /etc/issue
    Rationale:
    Display of a standardized and approved use notification before granting access to the operating system ensures privacy and security notification verbiage used is consistent with applicable federal laws, Executive Orders, directives, policies, regulations, standards, and guidance.
    Proper group ownership will ensure that only root user can modify the banner.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_groupowner_etc_issue

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Test for existence /etc/issue
      stat:
        path: /etc/issue
      register: file_exists
      tags:
      - configure_strategy
      - file_groupowner_etc_issue
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    
    - name: Ensure group owner 0 on /etc/issue
      file:
        path: /etc/issue
        group: '0'
      when: file_exists.stat is defined and file_exists.stat.exists
      tags:
      - configure_strategy
      - file_groupowner_etc_issue
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    chgrp 0 /etc/issue
    

    Rule   Verify Group Ownership of Message of the Day Banner   [ref]

    To properly set the group owner of /etc/motd, run the command:
    $ sudo chgrp root /etc/motd
    Rationale:
    Display of a standardized and approved use notification before granting access to the operating system ensures privacy and security notification verbiage used is consistent with applicable federal laws, Executive Orders, directives, policies, regulations, standards, and guidance.
    Proper group ownership will ensure that only root user can modify the banner.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_groupowner_etc_motd

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Test for existence /etc/motd
      stat:
        path: /etc/motd
      register: file_exists
      tags:
      - configure_strategy
      - file_groupowner_etc_motd
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    
    - name: Ensure group owner 0 on /etc/motd
      file:
        path: /etc/motd
        group: '0'
      when: file_exists.stat is defined and file_exists.stat.exists
      tags:
      - configure_strategy
      - file_groupowner_etc_motd
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    chgrp 0 /etc/motd
    

    Rule   Verify ownership of System Login Banner   [ref]

    To properly set the owner of /etc/issue, run the command:
    $ sudo chown root /etc/issue 
    Rationale:
    Display of a standardized and approved use notification before granting access to the operating system ensures privacy and security notification verbiage used is consistent with applicable federal laws, Executive Orders, directives, policies, regulations, standards, and guidance.
    Proper ownership will ensure that only root user can modify the banner.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_owner_etc_issue

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Test for existence /etc/issue
      stat:
        path: /etc/issue
      register: file_exists
      tags:
      - configure_strategy
      - file_owner_etc_issue
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    
    - name: Ensure owner 0 on /etc/issue
      file:
        path: /etc/issue
        owner: '0'
      when: file_exists.stat is defined and file_exists.stat.exists
      tags:
      - configure_strategy
      - file_owner_etc_issue
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    chown 0 /etc/issue
    

    Rule   Verify ownership of Message of the Day Banner   [ref]

    To properly set the owner of /etc/motd, run the command:
    $ sudo chown root /etc/motd 
    Rationale:
    Display of a standardized and approved use notification before granting access to the operating system ensures privacy and security notification verbiage used is consistent with applicable federal laws, Executive Orders, directives, policies, regulations, standards, and guidance.
    Proper ownership will ensure that only root user can modify the banner.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_owner_etc_motd

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Test for existence /etc/motd
      stat:
        path: /etc/motd
      register: file_exists
      tags:
      - configure_strategy
      - file_owner_etc_motd
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    
    - name: Ensure owner 0 on /etc/motd
      file:
        path: /etc/motd
        owner: '0'
      when: file_exists.stat is defined and file_exists.stat.exists
      tags:
      - configure_strategy
      - file_owner_etc_motd
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    chown 0 /etc/motd
    

    Rule   Verify permissions on System Login Banner   [ref]

    To properly set the permissions of /etc/issue, run the command:
    $ sudo chmod 0644 /etc/issue
    Rationale:
    Display of a standardized and approved use notification before granting access to the operating system ensures privacy and security notification verbiage used is consistent with applicable federal laws, Executive Orders, directives, policies, regulations, standards, and guidance.
    Proper permissions will ensure that only root user can modify the banner.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_permissions_etc_issue

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Test for existence /etc/issue
      stat:
        path: /etc/issue
      register: file_exists
      tags:
      - configure_strategy
      - file_permissions_etc_issue
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    
    - name: Ensure permission u-xs,g-xws,o-xwt on /etc/issue
      file:
        path: /etc/issue
        mode: u-xs,g-xws,o-xwt
      when: file_exists.stat is defined and file_exists.stat.exists
      tags:
      - configure_strategy
      - file_permissions_etc_issue
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    
    
    
    
    
    chmod u-xs,g-xws,o-xwt /etc/issue
    

    Rule   Verify permissions on Message of the Day Banner   [ref]

    To properly set the permissions of /etc/motd, run the command:
    $ sudo chmod 0644 /etc/motd
    Rationale:
    Display of a standardized and approved use notification before granting access to the operating system ensures privacy and security notification verbiage used is consistent with applicable federal laws, Executive Orders, directives, policies, regulations, standards, and guidance.
    Proper permissions will ensure that only root user can modify the banner.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_permissions_etc_motd

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Test for existence /etc/motd
      stat:
        path: /etc/motd
      register: file_exists
      tags:
      - configure_strategy
      - file_permissions_etc_motd
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    
    - name: Ensure permission u-xs,g-xws,o-xwt on /etc/motd
      file:
        path: /etc/motd
        mode: u-xs,g-xws,o-xwt
      when: file_exists.stat is defined and file_exists.stat.exists
      tags:
      - configure_strategy
      - file_permissions_etc_motd
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    
    
    
    
    
    chmod u-xs,g-xws,o-xwt /etc/motd
    
    Group   Protect Accounts by Configuring PAM   Group contains 4 groups and 6 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 https://fossies.org/linux/Linux-PAM-docs/doc/sag/Linux-PAM_SAG.pdf.
    Group   Set Lockouts for Failed Password Attempts   Group contains 2 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: password-auth   [ref]

    Do not allow users to reuse recent passwords. This can be accomplished by using the remember option for the pam_pwhistory PAM module.

    On systems with newer versions of authselect, the pam_pwhistory PAM module can be enabled via authselect feature:
    authselect enable-feature with-pwhistory
    Otherwise, it should be enabled using an authselect custom profile.

    Newer systems also have the /etc/security/pwhistory.conf file for setting pam_pwhistory module options. This file should be used whenever available. Otherwise, the pam_pwhistory module options can be set in PAM files.

    The value for remember option must be equal or greater than 5
    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.
    Warning:  Newer versions of authselect contain an authselect feature to easily and properly enable pam_pwhistory.so module. If this feature is not yet available in your system, an authselect custom profile must be used to avoid integrity issues in PAM files. If a custom profile was created and used in the system before this authselect feature was available, the new feature can't be used with this custom profile and the remediation will fail. In this case, the custom profile should be recreated or manually updated.
    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_pwhistory_remember_password_auth
    References:
    cis-csc1, 12, 15, 16, 5
    cjis5.6.2.1.1
    cobit5DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.10
    cui3.5.8
    disaCCI-000200
    isa-62443-20094.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
    isa-62443-2013SR 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
    iso27001-2013A.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
    nistIA-5(f), IA-5(1)(e)
    nist-csfPR.AC-1, PR.AC-6, PR.AC-7
    pcidssReq-8.2.5
    os-srgSRG-OS-000077-GPOS-00045
    pcidss48.3.7

    Rule   Limit Password Reuse: system-auth   [ref]

    Do not allow users to reuse recent passwords. This can be accomplished by using the remember option for the pam_pwhistory PAM module.

    On systems with newer versions of authselect, the pam_pwhistory PAM module can be enabled via authselect feature:
    authselect enable-feature with-pwhistory
    Otherwise, it should be enabled using an authselect custom profile.

    Newer systems also have the /etc/security/pwhistory.conf file for setting pam_pwhistory module options. This file should be used whenever available. Otherwise, the pam_pwhistory module options can be set in PAM files.

    The value for remember option must be equal or greater than 5
    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.
    Warning:  Newer versions of authselect contain an authselect feature to easily and properly enable pam_pwhistory.so module. If this feature is not yet available in your system, an authselect custom profile must be used to avoid integrity issues in PAM files.
    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_pwhistory_remember_system_auth
    References:
    cis-csc1, 12, 15, 16, 5
    cjis5.6.2.1.1
    cobit5DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.10
    cui3.5.8
    disaCCI-000200
    isa-62443-20094.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
    isa-62443-2013SR 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
    iso27001-2013A.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
    nistIA-5(f), IA-5(1)(e)
    nist-csfPR.AC-1, PR.AC-6, PR.AC-7
    pcidssReq-8.2.5
    os-srgSRG-OS-000077-GPOS-00045
    pcidss48.3.7
    Group   Set Password Quality Requirements   Group contains 1 group and 3 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 3 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 Different Categories   [ref]

    The pam_pwquality module's minclass parameter controls requirements for usage of different character classes, or types, of character that must exist in a password before it is considered valid. For example, setting this value to three (3) requires that any password must have characters from at least three different categories in order to be approved. The default value is zero (0), meaning there are no required classes. There are four categories available:
    * Upper-case characters
    * Lower-case characters
    * Digits
    * Special characters (for example, punctuation)
    
    Modify the minclass setting in /etc/security/pwquality.conf entry to require 4 differing categories of 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 character categories makes password guessing attacks more difficult by ensuring a larger search space.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_accounts_password_pam_minclass
    References:
    cis-csc1, 12, 15, 16, 5
    cobit5DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.10
    disaCCI-000195
    isa-62443-20094.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
    isa-62443-2013SR 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
    ism0421, 0422, 0431, 0974, 1173, 1401, 1504, 1505, 1546, 1557, 1558, 1559, 1560, 1561
    iso27001-2013A.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
    nistIA-5(c), IA-5(1)(a), CM-6(a), IA-5(4)
    nist-csfPR.AC-1, PR.AC-6, PR.AC-7
    os-srgSRG-OS-000072-GPOS-00040
    anssiR68

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:restrict
    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - 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_minclass
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
    - name: XCCDF Value var_password_pam_minclass # promote to variable
      set_fact:
        var_password_pam_minclass: !!str 4
      tags:
        - always
    
    - name: Ensure PAM Enforces Password Requirements - Minimum Different Categories -
        Ensure PAM variable minclass is set accordingly
      ansible.builtin.lineinfile:
        create: true
        dest: /etc/security/pwquality.conf
        regexp: ^#?\s*minclass
        line: minclass = {{ var_password_pam_minclass }}
      when: '"pam" in ansible_facts.packages'
      tags:
      - 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_minclass
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:restrict
    # Remediation is applicable only in certain platforms
    if rpm --quiet -q pam; then
    
    var_password_pam_minclass='4'
    
    
    
    
    
    
    # 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' <<< "^minclass")
    
    # shellcheck disable=SC2059
    printf -v formatted_output "%s = %s" "$stripped_key" "$var_password_pam_minclass"
    
    # 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 "^minclass\\>" "/etc/security/pwquality.conf"; then
        escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
        LC_ALL=C sed -i --follow-symlinks "s/^minclass\\>.*/$escaped_formatted_output/gi" "/etc/security/pwquality.conf"
    else
        if [[ -s "/etc/security/pwquality.conf" ]] && [[ -n "$(tail -c 1 -- "/etc/security/pwquality.conf" || true)" ]]; then
            LC_ALL=C sed -i --follow-symlinks '$a'\\ "/etc/security/pwquality.conf"
        fi
        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=14 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 compromise the password.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_accounts_password_pam_minlen
    References:
    cis-csc1, 12, 15, 16, 5
    cjis5.6.2.1.1
    cobit5DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.10
    disaCCI-000205
    isa-62443-20094.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
    isa-62443-2013SR 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
    ism0421, 0422, 0431, 0974, 1173, 1401, 1504, 1505, 1546, 1557, 1558, 1559, 1560, 1561
    iso27001-2013A.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
    nistIA-5(c), IA-5(1)(a), CM-6(a), IA-5(4)
    nist-csfPR.AC-1, PR.AC-6, PR.AC-7
    osppFMT_SMF_EXT.1
    pcidssReq-8.2.3
    os-srgSRG-OS-000078-GPOS-00046
    anssiR31, R68
    pcidss48.3.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:restrict
    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.6.2.1.1
      - 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
      - PCI-DSSv4-8.3.6
      - 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 14
      tags:
        - always
    
    - name: Ensure PAM Enforces Password Requirements - Minimum Length - Ensure PAM variable
        minlen is set accordingly
      ansible.builtin.lineinfile:
        create: true
        dest: /etc/security/pwquality.conf
        regexp: ^#?\s*minlen
        line: minlen = {{ var_password_pam_minlen }}
      when: '"pam" in ansible_facts.packages'
      tags:
      - CJIS-5.6.2.1.1
      - 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
      - PCI-DSSv4-8.3.6
      - accounts_password_pam_minlen
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:restrict
    # Remediation is applicable only in certain platforms
    if rpm --quiet -q pam; then
    
    var_password_pam_minlen='14'
    
    
    
    
    
    
    # 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
        escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
        LC_ALL=C sed -i --follow-symlinks "s/^minlen\\>.*/$escaped_formatted_output/gi" "/etc/security/pwquality.conf"
    else
        if [[ -s "/etc/security/pwquality.conf" ]] && [[ -n "$(tail -c 1 -- "/etc/security/pwquality.conf" || true)" ]]; then
            LC_ALL=C sed -i --follow-symlinks '$a'\\ "/etc/security/pwquality.conf"
        fi
        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 - Authentication Retry Prompts Permitted Per-Session   [ref]

    To configure the number of retry prompts that are permitted per-session: Edit the pam_pwquality.so statement in /etc/pam.d/system-auth to show retry=3 , or a lower value if site policy is more restrictive. The DoD requirement is a maximum of 3 prompts per session.
    Rationale:
    Setting the password retry prompts that are permitted on a per-session basis to a low value requires some software, such as SSH, to re-connect. This can slow down and draw additional attention to some types of password-guessing attacks. Note that this is different from account lockout, which is provided by the pam_faillock module.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_accounts_password_pam_retry
    References:
    cis-csc1, 11, 12, 15, 16, 3, 5, 9
    cjis5.5.3
    cobit5BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.10
    disaCCI-000192, CCI-000366
    isa-62443-20094.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, 4.3.4.3.2, 4.3.4.3.3
    isa-62443-2013SR 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 7.6
    iso27001-2013A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, 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
    nistCM-6(a), AC-7(a), IA-5(4)
    nist-csfPR.AC-1, PR.AC-6, PR.AC-7, PR.IP-1
    osppFMT_MOF_EXT.1
    os-srgSRG-OS-000069-GPOS-00037, SRG-OS-000480-GPOS-00227
    anssiR68

    # Remediation is applicable only in certain platforms
    if rpm --quiet -q pam; then
    
    var_password_pam_retry='3'
    
    
    
    	
    		if [ -e "/etc/pam.d/system-auth" ] ; then
        PAM_FILE_PATH="/etc/pam.d/system-auth"
        if [ -f /usr/bin/authselect ]; then
            
            if ! authselect check; then
            echo "
            authselect integrity check failed. Remediation aborted!
            This remediation could not be applied because an authselect profile was not selected or the selected profile is not intact.
            It is not recommended to manually edit the PAM files when authselect tool is available.
            In cases where the default authselect profile does not cover a specific demand, a custom authselect profile is recommended."
            exit 1
            fi
    
            CURRENT_PROFILE=$(authselect current -r | awk '{ print $1 }')
            # If not already in use, a custom profile is created preserving the enabled features.
            if [[ ! $CURRENT_PROFILE == custom/* ]]; then
                ENABLED_FEATURES=$(authselect current | tail -n+3 | awk '{ print $2 }')
                authselect create-profile hardening -b $CURRENT_PROFILE
                CURRENT_PROFILE="custom/hardening"
                
                authselect apply-changes -b --backup=before-hardening-custom-profile
                authselect select $CURRENT_PROFILE
                for feature in $ENABLED_FEATURES; do
                    authselect enable-feature $feature;
                done
                
                authselect apply-changes -b --backup=after-hardening-custom-profile
            fi
            PAM_FILE_NAME=$(basename "/etc/pam.d/system-auth")
            PAM_FILE_PATH="/etc/authselect/$CURRENT_PROFILE/$PAM_FILE_NAME"
    
            authselect apply-changes -b
        fi
        if ! grep -qP '^\s*password\s+'"requisite"'\s+pam_pwquality.so\s*.*' "$PAM_FILE_PATH"; then
                # Line matching group + control + module was not found. Check group + module.
                if [ "$(grep -cP '^\s*password\s+.*\s+pam_pwquality.so\s*' "$PAM_FILE_PATH")" -eq 1 ]; then
                    # The control is updated only if one single line matches.
                    sed -i -E --follow-symlinks 's/^(\s*password\s+).*(\bpam_pwquality.so.*)/\1'"requisite"' \2/' "$PAM_FILE_PATH"
                else
                    LAST_MATCH_LINE=$(grep -nP "^\s*account" "$PAM_FILE_PATH" | tail -n 1 | cut -d: -f 1)
                    if [ ! -z $LAST_MATCH_LINE ]; then
                        sed -i --follow-symlinks $LAST_MATCH_LINE' a password     '"requisite"'    pam_pwquality.so' "$PAM_FILE_PATH"
                    else
                        echo 'password    '"requisite"'    pam_pwquality.so' >> "$PAM_FILE_PATH"
                    fi
                fi
            fi
            # Check the option
            if ! grep -qP '^\s*password\s+'"requisite"'\s+pam_pwquality.so\s*.*\sretry\b' "$PAM_FILE_PATH"; then
                sed -i -E --follow-symlinks '/\s*password\s+'"requisite"'\s+pam_pwquality.so.*/ s/$/ retry='"$var_password_pam_retry"'/' "$PAM_FILE_PATH"
            else
                sed -i -E --follow-symlinks 's/(\s*password\s+'"requisite"'\s+pam_pwquality.so\s+.*)('"retry"'=)[[:alnum:]]+\s*(.*)/\1\2'"$var_password_pam_retry"' \3/' "$PAM_FILE_PATH"
            fi
        if [ -f /usr/bin/authselect ]; then
            
            authselect apply-changes -b
        fi
    else
        echo "/etc/pam.d/system-auth was not found" >&2
    fi
    
    else
        >&2 echo 'Remediation is not applicable, nothing was done'
    fi
    
    Group   Set Password Hashing Algorithm   Group contains 1 rule
    [ref]   The system's default algorithm for storing password hashes in /etc/shadow is SHA-512. This can be configured in several locations.

    Rule   Set PAM''s Password Hashing Algorithm   [ref]

    The PAM system service can be configured to only store encrypted representations of passwords. In "/etc/pam.d/system-auth", the password section of the file controls which PAM modules execute during a password change. Set the pam_unix.so module in the password section to include the argument sha512, as shown below:
    password    sufficient    pam_unix.so sha512 other arguments...
             

    This will help ensure when local users change their passwords, hashes for the new passwords will be generated using the SHA-512 algorithm. This is the default.
    Rationale:
    Passwords need to be protected at all times, and encryption is the standard method for protecting passwords. If passwords are not encrypted, they can be plainly read (i.e., clear text) and easily compromised. Passwords that are encrypted with a weak algorithm are no more protected than if they are kepy in plain text.

    This setting ensures user and group account administration utilities are configured to store only encrypted representations of passwords. Additionally, the crypt_style configuration option ensures the use of a strong hashing algorithm that makes password cracking attacks more difficult.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_set_password_hashing_algorithm_systemauth
    References:
    cis-csc1, 12, 15, 16, 5
    cjis5.6.2.2
    cobit5DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.10
    cui3.13.11
    disaCCI-000196, CCI-000803
    isa-62443-20094.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
    isa-62443-2013SR 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
    ism0418, 1055, 1402
    iso27001-2013A.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
    nistIA-5(c), IA-5(1)(c), CM-6(a)
    nist-csfPR.AC-1, PR.AC-6, PR.AC-7
    pcidssReq-8.2.1
    os-srgSRG-OS-000073-GPOS-00041, SRG-OS-000120-GPOS-00061
    anssiR68
    pcidss48.3.2

    Complexity:low
    Disruption:medium
    Reboot:false
    Strategy:configure
    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.6.2.2
      - NIST-800-171-3.13.11
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)(c)
      - NIST-800-53-IA-5(c)
      - PCI-DSS-Req-8.2.1
      - PCI-DSSv4-8.3.2
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - set_password_hashing_algorithm_systemauth
    
    - name: Set PAM's Password Hashing Algorithm - Check if /etc/pam.d/system-auth file
        is present
      ansible.builtin.stat:
        path: /etc/pam.d/system-auth
      register: result_pam_file_present
      when: '"pam" in ansible_facts.packages'
      tags:
      - CJIS-5.6.2.2
      - NIST-800-171-3.13.11
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)(c)
      - NIST-800-53-IA-5(c)
      - PCI-DSS-Req-8.2.1
      - PCI-DSSv4-8.3.2
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - set_password_hashing_algorithm_systemauth
    
    - name: Set PAM's Password Hashing Algorithm - Check the proper remediation for the
        system
      block:
    
      - name: Set PAM's Password Hashing Algorithm - Define the PAM file to be edited
          as a local fact
        ansible.builtin.set_fact:
          pam_file_path: /etc/pam.d/system-auth
    
      - name: Set PAM's Password Hashing Algorithm - Check if system relies on authselect
          tool
        ansible.builtin.stat:
          path: /usr/bin/authselect
        register: result_authselect_present
    
      - name: Set PAM's Password Hashing Algorithm - Ensure authselect custom profile
          is used if authselect is present
        block:
    
        - name: Set PAM's Password Hashing Algorithm - Check integrity of authselect current
            profile
          ansible.builtin.command:
            cmd: authselect check
          register: result_authselect_check_cmd
          changed_when: false
          failed_when: false
    
        - name: Set PAM's Password Hashing Algorithm - Informative message based on the
            authselect integrity check result
          ansible.builtin.assert:
            that:
            - result_authselect_check_cmd.rc == 0
            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 PAM's Password Hashing Algorithm - Get authselect current profile
          ansible.builtin.shell:
            cmd: authselect current -r | awk '{ print $1 }'
          register: result_authselect_profile
          changed_when: false
          when:
          - result_authselect_check_cmd is success
    
        - name: Set PAM's Password Hashing Algorithm - Define the current authselect profile
            as a local fact
          ansible.builtin.set_fact:
            authselect_current_profile: '{{ result_authselect_profile.stdout }}'
            authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
          when:
          - result_authselect_profile is not skipped
          - result_authselect_profile.stdout is match("custom/")
    
        - name: Set PAM's Password Hashing Algorithm - Define the new authselect custom
            profile as a local fact
          ansible.builtin.set_fact:
            authselect_current_profile: '{{ result_authselect_profile.stdout }}'
            authselect_custom_profile: custom/hardening
          when:
          - result_authselect_profile is not skipped
          - result_authselect_profile.stdout is not match("custom/")
    
        - name: Set PAM's Password Hashing Algorithm - Get authselect current features
            to also enable them in the custom profile
          ansible.builtin.shell:
            cmd: authselect current | tail -n+3 | awk '{ print $2 }'
          register: result_authselect_features
          changed_when: false
          when:
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")
    
        - name: Set PAM's Password Hashing Algorithm - Check if any custom profile with
            the same name was already created
          ansible.builtin.stat:
            path: /etc/authselect/{{ authselect_custom_profile }}
          register: result_authselect_custom_profile_present
          changed_when: false
          when:
          - authselect_current_profile is not match("custom/")
    
        - name: Set PAM's Password Hashing Algorithm - Create an authselect custom profile
            based on the current profile
          ansible.builtin.command:
            cmd: authselect create-profile hardening -b {{ authselect_current_profile
              }}
          when:
          - result_authselect_check_cmd is success
          - authselect_current_profile is not match("custom/")
          - not result_authselect_custom_profile_present.stat.exists
    
        - name: Set PAM's Password Hashing Algorithm - Ensure authselect changes are applied
          ansible.builtin.command:
            cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")
          - authselect_custom_profile is not match(authselect_current_profile)
    
        - name: Set PAM's Password Hashing Algorithm - Ensure the authselect custom profile
            is selected
          ansible.builtin.command:
            cmd: authselect select {{ authselect_custom_profile }}
          register: result_pam_authselect_select_profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - authselect_current_profile is not match("custom/")
          - authselect_custom_profile is not match(authselect_current_profile)
    
        - name: Set PAM's Password Hashing Algorithm - Restore the authselect features
            in the custom profile
          ansible.builtin.command:
            cmd: authselect enable-feature {{ item }}
          loop: '{{ result_authselect_features.stdout_lines }}'
          register: result_pam_authselect_restore_features
          when:
          - result_authselect_profile is not skipped
          - result_authselect_features is not skipped
          - result_pam_authselect_select_profile is not skipped
    
        - name: Set PAM's Password Hashing Algorithm - Ensure authselect changes are applied
          ansible.builtin.command:
            cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
          when:
          - result_authselect_check_cmd is success
          - result_authselect_profile is not skipped
          - result_pam_authselect_restore_features is not skipped
    
        - name: Set PAM's Password Hashing Algorithm - Change the PAM file to be edited
            according to the custom authselect profile
          ansible.builtin.set_fact:
            pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
              | basename }}
        when:
        - result_authselect_present.stat.exists
    
      - name: Set PAM's Password Hashing Algorithm - Check if expected PAM module line
          is present in {{ pam_file_path }}
        ansible.builtin.lineinfile:
          path: '{{ pam_file_path }}'
          regexp: ^\s*password\s+{{ 'sufficient' | regex_escape() }}\s+pam_unix.so\s*.*
          state: absent
        check_mode: true
        changed_when: false
        register: result_pam_line_present
    
      - name: Set PAM's Password Hashing Algorithm - Include or update the PAM module
          line in {{ pam_file_path }}
        block:
    
        - name: Set PAM's Password Hashing Algorithm - Check if required PAM module line
            is present in {{ pam_file_path }} with different control
          ansible.builtin.lineinfile:
            path: '{{ pam_file_path }}'
            regexp: ^\s*password\s+.*\s+pam_unix.so\s*
            state: absent
          check_mode: true
          changed_when: false
          register: result_pam_line_other_control_present
    
        - name: Set PAM's Password Hashing Algorithm - Ensure the correct control for
            the required PAM module line in {{ pam_file_path }}
          ansible.builtin.replace:
            dest: '{{ pam_file_path }}'
            regexp: ^(\s*password\s+).*(\bpam_unix.so.*)
            replace: \1sufficient \2
          register: result_pam_module_edit
          when:
          - result_pam_line_other_control_present.found == 1
    
        - name: Set PAM's Password Hashing Algorithm - Ensure the required PAM module
            line is included in {{ pam_file_path }}
          ansible.builtin.lineinfile:
            dest: '{{ pam_file_path }}'
            line: password    sufficient    pam_unix.so
          register: result_pam_module_add
          when:
          - result_pam_line_other_control_present.found == 0 or result_pam_line_other_control_present.found
            > 1
    
        - name: Set PAM's Password Hashing Algorithm - Ensure authselect changes are applied
          ansible.builtin.command:
            cmd: authselect apply-changes -b
          when:
          - result_authselect_present is defined
          - result_authselect_present.stat.exists
          - |-
            (result_pam_module_add is defined and result_pam_module_add.changed)
             or (result_pam_module_edit is defined and result_pam_module_edit.changed)
        when:
        - result_pam_line_present.found is defined
        - result_pam_line_present.found == 0
    
      - name: Set PAM's Password Hashing Algorithm - Check if the required PAM module
          option is present in {{ pam_file_path }}
        ansible.builtin.lineinfile:
          path: '{{ pam_file_path }}'
          regexp: ^\s*password\s+{{ 'sufficient' | regex_escape() }}\s+pam_unix.so\s*.*\ssha512\b
          state: absent
        check_mode: true
        changed_when: false
        register: result_pam_module_sha512_option_present
    
      - name: Set PAM's Password Hashing Algorithm - Ensure the "sha512" PAM option for
          "pam_unix.so" is included in {{ pam_file_path }}
        ansible.builtin.lineinfile:
          path: '{{ pam_file_path }}'
          backrefs: true
          regexp: ^(\s*password\s+{{ 'sufficient' | regex_escape() }}\s+pam_unix.so.*)
          line: \1 sha512
          state: present
        register: result_pam_sha512_add
        when:
        - result_pam_module_sha512_option_present.found == 0
    
      - name: Set PAM's Password Hashing Algorithm - Ensure authselect changes are applied
        ansible.builtin.command:
          cmd: authselect apply-changes -b
        when:
        - result_authselect_present.stat.exists
        - |-
          (result_pam_sha512_add is defined and result_pam_sha512_add.changed)
           or (result_pam_sha512_edit is defined and result_pam_sha512_edit.changed)
      when:
      - '"pam" in ansible_facts.packages'
      - result_pam_file_present.stat.exists
      tags:
      - CJIS-5.6.2.2
      - NIST-800-171-3.13.11
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)(c)
      - NIST-800-53-IA-5(c)
      - PCI-DSS-Req-8.2.1
      - PCI-DSSv4-8.3.2
      - configure_strategy
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - set_password_hashing_algorithm_systemauth
    

    # Remediation is applicable only in certain platforms
    if rpm --quiet -q pam; then
    
    if [ -e "/etc/pam.d/system-auth" ] ; then
        PAM_FILE_PATH="/etc/pam.d/system-auth"
        if [ -f /usr/bin/authselect ]; then
            
            if ! authselect check; then
            echo "
            authselect integrity check failed. Remediation aborted!
            This remediation could not be applied because an authselect profile was not selected or the selected profile is not intact.
            It is not recommended to manually edit the PAM files when authselect tool is available.
            In cases where the default authselect profile does not cover a specific demand, a custom authselect profile is recommended."
            exit 1
            fi
    
            CURRENT_PROFILE=$(authselect current -r | awk '{ print $1 }')
            # If not already in use, a custom profile is created preserving the enabled features.
            if [[ ! $CURRENT_PROFILE == custom/* ]]; then
                ENABLED_FEATURES=$(authselect current | tail -n+3 | awk '{ print $2 }')
                authselect create-profile hardening -b $CURRENT_PROFILE
                CURRENT_PROFILE="custom/hardening"
                
                authselect apply-changes -b --backup=before-hardening-custom-profile
                authselect select $CURRENT_PROFILE
                for feature in $ENABLED_FEATURES; do
                    authselect enable-feature $feature;
                done
                
                authselect apply-changes -b --backup=after-hardening-custom-profile
            fi
            PAM_FILE_NAME=$(basename "/etc/pam.d/system-auth")
            PAM_FILE_PATH="/etc/authselect/$CURRENT_PROFILE/$PAM_FILE_NAME"
    
            authselect apply-changes -b
        fi
        if ! grep -qP '^\s*password\s+'"sufficient"'\s+pam_unix.so\s*.*' "$PAM_FILE_PATH"; then
                # Line matching group + control + module was not found. Check group + module.
                if [ "$(grep -cP '^\s*password\s+.*\s+pam_unix.so\s*' "$PAM_FILE_PATH")" -eq 1 ]; then
                    # The control is updated only if one single line matches.
                    sed -i -E --follow-symlinks 's/^(\s*password\s+).*(\bpam_unix.so.*)/\1'"sufficient"' \2/' "$PAM_FILE_PATH"
                else
                    echo 'password    '"sufficient"'    pam_unix.so' >> "$PAM_FILE_PATH"
                fi
            fi
            # Check the option
            if ! grep -qP '^\s*password\s+'"sufficient"'\s+pam_unix.so\s*.*\ssha512\b' "$PAM_FILE_PATH"; then
                sed -i -E --follow-symlinks '/\s*password\s+'"sufficient"'\s+pam_unix.so.*/ s/$/ sha512/' "$PAM_FILE_PATH"
            fi
        if [ -f /usr/bin/authselect ]; then
            
            authselect apply-changes -b
        fi
    else
        echo "/etc/pam.d/system-auth was not found" >&2
    fi
    
    else
        >&2 echo 'Remediation is not applicable, nothing was done'
    fi
    
    Group   Protect Physical Console Access   Group contains 2 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.

    Rule   Require Authentication for Emergency Systemd Target   [ref]

    Emergency mode is intended as a system recovery method, providing a single user root access to the system during a failed boot sequence.

    By default, Emergency mode is protected by requiring a password and is set in /usr/lib/systemd/system/emergency.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_emergency_target_auth
    References:
    cis-csc1, 11, 12, 14, 15, 16, 18, 3, 5
    cobit5DSS05.02, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.06, DSS06.10
    cui3.1.1, 3.4.5
    disaCCI-000213
    hipaa164.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)
    isa-62443-20094.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
    isa-62443-2013SR 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
    ism0421, 0422, 0431, 0974, 1173, 1401, 1504, 1505, 1546, 1557, 1558, 1559, 1560, 1561
    iso27001-2013A.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
    nistIA-2, AC-3, CM-6(a)
    nist-csfPR.AC-1, PR.AC-4, PR.AC-6, PR.AC-7, PR.PT-3
    osppFIA_UAU.1
    os-srgSRG-OS-000080-GPOS-00048

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:restrict
    - name: Require emergency mode password
      lineinfile:
        create: true
        dest: /usr/lib/systemd/system/emergency.service
        regexp: ^#?ExecStart=
        line: ExecStart=-/bin/sh -c "/sbin/sulogin; /usr/bin/systemctl --fail --no-block
          default"
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - 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_emergency_target_auth
      - restrict_strategy
    

    # Remediation is applicable only in certain platforms
    if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
    
    service_file="/usr/lib/systemd/system/emergency.service"
    
    
    sulogin='/bin/sh -c "/sbin/sulogin; /usr/bin/systemctl --fail --no-block default"'
    
    
    if grep "^ExecStart=.*" "$service_file" ; then
        sed -i "s%^ExecStart=.*%ExecStart=-$sulogin%" "$service_file"
    else
        echo "ExecStart=-$sulogin" >> "$service_file"
    fi
    
    else
        >&2 echo 'Remediation is not applicable, nothing was done'
    fi
    

    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, 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
    References:
    cis-csc1, 11, 12, 14, 15, 16, 18, 3, 5
    cobit5DSS05.02, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.06, DSS06.10
    cui3.1.1, 3.4.5
    disaCCI-000213
    hipaa164.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)
    isa-62443-20094.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
    isa-62443-2013SR 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
    ism0421, 0422, 0431, 0974, 1173, 1401, 1504, 1505, 1546, 1557, 1558, 1559, 1560, 1561
    iso27001-2013A.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
    nerc-cipCIP-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
    nistIA-2, AC-3, CM-6(a)
    nist-csfPR.AC-1, PR.AC-4, PR.AC-6, PR.AC-7, PR.PT-3
    osppFIA_UAU.1
    os-srgSRG-OS-000080-GPOS-00048

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:restrict
    - name: Require single user mode password
      lineinfile:
        create: true
        dest: /usr/lib/systemd/system/rescue.service
        regexp: ^#?ExecStart=
        line: ExecStart=-/bin/sh -c "/sbin/sulogin; /usr/bin/systemctl --fail --no-block
          default"
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - 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='/bin/sh -c "/sbin/sulogin; /usr/bin/systemctl --fail --no-block default"'
    
    if grep "^ExecStart=.*" "$service_file" ; then
        sed -i "s%^ExecStart=.*%ExecStart=-$sulogin%" "$service_file"
    else
        echo "ExecStart=-$sulogin" >> "$service_file"
    fi
    
    else
        >&2 echo 'Remediation is not applicable, nothing was done'
    fi
    
    Group   Protect Accounts by Restricting Password-Based Login   Group contains 4 groups and 11 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 Account Expiration Parameters   Group contains 1 rule
    Group   Set Password Expiration Parameters   Group contains 2 rules
    [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

    Rule   Set Existing Passwords Maximum Age   [ref]

    Configure non-compliant accounts to enforce a 365-day maximum password lifetime restriction by running the following command:
    $ sudo chage -M 365
              USER
             
    Rationale:
    Any password, no matter how complex, can eventually be cracked. Therefore, passwords need to be changed periodically. If the operating system does not limit the lifetime of passwords and force users to change their passwords, there is the risk that the operating system passwords could be compromised.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_accounts_password_set_max_life_existing
    References:
    disaCCI-000199
    nistIA-5(f), IA-5(1)(d), CM-6(a)
    os-srgSRG-OS-000076-GPOS-00044
    pcidss48.3.9

    Rule   Set Existing Passwords Minimum Age   [ref]

    Configure non-compliant accounts to enforce a 24 hours/1 day minimum password lifetime by running the following command:
    $ sudo chage -m 1 USER
             
    Rationale:
    Enforcing a minimum password lifetime helps to prevent repeated password changes to defeat the password reuse or history enforcement requirement. If users are allowed to immediately and continually change their password, the password could be repeatedly changed in a short period of time to defeat the organization's policy regarding password reuse.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_accounts_password_set_min_life_existing
    References:
    disaCCI-000198
    nistIA-5(f), IA-5(1)(d), CM-6(a)
    os-srgSRG-OS-000075-GPOS-00043

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:restrict
    - name: XCCDF Value var_accounts_minimum_age_login_defs # promote to variable
      set_fact:
        var_accounts_minimum_age_login_defs: !!str 7
      tags:
        - always
    
    - name: Collect users with not correct minimum time period between password changes
      command: |
        awk -F':' '(/^[^:]+:[^!*]/ && ($4 < {{ var_accounts_minimum_age_login_defs }} || $4 == "")) {print $1}' /etc/shadow
      register: user_names
      tags:
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)(d)
      - NIST-800-53-IA-5(f)
      - accounts_password_set_min_life_existing
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
    
    - name: Change the minimum time period between password changes
      command: |
        chage -m {{ var_accounts_minimum_age_login_defs }} {{ item }}
      with_items: '{{ user_names.stdout_lines }}'
      when: user_names.stdout_lines | length > 0
      tags:
      - NIST-800-53-CM-6(a)
      - NIST-800-53-IA-5(1)(d)
      - NIST-800-53-IA-5(f)
      - accounts_password_set_min_life_existing
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:restrict
    
    var_accounts_minimum_age_login_defs='7'
    
    
    while IFS= read -r i; do
        
        chage -m $var_accounts_minimum_age_login_defs $i
    
    done <   <(awk -v var="$var_accounts_minimum_age_login_defs" -F: '(/^[^:]+:[^!*]/ && ($4 < var || $4 == "")) {print $1}' /etc/shadow)
    
    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   Verify No netrc Files Exist   [ref]

    The .netrc files contain login information used to auto-login into FTP servers and reside in the user's home directory. These files may contain unencrypted passwords to remote FTP servers making them susceptible to access by unauthorized users and should not be used. Any .netrc files should be removed.
    Rationale:
    Unencrypted passwords for remote FTP servers may be stored in .netrc files.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_no_netrc_files
    References:
    cis-csc1, 11, 12, 14, 15, 16, 18, 3, 5
    cobit5DSS05.02, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.06, DSS06.10
    disaCCI-000196
    isa-62443-20094.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
    isa-62443-2013SR 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
    iso27001-2013A.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
    nerc-cipCIP-003-8 R1.3, CIP-003-8 R3, CIP-003-8 R3.1, CIP-003-8 R3.2, CIP-003-8 R3.3, 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
    nistIA-5(h), IA-5(1)(c), CM-6(a), IA-5(7)
    nist-csfPR.AC-1, PR.AC-4, PR.AC-6, PR.AC-7, PR.PT-3
    Group   Restrict Root Logins   Group contains 4 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   Verify Only Root Has UID 0   [ref]

    If any account other than root has a UID of 0, this misconfiguration should be investigated and the accounts other than root should be removed or have their UID changed.
    If the account is associated with system commands or applications the UID should be changed to one greater than "0" but less than "1000." Otherwise assign a UID greater than "1000" that has not already been assigned.
    Rationale:
    An account has root authority if it has a UID of 0. Multiple accounts with a UID of 0 afford more opportunity for potential intruders to guess a password for a privileged account. Proper configuration of sudo is recommended to afford multiple system administrators access to root privileges in an accountable manner.
    Severity: 
    high
    Rule ID:xccdf_org.ssgproject.content_rule_accounts_no_uid_except_zero
    References:
    cis-csc1, 12, 13, 14, 15, 16, 18, 3, 5
    cobit5APO01.06, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.02, DSS06.03, DSS06.10
    cui3.1.1, 3.1.5
    disaCCI-000366
    isa-62443-20094.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
    isa-62443-2013SR 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
    iso27001-2013A.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
    nerc-cipCIP-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
    nistIA-2, AC-6(5), IA-4(b)
    nist-csfPR.AC-1, PR.AC-4, PR.AC-6, PR.AC-7, PR.DS-5
    pcidssReq-8.5
    os-srgSRG-OS-000480-GPOS-00227
    pcidss48.2.1

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:restrict
    - name: Get all /etc/passwd file entries
      getent:
        database: passwd
        split: ':'
      tags:
      - NIST-800-171-3.1.1
      - NIST-800-171-3.1.5
      - NIST-800-53-AC-6(5)
      - NIST-800-53-IA-2
      - NIST-800-53-IA-4(b)
      - PCI-DSS-Req-8.5
      - PCI-DSSv4-8.2.1
      - accounts_no_uid_except_zero
      - high_severity
      - low_complexity
      - low_disruption
      - no_reboot_needed
      - restrict_strategy
    
    - name: Lock the password of the user accounts other than root with uid 0
      command: passwd -l {{ item.key }}
      loop: '{{ getent_passwd | dict2items | rejectattr(''key'', ''search'', ''root'')
        | list }}'
      when: item.value.1  == '0'
      tags:
      - NIST-800-171-3.1.1
      - NIST-800-171-3.1.5
      - NIST-800-53-AC-6(5)
      - NIST-800-53-IA-2
      - NIST-800-53-IA-4(b)
      - PCI-DSS-Req-8.5
      - PCI-DSSv4-8.2.1
      - accounts_no_uid_except_zero
      - high_severity
      - low_complexity
      - low_disruption
      - no_reboot_needed
      - restrict_strategy
    

    awk -F: '$3 == 0 && $1 != "root" { print $1 }' /etc/passwd | xargs --no-run-if-empty --max-lines=1 passwd -l
    

    Rule   Verify Root Has A Primary GID 0   [ref]

    The root user should have a primary group of 0.
    Rationale:
    To help ensure that root-owned files are not inadvertently exposed to other users.
    Severity: 
    high
    Rule ID:xccdf_org.ssgproject.content_rule_accounts_root_gid_zero
    References:
    pcidssReq-8.1.1
    pcidss48.2.1

    Rule   Ensure that System Accounts Do Not Run a Shell Upon Login   [ref]

    Some accounts are not associated with a human user of the system, and exist to perform some administrative functions. Should an attacker be able to log into these accounts, they should not be granted access to a shell.

    The login shell for each local account is stored in the last field of each line in /etc/passwd. System accounts are those user accounts with a user ID less than 1000. The user ID is stored in the third field. If any system account other than root has a login shell, disable it with the command:
    $ sudo usermod -s /sbin/nologin account
             
    Warning:  Do not perform the steps in this section on the root account. Doing so might cause the system to become inaccessible.
    Rationale:
    Ensuring shells are not given to system accounts upon login makes it more difficult for attackers to make use of system accounts.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_no_shelllogin_for_systemaccounts
    References:
    cis-csc1, 12, 13, 14, 15, 16, 18, 3, 5, 7, 8
    cobit5DSS01.03, DSS03.05, DSS05.04, DSS05.05, DSS05.07, DSS06.03
    disaCCI-000366
    isa-62443-20094.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4
    isa-62443-2013SR 1.1, 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 6.2
    ism1491
    iso27001-2013A.12.4.1, A.12.4.3, 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
    nistAC-6, CM-6(a), CM-6(b), CM-6.1(iv)
    nist-csfDE.CM-1, DE.CM-3, PR.AC-1, PR.AC-4, PR.AC-6
    os-srgSRG-OS-000480-GPOS-00227
    pcidss48.2.2

    Complexity:low
    Disruption:medium
    Reboot:false
    Strategy:restrict
    - name: Ensure that System Accounts Do Not Run a Shell Upon Login - Get All Local
        Users From /etc/passwd
      ansible.builtin.getent:
        database: passwd
        split: ':'
      tags:
      - NIST-800-53-AC-6
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-6(b)
      - NIST-800-53-CM-6.1(iv)
      - PCI-DSSv4-8.2.2
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - no_shelllogin_for_systemaccounts
      - restrict_strategy
    
    - name: Ensure that System Accounts Do Not Run a Shell Upon Login - Create local_users
        Variable From getent_passwd Facts
      ansible.builtin.set_fact:
        local_users: '{{ ansible_facts.getent_passwd | dict2items }}'
      tags:
      - NIST-800-53-AC-6
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-6(b)
      - NIST-800-53-CM-6.1(iv)
      - PCI-DSSv4-8.2.2
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - no_shelllogin_for_systemaccounts
      - restrict_strategy
    
    - name: Ensure that System Accounts Do Not Run a Shell Upon Login -  Disable Login
        Shell for System Accounts
      ansible.builtin.user:
        name: '{{ item.key }}'
        shell: /sbin/nologin
      loop: '{{ local_users }}'
      when:
      - item.key not in ['root']
      - item.value[1]|int < 1000
      - item.value[5] not in ['/sbin/shutdown', '/sbin/halt', '/bin/sync']
      tags:
      - NIST-800-53-AC-6
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-6(b)
      - NIST-800-53-CM-6.1(iv)
      - PCI-DSSv4-8.2.2
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - no_shelllogin_for_systemaccounts
      - restrict_strategy
    

    Complexity:low
    Disruption:medium
    Reboot:false
    Strategy:restrict
    
    readarray -t systemaccounts < <(awk -F: '($3 < 1000 && $3 != root \
      && $7 != "\/sbin\/shutdown" && $7 != "\/sbin\/halt" && $7 != "\/bin\/sync") \
      { print $1 }' /etc/passwd)
    
    for systemaccount in "${systemaccounts[@]}"; do
        usermod -s /sbin/nologin "$systemaccount"
    done
    

    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
    Warning:  Members of "wheel" or GID 0 groups are checked by default if the group option is not set for pam_wheel.so module. Therefore, members of these groups should be manually checked or a different group should be informed according to the site policy.
    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
    References:
    osppFMT_SMF_EXT.1.1
    os-srgSRG-OS-000373-GPOS-00156, SRG-OS-000312-GPOS-00123

    Rule   Ensure All Groups on the System Have Unique Group ID   [ref]

    Change the group name or delete groups, so each has a unique id.
    Warning:  Automatic remediation of this control is not available due to the unique requirements of each system.
    Rationale:
    To assure accountability and prevent unauthenticated access, groups must be identified uniquely to prevent potential misuse and compromise of the system.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_group_unique_id
    References:
    disaCCI-000764
    os-srgSRG-OS-000104-GPOS-00051
    pcidss48.2.1

    Rule   Ensure All Groups on the System Have Unique Group Names   [ref]

    Change the group name or delete groups, so each has a unique name.
    Warning:  Automatic remediation of this control is not available due to the unique requirements of each system.
    Rationale:
    To assure accountability and prevent unauthenticated access, groups must be identified uniquely to prevent potential misuse and compromise of the system.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_group_unique_name
    References:
    pcidss48.2.1
    Group   Secure Session Configuration Files for Login Accounts   Group contains 2 groups and 6 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 No Dangerous Directories Exist in Root's Path   Group contains 2 rules
    [ref]   The active path of the root account can be obtained by starting a new root shell and running:
    # echo $PATH
    This will produce a colon-separated list of directories in the path.

    Certain path elements could be considered dangerous, as they could lead to root executing unknown or untrusted programs, which could contain malicious code. Since root may sometimes work inside untrusted directories, the . character, which represents the current directory, should never be in the root path, nor should any directory which can be written to by an unprivileged or semi-privileged (system) user.

    It is a good practice for administrators to always execute privileged commands by typing the full path to the command.

    Rule   Ensure that Root's Path Does Not Include World or Group-Writable Directories   [ref]

    For each element in root's path, run:
    # ls -ld DIR
             
    and ensure that write permissions are disabled for group and other.
    Rationale:
    Such entries increase the risk that root could execute code provided by unprivileged users, and potentially malicious code.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_accounts_root_path_dirs_no_write
    References:
    cis-csc11, 3, 9
    cobit5BAI10.01, BAI10.02, BAI10.03, BAI10.05
    disaCCI-000366
    isa-62443-20094.3.4.3.2, 4.3.4.3.3
    isa-62443-2013SR 7.6
    iso27001-2013A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4
    nistCM-6(a), CM-6(a)
    nist-csfPR.IP-1

    Rule   Ensure that Root's Path Does Not Include Relative Paths or Null Directories   [ref]

    Ensure that none of the directories in root's path is equal to a single . character, or that it contains any instances that lead to relative path traversal, such as .. or beginning a path without the slash (/) character. Also ensure that there are no "empty" elements in the path, such as in these examples:
    PATH=:/bin
    PATH=/bin:
    PATH=/bin::/sbin
    These empty elements have the same effect as a single . character.
    Rationale:
    Including these entries increases the risk that root could execute code from an untrusted location.
    Severity: 
    unknown
    Rule ID:xccdf_org.ssgproject.content_rule_root_path_no_dot
    References:
    cis-csc11, 3, 9
    cobit5BAI10.01, BAI10.02, BAI10.03, BAI10.05
    disaCCI-000366
    isa-62443-20094.3.4.3.2, 4.3.4.3.3
    isa-62443-2013SR 7.6
    iso27001-2013A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4
    nistCM-6(a), CM-6(a)
    nist-csfPR.IP-1
    Group   Ensure that Users Have Sensible Umask Values   Group contains 1 rule
    [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 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
             
    Note that /etc/profile also reads scrips within /etc/profile.d directory. These scripts are also valid files to set umask value. Therefore, they should also be considered during the check and properly remediated, if necessary.
    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
    References:
    cis-csc18
    cobit5APO13.01, BAI03.01, BAI03.02, BAI03.03
    disaCCI-000366
    isa-62443-20094.3.4.3.3
    iso27001-2013A.14.1.1, A.14.2.1, A.14.2.5, A.6.1.5
    nerc-cipCIP-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
    nistAC-6(1), CM-6(a)
    nist-csfPR.IP-2
    os-srgSRG-OS-000480-GPOS-00228, SRG-OS-000480-GPOS-00227
    anssiR36

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:restrict
    - name: XCCDF Value var_accounts_user_umask # promote to variable
      set_fact:
        var_accounts_user_umask: !!str 027
      tags:
        - always
    
    - name: Ensure the Default Umask is Set Correctly in /etc/profile - Locate Profile
        Configuration Files Where umask Is Defined
      ansible.builtin.find:
        paths:
        - /etc/profile.d
        patterns:
        - sh.local
        - '*.sh'
        contains: ^[\s]*umask\s+\d+
      register: result_profile_d_files
      tags:
      - 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: Ensure the Default Umask is Set Correctly in /etc/profile - Replace Existing
        umask Value in Files From /etc/profile.d
      ansible.builtin.replace:
        path: '{{ item.path }}'
        regexp: ^(\s*)umask\s+\d+
        replace: \1umask {{ var_accounts_user_umask }}
      loop: '{{ result_profile_d_files.files }}'
      register: result_umask_replaced_profile_d
      when: result_profile_d_files.matched
      tags:
      - 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: Ensure the Default Umask is Set Correctly in /etc/profile - Ensure umask Is
        Set in /etc/profile if Not Already Set Elsewhere
      ansible.builtin.lineinfile:
        create: true
        mode: 420
        path: /etc/profile
        line: umask {{ var_accounts_user_umask }}
      when: not result_profile_d_files.matched
      tags:
      - 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: Ensure the Default Umask is Set Correctly in /etc/profile - Ensure umask Value
        For All Existing umask Definition in /etc/profile
      ansible.builtin.replace:
        path: /etc/profile
        regexp: ^(\s*)umask\s+\d+
        replace: \1umask {{ var_accounts_user_umask }}
      register: result_umask_replaced_profile
      tags:
      - 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
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:restrict
    
    var_accounts_user_umask='027'
    
    
    readarray -t profile_files < <(find /etc/profile.d/ -type f -name '*.sh' -or -name 'sh.local')
    
    for file in "${profile_files[@]}" /etc/profile; do
      grep -qE '^[^#]*umask' "$file" && sed -i -E "s/^(\s*umask\s*)[0-7]+/\1$var_accounts_user_umask/g" "$file"
    done
    
    if ! grep -qrE '^[^#]*umask' /etc/profile*; then
      echo "umask $var_accounts_user_umask" >> /etc/profile
    fi
    

    Rule   Set Interactive Session Timeout   [ref]

    Setting the TMOUT option in /etc/profile ensures that all user sessions will terminate based on inactivity. The value of TMOUT should be exported and read only. The TMOUT setting in a file loaded by /etc/profile, e.g. /etc/profile.d/tmout.sh should read as follows:
    typeset -xr TMOUT=900
            
    or
    declare -xr TMOUT=900
            
    Using the typeset keyword is preferred for wider compatibility with ksh and other shells.
    Rationale:
    Terminating an idle session within a short time period reduces the window of opportunity for unauthorized personnel to take control of a management session enabled on the console or console port that has been left unattended.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_accounts_tmout
    References:
    cis-csc1, 12, 15, 16
    cobit5DSS05.04, DSS05.10, DSS06.10
    cui3.1.11
    disaCCI-000057, CCI-001133, CCI-002361
    isa-62443-20094.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
    isa-62443-2013SR 1.1, SR 1.10, SR 1.2, SR 1.5, SR 1.7, SR 1.8, SR 1.9
    iso27001-2013A.18.1.4, A.9.2.1, A.9.2.4, A.9.3.1, A.9.4.2, A.9.4.3
    nerc-cipCIP-004-6 R2.2.3, CIP-007-3 R5.1, CIP-007-3 R5.2, CIP-007-3 R5.3.1, CIP-007-3 R5.3.2, CIP-007-3 R5.3.3
    nistAC-12, SC-10, AC-2(5), CM-6(a)
    nist-csfPR.AC-7
    osppFMT_MOF_EXT.1
    os-srgSRG-OS-000163-GPOS-00072, SRG-OS-000029-GPOS-00010
    anssiR32
    pcidss48.6.1

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:restrict
    - name: XCCDF Value var_accounts_tmout # promote to variable
      set_fact:
        var_accounts_tmout: !!str 900
      tags:
        - always
    
    - name: Correct any occurrence of TMOUT in /etc/profile
      replace:
        path: /etc/profile
        regexp: ^[^#].*TMOUT=.*
        replace: typeset -xr TMOUT={{ var_accounts_tmout }}
      register: profile_replaced
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - NIST-800-171-3.1.11
      - NIST-800-53-AC-12
      - NIST-800-53-AC-2(5)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SC-10
      - PCI-DSSv4-8.6.1
      - accounts_tmout
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
    
    - name: Set Interactive Session Timeout
      lineinfile:
        path: /etc/profile.d/tmout.sh
        create: true
        regexp: TMOUT=
        line: typeset -xr TMOUT={{ var_accounts_tmout }}
        state: present
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - NIST-800-171-3.1.11
      - NIST-800-53-AC-12
      - NIST-800-53-AC-2(5)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-SC-10
      - PCI-DSSv4-8.6.1
      - accounts_tmout
      - 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
    
    var_accounts_tmout='900'
    
    
    # if 0, no occurence of tmout found, if 1, occurence found
    tmout_found=0
    
    
    for f in /etc/profile /etc/profile.d/*.sh; do
    
        if grep --silent '^[^#].*TMOUT' $f; then
            sed -i -E "s/^(.*)TMOUT\s*=\s*(\w|\$)*(.*)$/typeset -xr TMOUT=$var_accounts_tmout\3/g" $f
            tmout_found=1
        fi
    done
    
    if [ $tmout_found -eq 0 ]; then
            echo -e "\n# Set TMOUT to $var_accounts_tmout per security requirements" >> /etc/profile.d/tmout.sh
            echo "typeset -xr TMOUT=$var_accounts_tmout" >> /etc/profile.d/tmout.sh
    fi
    
    else
        >&2 echo 'Remediation is not applicable, nothing was done'
    fi
    

    Rule   All Interactive User Home Directories Must Be Group-Owned By The Primary Group   [ref]

    Change the group owner of interactive users home directory to the group found in /etc/passwd. To change the group owner of interactive users home directory, use the following command:
    $ sudo chgrp USER_GROUP /home/USER
            
    This rule ensures every home directory related to an interactive user is group-owned by an interactive user. It also ensures that interactive users are group-owners of one and only one home directory.
    Warning:  Due to OVAL limitation, this rule can report a false negative in a specific situation where two interactive users swap the group-ownership of their respective home directories.
    Rationale:
    If the Group Identifier (GID) of a local interactive users home directory is not the same as the primary GID of the user, this would allow unauthorized access to the users files, and users that share the same group may not be able to access files that they legitimately should.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_groupownership_home_directories
    References:
    disaCCI-000366
    os-srgSRG-OS-000480-GPOS-00227

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:restrict
    - name: Get all local users from /etc/passwd
      ansible.builtin.getent:
        database: passwd
        split: ':'
      tags:
      - file_groupownership_home_directories
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
    
    - name: Create local_users variable from the getent output
      ansible.builtin.set_fact:
        local_users: '{{ ansible_facts.getent_passwd|dict2items }}'
      tags:
      - file_groupownership_home_directories
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
    
    - name: Test for existence of home directories to avoid creating them, but only fixing
        group ownership
      ansible.builtin.stat:
        path: '{{ item.value[4] }}'
      register: path_exists
      loop: '{{ local_users }}'
      when:
      - item.value[1]|int >= 1000
      - item.value[1]|int != 65534
      tags:
      - file_groupownership_home_directories
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
    
    - name: Ensure interactive local users are the group-owners of their respective home
        directories
      ansible.builtin.file:
        path: '{{ item.0.value[4] }}'
        group: '{{ item.0.value[2] }}'
      loop: '{{ local_users|zip(path_exists.results)|list }}'
      when: item.1.stat is defined and item.1.stat.exists
      tags:
      - file_groupownership_home_directories
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:restrict
    
    awk -F':' '{ if ($3 >= 1000 && $3 != 65534) system("chgrp -f " $4" "$6) }' /etc/passwd
    

    Rule   All Interactive User Home Directories Must Be Owned By The Primary User   [ref]

    Change the owner of interactive users home directories to that correct owner. To change the owner of a interactive users home directory, use the following command:
    $ sudo chown USER /home/USER
            
    This rule ensures every home directory related to an interactive user is owned by an interactive user. It also ensures that interactive users are owners of one and only one home directory.
    Warning:  Due to OVAL limitation, this rule can report a false negative in a specific situation where two interactive users swap the ownership of their respective home directories.
    Rationale:
    If a local interactive user does not own their home directory, unauthorized users could access or modify the user's files, and the users may not be able to access their own files.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_ownership_home_directories
    References:
    disaCCI-000366
    os-srgSRG-OS-000480-GPOS-00227

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:restrict
    - name: Get all local users from /etc/passwd
      ansible.builtin.getent:
        database: passwd
        split: ':'
      tags:
      - file_ownership_home_directories
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
    
    - name: Create local_users variable from the getent output
      ansible.builtin.set_fact:
        local_users: '{{ ansible_facts.getent_passwd|dict2items }}'
      tags:
      - file_ownership_home_directories
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
    
    - name: Test for existence of home directories to avoid creating them, but only fixing
        ownership
      ansible.builtin.stat:
        path: '{{ item.value[4] }}'
      register: path_exists
      loop: '{{ local_users }}'
      when:
      - item.value[1]|int >= 1000
      - item.value[1]|int != 65534
      tags:
      - file_ownership_home_directories
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
    
    - name: Ensure interactive local users are the owners of their respective home directories
      ansible.builtin.file:
        path: '{{ item.0.value[4] }}'
        owner: '{{ item.0.value[1] }}'
      loop: '{{ local_users|zip(path_exists.results)|list }}'
      when: item.1.stat is defined and item.1.stat.exists
      tags:
      - file_ownership_home_directories
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:restrict
    
    awk -F':' '{ if ($3 >= 1000 && $3 != 65534) system("chown -f " $3" "$6) }' /etc/passwd
    
    Group   GRUB2 bootloader configuration   Group contains 1 group and 4 rules
    [ref]   During the boot process, the boot loader is responsible for starting the execution of the kernel and passing options to it. The boot loader allows for the selection of different kernels - possibly on different partitions or media. The default OpenEmbedded boot loader for x86 systems is called GRUB2. Options it can pass to the kernel include single-user mode, which provides root access without any authentication, and the ability to disable SELinux. To prevent local users from modifying the boot parameters and endangering security, protect the boot loader configuration with a password and ensure its configuration file's permissions are set properly.
    Group   Non-UEFI GRUB2 bootloader configuration   Group contains 4 rules
    [ref]   Non-UEFI GRUB2 bootloader configuration

    Rule   Verify /boot/grub2/grub.cfg Group Ownership   [ref]

    The file /boot/grub2/grub.cfg should be group-owned by the root group to prevent destruction or modification of the file. To properly set the group owner of /boot/grub2/grub.cfg, run the command:
    $ sudo chgrp root /boot/grub2/grub.cfg
    Rationale:
    The root group is a highly-privileged group. Furthermore, the group-owner of this file should not have any access privileges anyway.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_groupowner_grub2_cfg
    References:
    cis-csc12, 13, 14, 15, 16, 18, 3, 5
    cjis5.5.2.2
    cobit5APO01.06, DSS05.04, DSS05.07, DSS06.02
    cui3.4.5
    disaCCI-000225
    hipaa164.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)
    isa-62443-20094.3.3.7.3
    isa-62443-2013SR 2.1, SR 5.2
    iso27001-2013A.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
    nistCM-6(a), AC-6(1)
    nist-csfPR.AC-4, PR.DS-5
    pcidssReq-7.1
    os-srgSRG-OS-000480-GPOS-00227
    anssiR29
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.5.2.2
      - NIST-800-171-3.4.5
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-7.1
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_groupowner_grub2_cfg
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    
    - name: Test for existence /boot/grub2/grub.cfg
      stat:
        path: /boot/grub2/grub.cfg
      register: file_exists
      when:
      - '"/boot/efi" not in ansible_mounts | map(attribute="mount") | list'
      - '"grub2-common" in ansible_facts.packages'
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - CJIS-5.5.2.2
      - NIST-800-171-3.4.5
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-7.1
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_groupowner_grub2_cfg
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    
    - name: Ensure group owner 0 on /boot/grub2/grub.cfg
      file:
        path: /boot/grub2/grub.cfg
        group: '0'
      when:
      - '"/boot/efi" not in ansible_mounts | map(attribute="mount") | list'
      - '"grub2-common" in ansible_facts.packages'
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - file_exists.stat is defined and file_exists.stat.exists
      tags:
      - CJIS-5.5.2.2
      - NIST-800-171-3.4.5
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-7.1
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_groupowner_grub2_cfg
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    # Remediation is applicable only in certain platforms
    if [ ! -d /sys/firmware/efi ] && rpm --quiet -q grub2-common && { [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; }; then
    
    chgrp 0 /boot/grub2/grub.cfg
    
    else
        >&2 echo 'Remediation is not applicable, nothing was done'
    fi
    

    Rule   Verify /boot/grub2/grub.cfg User Ownership   [ref]

    The file /boot/grub2/grub.cfg should be owned by the root user to prevent destruction or modification of the file. To properly set the owner of /boot/grub2/grub.cfg, run the command:
    $ sudo chown root /boot/grub2/grub.cfg 
    Rationale:
    Only root should be able to modify important boot parameters.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_owner_grub2_cfg
    References:
    cis-csc12, 13, 14, 15, 16, 18, 3, 5
    cjis5.5.2.2
    cobit5APO01.06, DSS05.04, DSS05.07, DSS06.02
    cui3.4.5
    disaCCI-000225
    hipaa164.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)
    isa-62443-20094.3.3.7.3
    isa-62443-2013SR 2.1, SR 5.2
    iso27001-2013A.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
    nistCM-6(a), AC-6(1)
    nist-csfPR.AC-4, PR.DS-5
    pcidssReq-7.1
    os-srgSRG-OS-000480-GPOS-00227
    anssiR29
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - CJIS-5.5.2.2
      - NIST-800-171-3.4.5
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-7.1
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_owner_grub2_cfg
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    
    - name: Test for existence /boot/grub2/grub.cfg
      stat:
        path: /boot/grub2/grub.cfg
      register: file_exists
      when:
      - '"/boot/efi" not in ansible_mounts | map(attribute="mount") | list'
      - '"grub2-common" in ansible_facts.packages'
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - CJIS-5.5.2.2
      - NIST-800-171-3.4.5
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-7.1
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_owner_grub2_cfg
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    
    - name: Ensure owner 0 on /boot/grub2/grub.cfg
      file:
        path: /boot/grub2/grub.cfg
        owner: '0'
      when:
      - '"/boot/efi" not in ansible_mounts | map(attribute="mount") | list'
      - '"grub2-common" in ansible_facts.packages'
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - file_exists.stat is defined and file_exists.stat.exists
      tags:
      - CJIS-5.5.2.2
      - NIST-800-171-3.4.5
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-7.1
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_owner_grub2_cfg
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    # Remediation is applicable only in certain platforms
    if [ ! -d /sys/firmware/efi ] && rpm --quiet -q grub2-common && { [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; }; then
    
    chown 0 /boot/grub2/grub.cfg
    
    else
        >&2 echo 'Remediation is not applicable, nothing was done'
    fi
    

    Rule   Verify /boot/grub2/grub.cfg Permissions   [ref]

    File permissions for /boot/grub2/grub.cfg should be set to 600. To properly set the permissions of /boot/grub2/grub.cfg, run the command:
    $ sudo chmod 600 /boot/grub2/grub.cfg
    Rationale:
    Proper permissions ensure that only the root user can modify important boot parameters.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_permissions_grub2_cfg
    References:
    cis-csc12, 13, 14, 15, 16, 18, 3, 5
    cobit5APO01.06, DSS05.04, DSS05.07, DSS06.02
    cui3.4.5
    disaCCI-000225
    hipaa164.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)
    isa-62443-20094.3.3.7.3
    isa-62443-2013SR 2.1, SR 5.2
    iso27001-2013A.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
    nistCM-6(a), AC-6(1)
    nist-csfPR.AC-4, PR.DS-5
    anssiR29
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - NIST-800-171-3.4.5
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_permissions_grub2_cfg
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    
    - name: Test for existence /boot/grub2/grub.cfg
      stat:
        path: /boot/grub2/grub.cfg
      register: file_exists
      when:
      - '"/boot/efi" not in ansible_mounts | map(attribute="mount") | list'
      - '"grub2-common" in ansible_facts.packages'
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - NIST-800-171-3.4.5
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_permissions_grub2_cfg
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    
    - name: Ensure permission u-xs,g-xwrs,o-xwrt on /boot/grub2/grub.cfg
      file:
        path: /boot/grub2/grub.cfg
        mode: u-xs,g-xwrs,o-xwrt
      when:
      - '"/boot/efi" not in ansible_mounts | map(attribute="mount") | list'
      - '"grub2-common" in ansible_facts.packages'
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - file_exists.stat is defined and file_exists.stat.exists
      tags:
      - NIST-800-171-3.4.5
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_permissions_grub2_cfg
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    # Remediation is applicable only in certain platforms
    if [ ! -d /sys/firmware/efi ] && rpm --quiet -q grub2-common && { [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; }; then
    
    chmod u-xs,g-xwrs,o-xwrt /boot/grub2/grub.cfg
    
    else
        >&2 echo 'Remediation is not applicable, nothing was done'
    fi
    

    Rule   Set Boot Loader Password in grub2   [ref]

    The grub2 boot loader should have a superuser account and password protection enabled to protect boot-time settings.

    Since plaintext passwords are a security risk, generate a hash for the password by running the following command:
    # grub2-setpassword
    When prompted, enter the password that was selected.

    Warning:  To prevent hard-coded passwords, automatic remediation of this control is not available. Remediation must be automated as a component of machine provisioning, or followed manually as outlined above. Also, do NOT manually add the superuser account and password to the grub.cfg file as the grub2-mkconfig command overwrites this file.
    Rationale:
    Password protection on the boot loader configuration ensures users with physical access cannot trivially alter important bootloader settings. These include which kernel to use, and whether to enter single-user mode.
    Severity: 
    high
    Rule ID:xccdf_org.ssgproject.content_rule_grub2_password
    References:
    cis-csc1, 11, 12, 14, 15, 16, 18, 3, 5
    cobit5DSS05.02, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.06, DSS06.10
    cui3.4.5
    disaCCI-000213
    hipaa164.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)
    isa-62443-20094.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
    isa-62443-2013SR 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
    iso27001-2013A.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
    nistCM-6(a)
    nist-csfPR.AC-1, PR.AC-4, PR.AC-6, PR.AC-7, PR.PT-3
    osppFIA_UAU.1
    os-srgSRG-OS-000080-GPOS-00048
    anssiR5
    Group   Configure Syslog   Group contains 1 group and 3 rules
    [ref]   The syslog service has been the default Unix logging mechanism for many years. It has a number of downsides, including inconsistent log format, lack of authentication for received messages, and lack of authentication, encryption, or reliable transport for messages sent over a network. However, due to its long history, syslog is a de facto standard which is supported by almost all Unix applications.

    In OpenEmbedded, rsyslog has replaced ksyslogd as the syslog daemon of choice, and it includes some additional security features such as reliable, connection-oriented (i.e. TCP) transmission of logs, the option to log to database formats, and the encryption of log data en route to a central logging server. This section discusses how to configure rsyslog for best effect, and how to use tools provided with the system to maintain and monitor logs.
    Group   systemd-journald   Group contains 3 rules
    [ref]   systemd-journald is a system service that collects and stores logging data. It creates and maintains structured, indexed journals based on logging information that is received from a variety of sources. For more information on systemd-journald and additional systemd-journald configuration options, see https://systemd.io/.

    Rule   Ensure journald is configured to compress large log files   [ref]

    The journald system can compress large log files to avoid fill the system disk.
    Rationale:
    Log files that are not properly compressed run the risk of growing so large that they fill up the log partition. Valuable logging information could be lost if the log partition becomes full.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_journald_compress

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:restrict
    - name: Setting unquoted shell-style assignment of 'Compress' to 'yes' in '/etc/systemd/journald.conf'
      block:
    
      - name: Check for duplicate values
        lineinfile:
          path: /etc/systemd/journald.conf
          create: true
          regexp: ^\s*Compress=
          state: absent
        check_mode: true
        changed_when: false
        register: dupes
    
      - name: Deduplicate values from /etc/systemd/journald.conf
        lineinfile:
          path: /etc/systemd/journald.conf
          create: true
          regexp: ^\s*Compress=
          state: absent
        when: dupes.found is defined and dupes.found > 1
    
      - name: Insert correct line to /etc/systemd/journald.conf
        lineinfile:
          path: /etc/systemd/journald.conf
          create: true
          regexp: ^\s*Compress=
          line: Compress=yes
          state: present
          insertbefore: ^# Compress
          validate: /usr/bin/bash -n %s
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - journald_compress
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:restrict
    # Remediation is applicable only in certain platforms
    if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
    
    if [ -e "/etc/systemd/journald.conf" ] ; then
        
        LC_ALL=C sed -i "/^\s*Compress\s*=\s*/d" "/etc/systemd/journald.conf"
    else
        touch "/etc/systemd/journald.conf"
    fi
    # make sure file has newline at the end
    sed -i -e '$a\' "/etc/systemd/journald.conf"
    
    cp "/etc/systemd/journald.conf" "/etc/systemd/journald.conf.bak"
    # Insert before the line matching the regex '^#\s*Compress'.
    line_number="$(LC_ALL=C grep -n "^#\s*Compress" "/etc/systemd/journald.conf.bak" | LC_ALL=C sed 's/:.*//g')"
    if [ -z "$line_number" ]; then
        # There was no match of '^#\s*Compress', insert at
        # the end of the file.
        printf '%s\n' "Compress=yes" >> "/etc/systemd/journald.conf"
    else
        head -n "$(( line_number - 1 ))" "/etc/systemd/journald.conf.bak" > "/etc/systemd/journald.conf"
        printf '%s\n' "Compress=yes" >> "/etc/systemd/journald.conf"
        tail -n "+$(( line_number ))" "/etc/systemd/journald.conf.bak" >> "/etc/systemd/journald.conf"
    fi
    # Clean up after ourselves.
    rm "/etc/systemd/journald.conf.bak"
    
    else
        >&2 echo 'Remediation is not applicable, nothing was done'
    fi
    

    Rule   Ensure journald is configured to send logs to rsyslog   [ref]

    Data from journald may be stored in volatile memory or persisted locally. Utilities exist to accept remote export of journald logs.
    Rationale:
    Storing log data on a remote host protects log integrity from local attacks. If an attacker gains root access on the local system, they could tamper with or remove log data that is stored on the local system.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_journald_forward_to_syslog

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:restrict
    - name: Setting unquoted shell-style assignment of 'ForwardToSyslog' to 'yes' in '/etc/systemd/journald.conf'
      block:
    
      - name: Check for duplicate values
        lineinfile:
          path: /etc/systemd/journald.conf
          create: true
          regexp: ^\s*ForwardToSyslog=
          state: absent
        check_mode: true
        changed_when: false
        register: dupes
    
      - name: Deduplicate values from /etc/systemd/journald.conf
        lineinfile:
          path: /etc/systemd/journald.conf
          create: true
          regexp: ^\s*ForwardToSyslog=
          state: absent
        when: dupes.found is defined and dupes.found > 1
    
      - name: Insert correct line to /etc/systemd/journald.conf
        lineinfile:
          path: /etc/systemd/journald.conf
          create: true
          regexp: ^\s*ForwardToSyslog=
          line: ForwardToSyslog=yes
          state: present
          insertbefore: ^# ForwardToSyslog
          validate: /usr/bin/bash -n %s
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - journald_forward_to_syslog
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:restrict
    # Remediation is applicable only in certain platforms
    if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
    
    if [ -e "/etc/systemd/journald.conf" ] ; then
        
        LC_ALL=C sed -i "/^\s*ForwardToSyslog\s*=\s*/d" "/etc/systemd/journald.conf"
    else
        touch "/etc/systemd/journald.conf"
    fi
    # make sure file has newline at the end
    sed -i -e '$a\' "/etc/systemd/journald.conf"
    
    cp "/etc/systemd/journald.conf" "/etc/systemd/journald.conf.bak"
    # Insert before the line matching the regex '^#\s*ForwardToSyslog'.
    line_number="$(LC_ALL=C grep -n "^#\s*ForwardToSyslog" "/etc/systemd/journald.conf.bak" | LC_ALL=C sed 's/:.*//g')"
    if [ -z "$line_number" ]; then
        # There was no match of '^#\s*ForwardToSyslog', insert at
        # the end of the file.
        printf '%s\n' "ForwardToSyslog=yes" >> "/etc/systemd/journald.conf"
    else
        head -n "$(( line_number - 1 ))" "/etc/systemd/journald.conf.bak" > "/etc/systemd/journald.conf"
        printf '%s\n' "ForwardToSyslog=yes" >> "/etc/systemd/journald.conf"
        tail -n "+$(( line_number ))" "/etc/systemd/journald.conf.bak" >> "/etc/systemd/journald.conf"
    fi
    # Clean up after ourselves.
    rm "/etc/systemd/journald.conf.bak"
    
    else
        >&2 echo 'Remediation is not applicable, nothing was done'
    fi
    

    Rule   Ensure journald is configured to write log files to persistent disk   [ref]

    The journald system may store log files in volatile memory or locally on disk. If the logs are only stored in volatile memory they will we lost upon reboot.
    Rationale:
    Log files contain valuable data and need to be persistent to aid in possible investigations.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_journald_storage

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:restrict
    - name: Setting unquoted shell-style assignment of 'Storage' to 'persistent' in '/etc/systemd/journald.conf'
      block:
    
      - name: Check for duplicate values
        lineinfile:
          path: /etc/systemd/journald.conf
          create: true
          regexp: ^\s*Storage=
          state: absent
        check_mode: true
        changed_when: false
        register: dupes
    
      - name: Deduplicate values from /etc/systemd/journald.conf
        lineinfile:
          path: /etc/systemd/journald.conf
          create: true
          regexp: ^\s*Storage=
          state: absent
        when: dupes.found is defined and dupes.found > 1
    
      - name: Insert correct line to /etc/systemd/journald.conf
        lineinfile:
          path: /etc/systemd/journald.conf
          create: true
          regexp: ^\s*Storage=
          line: Storage=persistent
          state: present
          insertbefore: ^# Storage
          validate: /usr/bin/bash -n %s
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - journald_storage
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:restrict
    # Remediation is applicable only in certain platforms
    if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
    
    if [ -e "/etc/systemd/journald.conf" ] ; then
        
        LC_ALL=C sed -i "/^\s*Storage\s*=\s*/d" "/etc/systemd/journald.conf"
    else
        touch "/etc/systemd/journald.conf"
    fi
    # make sure file has newline at the end
    sed -i -e '$a\' "/etc/systemd/journald.conf"
    
    cp "/etc/systemd/journald.conf" "/etc/systemd/journald.conf.bak"
    # Insert before the line matching the regex '^#\s*Storage'.
    line_number="$(LC_ALL=C grep -n "^#\s*Storage" "/etc/systemd/journald.conf.bak" | LC_ALL=C sed 's/:.*//g')"
    if [ -z "$line_number" ]; then
        # There was no match of '^#\s*Storage', insert at
        # the end of the file.
        printf '%s\n' "Storage=persistent" >> "/etc/systemd/journald.conf"
    else
        head -n "$(( line_number - 1 ))" "/etc/systemd/journald.conf.bak" > "/etc/systemd/journald.conf"
        printf '%s\n' "Storage=persistent" >> "/etc/systemd/journald.conf"
        tail -n "+$(( line_number ))" "/etc/systemd/journald.conf.bak" >> "/etc/systemd/journald.conf"
    fi
    # Clean up after ourselves.
    rm "/etc/systemd/journald.conf.bak"
    
    else
        >&2 echo 'Remediation is not applicable, nothing was done'
    fi
    
    Group   Network Configuration and Firewalls   Group contains 5 groups and 4 rules
    [ref]   Most systems must be connected to a network of some sort, and this brings with it the substantial risk of network attack. This section discusses the security impact of decisions about networking which must be made when configuring a system.

    This section also discusses firewalls, network access controls, and other network security frameworks, which allow system-level rules to be written that can limit an attackers' ability to connect to your system. These rules can specify that network traffic should be allowed or denied from certain IP addresses, hosts, and networks. The rules can also specify which of the system's network services are available to particular hosts or networks.
    Group   firewalld   Group contains 1 group and 2 rules
    [ref]   The dynamic firewall daemon firewalld provides a dynamically managed firewall with support for network “zones” to assign a level of trust to a network and its associated connections and interfaces. It has support for IPv4 and IPv6 firewall settings. It supports Ethernet bridges and has a separation of runtime and permanent configuration options. It also has an interface for services or applications to add firewall rules directly.
    A graphical configuration tool, firewall-config, is used to configure firewalld, which in turn uses iptables tool to communicate with Netfilter in the kernel which implements packet filtering.
    The firewall service provided by firewalld is dynamic rather than static because changes to the configuration can be made at anytime and are immediately implemented. There is no need to save or apply the changes. No unintended disruption of existing network connections occurs as no part of the firewall has to be reloaded.
    Group   Inspect and Activate Default firewalld Rules   Group contains 2 rules
    [ref]   Firewalls can be used to separate networks into different zones based on the level of trust the user has decided to place on the devices and traffic within that network. NetworkManager informs firewalld to which zone an interface belongs. An interface's assigned zone can be changed by NetworkManager or via the firewall-config tool.
    The zone settings in /etc/firewalld/ are a range of preset settings which can be quickly applied to a network interface. These are the zones provided by firewalld sorted according to the default trust level of the zones from untrusted to trusted:
    • drop

      Any incoming network packets are dropped, there is no reply. Only outgoing network connections are possible.

    • block

      Any incoming network connections are rejected with an icmp-host-prohibited message for IPv4 and icmp6-adm-prohibited for IPv6. Only network connections initiated from within the system are possible.

    • public

      For use in public areas. You do not trust the other computers on the network to not harm your computer. Only selected incoming connections are accepted.

    • external

      For use on external networks with masquerading enabled especially for routers. You do not trust the other computers on the network to not harm your computer. Only selected incoming connections are accepted.

    • dmz

      For computers in your demilitarized zone that are publicly-accessible with limited access to your internal network. Only selected incoming connections are accepted.

    • work

      For use in work areas. You mostly trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted.

    • home

      For use in home areas. You mostly trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted.

    • internal

      For use on internal networks. You mostly trust the other computers on the networks to not harm your computer. Only selected incoming connections are accepted.

    • trusted

      All network connections are accepted.


    It is possible to designate one of these zones to be the default zone. When interface connections are added to NetworkManager, they are assigned to the default zone. On installation, the default zone in firewalld is set to be the public zone.
    To find out all the settings of a zone, for example the public zone, enter the following command as root:
    # firewall-cmd --zone=public --list-all
    Example output of this command might look like the following:
    # firewall-cmd --zone=public --list-all
    public
      interfaces:
      services: mdns dhcpv6-client ssh
      ports:
      forward-ports:
      icmp-blocks: source-quench
    
    To view the network zones currently active, enter the following command as root:
    # firewall-cmd --get-service
    The following listing displays the result of this command on common OpenEmbedded system:
    # firewall-cmd --get-service
    amanda-client bacula bacula-client dhcp dhcpv6 dhcpv6-client dns ftp
    high-availability http https imaps ipp ipp-client ipsec kerberos kpasswd
    ldap ldaps libvirt libvirt-tls mdns mountd ms-wbt mysql nfs ntp openvpn
    pmcd pmproxy pmwebapi pmwebapis pop3s postgresql proxy-dhcp radius rpc-bind
    samba samba-client smtp ssh telnet tftp tftp-client transmission-client
    vnc-server wbem-https
    
    Finally to view the network zones that will be active after the next firewalld service reload, enter the following command as root:
    # firewall-cmd --get-service --permanent

    Rule   Install firewalld Package   [ref]

    The firewalld package can be installed with the following command:
    $ sudo dnf install firewalld
    Rationale:
    "Firewalld" provides an easy and effective way to block/limit remote access to the system via ports, services, and protocols. Remote access services, such as those providing remote access to network devices and information systems, which lack automated control capabilities, increase risk and make remote user access management difficult at best. Remote access is access to DoD nonpublic information systems by an authorized user (or an information system) communicating through an external, non-organization-controlled network. Remote access methods include, for example, dial-up, broadband, and wireless. OpenEmbedded functionality (e.g., SSH) must be capable of taking enforcement action if the audit reveals unauthorized activity. Automated control of remote access sessions allows organizations to ensure ongoing compliance with remote access policies by enforcing connection rules of remote access applications on a variety of information system components (e.g., servers, workstations, notebook computers, smartphones, and tablets)."
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_package_firewalld_installed
    References:
    disaCCI-002314
    nistCM-6(a)
    osppFMT_SMF_EXT.1
    os-srgSRG-OS-000096-GPOS-00050, SRG-OS-000297-GPOS-00115, SRG-OS-000298-GPOS-00116, SRG-OS-000480-GPOS-00227, SRG-OS-000480-GPOS-00232
    pcidss41.2.1

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

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:enable
    - name: Ensure firewalld is installed
      package:
        name: firewalld
        state: present
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - NIST-800-53-CM-6(a)
      - PCI-DSSv4-1.2.1
      - enable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - package_firewalld_installed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:enable
    include install_firewalld
    
    class install_firewalld {
      package { 'firewalld':
        ensure => 'installed',
      }
    }
    

    Rule   Verify firewalld Enabled   [ref]

    The firewalld service can be enabled with the following command:
    $ sudo systemctl enable firewalld.service
    Rationale:
    Access control methods provide the ability to enhance system security posture by restricting services and known good IP addresses and address ranges. This prevents connections from unknown hosts and protocols.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_service_firewalld_enabled
    References:
    cis-csc11, 3, 9
    cobit5BAI10.01, BAI10.02, BAI10.03, BAI10.05
    cui3.1.3, 3.4.7
    disaCCI-000366, CCI-000382, CCI-002314
    isa-62443-20094.3.4.3.2, 4.3.4.3.3
    isa-62443-2013SR 7.6
    iso27001-2013A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4
    nerc-cipCIP-003-8 R4, CIP-003-8 R5, CIP-004-6 R3
    nistAC-4, CM-7(b), CA-3(5), SC-7(21), CM-6(a)
    nist-csfPR.IP-1
    osppFMT_SMF_EXT.1
    os-srgSRG-OS-000096-GPOS-00050, SRG-OS-000297-GPOS-00115, SRG-OS-000480-GPOS-00227, SRG-OS-000480-GPOS-00231, SRG-OS-000480-GPOS-00232
    pcidss41.2.1

    
    [customizations.services]
    enabled = ["firewalld"]
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:enable
    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - NIST-800-171-3.1.3
      - NIST-800-171-3.4.7
      - NIST-800-53-AC-4
      - NIST-800-53-CA-3(5)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-SC-7(21)
      - PCI-DSSv4-1.2.1
      - enable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_firewalld_enabled
    
    - name: Verify firewalld Enabled - Enable service firewalld
      block:
    
      - name: Gather the package facts
        package_facts:
          manager: auto
    
      - name: Verify firewalld Enabled - Enable Service firewalld
        ansible.builtin.systemd:
          name: firewalld
          enabled: true
          state: started
          masked: false
        when:
        - '"firewalld" in ansible_facts.packages'
      when:
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - '"firewalld" in ansible_facts.packages'
      tags:
      - NIST-800-171-3.1.3
      - NIST-800-171-3.4.7
      - NIST-800-53-AC-4
      - NIST-800-53-CA-3(5)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-SC-7(21)
      - PCI-DSSv4-1.2.1
      - enable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_firewalld_enabled
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:enable
    include enable_firewalld
    
    class enable_firewalld {
      service {'firewalld':
        enable => true,
        ensure => 'running',
      }
    }
    
    Group   iptables and ip6tables   Group contains 1 rule
    [ref]   A host-based firewall called netfilter is included as part of the Linux kernel distributed with the system. It is activated by default. This firewall is controlled by the program iptables, and the entire capability is frequently referred to by this name. An analogous program called ip6tables handles filtering for IPv6.

    Unlike TCP Wrappers, which depends on the network server program to support and respect the rules written, netfilter filtering occurs at the kernel level, before a program can even process the data from the network packet. As such, any program on the system is affected by the rules written.

    This section provides basic information about strengthening the iptables and ip6tables configurations included with the system. For more complete information that may allow the construction of a sophisticated ruleset tailored to your environment, please consult the references at the end of this section.

    Rule   Install iptables Package   [ref]

    The iptables package can be installed with the following command:
    $ sudo dnf install iptables
    Rationale:
    iptables controls the Linux kernel network packet filtering code. iptables allows system operators to set up firewalls and IP masquerading, etc.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_package_iptables_installed
    References:
    nistCM-6(a)
    pcidssReq-1.4.1
    os-srgSRG-OS-000480-GPOS-00227

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

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:enable
    - name: Ensure iptables is installed
      package:
        name: iptables
        state: present
      when: ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman",
        "container"] )
      tags:
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-1.4.1
      - enable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - package_iptables_installed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:enable
    include install_iptables
    
    class install_iptables {
      package { 'iptables':
        ensure => 'installed',
      }
    }
    
    Group   Wireless Networking   Group contains 1 group and 1 rule
    [ref]   Wireless networking, such as 802.11 (WiFi) and Bluetooth, can present a security risk to sensitive or classified systems and networks. Wireless networking hardware is much more likely to be included in laptop or portable systems than in desktops or servers.

    Removal of hardware provides the greatest assurance that the wireless capability remains disabled. Acquisition policies often include provisions to prevent the purchase of equipment that will be used in sensitive spaces and includes wireless capabilities. If it is impractical to remove the wireless hardware, and policy permits the device to enter sensitive spaces as long as wireless is disabled, efforts should instead focus on disabling wireless capability via software.
    Group   Disable Wireless Through Software Configuration   Group contains 1 rule
    [ref]   If it is impossible to remove the wireless hardware from the device in question, disable as much of it as possible through software. The following methods can disable software support for wireless networking, but note that these methods do not prevent malicious software or careless users from re-activating the devices.

    Rule   Deactivate Wireless Network Interfaces   [ref]

    Deactivating wireless network interfaces should prevent normal usage of the wireless capability.

    Configure the system to disable all wireless network interfaces with the following command:
    $ sudo nmcli radio all off
    Rationale:
    The use of wireless networking can introduce many different attack vectors into the organization's network. Common attack vectors such as malicious association and ad hoc networks will allow an attacker to spoof a wireless access point (AP), allowing validated systems to connect to the malicious AP and enabling the attacker to monitor and record network traffic. These malicious APs can also serve to create a man-in-the-middle attack or be used to create a denial of service to valid network resources.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_wireless_disable_interfaces
    References:
    cis-csc11, 12, 14, 15, 3, 8, 9
    cobit5APO13.01, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS01.04, DSS05.02, DSS05.03, DSS05.05, DSS06.06
    cui3.1.16
    disaCCI-000085, CCI-002418, CCI-002421, CCI-001443, CCI-001444
    isa-62443-20094.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3
    isa-62443-2013SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 7.1, SR 7.6
    ism1315, 1319
    iso27001-2013A.11.2.6, A.12.1.2, A.12.5.1, A.12.6.2, A.13.1.1, A.13.2.1, A.14.1.3, A.14.2.2, A.14.2.3, A.14.2.4, A.6.2.1, A.6.2.2, A.9.1.2
    nistAC-18(a), AC-18(3), CM-7(a), CM-7(b), CM-6(a), MP-7
    nist-csfPR.AC-3, PR.IP-1, PR.PT-3, PR.PT-4
    pcidssReq-1.3.3
    os-srgSRG-OS-000299-GPOS-00117, SRG-OS-000300-GPOS-00118, SRG-OS-000424-GPOS-00188, SRG-OS-000481-GPOS-000481
    pcidss41.3.3

    Complexity:low
    Disruption:medium
    Reboot:false
    Strategy:unknown
    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - NIST-800-171-3.1.16
      - NIST-800-53-AC-18(3)
      - NIST-800-53-AC-18(a)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - PCI-DSS-Req-1.3.3
      - PCI-DSSv4-1.3.3
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy
      - wireless_disable_interfaces
    
    - name: Service facts
      ansible.builtin.service_facts: null
      tags:
      - NIST-800-171-3.1.16
      - NIST-800-53-AC-18(3)
      - NIST-800-53-AC-18(a)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - PCI-DSS-Req-1.3.3
      - PCI-DSSv4-1.3.3
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy
      - wireless_disable_interfaces
    
    - name: Ensure NetworkManager is installed
      ansible.builtin.package:
        name: '{{ item }}'
        state: present
      with_items:
      - NetworkManager
      tags:
      - NIST-800-171-3.1.16
      - NIST-800-53-AC-18(3)
      - NIST-800-53-AC-18(a)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - PCI-DSS-Req-1.3.3
      - PCI-DSSv4-1.3.3
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy
      - wireless_disable_interfaces
    
    - name: NetworkManager Deactivate Wireless Network Interfaces
      command: nmcli radio wifi off
      when:
      - '''NetworkManager'' in ansible_facts.packages'
      - ansible_facts.services['NetworkManager.service'].state == 'running'
      tags:
      - NIST-800-171-3.1.16
      - NIST-800-53-AC-18(3)
      - NIST-800-53-AC-18(a)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - NIST-800-53-MP-7
      - PCI-DSS-Req-1.3.3
      - PCI-DSSv4-1.3.3
      - low_complexity
      - medium_disruption
      - medium_severity
      - no_reboot_needed
      - unknown_strategy
      - wireless_disable_interfaces
    

    
    if ! rpm -q --quiet "NetworkManager" ; then
        dnf install -y "NetworkManager"
    fi
    
    if command -v nmcli >/dev/null 2>&1 && systemctl is-active NetworkManager >/dev/null 2>&1; then
        nmcli radio all off
    fi
    
    if command -v wicked >/dev/null 2>&1 && systemctl is-active wickedd >/dev/null 2>&1; then
      if [ -n "$(find /sys/class/net/*/ -type d -name wireless)" ]; then
        interfaces=$(find /sys/class/net/*/wireless -type d -name wireless | xargs -0 dirname | xargs basename)
        for iface in $interfaces; do
          wicked ifdown $iface
          sed -i 's/STARTMODE=.*/STARTMODE=off/' /etc/sysconfig/network/ifcfg-$iface
        done
      fi
    fi
    
    Group   File Permissions and Masks   Group contains 4 groups and 25 rules
    [ref]   Traditional Unix security relies heavily on file and directory permissions to prevent unauthorized users from reading or modifying files to which they should not have access.

    Several of the commands in this section search filesystems for files or directories with certain characteristics, and are intended to be run on every local partition on a given system. When the variable PART appears in one of the commands below, it means that the command is intended to be run repeatedly, with the name of each local partition substituted for PART in turn.

    The following command prints a list of all xfs partitions on the local system, which is the default filesystem for OpenEmbedded installations:
    $ mount -t xfs | awk '{print $3}'
    For any systems that use a different local filesystem type, modify this command as appropriate.
    Group   Verify Permissions on Important Files and Directories   Group contains 1 group and 24 rules
    [ref]   Permissions for many files on a system must be set restrictively to ensure sensitive information is properly protected. This section discusses important permission restrictions which can be verified to ensure that no harmful discrepancies have arisen.
    Group   Verify Permissions on Files with Local Account Information and Credentials   Group contains 21 rules

    Rule   Verify Group Who Owns Backup group File   [ref]

    To properly set the group owner of /etc/group-, run the command:
    $ sudo chgrp root /etc/group-
    Rationale:
    The /etc/group- file is a backup file of /etc/group, and as such, it contains information regarding groups that are configured on the system. Protection of this file is important for system security.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_groupowner_backup_etc_group
    References:
    disaCCI-002223
    nistAC-6 (1)
    pcidssReq-8.7
    os-srgSRG-OS-000480-GPOS-00227
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Test for existence /etc/group-
      stat:
        path: /etc/group-
      register: file_exists
      tags:
      - NIST-800-53-AC-6 (1)
      - PCI-DSS-Req-8.7
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_groupowner_backup_etc_group
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    
    - name: Ensure group owner 0 on /etc/group-
      file:
        path: /etc/group-
        group: '0'
      when: file_exists.stat is defined and file_exists.stat.exists
      tags:
      - NIST-800-53-AC-6 (1)
      - PCI-DSS-Req-8.7
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_groupowner_backup_etc_group
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    chgrp 0 /etc/group-
    

    Rule   Verify Group Who Owns Backup gshadow File   [ref]

    To properly set the group owner of /etc/gshadow-, run the command:
    $ sudo chgrp root /etc/gshadow-
    Rationale:
    The /etc/gshadow- file is a backup of /etc/gshadow, and as such, it contains group password hashes. Protection of this file is critical for system security.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_groupowner_backup_etc_gshadow
    References:
    disaCCI-002223
    nistAC-6 (1)
    pcidssReq-8.7
    os-srgSRG-OS-000480-GPOS-00227

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Test for existence /etc/gshadow-
      stat:
        path: /etc/gshadow-
      register: file_exists
      tags:
      - NIST-800-53-AC-6 (1)
      - PCI-DSS-Req-8.7
      - configure_strategy
      - file_groupowner_backup_etc_gshadow
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    
    - name: Ensure group owner 0 on /etc/gshadow-
      file:
        path: /etc/gshadow-
        group: '0'
      when: file_exists.stat is defined and file_exists.stat.exists
      tags:
      - NIST-800-53-AC-6 (1)
      - PCI-DSS-Req-8.7
      - configure_strategy
      - file_groupowner_backup_etc_gshadow
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    chgrp 0 /etc/gshadow-
    

    Rule   Verify Group Who Owns Backup passwd File   [ref]

    To properly set the group owner of /etc/passwd-, run the command:
    $ sudo chgrp root /etc/passwd-
    Rationale:
    The /etc/passwd- file is a backup file of /etc/passwd, and as such, it contains information about the users that are configured on the system. Protection of this file is critical for system security.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_groupowner_backup_etc_passwd
    References:
    disaCCI-002223
    nistAC-6 (1)
    pcidssReq-8.7
    os-srgSRG-OS-000480-GPOS-00227
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Test for existence /etc/passwd-
      stat:
        path: /etc/passwd-
      register: file_exists
      tags:
      - NIST-800-53-AC-6 (1)
      - PCI-DSS-Req-8.7
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_groupowner_backup_etc_passwd
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    
    - name: Ensure group owner 0 on /etc/passwd-
      file:
        path: /etc/passwd-
        group: '0'
      when: file_exists.stat is defined and file_exists.stat.exists
      tags:
      - NIST-800-53-AC-6 (1)
      - PCI-DSS-Req-8.7
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_groupowner_backup_etc_passwd
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    chgrp 0 /etc/passwd-
    

    Rule   Verify User Who Owns Backup shadow File   [ref]

    To properly set the group owner of /etc/shadow-, run the command:
    $ sudo chgrp root /etc/shadow-
    Rationale:
    The /etc/shadow- file is a backup file of /etc/shadow, and as such, it contains the list of local system accounts and password hashes. Protection of this file is critical for system security.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_groupowner_backup_etc_shadow
    References:
    pcidssReq-8.7
    os-srgSRG-OS-000480-GPOS-00227
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Test for existence /etc/shadow-
      stat:
        path: /etc/shadow-
      register: file_exists
      tags:
      - PCI-DSS-Req-8.7
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_groupowner_backup_etc_shadow
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    
    - name: Ensure group owner 0 on /etc/shadow-
      file:
        path: /etc/shadow-
        group: '0'
      when: file_exists.stat is defined and file_exists.stat.exists
      tags:
      - PCI-DSS-Req-8.7
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_groupowner_backup_etc_shadow
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    chgrp 0 /etc/shadow-
    

    Rule   Verify Group Who Owns group File   [ref]

    To properly set the group owner of /etc/group, run the command:
    $ sudo chgrp root /etc/group
    Rationale:
    The /etc/group file contains information regarding groups that are configured on the system. Protection of this file is important for system security.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_groupowner_etc_group
    References:
    cis-csc12, 13, 14, 15, 16, 18, 3, 5
    cjis5.5.2.2
    cobit5APO01.06, DSS05.04, DSS05.07, DSS06.02
    isa-62443-20094.3.3.7.3
    isa-62443-2013SR 2.1, SR 5.2
    iso27001-2013A.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
    nerc-cipCIP-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
    nistCM-6(a), AC-6(1)
    nist-csfPR.AC-4, PR.DS-5
    pcidssReq-8.7.c
    os-srgSRG-OS-000480-GPOS-00227
    anssiR50
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Test for existence /etc/group
      stat:
        path: /etc/group
      register: file_exists
      tags:
      - CJIS-5.5.2.2
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.7.c
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_groupowner_etc_group
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    
    - name: Ensure group owner 0 on /etc/group
      file:
        path: /etc/group
        group: '0'
      when: file_exists.stat is defined and file_exists.stat.exists
      tags:
      - CJIS-5.5.2.2
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.7.c
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_groupowner_etc_group
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    chgrp 0 /etc/group
    

    Rule   Verify Group Who Owns gshadow File   [ref]

    To properly set the group owner of /etc/gshadow, run the command:
    $ sudo chgrp root /etc/gshadow
    Rationale:
    The /etc/gshadow file contains group password hashes. Protection of this file is critical for system security.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_groupowner_etc_gshadow
    References:
    cis-csc12, 13, 14, 15, 16, 18, 3, 5
    cobit5APO01.06, DSS05.04, DSS05.07, DSS06.02
    isa-62443-20094.3.3.7.3
    isa-62443-2013SR 2.1, SR 5.2
    iso27001-2013A.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
    nerc-cipCIP-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
    nistCM-6(a), AC-6(1)
    nist-csfPR.AC-4, PR.DS-5
    os-srgSRG-OS-000480-GPOS-00227
    anssiR50

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Test for existence /etc/gshadow
      stat:
        path: /etc/gshadow
      register: file_exists
      tags:
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - configure_strategy
      - file_groupowner_etc_gshadow
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    
    - name: Ensure group owner 0 on /etc/gshadow
      file:
        path: /etc/gshadow
        group: '0'
      when: file_exists.stat is defined and file_exists.stat.exists
      tags:
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - configure_strategy
      - file_groupowner_etc_gshadow
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    chgrp 0 /etc/gshadow
    

    Rule   Verify Group Who Owns passwd File   [ref]

    To properly set the group owner of /etc/passwd, run the command:
    $ sudo chgrp root /etc/passwd
    Rationale:
    The /etc/passwd file contains information about the users that are configured on the system. Protection of this file is critical for system security.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_groupowner_etc_passwd
    References:
    cis-csc12, 13, 14, 15, 16, 18, 3, 5
    cjis5.5.2.2
    cobit5APO01.06, DSS05.04, DSS05.07, DSS06.02
    isa-62443-20094.3.3.7.3
    isa-62443-2013SR 2.1, SR 5.2
    iso27001-2013A.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
    nerc-cipCIP-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
    nistCM-6(a), AC-6(1)
    nist-csfPR.AC-4, PR.DS-5
    pcidssReq-8.7.c
    os-srgSRG-OS-000480-GPOS-00227
    anssiR50
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Test for existence /etc/passwd
      stat:
        path: /etc/passwd
      register: file_exists
      tags:
      - CJIS-5.5.2.2
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.7.c
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_groupowner_etc_passwd
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    
    - name: Ensure group owner 0 on /etc/passwd
      file:
        path: /etc/passwd
        group: '0'
      when: file_exists.stat is defined and file_exists.stat.exists
      tags:
      - CJIS-5.5.2.2
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.7.c
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_groupowner_etc_passwd
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    chgrp 0 /etc/passwd
    

    Rule   Verify Group Who Owns shadow File   [ref]

    To properly set the group owner of /etc/shadow, run the command:
    $ sudo chgrp root /etc/shadow
    Rationale:
    The /etc/shadow file stores password hashes. Protection of this file is critical for system security.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_groupowner_etc_shadow
    References:
    cis-csc12, 13, 14, 15, 16, 18, 3, 5
    cjis5.5.2.2
    cobit5APO01.06, DSS05.04, DSS05.07, DSS06.02
    isa-62443-20094.3.3.7.3
    isa-62443-2013SR 2.1, SR 5.2
    iso27001-2013A.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
    nerc-cipCIP-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
    nistCM-6(a), AC-6(1)
    nist-csfPR.AC-4, PR.DS-5
    pcidssReq-8.7.c
    os-srgSRG-OS-000480-GPOS-00227
    anssiR50
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Test for existence /etc/shadow
      stat:
        path: /etc/shadow
      register: file_exists
      tags:
      - CJIS-5.5.2.2
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.7.c
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_groupowner_etc_shadow
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    
    - name: Ensure group owner 0 on /etc/shadow
      file:
        path: /etc/shadow
        group: '0'
      when: file_exists.stat is defined and file_exists.stat.exists
      tags:
      - CJIS-5.5.2.2
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.7.c
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_groupowner_etc_shadow
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    chgrp 0 /etc/shadow
    

    Rule   Verify User Who Owns Backup group File   [ref]

    To properly set the owner of /etc/group-, run the command:
    $ sudo chown root /etc/group- 
    Rationale:
    The /etc/group- file is a backup file of /etc/group, and as such, it contains information regarding groups that are configured on the system. Protection of this file is important for system security.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_owner_backup_etc_group
    References:
    disaCCI-002223
    nistAC-6 (1)
    pcidssReq-8.7.c
    os-srgSRG-OS-000480-GPOS-00227
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Test for existence /etc/group-
      stat:
        path: /etc/group-
      register: file_exists
      tags:
      - NIST-800-53-AC-6 (1)
      - PCI-DSS-Req-8.7.c
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_owner_backup_etc_group
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    
    - name: Ensure owner 0 on /etc/group-
      file:
        path: /etc/group-
        owner: '0'
      when: file_exists.stat is defined and file_exists.stat.exists
      tags:
      - NIST-800-53-AC-6 (1)
      - PCI-DSS-Req-8.7.c
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_owner_backup_etc_group
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    chown 0 /etc/group-
    

    Rule   Verify User Who Owns Backup gshadow File   [ref]

    To properly set the owner of /etc/gshadow-, run the command:
    $ sudo chown root /etc/gshadow- 
    Rationale:
    The /etc/gshadow- file is a backup of /etc/gshadow, and as such, it contains group password hashes. Protection of this file is critical for system security.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_owner_backup_etc_gshadow
    References:
    disaCCI-002223
    nistAC-6 (1)
    pcidssReq-8.7
    os-srgSRG-OS-000480-GPOS-00227

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Test for existence /etc/gshadow-
      stat:
        path: /etc/gshadow-
      register: file_exists
      tags:
      - NIST-800-53-AC-6 (1)
      - PCI-DSS-Req-8.7
      - configure_strategy
      - file_owner_backup_etc_gshadow
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    
    - name: Ensure owner 0 on /etc/gshadow-
      file:
        path: /etc/gshadow-
        owner: '0'
      when: file_exists.stat is defined and file_exists.stat.exists
      tags:
      - NIST-800-53-AC-6 (1)
      - PCI-DSS-Req-8.7
      - configure_strategy
      - file_owner_backup_etc_gshadow
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    chown 0 /etc/gshadow-
    

    Rule   Verify User Who Owns Backup passwd File   [ref]

    To properly set the owner of /etc/passwd-, run the command:
    $ sudo chown root /etc/passwd- 
    Rationale:
    The /etc/passwd- file is a backup file of /etc/passwd, and as such, it contains information about the users that are configured on the system. Protection of this file is critical for system security.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_owner_backup_etc_passwd
    References:
    disaCCI-002223
    nistAC-6 (1)
    pcidssReq-8.7.c
    os-srgSRG-OS-000480-GPOS-00227
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Test for existence /etc/passwd-
      stat:
        path: /etc/passwd-
      register: file_exists
      tags:
      - NIST-800-53-AC-6 (1)
      - PCI-DSS-Req-8.7.c
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_owner_backup_etc_passwd
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    
    - name: Ensure owner 0 on /etc/passwd-
      file:
        path: /etc/passwd-
        owner: '0'
      when: file_exists.stat is defined and file_exists.stat.exists
      tags:
      - NIST-800-53-AC-6 (1)
      - PCI-DSS-Req-8.7.c
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_owner_backup_etc_passwd
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    chown 0 /etc/passwd-
    

    Rule   Verify Group Who Owns Backup shadow File   [ref]

    To properly set the owner of /etc/shadow-, run the command:
    $ sudo chown root /etc/shadow- 
    Rationale:
    The /etc/shadow- file is a backup file of /etc/shadow, and as such, it contains the list of local system accounts and password hashes. Protection of this file is critical for system security.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_owner_backup_etc_shadow
    References:
    disaCCI-002223
    nistAC-6 (1)
    pcidssReq-8.7.c
    os-srgSRG-OS-000480-GPOS-00227
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Test for existence /etc/shadow-
      stat:
        path: /etc/shadow-
      register: file_exists
      tags:
      - NIST-800-53-AC-6 (1)
      - PCI-DSS-Req-8.7.c
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_owner_backup_etc_shadow
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    
    - name: Ensure owner 0 on /etc/shadow-
      file:
        path: /etc/shadow-
        owner: '0'
      when: file_exists.stat is defined and file_exists.stat.exists
      tags:
      - NIST-800-53-AC-6 (1)
      - PCI-DSS-Req-8.7.c
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_owner_backup_etc_shadow
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    chown 0 /etc/shadow-
    

    Rule   Verify User Who Owns group File   [ref]

    To properly set the owner of /etc/group, run the command:
    $ sudo chown root /etc/group 
    Rationale:
    The /etc/group file contains information regarding groups that are configured on the system. Protection of this file is important for system security.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_owner_etc_group
    References:
    cis-csc12, 13, 14, 15, 16, 18, 3, 5
    cjis5.5.2.2
    cobit5APO01.06, DSS05.04, DSS05.07, DSS06.02
    disaCCI-002223
    isa-62443-20094.3.3.7.3
    isa-62443-2013SR 2.1, SR 5.2
    iso27001-2013A.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
    nerc-cipCIP-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
    nistCM-6(a), AC-6(1)
    nist-csfPR.AC-4, PR.DS-5
    pcidssReq-8.7.c
    os-srgSRG-OS-000480-GPOS-00227
    anssiR50
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Test for existence /etc/group
      stat:
        path: /etc/group
      register: file_exists
      tags:
      - CJIS-5.5.2.2
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.7.c
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_owner_etc_group
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    
    - name: Ensure owner 0 on /etc/group
      file:
        path: /etc/group
        owner: '0'
      when: file_exists.stat is defined and file_exists.stat.exists
      tags:
      - CJIS-5.5.2.2
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.7.c
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_owner_etc_group
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    chown 0 /etc/group
    

    Rule   Verify User Who Owns gshadow File   [ref]

    To properly set the owner of /etc/gshadow, run the command:
    $ sudo chown root /etc/gshadow 
    Rationale:
    The /etc/gshadow file contains group password hashes. Protection of this file is critical for system security.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_owner_etc_gshadow
    References:
    cis-csc12, 13, 14, 15, 16, 18, 3, 5
    cobit5APO01.06, DSS05.04, DSS05.07, DSS06.02
    disaCCI-002223
    isa-62443-20094.3.3.7.3
    isa-62443-2013SR 2.1, SR 5.2
    iso27001-2013A.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
    nerc-cipCIP-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
    nistCM-6(a), AC-6(1)
    nist-csfPR.AC-4, PR.DS-5
    os-srgSRG-OS-000480-GPOS-00227
    anssiR50

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Test for existence /etc/gshadow
      stat:
        path: /etc/gshadow
      register: file_exists
      tags:
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - configure_strategy
      - file_owner_etc_gshadow
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    
    - name: Ensure owner 0 on /etc/gshadow
      file:
        path: /etc/gshadow
        owner: '0'
      when: file_exists.stat is defined and file_exists.stat.exists
      tags:
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - configure_strategy
      - file_owner_etc_gshadow
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    chown 0 /etc/gshadow
    

    Rule   Verify User Who Owns passwd File   [ref]

    To properly set the owner of /etc/passwd, run the command:
    $ sudo chown root /etc/passwd 
    Rationale:
    The /etc/passwd file contains information about the users that are configured on the system. Protection of this file is critical for system security.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_owner_etc_passwd
    References:
    cis-csc12, 13, 14, 15, 16, 18, 3, 5
    cjis5.5.2.2
    cobit5APO01.06, DSS05.04, DSS05.07, DSS06.02
    disaCCI-002223
    isa-62443-20094.3.3.7.3
    isa-62443-2013SR 2.1, SR 5.2
    iso27001-2013A.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
    nerc-cipCIP-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
    nistCM-6(a), AC-6(1)
    nist-csfPR.AC-4, PR.DS-5
    pcidssReq-8.7.c
    os-srgSRG-OS-000480-GPOS-00227
    anssiR50
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Test for existence /etc/passwd
      stat:
        path: /etc/passwd
      register: file_exists
      tags:
      - CJIS-5.5.2.2
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.7.c
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_owner_etc_passwd
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    
    - name: Ensure owner 0 on /etc/passwd
      file:
        path: /etc/passwd
        owner: '0'
      when: file_exists.stat is defined and file_exists.stat.exists
      tags:
      - CJIS-5.5.2.2
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.7.c
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_owner_etc_passwd
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    chown 0 /etc/passwd
    

    Rule   Verify User Who Owns shadow File   [ref]

    To properly set the owner of /etc/shadow, run the command:
    $ sudo chown root /etc/shadow 
    Rationale:
    The /etc/shadow file contains the list of local system accounts and stores password hashes. Protection of this file is critical for system security. Failure to give ownership of this file to root provides the designated owner with access to sensitive information which could weaken the system security posture.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_owner_etc_shadow
    References:
    cis-csc12, 13, 14, 15, 16, 18, 3, 5
    cjis5.5.2.2
    cobit5APO01.06, DSS05.04, DSS05.07, DSS06.02
    disaCCI-002223
    isa-62443-20094.3.3.7.3
    isa-62443-2013SR 2.1, SR 5.2
    iso27001-2013A.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
    nerc-cipCIP-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
    nistCM-6(a), AC-6(1)
    nist-csfPR.AC-4, PR.DS-5
    pcidssReq-8.7.c
    os-srgSRG-OS-000480-GPOS-00227
    anssiR50
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Test for existence /etc/shadow
      stat:
        path: /etc/shadow
      register: file_exists
      tags:
      - CJIS-5.5.2.2
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.7.c
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_owner_etc_shadow
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    
    - name: Ensure owner 0 on /etc/shadow
      file:
        path: /etc/shadow
        owner: '0'
      when: file_exists.stat is defined and file_exists.stat.exists
      tags:
      - CJIS-5.5.2.2
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.7.c
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_owner_etc_shadow
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    chown 0 /etc/shadow
    

    Rule   Verify Permissions on Backup group File   [ref]

    To properly set the permissions of /etc/group-, run the command:
    $ sudo chmod 0644 /etc/group-
    Rationale:
    The /etc/group- file is a backup file of /etc/group, and as such, it contains information regarding groups that are configured on the system. Protection of this file is important for system security.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_permissions_backup_etc_group
    References:
    disaCCI-002223
    nistAC-6 (1)
    pcidssReq-8.7.c
    os-srgSRG-OS-000480-GPOS-00227
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Test for existence /etc/group-
      stat:
        path: /etc/group-
      register: file_exists
      tags:
      - NIST-800-53-AC-6 (1)
      - PCI-DSS-Req-8.7.c
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_permissions_backup_etc_group
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    
    - name: Ensure permission u-xs,g-xws,o-xwt on /etc/group-
      file:
        path: /etc/group-
        mode: u-xs,g-xws,o-xwt
      when: file_exists.stat is defined and file_exists.stat.exists
      tags:
      - NIST-800-53-AC-6 (1)
      - PCI-DSS-Req-8.7.c
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_permissions_backup_etc_group
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    
    
    
    
    
    chmod u-xs,g-xws,o-xwt /etc/group-
    

    Rule   Verify Permissions on Backup passwd File   [ref]

    To properly set the permissions of /etc/passwd-, run the command:
    $ sudo chmod 0644 /etc/passwd-
    Rationale:
    The /etc/passwd- file is a backup file of /etc/passwd, and as such, it contains information about the users that are configured on the system. Protection of this file is critical for system security.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_permissions_backup_etc_passwd
    References:
    disaCCI-002223
    nistAC-6 (1)
    pcidssReq-8.7.c
    os-srgSRG-OS-000480-GPOS-00227
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Test for existence /etc/passwd-
      stat:
        path: /etc/passwd-
      register: file_exists
      tags:
      - NIST-800-53-AC-6 (1)
      - PCI-DSS-Req-8.7.c
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_permissions_backup_etc_passwd
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    
    - name: Ensure permission u-xs,g-xws,o-xwt on /etc/passwd-
      file:
        path: /etc/passwd-
        mode: u-xs,g-xws,o-xwt
      when: file_exists.stat is defined and file_exists.stat.exists
      tags:
      - NIST-800-53-AC-6 (1)
      - PCI-DSS-Req-8.7.c
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_permissions_backup_etc_passwd
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    
    
    
    
    
    chmod u-xs,g-xws,o-xwt /etc/passwd-
    

    Rule   Verify Permissions on Backup shadow File   [ref]

    To properly set the permissions of /etc/shadow-, run the command:
    $ sudo chmod 0000 /etc/shadow-
    Rationale:
    The /etc/shadow- file is a backup file of /etc/shadow, and as such, it contains the list of local system accounts and password hashes. Protection of this file is critical for system security.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_permissions_backup_etc_shadow
    References:
    disaCCI-002223
    nistAC-6 (1)
    pcidssReq-8.7.c
    os-srgSRG-OS-000480-GPOS-00227
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Test for existence /etc/shadow-
      stat:
        path: /etc/shadow-
      register: file_exists
      tags:
      - NIST-800-53-AC-6 (1)
      - PCI-DSS-Req-8.7.c
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_permissions_backup_etc_shadow
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    
    - name: Ensure permission u-xwrs,g-xwrs,o-xwrt on /etc/shadow-
      file:
        path: /etc/shadow-
        mode: u-xwrs,g-xwrs,o-xwrt
      when: file_exists.stat is defined and file_exists.stat.exists
      tags:
      - NIST-800-53-AC-6 (1)
      - PCI-DSS-Req-8.7.c
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_permissions_backup_etc_shadow
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    
    
    
    
    
    chmod u-xwrs,g-xwrs,o-xwrt /etc/shadow-
    

    Rule   Verify Permissions on group File   [ref]

    To properly set the permissions of /etc/group, run the command:
    $ sudo chmod 0644 /etc/group
    Rationale:
    The /etc/group file contains information regarding groups that are configured on the system. Protection of this file is important for system security.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_permissions_etc_group
    References:
    cis-csc12, 13, 14, 15, 16, 18, 3, 5
    cjis5.5.2.2
    cobit5APO01.06, DSS05.04, DSS05.07, DSS06.02
    disaCCI-002223
    isa-62443-20094.3.3.7.3
    isa-62443-2013SR 2.1, SR 5.2
    iso27001-2013A.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
    nerc-cipCIP-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
    nistCM-6(a), AC-6(1)
    nist-csfPR.AC-4, PR.DS-5
    pcidssReq-8.7.c
    os-srgSRG-OS-000480-GPOS-00227
    anssiR50
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Test for existence /etc/group
      stat:
        path: /etc/group
      register: file_exists
      tags:
      - CJIS-5.5.2.2
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.7.c
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_permissions_etc_group
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    
    - name: Ensure permission u-xs,g-xws,o-xwt on /etc/group
      file:
        path: /etc/group
        mode: u-xs,g-xws,o-xwt
      when: file_exists.stat is defined and file_exists.stat.exists
      tags:
      - CJIS-5.5.2.2
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.7.c
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_permissions_etc_group
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    
    
    
    
    
    chmod u-xs,g-xws,o-xwt /etc/group
    

    Rule   Verify Permissions on passwd File   [ref]

    To properly set the permissions of /etc/passwd, run the command:
    $ sudo chmod 0644 /etc/passwd
    Rationale:
    If the /etc/passwd file is writable by a group-owner or the world the risk of its compromise is increased. The file contains the list of accounts on the system and associated information, and protection of this file is critical for system security.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_permissions_etc_passwd
    References:
    cis-csc12, 13, 14, 15, 16, 18, 3, 5
    cjis5.5.2.2
    cobit5APO01.06, DSS05.04, DSS05.07, DSS06.02
    disaCCI-002223
    isa-62443-20094.3.3.7.3
    isa-62443-2013SR 2.1, SR 5.2
    iso27001-2013A.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
    nerc-cipCIP-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
    nistCM-6(a), AC-6(1)
    nist-csfPR.AC-4, PR.DS-5
    pcidssReq-8.7.c
    os-srgSRG-OS-000480-GPOS-00227
    anssiR50
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Test for existence /etc/passwd
      stat:
        path: /etc/passwd
      register: file_exists
      tags:
      - CJIS-5.5.2.2
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.7.c
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_permissions_etc_passwd
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    
    - name: Ensure permission u-xs,g-xws,o-xwt on /etc/passwd
      file:
        path: /etc/passwd
        mode: u-xs,g-xws,o-xwt
      when: file_exists.stat is defined and file_exists.stat.exists
      tags:
      - CJIS-5.5.2.2
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-8.7.c
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_permissions_etc_passwd
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    
    
    
    
    
    chmod u-xs,g-xws,o-xwt /etc/passwd
    

    Rule   Verify that All World-Writable Directories Have Sticky Bits Set   [ref]

    When the so-called 'sticky bit' is set on a directory, only the owner of a given file may remove that file from the directory. Without the sticky bit, any user with write access to a directory may remove any file in the directory. Setting the sticky bit prevents users from removing each other's files. In cases where there is no reason for a directory to be world-writable, a better solution is to remove that permission rather than to set the sticky bit. However, if a directory is used by a particular application, consult that application's documentation instead of blindly changing modes.
    To set the sticky bit on a world-writable directory DIR, run the following command:
    $ sudo chmod +t DIR
            
    Warning:  This rule can take a long time to perform the check and might consume a considerable amount of resources depending on the number of directories present on the system. It is not a problem in most cases, but especially systems with a large number of directories can be affected. See https://access.redhat.com/articles/6999111.
    Rationale:
    Failing to set the sticky bit on public directories allows unauthorized users to delete files in the directory structure.

    The only authorized public directories are those temporary directories supplied with the system, or those designed to be temporary file repositories. The setting is normally reserved for directories used by the system, by users for temporary file storage (such as /tmp), and for directories requiring global read/write access.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_dir_perms_world_writable_sticky_bits
    References:
    cis-csc12, 13, 14, 15, 16, 18, 3, 5
    cobit5APO01.06, DSS05.04, DSS05.07, DSS06.02
    disaCCI-001090
    isa-62443-20094.3.3.7.3
    isa-62443-2013SR 2.1, SR 5.2
    iso27001-2013A.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
    nerc-cipCIP-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
    nistCM-6(a), AC-6(1)
    nist-csfPR.AC-4, PR.DS-5
    os-srgSRG-OS-000138-GPOS-00069
    anssiR54
    pcidss42.2.6

    Rule   Ensure No World-Writable Files Exist   [ref]

    It is generally a good idea to remove global (other) write access to a file when it is discovered. However, check with documentation for specific applications before making changes. Also, monitor for recurring world-writable files, as these may be symptoms of a misconfigured application or user account. Finally, this applies to real files and not virtual files that are a part of pseudo file systems such as sysfs or procfs.
    Warning:  This rule can take a long time to perform the check and might consume a considerable amount of resources depending on the number of files present on the system. It is not a problem in most cases, but especially systems with a large number of files can be affected. See https://access.redhat.com/articles/6999111.
    Rationale:
    Data in world-writable files can be modified by any user on the system. In almost all circumstances, files can be configured using a combination of user and group permissions to support whatever legitimate access is needed without the risk caused by world-writable files.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_permissions_unauthorized_world_writable
    References:
    cis-csc12, 13, 14, 15, 16, 18, 3, 5
    cobit5APO01.06, DSS05.04, DSS05.07, DSS06.02
    isa-62443-20094.3.3.7.3
    isa-62443-2013SR 2.1, SR 5.2
    iso27001-2013A.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
    nerc-cipCIP-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
    nistCM-6(a), AC-6(1)
    nist-csfPR.AC-4, PR.DS-5
    anssiR54
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    
    FILTER_NODEV=$(awk '/nodev/ { print $2 }' /proc/filesystems | paste -sd,)
    PARTITIONS=$(findmnt -n -l -k -it $FILTER_NODEV | awk '{ print $1 }')
    for PARTITION in $PARTITIONS; do
      find "${PARTITION}" -xdev -type f -perm -002 -exec chmod o-w {} \; 2>/dev/null
    done
    
    # Ensure /tmp is also fixed whem tmpfs is used.
    if grep "^tmpfs /tmp" /proc/mounts; then
      find /tmp -xdev -type f -perm -002 -exec chmod o-w {} \; 2>/dev/null
    fi
    

    Rule   Ensure All Files Are Owned by a Group   [ref]

    If any file is not group-owned by a group present in /etc/group, the cause of the lack of group-ownership must be investigated. Following this, those files should be deleted or assigned to an appropriate group. Locate the mount points related to local devices by the following command:
    $ findmnt -n -l -k -it $(awk '/nodev/ { print $2 }' /proc/filesystems | paste -sd,)
    For all mount points listed by the previous command, it is necessary to search for files which do not belong to a valid group using the following command:
    $ sudo find MOUNTPOINT -xdev -nogroup 2>/dev/null
    Warning:  This rule only considers local groups as valid groups. If you have your groups defined outside /etc/group, the rule won't consider those.
    Warning:  This rule can take a long time to perform the check and might consume a considerable amount of resources depending on the number of files present on the system. It is not a problem in most cases, but especially systems with a large number of files can be affected. See https://access.redhat.com/articles/6999111.
    Rationale:
    Unowned files do not directly imply a security problem, but they are generally a sign that something is amiss. They may be caused by an intruder, by incorrect software installation or draft software removal, or by failure to remove all files belonging to a deleted account, or other similar cases. The files should be repaired so they will not cause problems when accounts are created in the future, and the cause should be discovered and addressed.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_permissions_ungroupowned
    References:
    cis-csc1, 11, 12, 13, 14, 15, 16, 18, 3, 5
    cobit5APO01.06, DSS05.02, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.02, DSS06.03, DSS06.06, DSS06.10
    disaCCI-000366, CCI-002165
    isa-62443-20094.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
    isa-62443-2013SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 5.2
    iso27001-2013A.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
    nistCM-6(a), AC-6(1)
    nist-csfPR.AC-1, PR.AC-4, PR.AC-6, PR.AC-7, PR.DS-5, PR.PT-3
    os-srgSRG-OS-000480-GPOS-00227
    anssiR53
    pcidss42.2.6
    Group   Restrict Programs from Dangerous Execution Patterns   Group contains 1 group and 1 rule
    [ref]   The recommendations in this section are designed to ensure that the system's features to protect against potentially dangerous program execution are activated. These protections are applied at the system initialization or kernel level, and defend against certain types of badly-configured or compromised programs.
    Group   Disable Core Dumps   Group contains 1 rule
    [ref]   A core dump file is the memory image of an executable program when it was terminated by the operating system due to errant behavior. In most cases, only software developers legitimately need to access these files. The core dump files may also contain sensitive information, or unnecessarily occupy large amounts of disk space.

    Once a hard limit is set in /etc/security/limits.conf, or to a file within the /etc/security/limits.d/ directory, a user cannot increase that limit within his or her own session. If access to core dumps is required, consider restricting them to only certain users or groups. See the limits.conf man page for more information.

    The core dumps of setuid programs are further protected. The sysctl variable fs.suid_dumpable controls whether the kernel allows core dumps from these programs at all. The default value of 0 is recommended.

    Rule   Disable Core Dumps for All Users   [ref]

    To disable core dumps for all users, add the following line to /etc/security/limits.conf, or to a file within the /etc/security/limits.d/ directory:
    *     hard   core    0
    Rationale:
    A core dump includes a memory image taken at the time the operating system terminates an application. The memory image could contain sensitive data and is generally useful only for developers trying to debug problems.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_disable_users_coredumps
    References:
    cis-csc1, 12, 13, 15, 16, 2, 7, 8
    cobit5APO13.01, BAI04.04, DSS01.03, DSS03.05, DSS05.07
    disaCCI-000366
    isa-62443-2013SR 6.2, SR 7.1, SR 7.2
    iso27001-2013A.12.1.3, A.17.2.1
    nistCM-6, SC-7(10)
    nist-csfDE.CM-1, PR.DS-4
    os-srgSRG-OS-000480-GPOS-00227
    pcidss43.3.1.1

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:restrict
    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - NIST-800-53-CM-6
      - NIST-800-53-SC-7(10)
      - PCI-DSSv4-3.3.1.1
      - disable_users_coredumps
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
    
    - name: Disable core dumps with limits
      lineinfile:
        dest: /etc/security/limits.conf
        regexp: ^[^#].*core
        line: '*        hard       core      0'
        create: true
      when: '"pam" in ansible_facts.packages'
      tags:
      - NIST-800-53-CM-6
      - NIST-800-53-SC-7(10)
      - PCI-DSSv4-3.3.1.1
      - disable_users_coredumps
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
    
    Group   Services   Group contains 33 groups and 64 rules
    [ref]   The best protection against vulnerable software is running less software. This section describes how to review the software which OpenEmbedded installs on a system and disable software which is not needed. It then enumerates the software packages installed on a default OpenEmbedded system and provides guidance about which ones can be safely disabled.

    OpenEmbedded provides a convenient minimal install option that essentially installs the bare necessities for a functional system. When building OpenEmbedded systems, it is highly recommended to select the minimal packages and then build up the system from there.
    Group   Avahi Server   Group contains 1 group and 1 rule
    [ref]   The Avahi daemon implements the DNS Service Discovery and Multicast DNS protocols, which provide service and host discovery on a network. It allows a system to automatically identify resources on the network, such as printers or web servers. This capability is also known as mDNSresponder and is a major part of Zeroconf networking.
    Group   Disable Avahi Server if Possible   Group contains 1 rule
    [ref]   Because the Avahi daemon service keeps an open network port, it is subject to network attacks. Disabling it can reduce the system's vulnerability to such attacks.

    Rule   Disable Avahi Server Software   [ref]

    The avahi-daemon service can be disabled with the following command:
    $ sudo systemctl mask --now avahi-daemon.service
    Rationale:
    Because the Avahi daemon service keeps an open network port, it is subject to network attacks. Its functionality is convenient but is only appropriate if the local network can be trusted.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_service_avahi-daemon_disabled
    References:
    cis-csc11, 14, 3, 9
    cobit5BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.05, DSS06.06
    disaCCI-000366
    isa-62443-20094.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3
    isa-62443-2013SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 7.6
    iso27001-2013A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, A.9.1.2
    nistCM-7(a), CM-7(b), CM-6(a)
    nist-csfPR.IP-1, PR.PT-3
    pcidss42.2.4

    
    [customizations.services]
    masked = ["avahi-daemon"]
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:disable
    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - PCI-DSSv4-2.2.4
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_avahi-daemon_disabled
    
    - name: Disable Avahi Server Software - Collect systemd Services Present in the System
      ansible.builtin.command: systemctl -q list-unit-files --type service
      register: service_exists
      changed_when: false
      failed_when: service_exists.rc not in [0, 1]
      check_mode: false
      when: ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman",
        "container"] and "avahi" in ansible_facts.packages )
      tags:
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - PCI-DSSv4-2.2.4
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_avahi-daemon_disabled
    
    - name: Disable Avahi Server Software - Ensure avahi-daemon.service is Masked
      ansible.builtin.systemd:
        name: avahi-daemon.service
        state: stopped
        enabled: false
        masked: true
      when:
      - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
        and "avahi" in ansible_facts.packages )
      - service_exists.stdout_lines is search("avahi-daemon.service", multiline=True)
      tags:
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - PCI-DSSv4-2.2.4
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_avahi-daemon_disabled
    
    - name: Unit Socket Exists - avahi-daemon.socket
      ansible.builtin.command: systemctl -q list-unit-files avahi-daemon.socket
      register: socket_file_exists
      changed_when: false
      failed_when: socket_file_exists.rc not in [0, 1]
      check_mode: false
      when: ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman",
        "container"] and "avahi" in ansible_facts.packages )
      tags:
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - PCI-DSSv4-2.2.4
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_avahi-daemon_disabled
    
    - name: Disable Avahi Server Software - Disable Socket avahi-daemon
      ansible.builtin.systemd:
        name: avahi-daemon.socket
        enabled: false
        state: stopped
        masked: true
      when:
      - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
        and "avahi" in ansible_facts.packages )
      - socket_file_exists.stdout_lines is search("avahi-daemon.socket", multiline=True)
      tags:
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - PCI-DSSv4-2.2.4
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_avahi-daemon_disabled
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:enable
    include disable_avahi-daemon
    
    class disable_avahi-daemon {
      service {'avahi-daemon':
        enable => false,
        ensure => 'stopped',
      }
    }
    
    Group   Cron and At Daemons   Group contains 1 group and 27 rules
    [ref]   The cron and at services are used to allow commands to be executed at a later time. The cron service is required by almost all systems to perform necessary maintenance tasks, while at may or may not be required on a given system. Both daemons should be configured defensively.
    Group   Restrict at and cron to Authorized Users if Necessary   Group contains 8 rules
    [ref]   The /etc/cron.allow and /etc/at.allow files contain lists of users who are allowed to use cron and at to delay execution of processes. If these files exist and if the corresponding files /etc/cron.deny and /etc/at.deny do not exist, then only users listed in the relevant allow files can run the crontab and at commands to submit jobs to be run at scheduled intervals. On many systems, only the system administrator needs the ability to schedule jobs. Note that even if a given user is not listed in cron.allow, cron jobs can still be run as that user. The cron.allow file controls only administrative access to the crontab command for scheduling and modifying cron jobs.

    To restrict at and cron to only authorized users:
    • Remove the cron.deny file:
      $ sudo rm /etc/cron.deny
    • Edit /etc/cron.allow, adding one line for each user allowed to use the crontab command to create cron jobs.
    • Remove the at.deny file:
      $ sudo rm /etc/at.deny
    • Edit /etc/at.allow, adding one line for each user allowed to use the at command to create at jobs.

    Rule   Ensure that /etc/at.deny does not exist   [ref]

    The file /etc/at.deny should not exist. Use /etc/at.allow instead.
    Rationale:
    Access to at should be restricted. It is easier to manage an allow list than a deny list.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_at_deny_not_exist
    References:
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:disable
    - name: Remove /etc/at.deny
      file:
        path: /etc/at.deny
        state: absent
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - PCI-DSSv4-2.2.6
      - disable_strategy
      - file_at_deny_not_exist
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:disable
    # Remediation is applicable only in certain platforms
    if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
    
    if [[ -f  /etc/at.deny ]]; then
            rm /etc/at.deny
        fi
    
    else
        >&2 echo 'Remediation is not applicable, nothing was done'
    fi
    

    Rule   Ensure that /etc/cron.deny does not exist   [ref]

    The file /etc/cron.deny should not exist. Use /etc/cron.allow instead.
    Rationale:
    Access to cron should be restricted. It is easier to manage an allow list than a deny list.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_cron_deny_not_exist
    References:
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:disable
    - name: Remove /etc/cron.deny
      file:
        path: /etc/cron.deny
        state: absent
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - PCI-DSSv4-2.2.6
      - disable_strategy
      - file_cron_deny_not_exist
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:disable
    # Remediation is applicable only in certain platforms
    if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
    
    if [[ -f  /etc/cron.deny ]]; then
            rm /etc/cron.deny
        fi
    
    else
        >&2 echo 'Remediation is not applicable, nothing was done'
    fi
    

    Rule   Verify Group Who Owns /etc/at.allow file   [ref]

    If /etc/at.allow exists, it must be group-owned by root. To properly set the group owner of /etc/at.allow, run the command:
    $ sudo chgrp root /etc/at.allow
    Rationale:
    If the owner of the at.allow file is not set to root, the possibility exists for an unauthorized user to view or edit sensitive information.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_groupowner_at_allow
    References:
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Test for existence /etc/at.allow
      stat:
        path: /etc/at.allow
      register: file_exists
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_groupowner_at_allow
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    
    - name: Ensure group owner 0 on /etc/at.allow
      file:
        path: /etc/at.allow
        group: '0'
      when:
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - file_exists.stat is defined and file_exists.stat.exists
      tags:
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_groupowner_at_allow
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    # Remediation is applicable only in certain platforms
    if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
    
    chgrp 0 /etc/at.allow
    
    else
        >&2 echo 'Remediation is not applicable, nothing was done'
    fi
    

    Rule   Verify Group Who Owns /etc/cron.allow file   [ref]

    If /etc/cron.allow exists, it must be group-owned by root. To properly set the group owner of /etc/cron.allow, run the command:
    $ sudo chgrp root /etc/cron.allow
    Rationale:
    If the owner of the cron.allow file is not set to root, the possibility exists for an unauthorized user to view or edit sensitive information.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_groupowner_cron_allow
    References:
    cis-csc12, 13, 14, 15, 16, 18, 3, 5
    cobit5APO01.06, DSS05.04, DSS05.07, DSS06.02
    disaCCI-000366
    isa-62443-20094.3.3.7.3
    isa-62443-2013SR 2.1, SR 5.2
    iso27001-2013A.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
    nistCM-6(a), AC-6(1)
    nist-csfPR.AC-4, PR.DS-5
    os-srgSRG-OS-000480-GPOS-00227
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Test for existence /etc/cron.allow
      stat:
        path: /etc/cron.allow
      register: file_exists
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_groupowner_cron_allow
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    
    - name: Ensure group owner 0 on /etc/cron.allow
      file:
        path: /etc/cron.allow
        group: '0'
      when:
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - file_exists.stat is defined and file_exists.stat.exists
      tags:
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_groupowner_cron_allow
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    # Remediation is applicable only in certain platforms
    if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
    
    chgrp 0 /etc/cron.allow
    
    else
        >&2 echo 'Remediation is not applicable, nothing was done'
    fi
    

    Rule   Verify User Who Owns /etc/at.allow file   [ref]

    If /etc/at.allow exists, it must be owned by root. To properly set the owner of /etc/at.allow, run the command:
    $ sudo chown root /etc/at.allow 
    Rationale:
    If the owner of the at.allow file is not set to root, the possibility exists for an unauthorized user to view or edit sensitive information.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_owner_at_allow
    References:
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Test for existence /etc/at.allow
      stat:
        path: /etc/at.allow
      register: file_exists
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_owner_at_allow
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    
    - name: Ensure owner 0 on /etc/at.allow
      file:
        path: /etc/at.allow
        owner: '0'
      when:
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - file_exists.stat is defined and file_exists.stat.exists
      tags:
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_owner_at_allow
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    # Remediation is applicable only in certain platforms
    if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
    
    chown 0 /etc/at.allow
    
    else
        >&2 echo 'Remediation is not applicable, nothing was done'
    fi
    

    Rule   Verify User Who Owns /etc/cron.allow file   [ref]

    If /etc/cron.allow exists, it must be owned by root. To properly set the owner of /etc/cron.allow, run the command:
    $ sudo chown root /etc/cron.allow 
    Rationale:
    If the owner of the cron.allow file is not set to root, the possibility exists for an unauthorized user to view or edit sensitive information.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_owner_cron_allow
    References:
    cis-csc12, 13, 14, 15, 16, 18, 3, 5
    cobit5APO01.06, DSS05.04, DSS05.07, DSS06.02
    disaCCI-000366
    isa-62443-20094.3.3.7.3
    isa-62443-2013SR 2.1, SR 5.2
    iso27001-2013A.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
    nistCM-6(a), AC-6(1)
    nist-csfPR.AC-4, PR.DS-5
    os-srgSRG-OS-000480-GPOS-00227
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Test for existence /etc/cron.allow
      stat:
        path: /etc/cron.allow
      register: file_exists
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_owner_cron_allow
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    
    - name: Ensure owner 0 on /etc/cron.allow
      file:
        path: /etc/cron.allow
        owner: '0'
      when:
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - file_exists.stat is defined and file_exists.stat.exists
      tags:
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_owner_cron_allow
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    # Remediation is applicable only in certain platforms
    if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
    
    chown 0 /etc/cron.allow
    
    else
        >&2 echo 'Remediation is not applicable, nothing was done'
    fi
    

    Rule   Verify Permissions on /etc/at.allow file   [ref]

    If /etc/at.allow exists, it must have permissions 0640 or more restrictive. To properly set the permissions of /etc/at.allow, run the command:
    $ sudo chmod 0640 /etc/at.allow
    Rationale:
    If the permissions of the at.allow file are not set to 0640 or more restrictive, the possibility exists for an unauthorized user to view or edit sensitive information.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_permissions_at_allow
    References:
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Test for existence /etc/at.allow
      stat:
        path: /etc/at.allow
      register: file_exists
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_permissions_at_allow
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    
    - name: Ensure permission u-xs,g-xws,o-xwrt on /etc/at.allow
      file:
        path: /etc/at.allow
        mode: u-xs,g-xws,o-xwrt
      when:
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - file_exists.stat is defined and file_exists.stat.exists
      tags:
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_permissions_at_allow
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    # Remediation is applicable only in certain platforms
    if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
    
    chmod u-xs,g-xws,o-xwrt /etc/at.allow
    
    else
        >&2 echo 'Remediation is not applicable, nothing was done'
    fi
    

    Rule   Verify Permissions on /etc/cron.allow file   [ref]

    If /etc/cron.allow exists, it must have permissions 0640 or more restrictive. To properly set the permissions of /etc/cron.allow, run the command:
    $ sudo chmod 0640 /etc/cron.allow
    Rationale:
    If the permissions of the cron.allow file are not set to 0640 or more restrictive, the possibility exists for an unauthorized user to view or edit sensitive information.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_permissions_cron_allow
    References:
    os-srgSRG-OS-000480-GPOS-00227
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Test for existence /etc/cron.allow
      stat:
        path: /etc/cron.allow
      register: file_exists
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_permissions_cron_allow
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    
    - name: Ensure permission u-xs,g-xws,o-xwrt on /etc/cron.allow
      file:
        path: /etc/cron.allow
        mode: u-xs,g-xws,o-xwrt
      when:
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - file_exists.stat is defined and file_exists.stat.exists
      tags:
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_permissions_cron_allow
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    # Remediation is applicable only in certain platforms
    if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
    
    chmod u-xs,g-xws,o-xwrt /etc/cron.allow
    
    else
        >&2 echo 'Remediation is not applicable, nothing was done'
    fi
    

    Rule   Enable cron Service   [ref]

    The crond service is used to execute commands at preconfigured times. It is required by almost all systems to perform necessary maintenance tasks, such as notifying root of system activity. The crond service can be enabled with the following command:
    $ sudo systemctl enable crond.service
    Rationale:
    Due to its usage for maintenance and security-supporting tasks, enabling the cron daemon is essential.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_service_crond_enabled
    References:
    cis-csc11, 14, 3, 9
    cobit5BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.05, DSS06.06
    hipaa164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii)
    isa-62443-20094.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3
    isa-62443-2013SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 7.6
    iso27001-2013A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, A.9.1.2
    nistCM-6(a)
    nist-csfPR.IP-1, PR.PT-3

    
    [customizations.services]
    enabled = ["crond"]
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:enable
    - name: Enable cron Service - Enable service crond
      block:
    
      - name: Gather the package facts
        package_facts:
          manager: auto
    
      - name: Enable cron Service - Enable Service crond
        ansible.builtin.systemd:
          name: crond
          enabled: true
          state: started
          masked: false
        when:
        - '"cronie" in ansible_facts.packages'
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - NIST-800-53-CM-6(a)
      - enable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_crond_enabled
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:enable
    include enable_crond
    
    class enable_crond {
      service {'crond':
        enable => true,
        ensure => 'running',
      }
    }
    

    Rule   Verify Group Who Owns cron.d   [ref]

    To properly set the group owner of /etc/cron.d, run the command:
    $ sudo chgrp root /etc/cron.d
    Rationale:
    Service configuration files enable or disable features of their respective services that if configured incorrectly can lead to insecure and vulnerable configurations. Therefore, service configuration files should be owned by the correct group to prevent unauthorized changes.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_groupowner_cron_d
    References:
    cis-csc12, 13, 14, 15, 16, 18, 3, 5
    cobit5APO01.06, DSS05.04, DSS05.07, DSS06.02
    isa-62443-20094.3.3.7.3
    isa-62443-2013SR 2.1, SR 5.2
    iso27001-2013A.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
    nistCM-6(a), AC-6(1)
    nist-csfPR.AC-4, PR.DS-5
    os-srgSRG-OS-000480-GPOS-00227
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Ensure group owner on /etc/cron.d/
      file:
        path: /etc/cron.d/
        state: directory
        group: '0'
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_groupowner_cron_d
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    # Remediation is applicable only in certain platforms
    if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
    
    find -H /etc/cron.d/ -maxdepth 1 -type d -exec chgrp 0 {} \;
    
    else
        >&2 echo 'Remediation is not applicable, nothing was done'
    fi
    

    Rule   Verify Group Who Owns cron.daily   [ref]

    To properly set the group owner of /etc/cron.daily, run the command:
    $ sudo chgrp root /etc/cron.daily
    Rationale:
    Service configuration files enable or disable features of their respective services that if configured incorrectly can lead to insecure and vulnerable configurations. Therefore, service configuration files should be owned by the correct group to prevent unauthorized changes.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_groupowner_cron_daily
    References:
    cis-csc12, 13, 14, 15, 16, 18, 3, 5
    cobit5APO01.06, DSS05.04, DSS05.07, DSS06.02
    isa-62443-20094.3.3.7.3
    isa-62443-2013SR 2.1, SR 5.2
    iso27001-2013A.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
    nistCM-6(a), AC-6(1)
    nist-csfPR.AC-4, PR.DS-5
    os-srgSRG-OS-000480-GPOS-00227
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Ensure group owner on /etc/cron.daily/
      file:
        path: /etc/cron.daily/
        state: directory
        group: '0'
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_groupowner_cron_daily
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    # Remediation is applicable only in certain platforms
    if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
    
    find -H /etc/cron.daily/ -maxdepth 1 -type d -exec chgrp 0 {} \;
    
    else
        >&2 echo 'Remediation is not applicable, nothing was done'
    fi
    

    Rule   Verify Group Who Owns cron.hourly   [ref]

    To properly set the group owner of /etc/cron.hourly, run the command:
    $ sudo chgrp root /etc/cron.hourly
    Rationale:
    Service configuration files enable or disable features of their respective services that if configured incorrectly can lead to insecure and vulnerable configurations. Therefore, service configuration files should be owned by the correct group to prevent unauthorized changes.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_groupowner_cron_hourly
    References:
    cis-csc12, 13, 14, 15, 16, 18, 3, 5
    cobit5APO01.06, DSS05.04, DSS05.07, DSS06.02
    isa-62443-20094.3.3.7.3
    isa-62443-2013SR 2.1, SR 5.2
    iso27001-2013A.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
    nistCM-6(a), AC-6(1)
    nist-csfPR.AC-4, PR.DS-5
    os-srgSRG-OS-000480-GPOS-00227
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Ensure group owner on /etc/cron.hourly/
      file:
        path: /etc/cron.hourly/
        state: directory
        group: '0'
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_groupowner_cron_hourly
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    # Remediation is applicable only in certain platforms
    if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
    
    find -H /etc/cron.hourly/ -maxdepth 1 -type d -exec chgrp 0 {} \;
    
    else
        >&2 echo 'Remediation is not applicable, nothing was done'
    fi
    

    Rule   Verify Group Who Owns cron.monthly   [ref]

    To properly set the group owner of /etc/cron.monthly, run the command:
    $ sudo chgrp root /etc/cron.monthly
    Rationale:
    Service configuration files enable or disable features of their respective services that if configured incorrectly can lead to insecure and vulnerable configurations. Therefore, service configuration files should be owned by the correct group to prevent unauthorized changes.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_groupowner_cron_monthly
    References:
    cis-csc12, 13, 14, 15, 16, 18, 3, 5
    cobit5APO01.06, DSS05.04, DSS05.07, DSS06.02
    isa-62443-20094.3.3.7.3
    isa-62443-2013SR 2.1, SR 5.2
    iso27001-2013A.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
    nistCM-6(a), AC-6(1)
    nist-csfPR.AC-4, PR.DS-5
    os-srgSRG-OS-000480-GPOS-00227
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Ensure group owner on /etc/cron.monthly/
      file:
        path: /etc/cron.monthly/
        state: directory
        group: '0'
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_groupowner_cron_monthly
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    # Remediation is applicable only in certain platforms
    if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
    
    find -H /etc/cron.monthly/ -maxdepth 1 -type d -exec chgrp 0 {} \;
    
    else
        >&2 echo 'Remediation is not applicable, nothing was done'
    fi
    

    Rule   Verify Group Who Owns cron.weekly   [ref]

    To properly set the group owner of /etc/cron.weekly, run the command:
    $ sudo chgrp root /etc/cron.weekly
    Rationale:
    Service configuration files enable or disable features of their respective services that if configured incorrectly can lead to insecure and vulnerable configurations. Therefore, service configuration files should be owned by the correct group to prevent unauthorized changes.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_groupowner_cron_weekly
    References:
    cis-csc12, 13, 14, 15, 16, 18, 3, 5
    cobit5APO01.06, DSS05.04, DSS05.07, DSS06.02
    isa-62443-20094.3.3.7.3
    isa-62443-2013SR 2.1, SR 5.2
    iso27001-2013A.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
    nistCM-6(a), AC-6(1)
    nist-csfPR.AC-4, PR.DS-5
    os-srgSRG-OS-000480-GPOS-00227
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Ensure group owner on /etc/cron.weekly/
      file:
        path: /etc/cron.weekly/
        state: directory
        group: '0'
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_groupowner_cron_weekly
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    # Remediation is applicable only in certain platforms
    if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
    
    find -H /etc/cron.weekly/ -maxdepth 1 -type d -exec chgrp 0 {} \;
    
    else
        >&2 echo 'Remediation is not applicable, nothing was done'
    fi
    

    Rule   Verify Group Who Owns Crontab   [ref]

    To properly set the group owner of /etc/crontab, run the command:
    $ sudo chgrp root /etc/crontab
    Rationale:
    Service configuration files enable or disable features of their respective services that if configured incorrectly can lead to insecure and vulnerable configurations. Therefore, service configuration files should be owned by the correct group to prevent unauthorized changes.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_groupowner_crontab
    References:
    cis-csc12, 13, 14, 15, 16, 18, 3, 5
    cobit5APO01.06, DSS05.04, DSS05.07, DSS06.02
    isa-62443-20094.3.3.7.3
    isa-62443-2013SR 2.1, SR 5.2
    iso27001-2013A.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
    nistCM-6(a), AC-6(1)
    nist-csfPR.AC-4, PR.DS-5
    os-srgSRG-OS-000480-GPOS-00227
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Test for existence /etc/crontab
      stat:
        path: /etc/crontab
      register: file_exists
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_groupowner_crontab
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    
    - name: Ensure group owner 0 on /etc/crontab
      file:
        path: /etc/crontab
        group: '0'
      when:
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - file_exists.stat is defined and file_exists.stat.exists
      tags:
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_groupowner_crontab
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    # Remediation is applicable only in certain platforms
    if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
    
    chgrp 0 /etc/crontab
    
    else
        >&2 echo 'Remediation is not applicable, nothing was done'
    fi
    

    Rule   Verify Owner on cron.d   [ref]

    To properly set the owner of /etc/cron.d, run the command:
    $ sudo chown root /etc/cron.d 
    Rationale:
    Service configuration files enable or disable features of their respective services that if configured incorrectly can lead to insecure and vulnerable configurations. Therefore, service configuration files should be owned by the correct user to prevent unauthorized changes.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_owner_cron_d
    References:
    cis-csc12, 13, 14, 15, 16, 18, 3, 5
    cobit5APO01.06, DSS05.04, DSS05.07, DSS06.02
    isa-62443-20094.3.3.7.3
    isa-62443-2013SR 2.1, SR 5.2
    iso27001-2013A.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
    nistCM-6(a), AC-6(1)
    nist-csfPR.AC-4, PR.DS-5
    os-srgSRG-OS-000480-GPOS-00227
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Ensure owner on directory /etc/cron.d/
      file:
        path: /etc/cron.d/
        state: directory
        owner: '0'
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_owner_cron_d
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    # Remediation is applicable only in certain platforms
    if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
    
    find -H /etc/cron.d/ -maxdepth 1 -type d -exec chown 0 {} \;
    
    else
        >&2 echo 'Remediation is not applicable, nothing was done'
    fi
    

    Rule   Verify Owner on cron.daily   [ref]

    To properly set the owner of /etc/cron.daily, run the command:
    $ sudo chown root /etc/cron.daily 
    Rationale:
    Service configuration files enable or disable features of their respective services that if configured incorrectly can lead to insecure and vulnerable configurations. Therefore, service configuration files should be owned by the correct user to prevent unauthorized changes.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_owner_cron_daily
    References:
    cis-csc12, 13, 14, 15, 16, 18, 3, 5
    cobit5APO01.06, DSS05.04, DSS05.07, DSS06.02
    isa-62443-20094.3.3.7.3
    isa-62443-2013SR 2.1, SR 5.2
    iso27001-2013A.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
    nistCM-6(a), AC-6(1)
    nist-csfPR.AC-4, PR.DS-5
    os-srgSRG-OS-000480-GPOS-00227
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Ensure owner on directory /etc/cron.daily/
      file:
        path: /etc/cron.daily/
        state: directory
        owner: '0'
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_owner_cron_daily
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    # Remediation is applicable only in certain platforms
    if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
    
    find -H /etc/cron.daily/ -maxdepth 1 -type d -exec chown 0 {} \;
    
    else
        >&2 echo 'Remediation is not applicable, nothing was done'
    fi
    

    Rule   Verify Owner on cron.hourly   [ref]

    To properly set the owner of /etc/cron.hourly, run the command:
    $ sudo chown root /etc/cron.hourly 
    Rationale:
    Service configuration files enable or disable features of their respective services that if configured incorrectly can lead to insecure and vulnerable configurations. Therefore, service configuration files should be owned by the correct user to prevent unauthorized changes.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_owner_cron_hourly
    References:
    cis-csc12, 13, 14, 15, 16, 18, 3, 5
    cobit5APO01.06, DSS05.04, DSS05.07, DSS06.02
    isa-62443-20094.3.3.7.3
    isa-62443-2013SR 2.1, SR 5.2
    iso27001-2013A.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
    nistCM-6(a), AC-6(1)
    nist-csfPR.AC-4, PR.DS-5
    os-srgSRG-OS-000480-GPOS-00227
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Ensure owner on directory /etc/cron.hourly/
      file:
        path: /etc/cron.hourly/
        state: directory
        owner: '0'
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_owner_cron_hourly
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    # Remediation is applicable only in certain platforms
    if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
    
    find -H /etc/cron.hourly/ -maxdepth 1 -type d -exec chown 0 {} \;
    
    else
        >&2 echo 'Remediation is not applicable, nothing was done'
    fi
    

    Rule   Verify Owner on cron.monthly   [ref]

    To properly set the owner of /etc/cron.monthly, run the command:
    $ sudo chown root /etc/cron.monthly 
    Rationale:
    Service configuration files enable or disable features of their respective services that if configured incorrectly can lead to insecure and vulnerable configurations. Therefore, service configuration files should be owned by the correct user to prevent unauthorized changes.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_owner_cron_monthly
    References:
    cis-csc12, 13, 14, 15, 16, 18, 3, 5
    cobit5APO01.06, DSS05.04, DSS05.07, DSS06.02
    isa-62443-20094.3.3.7.3
    isa-62443-2013SR 2.1, SR 5.2
    iso27001-2013A.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
    nistCM-6(a), AC-6(1)
    nist-csfPR.AC-4, PR.DS-5
    os-srgSRG-OS-000480-GPOS-00227
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Ensure owner on directory /etc/cron.monthly/
      file:
        path: /etc/cron.monthly/
        state: directory
        owner: '0'
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_owner_cron_monthly
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    # Remediation is applicable only in certain platforms
    if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
    
    find -H /etc/cron.monthly/ -maxdepth 1 -type d -exec chown 0 {} \;
    
    else
        >&2 echo 'Remediation is not applicable, nothing was done'
    fi
    

    Rule   Verify Owner on cron.weekly   [ref]

    To properly set the owner of /etc/cron.weekly, run the command:
    $ sudo chown root /etc/cron.weekly 
    Rationale:
    Service configuration files enable or disable features of their respective services that if configured incorrectly can lead to insecure and vulnerable configurations. Therefore, service configuration files should be owned by the correct user to prevent unauthorized changes.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_owner_cron_weekly
    References:
    cis-csc12, 13, 14, 15, 16, 18, 3, 5
    cobit5APO01.06, DSS05.04, DSS05.07, DSS06.02
    isa-62443-20094.3.3.7.3
    isa-62443-2013SR 2.1, SR 5.2
    iso27001-2013A.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
    nistCM-6(a), AC-6(1)
    nist-csfPR.AC-4, PR.DS-5
    os-srgSRG-OS-000480-GPOS-00227
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Ensure owner on directory /etc/cron.weekly/
      file:
        path: /etc/cron.weekly/
        state: directory
        owner: '0'
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_owner_cron_weekly
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    # Remediation is applicable only in certain platforms
    if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
    
    find -H /etc/cron.weekly/ -maxdepth 1 -type d -exec chown 0 {} \;
    
    else
        >&2 echo 'Remediation is not applicable, nothing was done'
    fi
    

    Rule   Verify Owner on crontab   [ref]

    To properly set the owner of /etc/crontab, run the command:
    $ sudo chown root /etc/crontab 
    Rationale:
    Service configuration files enable or disable features of their respective services that if configured incorrectly can lead to insecure and vulnerable configurations. Therefore, service configuration files should be owned by the correct user to prevent unauthorized changes.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_owner_crontab
    References:
    cis-csc12, 13, 14, 15, 16, 18, 3, 5
    cobit5APO01.06, DSS05.04, DSS05.07, DSS06.02
    isa-62443-20094.3.3.7.3
    isa-62443-2013SR 2.1, SR 5.2
    iso27001-2013A.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
    nistCM-6(a), AC-6(1)
    nist-csfPR.AC-4, PR.DS-5
    os-srgSRG-OS-000480-GPOS-00227
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Test for existence /etc/crontab
      stat:
        path: /etc/crontab
      register: file_exists
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_owner_crontab
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    
    - name: Ensure owner 0 on /etc/crontab
      file:
        path: /etc/crontab
        owner: '0'
      when:
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - file_exists.stat is defined and file_exists.stat.exists
      tags:
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_owner_crontab
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    # Remediation is applicable only in certain platforms
    if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
    
    chown 0 /etc/crontab
    
    else
        >&2 echo 'Remediation is not applicable, nothing was done'
    fi
    

    Rule   Verify Permissions on cron.d   [ref]

    To properly set the permissions of /etc/cron.d, run the command:
    $ sudo chmod 0700 /etc/cron.d
    Rationale:
    Service configuration files enable or disable features of their respective services that if configured incorrectly can lead to insecure and vulnerable configurations. Therefore, service configuration files should have the correct access rights to prevent unauthorized changes.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_permissions_cron_d
    References:
    cis-csc12, 13, 14, 15, 16, 18, 3, 5
    cobit5APO01.06, DSS05.04, DSS05.07, DSS06.02
    isa-62443-20094.3.3.7.3
    isa-62443-2013SR 2.1, SR 5.2
    iso27001-2013A.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
    nistCM-6(a), AC-6(1)
    nist-csfPR.AC-4, PR.DS-5
    os-srgSRG-OS-000480-GPOS-00227
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Find /etc/cron.d/ file(s)
      command: 'find -H /etc/cron.d/ -maxdepth 1 -perm /u+s,g+xwrs,o+xwrt  -type d '
      register: files_found
      changed_when: false
      failed_when: false
      check_mode: false
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_permissions_cron_d
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    
    - name: Set permissions for /etc/cron.d/ file(s)
      file:
        path: '{{ item }}'
        mode: u-s,g-xwrs,o-xwrt
        state: directory
      with_items:
      - '{{ files_found.stdout_lines }}'
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_permissions_cron_d
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    # Remediation is applicable only in certain platforms
    if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
    
    find -H /etc/cron.d/ -maxdepth 1 -perm /u+s,g+xwrs,o+xwrt -type d -exec chmod u-s,g-xwrs,o-xwrt {} \;
    
    else
        >&2 echo 'Remediation is not applicable, nothing was done'
    fi
    

    Rule   Verify Permissions on cron.daily   [ref]

    To properly set the permissions of /etc/cron.daily, run the command:
    $ sudo chmod 0700 /etc/cron.daily
    Rationale:
    Service configuration files enable or disable features of their respective services that if configured incorrectly can lead to insecure and vulnerable configurations. Therefore, service configuration files should have the correct access rights to prevent unauthorized changes.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_permissions_cron_daily
    References:
    cis-csc12, 13, 14, 15, 16, 18, 3, 5
    cobit5APO01.06, DSS05.04, DSS05.07, DSS06.02
    isa-62443-20094.3.3.7.3
    isa-62443-2013SR 2.1, SR 5.2
    iso27001-2013A.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
    nistCM-6(a), AC-6(1)
    nist-csfPR.AC-4, PR.DS-5
    os-srgSRG-OS-000480-GPOS-00227
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Find /etc/cron.daily/ file(s)
      command: 'find -H /etc/cron.daily/ -maxdepth 1 -perm /u+s,g+xwrs,o+xwrt  -type d '
      register: files_found
      changed_when: false
      failed_when: false
      check_mode: false
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_permissions_cron_daily
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    
    - name: Set permissions for /etc/cron.daily/ file(s)
      file:
        path: '{{ item }}'
        mode: u-s,g-xwrs,o-xwrt
        state: directory
      with_items:
      - '{{ files_found.stdout_lines }}'
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_permissions_cron_daily
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    # Remediation is applicable only in certain platforms
    if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
    
    find -H /etc/cron.daily/ -maxdepth 1 -perm /u+s,g+xwrs,o+xwrt -type d -exec chmod u-s,g-xwrs,o-xwrt {} \;
    
    else
        >&2 echo 'Remediation is not applicable, nothing was done'
    fi
    

    Rule   Verify Permissions on cron.hourly   [ref]

    To properly set the permissions of /etc/cron.hourly, run the command:
    $ sudo chmod 0700 /etc/cron.hourly
    Rationale:
    Service configuration files enable or disable features of their respective services that if configured incorrectly can lead to insecure and vulnerable configurations. Therefore, service configuration files should have the correct access rights to prevent unauthorized changes.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_permissions_cron_hourly
    References:
    cis-csc12, 13, 14, 15, 16, 18, 3, 5
    cobit5APO01.06, DSS05.04, DSS05.07, DSS06.02
    isa-62443-20094.3.3.7.3
    isa-62443-2013SR 2.1, SR 5.2
    iso27001-2013A.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
    nistCM-6(a), AC-6(1)
    nist-csfPR.AC-4, PR.DS-5
    os-srgSRG-OS-000480-GPOS-00227
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Find /etc/cron.hourly/ file(s)
      command: 'find -H /etc/cron.hourly/ -maxdepth 1 -perm /u+s,g+xwrs,o+xwrt  -type
        d '
      register: files_found
      changed_when: false
      failed_when: false
      check_mode: false
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_permissions_cron_hourly
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    
    - name: Set permissions for /etc/cron.hourly/ file(s)
      file:
        path: '{{ item }}'
        mode: u-s,g-xwrs,o-xwrt
        state: directory
      with_items:
      - '{{ files_found.stdout_lines }}'
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_permissions_cron_hourly
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    # Remediation is applicable only in certain platforms
    if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
    
    find -H /etc/cron.hourly/ -maxdepth 1 -perm /u+s,g+xwrs,o+xwrt -type d -exec chmod u-s,g-xwrs,o-xwrt {} \;
    
    else
        >&2 echo 'Remediation is not applicable, nothing was done'
    fi
    

    Rule   Verify Permissions on cron.monthly   [ref]

    To properly set the permissions of /etc/cron.monthly, run the command:
    $ sudo chmod 0700 /etc/cron.monthly
    Rationale:
    Service configuration files enable or disable features of their respective services that if configured incorrectly can lead to insecure and vulnerable configurations. Therefore, service configuration files should have the correct access rights to prevent unauthorized changes.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_permissions_cron_monthly
    References:
    cis-csc12, 13, 14, 15, 16, 18, 3, 5
    cobit5APO01.06, DSS05.04, DSS05.07, DSS06.02
    isa-62443-20094.3.3.7.3
    isa-62443-2013SR 2.1, SR 5.2
    iso27001-2013A.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
    nistCM-6(a), AC-6(1)
    nist-csfPR.AC-4, PR.DS-5
    os-srgSRG-OS-000480-GPOS-00227
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Find /etc/cron.monthly/ file(s)
      command: 'find -H /etc/cron.monthly/ -maxdepth 1 -perm /u+s,g+xwrs,o+xwrt  -type
        d '
      register: files_found
      changed_when: false
      failed_when: false
      check_mode: false
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_permissions_cron_monthly
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    
    - name: Set permissions for /etc/cron.monthly/ file(s)
      file:
        path: '{{ item }}'
        mode: u-s,g-xwrs,o-xwrt
        state: directory
      with_items:
      - '{{ files_found.stdout_lines }}'
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_permissions_cron_monthly
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    # Remediation is applicable only in certain platforms
    if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
    
    find -H /etc/cron.monthly/ -maxdepth 1 -perm /u+s,g+xwrs,o+xwrt -type d -exec chmod u-s,g-xwrs,o-xwrt {} \;
    
    else
        >&2 echo 'Remediation is not applicable, nothing was done'
    fi
    

    Rule   Verify Permissions on cron.weekly   [ref]

    To properly set the permissions of /etc/cron.weekly, run the command:
    $ sudo chmod 0700 /etc/cron.weekly
    Rationale:
    Service configuration files enable or disable features of their respective services that if configured incorrectly can lead to insecure and vulnerable configurations. Therefore, service configuration files should have the correct access rights to prevent unauthorized changes.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_permissions_cron_weekly
    References:
    cis-csc12, 13, 14, 15, 16, 18, 3, 5
    cobit5APO01.06, DSS05.04, DSS05.07, DSS06.02
    isa-62443-20094.3.3.7.3
    isa-62443-2013SR 2.1, SR 5.2
    iso27001-2013A.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
    nistCM-6(a), AC-6(1)
    nist-csfPR.AC-4, PR.DS-5
    os-srgSRG-OS-000480-GPOS-00227
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Find /etc/cron.weekly/ file(s)
      command: 'find -H /etc/cron.weekly/ -maxdepth 1 -perm /u+s,g+xwrs,o+xwrt  -type
        d '
      register: files_found
      changed_when: false
      failed_when: false
      check_mode: false
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_permissions_cron_weekly
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    
    - name: Set permissions for /etc/cron.weekly/ file(s)
      file:
        path: '{{ item }}'
        mode: u-s,g-xwrs,o-xwrt
        state: directory
      with_items:
      - '{{ files_found.stdout_lines }}'
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_permissions_cron_weekly
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    # Remediation is applicable only in certain platforms
    if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
    
    find -H /etc/cron.weekly/ -maxdepth 1 -perm /u+s,g+xwrs,o+xwrt -type d -exec chmod u-s,g-xwrs,o-xwrt {} \;
    
    else
        >&2 echo 'Remediation is not applicable, nothing was done'
    fi
    

    Rule   Verify Permissions on crontab   [ref]

    To properly set the permissions of /etc/crontab, run the command:
    $ sudo chmod 0600 /etc/crontab
    Rationale:
    Service configuration files enable or disable features of their respective services that if configured incorrectly can lead to insecure and vulnerable configurations. Therefore, service configuration files should have the correct access rights to prevent unauthorized changes.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_permissions_crontab
    References:
    cis-csc12, 13, 14, 15, 16, 18, 3, 5
    cobit5APO01.06, DSS05.04, DSS05.07, DSS06.02
    isa-62443-20094.3.3.7.3
    isa-62443-2013SR 2.1, SR 5.2
    iso27001-2013A.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
    nistCM-6(a), AC-6(1)
    nist-csfPR.AC-4, PR.DS-5
    os-srgSRG-OS-000480-GPOS-00227
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Test for existence /etc/crontab
      stat:
        path: /etc/crontab
      register: file_exists
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_permissions_crontab
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    
    - name: Ensure permission u-xs,g-xwrs,o-xwrt on /etc/crontab
      file:
        path: /etc/crontab
        mode: u-xs,g-xwrs,o-xwrt
      when:
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - file_exists.stat is defined and file_exists.stat.exists
      tags:
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - file_permissions_crontab
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    # Remediation is applicable only in certain platforms
    if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
    
    chmod u-xs,g-xwrs,o-xwrt /etc/crontab
    
    else
        >&2 echo 'Remediation is not applicable, nothing was done'
    fi
    
    Group   DHCP   Group contains 1 group and 1 rule
    [ref]   The Dynamic Host Configuration Protocol (DHCP) allows systems to request and obtain an IP address and other configuration parameters from a server.

    This guide recommends configuring networking on clients by manually editing the appropriate files under /etc/sysconfig. Use of DHCP can make client systems vulnerable to compromise by rogue DHCP servers, and should be avoided unless necessary. If using DHCP is necessary, however, there are best practices that should be followed to minimize security risk.
    Group   Disable DHCP Server   Group contains 1 rule
    [ref]   The DHCP server dhcpd is not installed or activated by default. If the software was installed and activated, but the system does not need to act as a DHCP server, it should be disabled and removed.

    Rule   Disable DHCP Service   [ref]

    The dhcpd service should be disabled on any system that does not need to act as a DHCP server. The dhcpd service can be disabled with the following command:
    $ sudo systemctl mask --now dhcpd.service
    Rationale:
    Unmanaged or unintentionally activated DHCP servers may provide faulty information to clients, interfering with the operation of a legitimate site DHCP server if there is one.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_service_dhcpd_disabled
    References:
    cis-csc11, 14, 3, 9
    cobit5BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.05, DSS06.06
    disaCCI-000366
    isa-62443-20094.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3
    isa-62443-2013SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 7.6
    iso27001-2013A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, A.9.1.2
    nistCM-7(a), CM-7(b), CM-6(a)
    nist-csfPR.IP-1, PR.PT-3

    
    [customizations.services]
    masked = ["dhcpd"]
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:disable
    - name: Disable DHCP Service - Collect systemd Services Present in the System
      ansible.builtin.command: systemctl -q list-unit-files --type service
      register: service_exists
      changed_when: false
      failed_when: service_exists.rc not in [0, 1]
      check_mode: false
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_dhcpd_disabled
    
    - name: Disable DHCP Service - Ensure dhcpd.service is Masked
      ansible.builtin.systemd:
        name: dhcpd.service
        state: stopped
        enabled: false
        masked: true
      when:
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - service_exists.stdout_lines is search("dhcpd.service", multiline=True)
      tags:
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_dhcpd_disabled
    
    - name: Unit Socket Exists - dhcpd.socket
      ansible.builtin.command: systemctl -q list-unit-files dhcpd.socket
      register: socket_file_exists
      changed_when: false
      failed_when: socket_file_exists.rc not in [0, 1]
      check_mode: false
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_dhcpd_disabled
    
    - name: Disable DHCP Service - Disable Socket dhcpd
      ansible.builtin.systemd:
        name: dhcpd.socket
        enabled: false
        state: stopped
        masked: true
      when:
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - socket_file_exists.stdout_lines is search("dhcpd.socket", multiline=True)
      tags:
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_dhcpd_disabled
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:enable
    include disable_dhcpd
    
    class disable_dhcpd {
      service {'dhcpd':
        enable => false,
        ensure => 'stopped',
      }
    }
    
    Group   DNS Server   Group contains 1 group and 1 rule
    [ref]   Most organizations have an operational need to run at least one nameserver. However, there are many common attacks involving DNS server software, and this server software should be disabled on any system on which it is not needed.
    Group   Disable DNS Server   Group contains 1 rule
    [ref]   DNS software should be disabled on any systems which does not need to be a nameserver. Note that the BIND DNS server software is not installed on OpenEmbedded by default. The remainder of this section discusses secure configuration of systems which must be nameservers.

    Rule   Disable named Service   [ref]

    The named service can be disabled with the following command:
    $ sudo systemctl mask --now named.service
    Rationale:
    All network services involve some risk of compromise due to implementation flaws and should be disabled if possible.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_service_named_disabled
    References:
    cis-csc11, 14, 3, 9
    cobit5BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.05, DSS06.06
    disaCCI-000366
    isa-62443-20094.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3
    isa-62443-2013SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 7.6
    iso27001-2013A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, A.9.1.2
    nistCM-7(a), CM-7(b), CM-6(a)
    nist-csfPR.IP-1, PR.PT-3

    
    [customizations.services]
    masked = ["named"]
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:disable
    - name: Disable named Service - Collect systemd Services Present in the System
      ansible.builtin.command: systemctl -q list-unit-files --type service
      register: service_exists
      changed_when: false
      failed_when: service_exists.rc not in [0, 1]
      check_mode: false
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_named_disabled
    
    - name: Disable named Service - Ensure named.service is Masked
      ansible.builtin.systemd:
        name: named.service
        state: stopped
        enabled: false
        masked: true
      when:
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - service_exists.stdout_lines is search("named.service", multiline=True)
      tags:
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_named_disabled
    
    - name: Unit Socket Exists - named.socket
      ansible.builtin.command: systemctl -q list-unit-files named.socket
      register: socket_file_exists
      changed_when: false
      failed_when: socket_file_exists.rc not in [0, 1]
      check_mode: false
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_named_disabled
    
    - name: Disable named Service - Disable Socket named
      ansible.builtin.systemd:
        name: named.socket
        enabled: false
        state: stopped
        masked: true
      when:
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - socket_file_exists.stdout_lines is search("named.socket", multiline=True)
      tags:
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_named_disabled
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:enable
    include disable_named
    
    class disable_named {
      service {'named':
        enable => false,
        ensure => 'stopped',
      }
    }
    
    Group   FTP Server   Group contains 1 group and 1 rule
    [ref]   FTP is a common method for allowing remote access to files. Like telnet, the FTP protocol is unencrypted, which means that passwords and other data transmitted during the session can be captured and that the session is vulnerable to hijacking. Therefore, running the FTP server software is not recommended.

    However, there are some FTP server configurations which may be appropriate for some environments, particularly those which allow only read-only anonymous access as a means of downloading data available to the public.
    Group   Disable vsftpd if Possible   Group contains 1 rule
    [ref]   To minimize attack surface, disable vsftpd if at all possible.

    Rule   Disable vsftpd Service   [ref]

    The vsftpd service can be disabled with the following command:
    $ sudo systemctl mask --now vsftpd.service
    Rationale:
    Running FTP server software provides a network-based avenue of attack, and should be disabled if not needed. Furthermore, the FTP protocol is unencrypted and creates a risk of compromising sensitive information.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_service_vsftpd_disabled
    References:
    cis-csc11, 14, 3, 9
    cobit5BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.05, DSS06.06
    disaCCI-001436
    isa-62443-20094.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3
    isa-62443-2013SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 7.6
    iso27001-2013A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, A.9.1.2
    nistCM-7(a), CM-7(b), CM-6(a)
    nist-csfPR.IP-1, PR.PT-3

    
    [customizations.services]
    masked = ["vsftpd"]
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:disable
    - name: Disable vsftpd Service - Collect systemd Services Present in the System
      ansible.builtin.command: systemctl -q list-unit-files --type service
      register: service_exists
      changed_when: false
      failed_when: service_exists.rc not in [0, 1]
      check_mode: false
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_vsftpd_disabled
    
    - name: Disable vsftpd Service - Ensure vsftpd.service is Masked
      ansible.builtin.systemd:
        name: vsftpd.service
        state: stopped
        enabled: false
        masked: true
      when:
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - service_exists.stdout_lines is search("vsftpd.service", multiline=True)
      tags:
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_vsftpd_disabled
    
    - name: Unit Socket Exists - vsftpd.socket
      ansible.builtin.command: systemctl -q list-unit-files vsftpd.socket
      register: socket_file_exists
      changed_when: false
      failed_when: socket_file_exists.rc not in [0, 1]
      check_mode: false
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_vsftpd_disabled
    
    - name: Disable vsftpd Service - Disable Socket vsftpd
      ansible.builtin.systemd:
        name: vsftpd.socket
        enabled: false
        state: stopped
        masked: true
      when:
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - socket_file_exists.stdout_lines is search("vsftpd.socket", multiline=True)
      tags:
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_vsftpd_disabled
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:enable
    include disable_vsftpd
    
    class disable_vsftpd {
      service {'vsftpd':
        enable => false,
        ensure => 'stopped',
      }
    }
    
    Group   Web Server   Group contains 1 group and 1 rule
    [ref]   The web server is responsible for providing access to content via the HTTP protocol. Web servers represent a significant security risk because:

    • The HTTP port is commonly probed by malicious sources
    • Web server software is very complex, and includes a long history of vulnerabilities
    • The HTTP protocol is unencrypted and vulnerable to passive monitoring


    The system's default web server software is Apache 2 and is provided in the RPM package httpd.
    Group   Disable Apache if Possible   Group contains 1 rule
    [ref]   If Apache was installed and activated, but the system does not need to act as a web server, then it should be disabled and removed from the system.

    Rule   Disable httpd Service   [ref]

    The httpd service can be disabled with the following command:
    $ sudo systemctl mask --now httpd.service
    Rationale:
    Running web server software provides a network-based avenue of attack, and should be disabled if not needed.
    Severity: 
    unknown
    Rule ID:xccdf_org.ssgproject.content_rule_service_httpd_disabled
    References:
    cis-csc11, 14, 3, 9
    cobit5BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.05, DSS06.06
    isa-62443-20094.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3
    isa-62443-2013SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 7.6
    iso27001-2013A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, A.9.1.2
    nistCM-7(a), CM-7(b), CM-6(a)
    nist-csfPR.IP-1, PR.PT-3

    
    [customizations.services]
    masked = ["httpd"]
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:disable
    - name: Disable httpd Service - Collect systemd Services Present in the System
      ansible.builtin.command: systemctl -q list-unit-files --type service
      register: service_exists
      changed_when: false
      failed_when: service_exists.rc not in [0, 1]
      check_mode: false
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - low_disruption
      - no_reboot_needed
      - service_httpd_disabled
      - unknown_severity
    
    - name: Disable httpd Service - Ensure httpd.service is Masked
      ansible.builtin.systemd:
        name: httpd.service
        state: stopped
        enabled: false
        masked: true
      when:
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - service_exists.stdout_lines is search("httpd.service", multiline=True)
      tags:
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - low_disruption
      - no_reboot_needed
      - service_httpd_disabled
      - unknown_severity
    
    - name: Unit Socket Exists - httpd.socket
      ansible.builtin.command: systemctl -q list-unit-files httpd.socket
      register: socket_file_exists
      changed_when: false
      failed_when: socket_file_exists.rc not in [0, 1]
      check_mode: false
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - low_disruption
      - no_reboot_needed
      - service_httpd_disabled
      - unknown_severity
    
    - name: Disable httpd Service - Disable Socket httpd
      ansible.builtin.systemd:
        name: httpd.socket
        enabled: false
        state: stopped
        masked: true
      when:
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - socket_file_exists.stdout_lines is search("httpd.socket", multiline=True)
      tags:
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - low_disruption
      - no_reboot_needed
      - service_httpd_disabled
      - unknown_severity
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:enable
    include disable_httpd
    
    class disable_httpd {
      service {'httpd':
        enable => false,
        ensure => 'stopped',
      }
    }
    
    Group   IMAP and POP3 Server   Group contains 1 group and 1 rule
    [ref]   Dovecot provides IMAP and POP3 services. It is not installed by default. The project page at http://www.dovecot.org contains more detailed information about Dovecot configuration.
    Group   Disable Dovecot   Group contains 1 rule
    [ref]   If the system does not need to operate as an IMAP or POP3 server, the dovecot software should be disabled and removed.

    Rule   Disable Dovecot Service   [ref]

    The dovecot service can be disabled with the following command:
    $ sudo systemctl mask --now dovecot.service
    Rationale:
    Running an IMAP or POP3 server provides a network-based avenue of attack, and should be disabled if not needed.
    Severity: 
    unknown
    Rule ID:xccdf_org.ssgproject.content_rule_service_dovecot_disabled

    
    [customizations.services]
    masked = ["dovecot"]
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:disable
    - name: Disable Dovecot Service - Collect systemd Services Present in the System
      ansible.builtin.command: systemctl -q list-unit-files --type service
      register: service_exists
      changed_when: false
      failed_when: service_exists.rc not in [0, 1]
      check_mode: false
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - disable_strategy
      - low_complexity
      - low_disruption
      - no_reboot_needed
      - service_dovecot_disabled
      - unknown_severity
    
    - name: Disable Dovecot Service - Ensure dovecot.service is Masked
      ansible.builtin.systemd:
        name: dovecot.service
        state: stopped
        enabled: false
        masked: true
      when:
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - service_exists.stdout_lines is search("dovecot.service", multiline=True)
      tags:
      - disable_strategy
      - low_complexity
      - low_disruption
      - no_reboot_needed
      - service_dovecot_disabled
      - unknown_severity
    
    - name: Unit Socket Exists - dovecot.socket
      ansible.builtin.command: systemctl -q list-unit-files dovecot.socket
      register: socket_file_exists
      changed_when: false
      failed_when: socket_file_exists.rc not in [0, 1]
      check_mode: false
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - disable_strategy
      - low_complexity
      - low_disruption
      - no_reboot_needed
      - service_dovecot_disabled
      - unknown_severity
    
    - name: Disable Dovecot Service - Disable Socket dovecot
      ansible.builtin.systemd:
        name: dovecot.socket
        enabled: false
        state: stopped
        masked: true
      when:
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - socket_file_exists.stdout_lines is search("dovecot.socket", multiline=True)
      tags:
      - disable_strategy
      - low_complexity
      - low_disruption
      - no_reboot_needed
      - service_dovecot_disabled
      - unknown_severity
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:enable
    include disable_dovecot
    
    class disable_dovecot {
      service {'dovecot':
        enable => false,
        ensure => 'stopped',
      }
    }
    
    Group   LDAP   Group contains 1 group and 1 rule
    [ref]   LDAP is a popular directory service, that is, a standardized way of looking up information from a central database. OpenEmbedded includes software that enables a system to act as both an LDAP client and server.
    Group   Configure OpenLDAP Server   Group contains 1 rule
    [ref]   This section details some security-relevant settings for an OpenLDAP server.

    Rule   Disable LDAP Server (slapd)   [ref]

    The Lightweight Directory Access Protocol (LDAP) is a service that provides a method for looking up information from a central database.
    Rationale:
    If the system will not need to act as an LDAP server, it is recommended that the software be disabled to reduce the potential attack surface.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_service_slapd_disabled

    
    [customizations.services]
    masked = ["slapd"]
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:disable
    - name: Disable LDAP Server (slapd) - Collect systemd Services Present in the System
      ansible.builtin.command: systemctl -q list-unit-files --type service
      register: service_exists
      changed_when: false
      failed_when: service_exists.rc not in [0, 1]
      check_mode: false
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_slapd_disabled
    
    - name: Disable LDAP Server (slapd) - Ensure slapd.service is Masked
      ansible.builtin.systemd:
        name: slapd.service
        state: stopped
        enabled: false
        masked: true
      when:
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - service_exists.stdout_lines is search("slapd.service", multiline=True)
      tags:
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_slapd_disabled
    
    - name: Unit Socket Exists - slapd.socket
      ansible.builtin.command: systemctl -q list-unit-files slapd.socket
      register: socket_file_exists
      changed_when: false
      failed_when: socket_file_exists.rc not in [0, 1]
      check_mode: false
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_slapd_disabled
    
    - name: Disable LDAP Server (slapd) - Disable Socket slapd
      ansible.builtin.systemd:
        name: slapd.socket
        enabled: false
        state: stopped
        masked: true
      when:
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - socket_file_exists.stdout_lines is search("slapd.socket", multiline=True)
      tags:
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_slapd_disabled
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:enable
    include disable_slapd
    
    class disable_slapd {
      service {'slapd':
        enable => false,
        ensure => 'stopped',
      }
    }
    
    Group   NFS and RPC   Group contains 4 groups and 2 rules
    [ref]   The Network File System is a popular distributed filesystem for the Unix environment, and is very widely deployed. This section discusses the circumstances under which it is possible to disable NFS and its dependencies, and then details steps which should be taken to secure NFS's configuration. This section is relevant to systems operating as NFS clients, as well as to those operating as NFS servers.
    Group   Disable All NFS Services if Possible   Group contains 1 group and 1 rule
    [ref]   If there is not a reason for the system to operate as either an NFS client or an NFS server, follow all instructions in this section to disable subsystems required by NFS.
    Warning:  The steps in this section will prevent a system from operating as either an NFS client or an NFS server. Only perform these steps on systems which do not need NFS at all.
    Group   Disable Services Used Only by NFS   Group contains 1 rule
    [ref]   If NFS is not needed, disable the NFS client daemons nfslock, rpcgssd, and rpcidmapd.

    All of these daemons run with elevated privileges, and many listen for network connections. If they are not needed, they should be disabled to improve system security posture.

    Rule   Disable rpcbind Service   [ref]

    The rpcbind utility maps RPC services to the ports on which they listen. RPC processes notify rpcbind when they start, registering the ports they are listening on and the RPC program numbers they expect to serve. The rpcbind service redirects the client to the proper port number so it can communicate with the requested service. If the system does not require RPC (such as for NFS servers) then this service should be disabled. The rpcbind service can be disabled with the following command:
    $ sudo systemctl mask --now rpcbind.service
    Rationale:
    If the system does not require rpc based services, it is recommended that rpcbind be disabled to reduce the attack surface.
    Severity: 
    low
    Rule ID:xccdf_org.ssgproject.content_rule_service_rpcbind_disabled
    References:
    pcidss42.2.4

    
    [customizations.services]
    masked = ["rpcbind"]
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:disable
    - name: Disable rpcbind Service - Collect systemd Services Present in the System
      ansible.builtin.command: systemctl -q list-unit-files --type service
      register: service_exists
      changed_when: false
      failed_when: service_exists.rc not in [0, 1]
      check_mode: false
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - PCI-DSSv4-2.2.4
      - disable_strategy
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed
      - service_rpcbind_disabled
    
    - name: Disable rpcbind Service - Ensure rpcbind.service is Masked
      ansible.builtin.systemd:
        name: rpcbind.service
        state: stopped
        enabled: false
        masked: true
      when:
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - service_exists.stdout_lines is search("rpcbind.service", multiline=True)
      tags:
      - PCI-DSSv4-2.2.4
      - disable_strategy
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed
      - service_rpcbind_disabled
    
    - name: Unit Socket Exists - rpcbind.socket
      ansible.builtin.command: systemctl -q list-unit-files rpcbind.socket
      register: socket_file_exists
      changed_when: false
      failed_when: socket_file_exists.rc not in [0, 1]
      check_mode: false
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - PCI-DSSv4-2.2.4
      - disable_strategy
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed
      - service_rpcbind_disabled
    
    - name: Disable rpcbind Service - Disable Socket rpcbind
      ansible.builtin.systemd:
        name: rpcbind.socket
        enabled: false
        state: stopped
        masked: true
      when:
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - socket_file_exists.stdout_lines is search("rpcbind.socket", multiline=True)
      tags:
      - PCI-DSSv4-2.2.4
      - disable_strategy
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed
      - service_rpcbind_disabled
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:enable
    include disable_rpcbind
    
    class disable_rpcbind {
      service {'rpcbind':
        enable => false,
        ensure => 'stopped',
      }
    }
    
    Group   Configure NFS Clients   Group contains 1 group and 1 rule
    [ref]   The steps in this section are appropriate for systems which operate as NFS clients.
    Group   Disable NFS Server Daemons   Group contains 1 rule
    [ref]   There is no need to run the NFS server daemons nfs and rpcsvcgssd except on a small number of properly secured systems designated as NFS servers. Ensure that these daemons are turned off on clients.

    Rule   Disable Network File System (nfs)   [ref]

    The Network File System (NFS) service allows remote hosts to mount and interact with shared filesystems on the local system. If the local system is not designated as a NFS server then this service should be disabled. The nfs-server service can be disabled with the following command:
    $ sudo systemctl mask --now nfs-server.service
    Rationale:
    Unnecessary services should be disabled to decrease the attack surface of the system.
    Severity: 
    unknown
    Rule ID:xccdf_org.ssgproject.content_rule_service_nfs_disabled
    References:
    cis-csc11, 12, 14, 15, 16, 18, 3, 5
    cobit5DSS05.02, DSS05.04, DSS05.05, DSS05.07, DSS06.03, DSS06.06
    isa-62443-20094.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
    isa-62443-2013SR 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
    iso27001-2013A.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
    nistCM-7(a), CM-7(b), CM-6(a)
    nist-csfPR.AC-4, PR.AC-6, PR.PT-3

    
    [customizations.services]
    masked = ["nfs-server"]
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:disable
    - name: Disable Network File System (nfs) - Collect systemd Services Present in the
        System
      ansible.builtin.command: systemctl -q list-unit-files --type service
      register: service_exists
      changed_when: false
      failed_when: service_exists.rc not in [0, 1]
      check_mode: false
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - low_disruption
      - no_reboot_needed
      - service_nfs_disabled
      - unknown_severity
    
    - name: Disable Network File System (nfs) - Ensure nfs-server.service is Masked
      ansible.builtin.systemd:
        name: nfs-server.service
        state: stopped
        enabled: false
        masked: true
      when:
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - service_exists.stdout_lines is search("nfs-server.service", multiline=True)
      tags:
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - low_disruption
      - no_reboot_needed
      - service_nfs_disabled
      - unknown_severity
    
    - name: Unit Socket Exists - nfs-server.socket
      ansible.builtin.command: systemctl -q list-unit-files nfs-server.socket
      register: socket_file_exists
      changed_when: false
      failed_when: socket_file_exists.rc not in [0, 1]
      check_mode: false
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - low_disruption
      - no_reboot_needed
      - service_nfs_disabled
      - unknown_severity
    
    - name: Disable Network File System (nfs) - Disable Socket nfs-server
      ansible.builtin.systemd:
        name: nfs-server.socket
        enabled: false
        state: stopped
        masked: true
      when:
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - socket_file_exists.stdout_lines is search("nfs-server.socket", multiline=True)
      tags:
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - low_disruption
      - no_reboot_needed
      - service_nfs_disabled
      - unknown_severity
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:enable
    include disable_nfs-server
    
    class disable_nfs-server {
      service {'nfs-server':
        enable => false,
        ensure => 'stopped',
      }
    }
    
    Group   Obsolete Services   Group contains 2 groups and 3 rules
    [ref]   This section discusses a number of network-visible services which have historically caused problems for system security, and for which disabling or severely limiting the service has been the best available guidance for some time. As a result of this, many of these services are not installed as part of OpenEmbedded by default.

    Organizations which are running these services should switch to more secure equivalents as soon as possible. If it remains absolutely necessary to run one of these services for legacy reasons, care should be taken to restrict the service as much as possible, for instance by configuring host firewall software such as iptables to restrict access to the vulnerable service to only those remote hosts which have a known need to use it.
    Group   NIS   Group contains 1 rule
    [ref]   The Network Information Service (NIS), also known as 'Yellow Pages' (YP), and its successor NIS+ have been made obsolete by Kerberos, LDAP, and other modern centralized authentication services. NIS should not be used because it suffers from security problems inherent in its design, such as inadequate protection of important authentication information.

    Rule   Disable ypserv Service   [ref]

    The ypserv service, which allows the system to act as a client in a NIS or NIS+ domain, should be disabled. The ypserv service can be disabled with the following command:
    $ sudo systemctl mask --now ypserv.service
    Rationale:
    Disabling the ypserv service ensures the system is not acting as a client in a NIS or NIS+ domain. This service should be disabled unless in use.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_service_ypserv_disabled

    
    [customizations.services]
    masked = ["ypserv"]
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:disable
    - name: Disable ypserv Service - Collect systemd Services Present in the System
      ansible.builtin.command: systemctl -q list-unit-files --type service
      register: service_exists
      changed_when: false
      failed_when: service_exists.rc not in [0, 1]
      check_mode: false
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_ypserv_disabled
    
    - name: Disable ypserv Service - Ensure ypserv.service is Masked
      ansible.builtin.systemd:
        name: ypserv.service
        state: stopped
        enabled: false
        masked: true
      when:
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - service_exists.stdout_lines is search("ypserv.service", multiline=True)
      tags:
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_ypserv_disabled
    
    - name: Unit Socket Exists - ypserv.socket
      ansible.builtin.command: systemctl -q list-unit-files ypserv.socket
      register: socket_file_exists
      changed_when: false
      failed_when: socket_file_exists.rc not in [0, 1]
      check_mode: false
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_ypserv_disabled
    
    - name: Disable ypserv Service - Disable Socket ypserv
      ansible.builtin.systemd:
        name: ypserv.socket
        enabled: false
        state: stopped
        masked: true
      when:
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - socket_file_exists.stdout_lines is search("ypserv.socket", multiline=True)
      tags:
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_ypserv_disabled
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:enable
    include disable_ypserv
    
    class disable_ypserv {
      service {'ypserv':
        enable => false,
        ensure => 'stopped',
      }
    }
    
    Group   Rlogin, Rsh, and Rexec   Group contains 1 rule
    [ref]   The Berkeley r-commands are legacy services which allow cleartext remote access and have an insecure trust model.

    Rule   Remove Rsh Trust Files   [ref]

    The files /etc/hosts.equiv and ~/.rhosts (in each user's home directory) list remote hosts and users that are trusted by the local system when using the rshd daemon. To remove these files, run the following command to delete them from any location:
    $ sudo rm /etc/hosts.equiv
    $ rm ~/.rhosts
    Rationale:
    This action is only meaningful if .rhosts support is permitted through PAM. Trust files are convenient, but when used in conjunction with the R-services, they can allow unauthenticated access to a system.
    Severity: 
    high
    Rule ID:xccdf_org.ssgproject.content_rule_no_rsh_trust_files
    References:
    cis-csc11, 12, 14, 15, 3, 8, 9
    cobit5APO13.01, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS01.04, DSS05.02, DSS05.03, DSS05.05, DSS06.06
    disaCCI-001436
    hipaa164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii)
    isa-62443-20094.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3
    isa-62443-2013SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 7.1, SR 7.6
    iso27001-2013A.11.2.6, A.12.1.2, A.12.5.1, A.12.6.2, A.13.1.1, A.13.2.1, A.14.1.3, A.14.2.2, A.14.2.3, A.14.2.4, A.6.2.1, A.6.2.2, A.9.1.2
    nistCM-7(a), CM-7(b), CM-6(a)
    nist-csfPR.AC-3, PR.IP-1, PR.PT-3, PR.PT-4

    Rule   Ensure rsyncd service is disabled   [ref]

    The rsyncd service can be disabled with the following command:
    $ sudo systemctl mask --now rsyncd.service
    Rationale:
    The rsyncd service presents a security risk as it uses unencrypted protocols for communication.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_service_rsyncd_disabled
    References:
    pcidss42.2.4

    
    [customizations.services]
    masked = ["rsyncd"]
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:disable
    - name: Ensure rsyncd service is disabled - Collect systemd Services Present in the
        System
      ansible.builtin.command: systemctl -q list-unit-files --type service
      register: service_exists
      changed_when: false
      failed_when: service_exists.rc not in [0, 1]
      check_mode: false
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - PCI-DSSv4-2.2.4
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_rsyncd_disabled
    
    - name: Ensure rsyncd service is disabled - Ensure rsyncd.service is Masked
      ansible.builtin.systemd:
        name: rsyncd.service
        state: stopped
        enabled: false
        masked: true
      when:
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - service_exists.stdout_lines is search("rsyncd.service", multiline=True)
      tags:
      - PCI-DSSv4-2.2.4
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_rsyncd_disabled
    
    - name: Unit Socket Exists - rsyncd.socket
      ansible.builtin.command: systemctl -q list-unit-files rsyncd.socket
      register: socket_file_exists
      changed_when: false
      failed_when: socket_file_exists.rc not in [0, 1]
      check_mode: false
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - PCI-DSSv4-2.2.4
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_rsyncd_disabled
    
    - name: Ensure rsyncd service is disabled - Disable Socket rsyncd
      ansible.builtin.systemd:
        name: rsyncd.socket
        enabled: false
        state: stopped
        masked: true
      when:
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - socket_file_exists.stdout_lines is search("rsyncd.socket", multiline=True)
      tags:
      - PCI-DSSv4-2.2.4
      - disable_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - service_rsyncd_disabled
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:enable
    include disable_rsyncd
    
    class disable_rsyncd {
      service {'rsyncd':
        enable => false,
        ensure => 'stopped',
      }
    }
    
    Group   Print Support   Group contains 1 rule
    [ref]   The Common Unix Printing System (CUPS) service provides both local and network printing support. A system running the CUPS service can accept print jobs from other systems, process them, and send them to the appropriate printer. It also provides an interface for remote administration through a web browser. The CUPS service is installed and activated by default. The project homepage and more detailed documentation are available at http://www.cups.org.

    Rule   Disable the CUPS Service   [ref]

    The cups service can be disabled with the following command:
    $ sudo systemctl mask --now cups.service
    Rationale:
    Turn off unneeded services to reduce attack surface.
    Severity: 
    unknown
    Rule ID:xccdf_org.ssgproject.content_rule_service_cups_disabled
    References:
    cis-csc11, 14, 3, 9
    cobit5BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.05, DSS06.06
    isa-62443-20094.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3
    isa-62443-2013SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 7.6
    iso27001-2013A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, A.9.1.2
    nistCM-7(a), CM-7(b), CM-6(a)
    nist-csfPR.IP-1, PR.PT-3

    
    [customizations.services]
    masked = ["cups"]
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:disable
    - name: Disable the CUPS Service - Collect systemd Services Present in the System
      ansible.builtin.command: systemctl -q list-unit-files --type service
      register: service_exists
      changed_when: false
      failed_when: service_exists.rc not in [0, 1]
      check_mode: false
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - low_disruption
      - no_reboot_needed
      - service_cups_disabled
      - unknown_severity
    
    - name: Disable the CUPS Service - Ensure cups.service is Masked
      ansible.builtin.systemd:
        name: cups.service
        state: stopped
        enabled: false
        masked: true
      when:
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - service_exists.stdout_lines is search("cups.service", multiline=True)
      tags:
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - low_disruption
      - no_reboot_needed
      - service_cups_disabled
      - unknown_severity
    
    - name: Unit Socket Exists - cups.socket
      ansible.builtin.command: systemctl -q list-unit-files cups.socket
      register: socket_file_exists
      changed_when: false
      failed_when: socket_file_exists.rc not in [0, 1]
      check_mode: false
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - low_disruption
      - no_reboot_needed
      - service_cups_disabled
      - unknown_severity
    
    - name: Disable the CUPS Service - Disable Socket cups
      ansible.builtin.systemd:
        name: cups.socket
        enabled: false
        state: stopped
        masked: true
      when:
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - socket_file_exists.stdout_lines is search("cups.socket", multiline=True)
      tags:
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - disable_strategy
      - low_complexity
      - low_disruption
      - no_reboot_needed
      - service_cups_disabled
      - unknown_severity
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:enable
    include disable_cups
    
    class disable_cups {
      service {'cups':
        enable => false,
        ensure => 'stopped',
      }
    }
    
    Group   Proxy Server   Group contains 1 group and 1 rule
    [ref]   A proxy server is a very desirable target for a potential adversary because much (or all) sensitive data for a given infrastructure may flow through it. Therefore, if one is required, the system acting as a proxy server should be dedicated to that purpose alone and be stored in a physically secure location. The system's default proxy server software is Squid, and provided in an RPM package of the same name.
    Group   Disable Squid if Possible   Group contains 1 rule
    [ref]   If Squid was installed and activated, but the system does not need to act as a proxy server, then it should be disabled and removed.

    Rule   Disable Squid   [ref]

    The squid service can be disabled with the following command:
    $ sudo systemctl mask --now squid.service
    Rationale:
    Running proxy server software provides a network-based avenue of attack, and should be removed if not needed.
    Severity: 
    unknown
    Rule ID:xccdf_org.ssgproject.content_rule_service_squid_disabled

    
    [customizations.services]
    masked = ["squid"]
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:disable
    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - disable_strategy
      - low_complexity
      - low_disruption
      - no_reboot_needed
      - service_squid_disabled
      - unknown_severity
    
    - name: Disable Squid - Collect systemd Services Present in the System
      ansible.builtin.command: systemctl -q list-unit-files --type service
      register: service_exists
      changed_when: false
      failed_when: service_exists.rc not in [0, 1]
      check_mode: false
      when: ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman",
        "container"] and "squid" in ansible_facts.packages )
      tags:
      - disable_strategy
      - low_complexity
      - low_disruption
      - no_reboot_needed
      - service_squid_disabled
      - unknown_severity
    
    - name: Disable Squid - Ensure squid.service is Masked
      ansible.builtin.systemd:
        name: squid.service
        state: stopped
        enabled: false
        masked: true
      when:
      - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
        and "squid" in ansible_facts.packages )
      - service_exists.stdout_lines is search("squid.service", multiline=True)
      tags:
      - disable_strategy
      - low_complexity
      - low_disruption
      - no_reboot_needed
      - service_squid_disabled
      - unknown_severity
    
    - name: Unit Socket Exists - squid.socket
      ansible.builtin.command: systemctl -q list-unit-files squid.socket
      register: socket_file_exists
      changed_when: false
      failed_when: socket_file_exists.rc not in [0, 1]
      check_mode: false
      when: ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman",
        "container"] and "squid" in ansible_facts.packages )
      tags:
      - disable_strategy
      - low_complexity
      - low_disruption
      - no_reboot_needed
      - service_squid_disabled
      - unknown_severity
    
    - name: Disable Squid - Disable Socket squid
      ansible.builtin.systemd:
        name: squid.socket
        enabled: false
        state: stopped
        masked: true
      when:
      - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
        and "squid" in ansible_facts.packages )
      - socket_file_exists.stdout_lines is search("squid.socket", multiline=True)
      tags:
      - disable_strategy
      - low_complexity
      - low_disruption
      - no_reboot_needed
      - service_squid_disabled
      - unknown_severity
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:enable
    include disable_squid
    
    class disable_squid {
      service {'squid':
        enable => false,
        ensure => 'stopped',
      }
    }
    
    Group   Samba(SMB) Microsoft Windows File Sharing Server   Group contains 1 group and 1 rule
    [ref]   When properly configured, the Samba service allows Linux systems to provide file and print sharing to Microsoft Windows systems. There are two software packages that provide Samba support. The first, samba-client, provides a series of command line tools that enable a client system to access Samba shares. The second, simply labeled samba, provides the Samba service. It is this second package that allows a Linux system to act as an Active Directory server, a domain controller, or as a domain member. Only the samba-client package is installed by default.
    Group   Disable Samba if Possible   Group contains 1 rule
    [ref]   Even after the Samba server package has been installed, it will remain disabled. Do not enable this service unless it is absolutely necessary to provide Microsoft Windows file and print sharing functionality.

    Rule   Disable Samba   [ref]

    The smb service can be disabled with the following command:
    $ sudo systemctl mask --now smb.service
    Rationale:
    Running a Samba server provides a network-based avenue of attack, and should be disabled if not needed.
    Severity: 
    low
    Rule ID:xccdf_org.ssgproject.content_rule_service_smb_disabled
    References:
    disaCCI-001436

    
    [customizations.services]
    masked = ["smb"]
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:disable
    - name: Disable Samba - Collect systemd Services Present in the System
      ansible.builtin.command: systemctl -q list-unit-files --type service
      register: service_exists
      changed_when: false
      failed_when: service_exists.rc not in [0, 1]
      check_mode: false
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - disable_strategy
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed
      - service_smb_disabled
    
    - name: Disable Samba - Ensure smb.service is Masked
      ansible.builtin.systemd:
        name: smb.service
        state: stopped
        enabled: false
        masked: true
      when:
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - service_exists.stdout_lines is search("smb.service", multiline=True)
      tags:
      - disable_strategy
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed
      - service_smb_disabled
    
    - name: Unit Socket Exists - smb.socket
      ansible.builtin.command: systemctl -q list-unit-files smb.socket
      register: socket_file_exists
      changed_when: false
      failed_when: socket_file_exists.rc not in [0, 1]
      check_mode: false
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - disable_strategy
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed
      - service_smb_disabled
    
    - name: Disable Samba - Disable Socket smb
      ansible.builtin.systemd:
        name: smb.socket
        enabled: false
        state: stopped
        masked: true
      when:
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - socket_file_exists.stdout_lines is search("smb.socket", multiline=True)
      tags:
      - disable_strategy
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed
      - service_smb_disabled
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:enable
    include disable_smb
    
    class disable_smb {
      service {'smb':
        enable => false,
        ensure => 'stopped',
      }
    }
    
    Group   SNMP Server   Group contains 1 group and 1 rule
    [ref]   The Simple Network Management Protocol allows administrators to monitor the state of network devices, including computers. Older versions of SNMP were well-known for weak security, such as plaintext transmission of the community string (used for authentication) and usage of easily-guessable choices for the community string.
    Group   Disable SNMP Server if Possible   Group contains 1 rule
    [ref]   The system includes an SNMP daemon that allows for its remote monitoring, though it not installed by default. If it was installed and activated but is not needed, the software should be disabled and removed.

    Rule   Disable snmpd Service   [ref]

    The snmpd service can be disabled with the following command:
    $ sudo systemctl mask --now snmpd.service
    Rationale:
    Running SNMP software provides a network-based avenue of attack, and should be disabled if not needed.
    Severity: 
    low
    Rule ID:xccdf_org.ssgproject.content_rule_service_snmpd_disabled
    References:
    ism1311

    
    [customizations.services]
    masked = ["snmpd"]
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:disable
    - name: Gather the package facts
      package_facts:
        manager: auto
      tags:
      - disable_strategy
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed
      - service_snmpd_disabled
    
    - name: Disable snmpd Service - Collect systemd Services Present in the System
      ansible.builtin.command: systemctl -q list-unit-files --type service
      register: service_exists
      changed_when: false
      failed_when: service_exists.rc not in [0, 1]
      check_mode: false
      when: ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman",
        "container"] and "net-snmp" in ansible_facts.packages )
      tags:
      - disable_strategy
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed
      - service_snmpd_disabled
    
    - name: Disable snmpd Service - Ensure snmpd.service is Masked
      ansible.builtin.systemd:
        name: snmpd.service
        state: stopped
        enabled: false
        masked: true
      when:
      - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
        and "net-snmp" in ansible_facts.packages )
      - service_exists.stdout_lines is search("snmpd.service", multiline=True)
      tags:
      - disable_strategy
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed
      - service_snmpd_disabled
    
    - name: Unit Socket Exists - snmpd.socket
      ansible.builtin.command: systemctl -q list-unit-files snmpd.socket
      register: socket_file_exists
      changed_when: false
      failed_when: socket_file_exists.rc not in [0, 1]
      check_mode: false
      when: ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman",
        "container"] and "net-snmp" in ansible_facts.packages )
      tags:
      - disable_strategy
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed
      - service_snmpd_disabled
    
    - name: Disable snmpd Service - Disable Socket snmpd
      ansible.builtin.systemd:
        name: snmpd.socket
        enabled: false
        state: stopped
        masked: true
      when:
      - ( ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
        and "net-snmp" in ansible_facts.packages )
      - socket_file_exists.stdout_lines is search("snmpd.socket", multiline=True)
      tags:
      - disable_strategy
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed
      - service_snmpd_disabled
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:enable
    include disable_snmpd
    
    class disable_snmpd {
      service {'snmpd':
        enable => false,
        ensure => 'stopped',
      }
    }
    
    Group   SSH Server   Group contains 1 group and 21 rules
    [ref]   The SSH protocol is recommended for remote login and remote file transfer. SSH provides confidentiality and integrity for data exchanged between two systems, as well as server authentication, through the use of public key cryptography. The implementation included with the system is called OpenSSH, and more detailed documentation is available from its website, https://www.openssh.com. Its server program is called sshd and provided by the RPM package openssh-server.
    Group   Configure OpenSSH Server if Necessary   Group contains 16 rules
    [ref]   If the system needs to act as an SSH server, then certain changes should be made to the OpenSSH daemon configuration file /etc/ssh/sshd_config. The following recommendations can be applied to this file. See the sshd_config(5) man page for more detailed information.

    Rule   Set SSH Client Alive Count Max   [ref]

    The SSH server sends at most ClientAliveCountMax messages during a SSH session and waits for a response from the SSH client. The option ClientAliveInterval configures timeout after each ClientAliveCountMax message. If the SSH server does not receive a response from the client, then the connection is considered unresponsive and terminated. For SSH earlier than v8.2, a ClientAliveCountMax value of 0 causes a timeout precisely when the ClientAliveInterval is set. Starting with v8.2, a value of 0 disables the timeout functionality completely. If the option is set to a number greater than 0, then the session will be disconnected after ClientAliveInterval * ClientAliveCountMax seconds without receiving a keep alive message.
    Rationale:
    This ensures a user login will be terminated as soon as the ClientAliveInterval is reached.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_sshd_set_keepalive
    References:
    cis-csc1, 12, 13, 14, 15, 16, 18, 3, 5, 7, 8
    cjis5.5.6
    cobit5APO13.01, BAI03.01, BAI03.02, BAI03.03, DSS01.03, DSS03.05, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.10
    cui3.1.11
    disaCCI-000879, CCI-001133, CCI-002361
    hipaa164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii)
    isa-62443-20094.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, 4.3.4.3.3
    isa-62443-2013SR 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 6.2
    iso27001-2013A.12.4.1, A.12.4.3, A.14.1.1, A.14.2.1, A.14.2.5, A.18.1.4, A.6.1.2, A.6.1.5, 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
    nerc-cipCIP-004-6 R2.2.3, CIP-007-3 R5.1, CIP-007-3 R5.2, CIP-007-3 R5.3.1, CIP-007-3 R5.3.2, CIP-007-3 R5.3.3
    nistAC-2(5), AC-12, AC-17(a), SC-10, CM-6(a)
    nist-csfDE.CM-1, DE.CM-3, PR.AC-1, PR.AC-4, PR.AC-6, PR.AC-7, PR.IP-2
    pcidssReq-8.1.8
    os-srgSRG-OS-000163-GPOS-00072, SRG-OS-000279-GPOS-00109
    pcidss48.2.8

    Rule   Set SSH Client Alive Interval   [ref]

    SSH allows administrators to set a network responsiveness timeout interval. After this interval has passed, the unresponsive client will be automatically logged out.

    To set this timeout interval, edit the following line in /etc/ssh/sshd_config as follows:
    ClientAliveInterval 900
            


    The timeout interval is given in seconds. For example, have a timeout of 10 minutes, set interval to 600.

    If a shorter timeout has already been set for the login shell, that value will preempt any SSH setting made in /etc/ssh/sshd_config. Keep in mind that some processes may stop SSH from correctly detecting that the user is idle.
    Warning:  SSH disconnecting unresponsive clients will not have desired effect without also configuring ClientAliveCountMax in the SSH service configuration.
    Warning:  Following conditions may prevent the SSH session to time out:
    • Remote processes on the remote machine generates output. As the output has to be transferred over the network to the client, the timeout is reset every time such transfer happens.
    • Any scp or sftp activity by the same user to the host resets the timeout.
    Rationale:
    Terminating an idle ssh session within a short time period reduces the window of opportunity for unauthorized personnel to take control of a management session enabled on the console or console port that has been let unattended.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_sshd_set_idle_timeout
    References:
    cis-csc1, 12, 13, 14, 15, 16, 18, 3, 5, 7, 8
    cjis5.5.6
    cobit5APO13.01, BAI03.01, BAI03.02, BAI03.03, DSS01.03, DSS03.05, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.10
    cui3.1.11
    disaCCI-000879, CCI-001133, CCI-002361
    isa-62443-20094.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, 4.3.4.3.3
    isa-62443-2013SR 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 6.2
    iso27001-2013A.12.4.1, A.12.4.3, A.14.1.1, A.14.2.1, A.14.2.5, A.18.1.4, A.6.1.2, A.6.1.5, 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
    nerc-cipCIP-004-6 R2.2.3, CIP-007-3 R5.1, CIP-007-3 R5.2, CIP-007-3 R5.3.1, CIP-007-3 R5.3.2, CIP-007-3 R5.3.3
    nistCM-6(a), AC-17(a), AC-2(5), AC-12, AC-17(a), SC-10, CM-6(a)
    nist-csfDE.CM-1, DE.CM-3, PR.AC-1, PR.AC-4, PR.AC-6, PR.AC-7, PR.IP-2
    pcidssReq-8.1.8
    os-srgSRG-OS-000126-GPOS-00066, SRG-OS-000163-GPOS-00072, SRG-OS-000279-GPOS-00109, SRG-OS-000395-GPOS-00175
    pcidss48.2.8

    # Remediation is applicable only in certain platforms
    if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
    
    sshd_idle_timeout_value='900'
    
    
    if [ -e "/etc/ssh/sshd_config" ] ; then
        
        LC_ALL=C sed -i "/^\s*ClientAliveInterval\s\+/Id" "/etc/ssh/sshd_config"
    else
        touch "/etc/ssh/sshd_config"
    fi
    # make sure file has newline at the end
    sed -i -e '$a\' "/etc/ssh/sshd_config"
    
    cp "/etc/ssh/sshd_config" "/etc/ssh/sshd_config.bak"
    # Insert at the beginning of the file
    printf '%s\n' "ClientAliveInterval $sshd_idle_timeout_value" > "/etc/ssh/sshd_config"
    cat "/etc/ssh/sshd_config.bak" >> "/etc/ssh/sshd_config"
    # Clean up after ourselves.
    rm "/etc/ssh/sshd_config.bak"
    
    else
        >&2 echo 'Remediation is not applicable, nothing was done'
    fi
    

    Rule   Disable Host-Based Authentication   [ref]

    SSH's cryptographic host-based authentication is more secure than .rhosts authentication. However, it is not recommended that hosts unilaterally trust one another, even within an organization.
    The default SSH configuration disables host-based authentication. The appropriate configuration is used if no value is set for HostbasedAuthentication.
    To explicitly disable host-based authentication, add or correct the following line in /etc/ssh/sshd_config:
    HostbasedAuthentication no
    Rationale:
    SSH trust relationships mean a compromise on one host can allow an attacker to move trivially to other hosts.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_disable_host_auth
    References:
    cis-csc11, 12, 14, 15, 16, 18, 3, 5, 9
    cjis5.5.6
    cobit5BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.04, DSS05.05, DSS05.07, DSS06.03, DSS06.06
    cui3.1.12
    disaCCI-000366
    hipaa164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii)
    isa-62443-20094.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, 4.3.4.3.2, 4.3.4.3.3
    isa-62443-2013SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 7.6
    ism0421, 0422, 0431, 0974, 1173, 1401, 1504, 1505, 1546, 1557, 1558, 1559, 1560, 1561
    iso27001-2013A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, 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
    nerc-cipCIP-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
    nistAC-3, AC-17(a), CM-7(a), CM-7(b), CM-6(a)
    nist-csfPR.AC-4, PR.AC-6, PR.IP-1, PR.PT-3
    osppFIA_UAU.1
    os-srgSRG-OS-000480-GPOS-00229
    pcidss48.3.1

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:restrict
    - name: Disable Host-Based Authentication
      block:
    
      - name: Check for duplicate values
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)^\s*HostbasedAuthentication\s+
          state: absent
        check_mode: true
        changed_when: false
        register: dupes
    
      - name: Deduplicate values from /etc/ssh/sshd_config
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)^\s*HostbasedAuthentication\s+
          state: absent
        when: dupes.found is defined and dupes.found > 1
    
      - name: Insert correct line to /etc/ssh/sshd_config
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)^\s*HostbasedAuthentication\s+
          line: HostbasedAuthentication no
          state: present
          insertbefore: BOF
          validate: /usr/sbin/sshd -t -f %s
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - CJIS-5.5.6
      - NIST-800-171-3.1.12
      - NIST-800-53-AC-17(a)
      - NIST-800-53-AC-3
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - PCI-DSSv4-8.3.1
      - disable_host_auth
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:restrict
    # Remediation is applicable only in certain platforms
    if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
    
    if [ -e "/etc/ssh/sshd_config" ] ; then
        
        LC_ALL=C sed -i "/^\s*HostbasedAuthentication\s\+/Id" "/etc/ssh/sshd_config"
    else
        touch "/etc/ssh/sshd_config"
    fi
    # make sure file has newline at the end
    sed -i -e '$a\' "/etc/ssh/sshd_config"
    
    cp "/etc/ssh/sshd_config" "/etc/ssh/sshd_config.bak"
    # Insert at the beginning of the file
    printf '%s\n' "HostbasedAuthentication no" > "/etc/ssh/sshd_config"
    cat "/etc/ssh/sshd_config.bak" >> "/etc/ssh/sshd_config"
    # Clean up after ourselves.
    rm "/etc/ssh/sshd_config.bak"
    
    else
        >&2 echo 'Remediation is not applicable, nothing was done'
    fi
    

    Rule   Allow Only SSH Protocol 2   [ref]

    Only SSH protocol version 2 connections should be permitted. The default setting in /etc/ssh/sshd_config is correct, and can be verified by ensuring that the following line appears:
    Protocol 2
    Warning:  As of openssh-server version 7.4 and above, the only protocol supported is version 2, and line
    Protocol 2
    in /etc/ssh/sshd_config is not necessary.
    Rationale:
    SSH protocol version 1 is an insecure implementation of the SSH protocol and has many well-known vulnerability exploits. Exploits of the SSH daemon could provide immediate root access to the system.
    Severity: 
    high
    Rule ID:xccdf_org.ssgproject.content_rule_sshd_allow_only_protocol2
    References:
    cis-csc1, 12, 15, 16, 5, 8
    cjis5.5.6
    cobit5APO13.01, DSS01.04, DSS05.02, DSS05.03, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.10
    cui3.1.13, 3.5.4
    disaCCI-000197, CCI-000366
    hipaa164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii)
    isa-62443-20094.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
    isa-62443-2013SR 1.1, SR 1.10, SR 1.13, 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 2.6, 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
    ism0487, 1449, 1506
    iso27001-2013A.11.2.6, A.13.1.1, A.13.2.1, A.14.1.3, A.18.1.4, A.6.2.1, A.6.2.2, 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
    nerc-cipCIP-003-8 R4.2, CIP-007-3 R5.1, CIP-007-3 R7.1
    nistCM-6(a), AC-17(a), AC-17(2), IA-5(1)(c), SC-13, MA-4(6)
    nist-csfPR.AC-1, PR.AC-3, PR.AC-6, PR.AC-7, PR.PT-4
    os-srgSRG-OS-000074-GPOS-00042, SRG-OS-000480-GPOS-00227

    Rule   Disable SSH Access via Empty Passwords   [ref]

    Disallow SSH login with empty passwords. The default SSH configuration disables logins with empty passwords. The appropriate configuration is used if no value is set for PermitEmptyPasswords.
    To explicitly disallow SSH login from accounts with empty passwords, add or correct the following line in /etc/ssh/sshd_config:
    PermitEmptyPasswords no
    Any accounts with empty passwords should be disabled immediately, and PAM configuration should prevent users from being able to assign themselves empty passwords.
    Rationale:
    Configuring this setting for the SSH daemon provides additional assurance that remote login via SSH will require a password, even in the event of misconfiguration elsewhere.
    Severity: 
    high
    Rule ID:xccdf_org.ssgproject.content_rule_sshd_disable_empty_passwords
    References:
    cis-csc11, 12, 13, 14, 15, 16, 18, 3, 5, 9
    cjis5.5.6
    cobit5APO01.06, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.04, DSS05.05, DSS05.07, DSS06.02, DSS06.03, DSS06.06
    cui3.1.1, 3.1.5
    disaCCI-000366, CCI-000766
    hipaa164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii)
    isa-62443-20094.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, 4.3.4.3.2, 4.3.4.3.3
    isa-62443-2013SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 5.2, SR 7.6
    iso27001-2013A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.12.1.2, A.12.5.1, A.12.6.2, 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.14.2.2, A.14.2.3, A.14.2.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.3, A.9.4.1, A.9.4.4, A.9.4.5
    nistAC-17(a), CM-7(a), CM-7(b), CM-6(a)
    nist-csfPR.AC-4, PR.AC-6, PR.DS-5, PR.IP-1, PR.PT-3
    osppFIA_UAU.1
    pcidssReq-2.2.4
    os-srgSRG-OS-000106-GPOS-00053, SRG-OS-000480-GPOS-00229, SRG-OS-000480-GPOS-00227
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:restrict
    - name: Disable SSH Access via Empty Passwords
      block:
    
      - name: Check for duplicate values
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)^\s*PermitEmptyPasswords\s+
          state: absent
        check_mode: true
        changed_when: false
        register: dupes
    
      - name: Deduplicate values from /etc/ssh/sshd_config
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)^\s*PermitEmptyPasswords\s+
          state: absent
        when: dupes.found is defined and dupes.found > 1
    
      - name: Insert correct line to /etc/ssh/sshd_config
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)^\s*PermitEmptyPasswords\s+
          line: PermitEmptyPasswords no
          state: present
          insertbefore: BOF
          validate: /usr/sbin/sshd -t -f %s
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - CJIS-5.5.6
      - NIST-800-171-3.1.1
      - NIST-800-171-3.1.5
      - NIST-800-53-AC-17(a)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - PCI-DSS-Req-2.2.4
      - PCI-DSSv4-2.2.6
      - high_severity
      - low_complexity
      - low_disruption
      - no_reboot_needed
      - restrict_strategy
      - sshd_disable_empty_passwords
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:restrict
    # Remediation is applicable only in certain platforms
    if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
    
    if [ -e "/etc/ssh/sshd_config" ] ; then
        
        LC_ALL=C sed -i "/^\s*PermitEmptyPasswords\s\+/Id" "/etc/ssh/sshd_config"
    else
        touch "/etc/ssh/sshd_config"
    fi
    # make sure file has newline at the end
    sed -i -e '$a\' "/etc/ssh/sshd_config"
    
    cp "/etc/ssh/sshd_config" "/etc/ssh/sshd_config.bak"
    # Insert at the beginning of the file
    printf '%s\n' "PermitEmptyPasswords no" > "/etc/ssh/sshd_config"
    cat "/etc/ssh/sshd_config.bak" >> "/etc/ssh/sshd_config"
    # Clean up after ourselves.
    rm "/etc/ssh/sshd_config.bak"
    
    else
        >&2 echo 'Remediation is not applicable, nothing was done'
    fi
    

    Rule   Disable SSH Support for .rhosts Files   [ref]

    SSH can emulate the behavior of the obsolete rsh command in allowing users to enable insecure access to their accounts via .rhosts files.
    The default SSH configuration disables support for .rhosts. The appropriate configuration is used if no value is set for IgnoreRhosts.
    To explicitly disable support for .rhosts files, add or correct the following line in /etc/ssh/sshd_config:
    IgnoreRhosts yes
    Rationale:
    SSH trust relationships mean a compromise on one host can allow an attacker to move trivially to other hosts.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_sshd_disable_rhosts
    References:
    cis-csc11, 12, 14, 15, 16, 18, 3, 5, 9
    cjis5.5.6
    cobit5BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.04, DSS05.05, DSS05.07, DSS06.03, DSS06.06
    cui3.1.12
    disaCCI-000366
    isa-62443-20094.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, 4.3.4.3.2, 4.3.4.3.3
    isa-62443-2013SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 7.6
    iso27001-2013A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, 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
    nistAC-17(a), CM-7(a), CM-7(b), CM-6(a)
    nist-csfPR.AC-4, PR.AC-6, PR.IP-1, PR.PT-3
    osppFIA_UAU.1
    os-srgSRG-OS-000480-GPOS-00227
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:restrict
    - name: Disable SSH Support for .rhosts Files
      block:
    
      - name: Check for duplicate values
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)^\s*IgnoreRhosts\s+
          state: absent
        check_mode: true
        changed_when: false
        register: dupes
    
      - name: Deduplicate values from /etc/ssh/sshd_config
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)^\s*IgnoreRhosts\s+
          state: absent
        when: dupes.found is defined and dupes.found > 1
    
      - name: Insert correct line to /etc/ssh/sshd_config
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)^\s*IgnoreRhosts\s+
          line: IgnoreRhosts yes
          state: present
          insertbefore: BOF
          validate: /usr/sbin/sshd -t -f %s
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - CJIS-5.5.6
      - NIST-800-171-3.1.12
      - NIST-800-53-AC-17(a)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - PCI-DSSv4-2.2.6
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sshd_disable_rhosts
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:restrict
    # Remediation is applicable only in certain platforms
    if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
    
    if [ -e "/etc/ssh/sshd_config" ] ; then
        
        LC_ALL=C sed -i "/^\s*IgnoreRhosts\s\+/Id" "/etc/ssh/sshd_config"
    else
        touch "/etc/ssh/sshd_config"
    fi
    # make sure file has newline at the end
    sed -i -e '$a\' "/etc/ssh/sshd_config"
    
    cp "/etc/ssh/sshd_config" "/etc/ssh/sshd_config.bak"
    # Insert at the beginning of the file
    printf '%s\n' "IgnoreRhosts yes" > "/etc/ssh/sshd_config"
    cat "/etc/ssh/sshd_config.bak" >> "/etc/ssh/sshd_config"
    # Clean up after ourselves.
    rm "/etc/ssh/sshd_config.bak"
    
    else
        >&2 echo 'Remediation is not applicable, nothing was done'
    fi
    

    Rule   Do Not Allow SSH Environment Options   [ref]

    Ensure that users are not able to override environment variables of the SSH daemon.
    The default SSH configuration disables environment processing. The appropriate configuration is used if no value is set for PermitUserEnvironment.
    To explicitly disable Environment options, add or correct the following /etc/ssh/sshd_config:
    PermitUserEnvironment no
    Rationale:
    SSH environment options potentially allow users to bypass access restriction in some configurations.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_sshd_do_not_permit_user_env
    References:
    cis-csc11, 3, 9
    cjis5.5.6
    cobit5BAI10.01, BAI10.02, BAI10.03, BAI10.05
    cui3.1.12
    disaCCI-000366
    hipaa164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii)
    isa-62443-20094.3.4.3.2, 4.3.4.3.3
    isa-62443-2013SR 7.6
    iso27001-2013A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4
    nistAC-17(a), CM-7(a), CM-7(b), CM-6(a)
    nist-csfPR.IP-1
    pcidssReq-2.2.4
    os-srgSRG-OS-000480-GPOS-00229
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:restrict
    - name: Do Not Allow SSH Environment Options
      block:
    
      - name: Check for duplicate values
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)^\s*PermitUserEnvironment\s+
          state: absent
        check_mode: true
        changed_when: false
        register: dupes
    
      - name: Deduplicate values from /etc/ssh/sshd_config
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)^\s*PermitUserEnvironment\s+
          state: absent
        when: dupes.found is defined and dupes.found > 1
    
      - name: Insert correct line to /etc/ssh/sshd_config
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)^\s*PermitUserEnvironment\s+
          line: PermitUserEnvironment no
          state: present
          insertbefore: BOF
          validate: /usr/sbin/sshd -t -f %s
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - CJIS-5.5.6
      - NIST-800-171-3.1.12
      - NIST-800-53-AC-17(a)
      - NIST-800-53-CM-6(a)
      - NIST-800-53-CM-7(a)
      - NIST-800-53-CM-7(b)
      - PCI-DSS-Req-2.2.4
      - PCI-DSSv4-2.2.6
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sshd_do_not_permit_user_env
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:restrict
    # Remediation is applicable only in certain platforms
    if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
    
    if [ -e "/etc/ssh/sshd_config" ] ; then
        
        LC_ALL=C sed -i "/^\s*PermitUserEnvironment\s\+/Id" "/etc/ssh/sshd_config"
    else
        touch "/etc/ssh/sshd_config"
    fi
    # make sure file has newline at the end
    sed -i -e '$a\' "/etc/ssh/sshd_config"
    
    cp "/etc/ssh/sshd_config" "/etc/ssh/sshd_config.bak"
    # Insert at the beginning of the file
    printf '%s\n' "PermitUserEnvironment no" > "/etc/ssh/sshd_config"
    cat "/etc/ssh/sshd_config.bak" >> "/etc/ssh/sshd_config"
    # Clean up after ourselves.
    rm "/etc/ssh/sshd_config.bak"
    
    else
        >&2 echo 'Remediation is not applicable, nothing was done'
    fi
    

    Rule   Enable PAM   [ref]

    UsePAM Enables the Pluggable Authentication Module interface. If set to “yes” this will enable PAM authentication using ChallengeResponseAuthentication and PasswordAuthentication in addition to PAM account and session module processing for all authentication types. To enable PAM authentication, add or correct the following line in /etc/ssh/sshd_config:
    UsePAM yes
    Rationale:
    When UsePAM is set to yes, PAM runs through account and session types properly. This is important if you want to restrict access to services based off of IP, time or other factors of the account. Additionally, you can make sure users inherit certain environment variables on login or disallow access to the server.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_sshd_enable_pam
    References:
    disaCCI-000877
    os-srgSRG-OS-000125-GPOS-00065
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:restrict
    - name: Enable PAM
      block:
    
      - name: Check for duplicate values
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)^\s*UsePAM\s+
          state: absent
        check_mode: true
        changed_when: false
        register: dupes
    
      - name: Deduplicate values from /etc/ssh/sshd_config
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)^\s*UsePAM\s+
          state: absent
        when: dupes.found is defined and dupes.found > 1
    
      - name: Insert correct line to /etc/ssh/sshd_config
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)^\s*UsePAM\s+
          line: UsePAM yes
          state: present
          insertbefore: BOF
          validate: /usr/sbin/sshd -t -f %s
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - PCI-DSSv4-2.2.6
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sshd_enable_pam
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:restrict
    # Remediation is applicable only in certain platforms
    if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
    
    if [ -e "/etc/ssh/sshd_config" ] ; then
        
        LC_ALL=C sed -i "/^\s*UsePAM\s\+/Id" "/etc/ssh/sshd_config"
    else
        touch "/etc/ssh/sshd_config"
    fi
    # make sure file has newline at the end
    sed -i -e '$a\' "/etc/ssh/sshd_config"
    
    cp "/etc/ssh/sshd_config" "/etc/ssh/sshd_config.bak"
    # Insert at the beginning of the file
    printf '%s\n' "UsePAM yes" > "/etc/ssh/sshd_config"
    cat "/etc/ssh/sshd_config.bak" >> "/etc/ssh/sshd_config"
    # Clean up after ourselves.
    rm "/etc/ssh/sshd_config.bak"
    
    else
        >&2 echo 'Remediation is not applicable, nothing was done'
    fi
    

    Rule   Enable SSH Warning Banner   [ref]

    To enable the warning banner and ensure it is consistent across the system, add or correct the following line in /etc/ssh/sshd_config:
    Banner /etc/issue
    Another section contains information on how to create an appropriate system-wide warning banner.
    Rationale:
    The warning message reinforces policy awareness during the logon process and facilitates possible legal action against attackers. Alternatively, systems whose ownership should not be obvious should ensure usage of a banner that does not provide easy attribution.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_sshd_enable_warning_banner
    References:
    cis-csc1, 12, 15, 16
    cjis5.5.6
    cobit5DSS05.04, DSS05.10, DSS06.10
    cui3.1.9
    disaCCI-000048, CCI-000050, CCI-001384, CCI-001385, CCI-001386, CCI-001387, CCI-001388
    hipaa164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii)
    isa-62443-20094.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
    isa-62443-2013SR 1.1, SR 1.10, SR 1.2, SR 1.5, SR 1.7, SR 1.8, SR 1.9
    iso27001-2013A.18.1.4, A.9.2.1, A.9.2.4, A.9.3.1, A.9.4.2, A.9.4.3
    nistAC-8(a), AC-8(c), AC-17(a), CM-6(a)
    nist-csfPR.AC-7
    osppFTA_TAB.1
    pcidssReq-2.2.4
    os-srgSRG-OS-000023-GPOS-00006, SRG-OS-000228-GPOS-00088

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:restrict
    - name: Enable SSH Warning Banner
      block:
    
      - name: Check for duplicate values
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)^\s*Banner\s+
          state: absent
        check_mode: true
        changed_when: false
        register: dupes
    
      - name: Deduplicate values from /etc/ssh/sshd_config
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)^\s*Banner\s+
          state: absent
        when: dupes.found is defined and dupes.found > 1
    
      - name: Insert correct line to /etc/ssh/sshd_config
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)^\s*Banner\s+
          line: Banner /etc/issue
          state: present
          insertbefore: BOF
          validate: /usr/sbin/sshd -t -f %s
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - CJIS-5.5.6
      - NIST-800-171-3.1.9
      - NIST-800-53-AC-17(a)
      - NIST-800-53-AC-8(a)
      - NIST-800-53-AC-8(c)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-2.2.4
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sshd_enable_warning_banner
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:restrict
    # Remediation is applicable only in certain platforms
    if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
    
    if [ -e "/etc/ssh/sshd_config" ] ; then
        
        LC_ALL=C sed -i "/^\s*Banner\s\+/Id" "/etc/ssh/sshd_config"
    else
        touch "/etc/ssh/sshd_config"
    fi
    # make sure file has newline at the end
    sed -i -e '$a\' "/etc/ssh/sshd_config"
    
    cp "/etc/ssh/sshd_config" "/etc/ssh/sshd_config.bak"
    # Insert at the beginning of the file
    printf '%s\n' "Banner /etc/issue" > "/etc/ssh/sshd_config"
    cat "/etc/ssh/sshd_config.bak" >> "/etc/ssh/sshd_config"
    # Clean up after ourselves.
    rm "/etc/ssh/sshd_config.bak"
    
    else
        >&2 echo 'Remediation is not applicable, nothing was done'
    fi
    

    Rule   Set LogLevel to INFO   [ref]

    The INFO parameter specifices that record login and logout activity will be logged.
    The default SSH configuration sets the log level to INFO. The appropriate configuration is used if no value is set for LogLevel.
    To explicitly specify the log level in SSH, add or correct the following line in /etc/ssh/sshd_config:
    LogLevel INFO
    Rationale:
    SSH provides several logging levels with varying amounts of verbosity. DEBUG is specifically not recommended other than strictly for debugging SSH communications since it provides so much data that it is difficult to identify important security information. INFO level is the basic level that only records login activity of SSH users. In many situations, such as Incident Response, it is important to determine when a particular user was active on a system. The logout record can eliminate those users who disconnected, which helps narrow the field.
    Severity: 
    low
    Rule ID:xccdf_org.ssgproject.content_rule_sshd_set_loglevel_info
    References:
    nistAC-17(a), CM-6(a)

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:restrict
    - name: Set LogLevel to INFO
      block:
    
      - name: Check for duplicate values
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)^\s*LogLevel\s+
          state: absent
        check_mode: true
        changed_when: false
        register: dupes
    
      - name: Deduplicate values from /etc/ssh/sshd_config
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)^\s*LogLevel\s+
          state: absent
        when: dupes.found is defined and dupes.found > 1
    
      - name: Insert correct line to /etc/ssh/sshd_config
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)^\s*LogLevel\s+
          line: LogLevel INFO
          state: present
          insertbefore: BOF
          validate: /usr/sbin/sshd -t -f %s
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - NIST-800-53-AC-17(a)
      - NIST-800-53-CM-6(a)
      - low_complexity
      - low_disruption
      - low_severity
      - no_reboot_needed
      - restrict_strategy
      - sshd_set_loglevel_info
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:restrict
    # Remediation is applicable only in certain platforms
    if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
    
    if [ -e "/etc/ssh/sshd_config" ] ; then
        
        LC_ALL=C sed -i "/^\s*LogLevel\s\+/Id" "/etc/ssh/sshd_config"
    else
        touch "/etc/ssh/sshd_config"
    fi
    # make sure file has newline at the end
    sed -i -e '$a\' "/etc/ssh/sshd_config"
    
    cp "/etc/ssh/sshd_config" "/etc/ssh/sshd_config.bak"
    # Insert at the beginning of the file
    printf '%s\n' "LogLevel INFO" > "/etc/ssh/sshd_config"
    cat "/etc/ssh/sshd_config.bak" >> "/etc/ssh/sshd_config"
    # Clean up after ourselves.
    rm "/etc/ssh/sshd_config.bak"
    
    else
        >&2 echo 'Remediation is not applicable, nothing was done'
    fi
    

    Rule   Set SSH Daemon LogLevel to VERBOSE   [ref]

    The VERBOSE parameter configures the SSH daemon to record login and logout activity. To specify the log level in SSH, add or correct the following line in /etc/ssh/sshd_config:
    LogLevel VERBOSE
    Rationale:
    SSH provides several logging levels with varying amounts of verbosity. DEBUG is specifically not recommended other than strictly for debugging SSH communications since it provides so much data that it is difficult to identify important security information. INFO or VERBOSE level is the basic level that only records login activity of SSH users. In many situations, such as Incident Response, it is important to determine when a particular user was active on a system. The logout record can eliminate those users who disconnected, which helps narrow the field.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_sshd_set_loglevel_verbose
    References:
    disaCCI-000067
    nerc-cipCIP-007-3 R7.1
    nistAC-17(a), AC-17(1), CM-6(a)
    pcidssReq-2.2.4
    os-srgSRG-OS-000032-GPOS-00013
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:restrict
    - name: Set SSH Daemon LogLevel to VERBOSE
      block:
    
      - name: Check for duplicate values
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)^\s*LogLevel\s+
          state: absent
        check_mode: true
        changed_when: false
        register: dupes
    
      - name: Deduplicate values from /etc/ssh/sshd_config
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)^\s*LogLevel\s+
          state: absent
        when: dupes.found is defined and dupes.found > 1
    
      - name: Insert correct line to /etc/ssh/sshd_config
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)^\s*LogLevel\s+
          line: LogLevel VERBOSE
          state: present
          insertbefore: BOF
          validate: /usr/sbin/sshd -t -f %s
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - NIST-800-53-AC-17(1)
      - NIST-800-53-AC-17(a)
      - NIST-800-53-CM-6(a)
      - PCI-DSS-Req-2.2.4
      - PCI-DSSv4-2.2.6
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sshd_set_loglevel_verbose
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:restrict
    # Remediation is applicable only in certain platforms
    if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
    
    if [ -e "/etc/ssh/sshd_config" ] ; then
        
        LC_ALL=C sed -i "/^\s*LogLevel\s\+/Id" "/etc/ssh/sshd_config"
    else
        touch "/etc/ssh/sshd_config"
    fi
    # make sure file has newline at the end
    sed -i -e '$a\' "/etc/ssh/sshd_config"
    
    cp "/etc/ssh/sshd_config" "/etc/ssh/sshd_config.bak"
    # Insert at the beginning of the file
    printf '%s\n' "LogLevel VERBOSE" > "/etc/ssh/sshd_config"
    cat "/etc/ssh/sshd_config.bak" >> "/etc/ssh/sshd_config"
    # Clean up after ourselves.
    rm "/etc/ssh/sshd_config.bak"
    
    else
        >&2 echo 'Remediation is not applicable, nothing was done'
    fi
    

    Rule   Set SSH authentication attempt limit   [ref]

    The MaxAuthTries parameter specifies the maximum number of authentication attempts permitted per connection. Once the number of failures reaches half this value, additional failures are logged. to set MaxAUthTries edit /etc/ssh/sshd_config as follows:
    MaxAuthTries 4
            
    Rationale:
    Setting the MaxAuthTries parameter to a low number will minimize the risk of successful brute force attacks to the SSH server.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_sshd_set_max_auth_tries
    References:
    ism0421, 0422, 0431, 0974, 1173, 1401, 1504, 1505, 1546, 1557, 1558, 1559, 1560, 1561
    pcidss42.2.6

    Rule   Set SSH MaxSessions limit   [ref]

    The MaxSessions parameter specifies the maximum number of open sessions permitted from a given connection. To set MaxSessions edit /etc/ssh/sshd_config as follows:
    MaxSessions 10
            
    Rationale:
    To protect a system from denial of service due to a large number of concurrent sessions, use the rate limiting function of MaxSessions to protect availability of sshd logins and prevent overwhelming the daemon.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_sshd_set_max_sessions
    References:
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: XCCDF Value var_sshd_max_sessions # promote to variable
      set_fact:
        var_sshd_max_sessions: !!str 10
      tags:
        - always
    
    - name: Set SSH MaxSessions limit
      block:
    
      - name: Check for duplicate values
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)^\s*MaxSessions\s+
          state: absent
        check_mode: true
        changed_when: false
        register: dupes
    
      - name: Deduplicate values from /etc/ssh/sshd_config
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)^\s*MaxSessions\s+
          state: absent
        when: dupes.found is defined and dupes.found > 1
    
      - name: Insert correct line to /etc/ssh/sshd_config
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)^\s*MaxSessions\s+
          line: MaxSessions {{ var_sshd_max_sessions }}
          state: present
          insertbefore: BOF
          validate: /usr/sbin/sshd -t -f %s
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - PCI-DSSv4-2.2.6
      - configure_strategy
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - sshd_set_max_sessions
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    # Remediation is applicable only in certain platforms
    if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
    
    var_sshd_max_sessions='10'
    
    
    if [ -e "/etc/ssh/sshd_config" ] ; then
        
        LC_ALL=C sed -i "/^\s*MaxSessions\s\+/Id" "/etc/ssh/sshd_config"
    else
        touch "/etc/ssh/sshd_config"
    fi
    # make sure file has newline at the end
    sed -i -e '$a\' "/etc/ssh/sshd_config"
    
    cp "/etc/ssh/sshd_config" "/etc/ssh/sshd_config.bak"
    # Insert at the beginning of the file
    printf '%s\n' "MaxSessions $var_sshd_max_sessions" > "/etc/ssh/sshd_config"
    cat "/etc/ssh/sshd_config.bak" >> "/etc/ssh/sshd_config"
    # Clean up after ourselves.
    rm "/etc/ssh/sshd_config.bak"
    
    else
        >&2 echo 'Remediation is not applicable, nothing was done'
    fi
    

    Rule   Ensure SSH MaxStartups is configured   [ref]

    The MaxStartups parameter specifies the maximum number of concurrent unauthenticated connections to the SSH daemon. Additional connections will be dropped until authentication succeeds or the LoginGraceTime expires for a connection. To confgure MaxStartups, you should add or correct the following line in the /etc/ssh/sshd_config file:
    MaxStartups 10:30:60
            
    CIS recommends a MaxStartups value of '10:30:60', or more restrictive where dictated by site policy.
    Rationale:
    To protect a system from denial of service due to a large number of pending authentication connection attempts, use the rate limiting function of MaxStartups to protect availability of sshd logins and prevent overwhelming the daemon.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_sshd_set_maxstartups
    References:
    pcidss42.2.6

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:restrict
    - name: XCCDF Value var_sshd_set_maxstartups # promote to variable
      set_fact:
        var_sshd_set_maxstartups: !!str 10:30:60
      tags:
        - always
    
    - name: Ensure SSH MaxStartups is configured
      block:
    
      - name: Check for duplicate values
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)^\s*MaxStartups\s+
          state: absent
        check_mode: true
        changed_when: false
        register: dupes
    
      - name: Deduplicate values from /etc/ssh/sshd_config
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)^\s*MaxStartups\s+
          state: absent
        when: dupes.found is defined and dupes.found > 1
    
      - name: Insert correct line to /etc/ssh/sshd_config
        lineinfile:
          path: /etc/ssh/sshd_config
          create: true
          regexp: (?i)^\s*MaxStartups\s+
          line: MaxStartups {{ var_sshd_set_maxstartups }}
          state: present
          insertbefore: BOF
          validate: /usr/sbin/sshd -t -f %s
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - PCI-DSSv4-2.2.6
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
      - restrict_strategy
      - sshd_set_maxstartups
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:restrict
    # Remediation is applicable only in certain platforms
    if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
    
    var_sshd_set_maxstartups='10:30:60'
    
    
    if [ -e "/etc/ssh/sshd_config" ] ; then
        
        LC_ALL=C sed -i "/^\s*MaxStartups\s\+/Id" "/etc/ssh/sshd_config"
    else
        touch "/etc/ssh/sshd_config"
    fi
    # make sure file has newline at the end
    sed -i -e '$a\' "/etc/ssh/sshd_config"
    
    cp "/etc/ssh/sshd_config" "/etc/ssh/sshd_config.bak"
    # Insert at the beginning of the file
    printf '%s\n' "MaxStartups $var_sshd_set_maxstartups" > "/etc/ssh/sshd_config"
    cat "/etc/ssh/sshd_config.bak" >> "/etc/ssh/sshd_config"
    # Clean up after ourselves.
    rm "/etc/ssh/sshd_config.bak"
    
    else
        >&2 echo 'Remediation is not applicable, nothing was done'
    fi
    

    Rule   Verify Group Who Owns SSH Server config file   [ref]

    To properly set the group owner of /etc/ssh/sshd_config, run the command:
    $ sudo chgrp root /etc/ssh/sshd_config
    Rationale:
    Service configuration files enable or disable features of their respective services that if configured incorrectly can lead to insecure and vulnerable configurations. Therefore, service configuration files should be owned by the correct group to prevent unauthorized changes.
    Severity: 
    medium
    Rule ID:xccdf_org.ssgproject.content_rule_file_groupowner_sshd_config
    References:
    cis-csc12, 13, 14, 15, 16, 18, 3, 5
    cobit5APO01.06, DSS05.04, DSS05.07, DSS06.02
    isa-62443-20094.3.3.7.3
    isa-62443-2013SR 2.1, SR 5.2
    iso27001-2013A.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
    nerc-cipCIP-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
    nistAC-17(a), CM-6(a), AC-6(1)
    nist-csfPR.AC-4, PR.DS-5
    os-srgSRG-OS-000480-GPOS-00227
    anssiR50

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    - name: Test for existence /etc/ssh/sshd_config
      stat:
        path: /etc/ssh/sshd_config
      register: file_exists
      when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      tags:
      - NIST-800-53-AC-17(a)
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - configure_strategy
      - file_groupowner_sshd_config
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    
    - name: Ensure group owner 0 on /etc/ssh/sshd_config
      file:
        path: /etc/ssh/sshd_config
        group: '0'
      when:
      - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
      - file_exists.stat is defined and file_exists.stat.exists
      tags:
      - NIST-800-53-AC-17(a)
      - NIST-800-53-AC-6(1)
      - NIST-800-53-CM-6(a)
      - configure_strategy
      - file_groupowner_sshd_config
      - low_complexity
      - low_disruption
      - medium_severity
      - no_reboot_needed
    

    Complexity:low
    Disruption:low
    Reboot:false
    Strategy:configure
    # Remediation is applicable only in certain platforms
    if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
    
    chgrp 0 /etc/ssh/sshd_config
    
    else
        >&2 echo 'Remediation is not applicable, nothing was done'
    fi
    

    Rule   Verify Owner on SSH Server config file   [ref]

    To properly set the owner of /etc/ssh/sshd_config, run the command:
    $ sudo chow