Guide to the Secure Configuration of Debian 13

with profile CIS Debian Benchmark for Level 1 - Server
This profile defines a baseline that aligns to the "Level 1 - Server" configuration from the Center for Internet Security® Debian 13 Benchmark™, v1.0.0, released 2025-12-16. This profile includes Center for Internet Security® Debian 13 Benchmark™ content.
This guide presents a catalog of security-relevant configuration settings for Debian 13. 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 TitleCIS Debian Benchmark for Level 1 - Server
Profile IDxccdf_org.ssgproject.content_profile_cis_level1_server

CPE Platforms

  • cpe:/o:debian:debian_linux:13

Revision History

Current version: 0.1.82

  • draft (as of 2026-06-08)

Table of Contents

  1. System Settings
    1. Installing and Maintaining Software
    2. Account and Access Control
    3. AppArmor
    4. GRUB2 bootloader configuration
    5. Network Configuration and Firewalls
    6. File Permissions and Masks

Checklist

Group   Guide to the Secure Configuration of Debian 13   Group contains 19 groups and 46 rules
Group   System Settings   Group contains 18 groups and 46 rules
[ref]   Contains rules that check correct system settings.
Group   Installing and Maintaining Software   Group contains 2 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 1 rule
[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   Disk Partitioning   Group contains 2 rules
[ref]   To ensure separation and protection of data, there are top-level system directories which should be placed on their own physical partition or logical volume. The installer's default partitioning scheme creates separate logical volumes for /, /boot, and swap.
  • If starting with any of the default layouts, check the box to \"Review and modify partitioning.\" This allows for the easy creation of additional logical volumes inside the volume group already created, though it may require making /'s logical volume smaller to create space. In general, using logical volumes is preferable to using partitions because they can be more easily adjusted later.
  • If creating a custom layout, create the partitions mentioned in the previous paragraph (which the installer will require anyway), as well as separate ones described in the following sections.
If a system has already been installed, and the default partitioning scheme was used, it is possible but nontrivial to modify it to create separate logical volumes for the directories listed above. The Logical Volume Manager (LVM) makes this possible.

Rule   Ensure /dev/shm is configured   [ref]

The /dev/shm is a traditional shared memory concept. One program will create a memory portion, which other processes (if permitted) can access. If /dev/shm is not configured, tmpfs will be mounted to /dev/shm by systemd.
Warning:  This rule does not have a remediation. It is expected that this will be managed by systemd and will be a tmpfs partition.
Rationale:
Any user can upload and execute files inside the /dev/shm similar to the /tmp partition. Configuring /dev/shm allows an administrator to set the noexec option on the mount, making /dev/shm useless for an attacker to install executable code. It would also prevent an attacker from establishing a hardlink to a system setuid program and wait for it to be updated. Once the program was updated, the hardlink would be broken and the attacker would have his own copy of the program. If the program happened to have a security vulnerability, the attacker could continue to exploit the known flaw.
Severity: 
low
Rule ID:xccdf_org.ssgproject.content_rule_partition_for_dev_shm
References:
cis1.1.2.2.1

Rule   Ensure /tmp Located On Separate Partition   [ref]

The /tmp directory is a world-writable directory used for temporary file storage. Ensure it has its own partition or logical volume at installation time, or migrate it using LVM.
Rationale:
The /tmp partition is used as temporary storage by many programs. Placing /tmp in its own partition enables the setting of more restrictive mount options, which can help protect programs which use it.
Severity: 
low
Rule ID:xccdf_org.ssgproject.content_rule_partition_for_tmp
References:
cis-csc12, 15, 8
cobit5APO13.01, DSS05.02
isa-62443-2013SR 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.13.1.1, A.13.2.1, A.14.1.3
nistCM-6(a), SC-5(2)
nist-csfPR.PT-4
os-srgSRG-OS-000480-GPOS-00227
cis1.1.2.1.1
Group   Account and Access Control   Group contains 1 group and 1 rule
[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 Debian 13.
Group   Warning Banners for System Accesses   Group contains 1 rule
[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   Ensure Message Of The Day Is Configured Properly   [ref]

To configure the system message of the day banner edit the /etc/motd file. Replace the default text with a message compliant with the local site policy. The message should not contain information about operating system version, release, kernel version or patch level. The recommended banner text can be tailored in the XCCDF Value xccdf_org.ssgproject.content_value_cis_banner_text:
Authorized users only. All activity may be monitored and reported.
Rationale:
Warning messages inform users who are attempting to login to the system of their legal status regarding the system and must include the name of the organization that owns the system and any monitoring policies that are in place. Displaying OS and patch level information in login banners also has the side effect of providing detailed system information to attackers attempting to target specific exploits of a system. Authorized users can easily get this information by running the uname -a command once they have logged in.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_banner_etc_motd_cis
References:
cis1.6.1

Complexity:low
Disruption:low
Reboot:false
Strategy:restrict
# Remediation is applicable only in certain platforms
if dpkg-query --show --showformat='${db:Status-Status}' 'linux-base' 2>/dev/null | grep -q '^installed$'; then

cis_banner_text='Authorized users only. All activity may be monitored and reported.'

echo "$cis_banner_text" > "/etc/motd"

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

Complexity:low
Disruption:low
Reboot:false
Strategy:restrict
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - banner_etc_motd_cis
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy
- name: XCCDF Value cis_banner_text # promote to variable
  set_fact:
    cis_banner_text: !!str Authorized users only. All activity may be monitored and reported.
  tags:
    - always

- name: Ensure Message Of The Day Is Configured Properly - Copy using inline content
  ansible.builtin.copy:
    content: '{{ cis_banner_text }}'
    dest: /etc/motd
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - banner_etc_motd_cis
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy
Group   AppArmor   Group contains 3 rules
[ref]   Many security vulnerabilities result from bugs in trusted programs. A trusted program runs with privileges that attackers want to possess. The program fails to keep that trust if there is a bug in the program that allows the attacker to acquire said privilege.

AppArmor® is an application security solution designed specifically to apply privilege confinement to suspect programs. AppArmor allows the administrator to specify the domain of activities the program can perform by developing a security profile. A security profile is a listing of files that the program may access and the operations the program may perform. AppArmor secures applications by enforcing good application behavior without relying on attack signatures, so it can prevent attacks even if previously unknown vulnerabilities are being exploited.

Rule   Ensure AppArmor Utils is installed   [ref]

AppArmor provide Mandatory Access Controls.
Rationale:
Without a Mandatory Access Control system installed only the default Discretionary Access Control system will be available.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_package_apparmor-utils_installed
References:
cis1.3.1.1

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

DEBIAN_FRONTEND=noninteractive apt-get -o DPkg::Lock::Timeout=60 install -y "apparmor-utils"

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


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

Complexity:low
Disruption:low
Reboot:false
Strategy:enable
include install_apparmor-utils

class install_apparmor-utils {
  package { 'apparmor-utils':
    ensure => 'installed',
  }
}

Complexity:low
Disruption:low
Reboot:false
Strategy:enable
- name: Ensure apparmor-utils is installed
  ansible.builtin.package:
    name: apparmor-utils
    state: present
  when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
  tags:
  - enable_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - package_apparmor-utils_installed

Rule   Ensure AppArmor is installed   [ref]

AppArmor provide Mandatory Access Controls.
Rationale:
Without a Mandatory Access Control system installed only the default Discretionary Access Control system will be available.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_package_apparmor_installed
References:
os-srgSRG-OS-000368-GPOS-00154, SRG-OS-000312-GPOS-00122, SRG-OS-000312-GPOS-00123, SRG-OS-000312-GPOS-00124, SRG-OS-000324-GPOS-00125, SRG-OS-000370-GPOS-00155
anssiR45
cis1.3.1.1

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

DEBIAN_FRONTEND=noninteractive apt-get -o DPkg::Lock::Timeout=60 install -y "apparmor"

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


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

Complexity:low
Disruption:low
Reboot:false
Strategy:enable
include install_apparmor

class install_apparmor {
  package { 'apparmor':
    ensure => 'installed',
  }
}

Complexity:low
Disruption:low
Reboot:false
Strategy:enable
- name: Ensure apparmor is installed
  ansible.builtin.package:
    name: apparmor
    state: present
  when: ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
  tags:
  - enable_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - package_apparmor_installed

Rule   Ensure AppArmor is enabled in the bootloader configuration   [ref]

Configure AppArmor to be enabled at boot time and verify that it has not been overwritten by the bootloader boot parameters. Note: This recommendation is designed around the grub bootloader, if LILO or another bootloader is in use in your environment, enact equivalent settings.
Rationale:
AppArmor must be enabled at boot time in your bootloader configuration to ensure that the controls it provides are not overridden.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_grub2_enable_apparmor
References:
anssiR45
cis1.3.1.2

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

# Correct the form of default kernel command line in GRUB
if grep -q '^\s*GRUB_CMDLINE_LINUX=.*apparmor=.*\"' '/etc/default/grub' ; then
    # modify the GRUB command-line if an apparmor= arg already exists
    sed -i 's/\(^\s*GRUB_CMDLINE_LINUX=".*\)apparmor=[^[:space:]]\+\(.*"\)/\1apparmor=1\2/' '/etc/default/grub'
# Add to already existing parameters
elif grep -q '^\s*GRUB_CMDLINE_LINUX=' '/etc/default/grub' ; then
    # no apparmor=arg is present, append it
    sed -i 's/\(^\s*GRUB_CMDLINE_LINUX=".*\)"/\1 apparmor=1"/' '/etc/default/grub'
# Add parameters line if completely missing
else
    echo 'GRUB_CMDLINE_LINUX="apparmor=1"' >> '/etc/default/grub'
fi
# Correct the form of default kernel command line in GRUB
if grep -q '^\s*GRUB_CMDLINE_LINUX=.*security=.*\"' '/etc/default/grub' ; then
    # modify the GRUB command-line if an security= arg already exists
    sed -i 's/\(^\s*GRUB_CMDLINE_LINUX=".*\)security=[^[:space:]]\+\(.*"\)/\1security=apparmor\2/' '/etc/default/grub'
# Add to already existing parameters
elif grep -q '^\s*GRUB_CMDLINE_LINUX=' '/etc/default/grub' ; then
    # no security=arg is present, append it
    sed -i 's/\(^\s*GRUB_CMDLINE_LINUX=".*\)"/\1 security=apparmor"/' '/etc/default/grub'
# Add parameters line if completely missing
else
    echo 'GRUB_CMDLINE_LINUX="security=apparmor"' >> '/etc/default/grub'
fi


update-grub

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi
Group   GRUB2 bootloader configuration   Group contains 2 groups 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 Debian 13 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 3 rules
[ref]   Non-UEFI GRUB2 bootloader configuration

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

The file /boot/grub/grub.cfg should be owned by the root user to prevent destruction or modification of the file. To properly set the owner of /boot/grub/grub.cfg, run the command:
$ sudo chown root /boot/grub/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
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
cis1.4.2
pcidss42.2.6, 2.2

Complexity:low
Disruption:low
Reboot:false
Strategy:configure
# Remediation is applicable only in certain platforms
if ( dpkg-query --show --showformat='${db:Status-Status}' 'grub2-common' 2>/dev/null | grep -q '^installed$' && dpkg-query --show --showformat='${db:Status-Status}' 'linux-base' 2>/dev/null | grep -q '^installed$' ) && [ ! -d /sys/firmware/efi ] && { ( ! ( [ -f /.dockerenv ] || [ -f /run/.containerenv ] ) ); }; then

newown=""
if id "0" >/dev/null 2>&1; then
  newown="0"
fi

if [[ -z "$newown" ]]; then
  >&2 echo "0 is not a defined user on the system"
else
if ! stat -c "%u %U" "/boot/grub/grub.cfg" | grep -E -w -q "0"; then
    chown --no-dereference "$newown" /boot/grub/grub.cfg
fi

fi

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

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
  - PCI-DSSv4-2.2.6
  - configure_strategy
  - file_owner_grub2_cfg
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed

- name: Set the file_owner_grub2_cfg_newown variable if represented by uid
  ansible.builtin.set_fact:
    file_owner_grub2_cfg_newown: '0'
  when:
  - ( "grub2-common" in ansible_facts.packages and "linux-base" in ansible_facts.packages
    )
  - not ('/sys/firmware/efi' is directory)
  - not ( ansible_virtualization_type 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
  - 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/grub/grub.cfg
  ansible.builtin.stat:
    path: /boot/grub/grub.cfg
  register: file_exists
  when:
  - ( "grub2-common" in ansible_facts.packages and "linux-base" in ansible_facts.packages
    )
  - not ('/sys/firmware/efi' is directory)
  - not ( ansible_virtualization_type 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
  - PCI-DSSv4-2.2.6
  - configure_strategy
  - file_owner_grub2_cfg
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed

- name: Ensure owner on /boot/grub/grub.cfg
  ansible.builtin.file:
    path: /boot/grub/grub.cfg
    follow: false
    owner: '{{ file_owner_grub2_cfg_newown }}'
  when:
  - ( "grub2-common" in ansible_facts.packages and "linux-base" in ansible_facts.packages
    )
  - not ('/sys/firmware/efi' is directory)
  - not ( ansible_virtualization_type 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
  - PCI-DSSv4-2.2.6
  - configure_strategy
  - file_owner_grub2_cfg
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed

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

File permissions for /boot/grub/grub.cfg should be set to 600. To properly set the permissions of /boot/grub/grub.cfg, run the command:
$ sudo chmod 600 /boot/grub/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
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
cis1.4.2
pcidss42.2.6, 2.2

Complexity:low
Disruption:low
Reboot:false
Strategy:configure
# Remediation is applicable only in certain platforms
if ( dpkg-query --show --showformat='${db:Status-Status}' 'grub2-common' 2>/dev/null | grep -q '^installed$' && dpkg-query --show --showformat='${db:Status-Status}' 'linux-base' 2>/dev/null | grep -q '^installed$' ) && [ ! -d /sys/firmware/efi ] && { ( ! ( [ -f /.dockerenv ] || [ -f /run/.containerenv ] ) ); }; then

chmod u-xs,g-xwrs,o-xwrt /boot/grub/grub.cfg

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

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
  - 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/grub/grub.cfg
  ansible.builtin.stat:
    path: /boot/grub/grub.cfg
  register: file_exists
  when:
  - ( "grub2-common" in ansible_facts.packages and "linux-base" in ansible_facts.packages
    )
  - not ('/sys/firmware/efi' is directory)
  - not ( ansible_virtualization_type 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
  - 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/grub/grub.cfg
  ansible.builtin.file:
    path: /boot/grub/grub.cfg
    mode: u-xs,g-xwrs,o-xwrt
  when:
  - ( "grub2-common" in ansible_facts.packages and "linux-base" in ansible_facts.packages
    )
  - not ('/sys/firmware/efi' is directory)
  - not ( ansible_virtualization_type 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
  - PCI-DSSv4-2.2.6
  - configure_strategy
  - file_permissions_grub2_cfg
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed

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
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
cis1.4.1
Group   UEFI GRUB2 bootloader configuration   Group contains 1 rule
[ref]   UEFI GRUB2 bootloader configuration
Warning:  UEFI generally uses vfat file systems, which does not support Unix-style permissions managed by chmod command. In this case, in order to change file permissions for files within /boot/efi it is necessary to update the mount options in /etc/fstab file and reboot the system.

Rule   Set the UEFI Boot Loader Password   [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_uefi_password
References:
cis-csc11, 12, 14, 15, 16, 18, 3, 5
cobit5DSS05.02, DSS05.04, DSS05.05, DSS05.07, DSS06.03, DSS06.06
cui3.4.5
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.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-6(a)
nist-csfPR.AC-4, PR.AC-6, PR.PT-3
osppFIA_UAU.1
os-srgSRG-OS-000080-GPOS-00048
anssiR5
cis1.4.1
Group   Network Configuration and Firewalls   Group contains 1 group and 1 rule
[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   Uncommon Network Protocols   Group contains 1 rule
[ref]   The system includes support for several network protocols which are not commonly used. Although security vulnerabilities in kernel networking code are not frequently discovered, the consequences can be dramatic. Ensuring uncommon network protocols are disabled reduces the system's risk to attacks targeted at its implementation of those protocols.
Warning:  Although these protocols are not commonly used, avoid disruption in your network environment by ensuring they are not needed prior to disabling them.

Rule   Disable IEEE 1394 (FireWire) Support   [ref]

The IEEE 1394 (FireWire) is a serial bus standard for high-speed real-time communication. To configure the system to prevent the firewire-core kernel module from being loaded, add the following line to the file /etc/modprobe.d/firewire-core.conf:
install firewire-core /bin/false
This entry will cause a non-zero return value during a firewire-core module installation and additionally convey the meaning of the entry to the user in form of an error message. If you would like to omit a non-zero return value and an error message, you may want to add a different line instead (both /bin/true and /bin/false are allowed by OVAL and will be accepted by the scan):
install firewire-core /bin/true
Rationale:
Disabling FireWire protects the system against exploitation of any flaws in its implementation.
Severity: 
low
Rule ID:xccdf_org.ssgproject.content_rule_kernel_module_firewire-core_disabled
References:
nistAC-18
os-srgSRG-OS-000095-GPOS-00049
cis1.1.1.9

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
# Remediation is applicable only in certain platforms
if dpkg-query --show --showformat='${db:Status-Status}' 'linux-base' 2>/dev/null | grep -q '^installed$'; then

if LC_ALL=C grep -q -m 1 "^install firewire-core" /etc/modprobe.d/firewire-core.conf ; then
	
	sed -i 's#^install firewire-core.*#install firewire-core /bin/false#g' /etc/modprobe.d/firewire-core.conf
else
	echo -e "\n# Disable per security requirements" >> /etc/modprobe.d/firewire-core.conf
	echo "install firewire-core /bin/false" >> /etc/modprobe.d/firewire-core.conf
fi

if ! LC_ALL=C grep -q -m 1 "^blacklist firewire-core$" /etc/modprobe.d/firewire-core.conf ; then
	echo "blacklist firewire-core" >> /etc/modprobe.d/firewire-core.conf
fi

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi
Group   File Permissions and Masks   Group contains 6 groups and 34 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 Debian 13 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 rule
[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   Restrict Dynamic Mounting and Unmounting of Filesystems   Group contains 6 rules
[ref]   Linux includes a number of facilities for the automated addition and removal of filesystems on a running system. These facilities may be necessary in many environments, but this capability also carries some risk -- whether direct risk from allowing users to introduce arbitrary filesystems, or risk that software flaws in the automated mount facility itself could allow an attacker to compromise the system.

This command can be used to list the types of filesystems that are available to the currently executing kernel:
$ find /lib/modules/`uname -r`/kernel/fs -type f -name '*.ko'
If these filesystems are not required then they can be explicitly disabled in a configuratio file in /etc/modprobe.d.

Rule   Disable Mounting of cramfs   [ref]

To configure the system to prevent the cramfs kernel module from being loaded, add the following line to the file /etc/modprobe.d/cramfs.conf:
install cramfs /bin/false
This entry will cause a non-zero return value during a cramfs module installation and additionally convey the meaning of the entry to the user in form of an error message. If you would like to omit a non-zero return value and an error message, you may want to add a different line instead (both /bin/true and /bin/false are allowed by OVAL and will be accepted by the scan):
install cramfs /bin/true
This effectively prevents usage of this uncommon filesystem. The cramfs filesystem type is a compressed read-only Linux filesystem embedded in small footprint systems. A cramfs image can be used without having to first decompress the image.
Rationale:
Removing support for unneeded filesystem types reduces the local attack surface of the server.
Severity: 
low
Rule ID:xccdf_org.ssgproject.content_rule_kernel_module_cramfs_disabled
References:
cis-csc11, 14, 3, 9
cobit5BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.05, DSS06.06
cui3.4.6
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
os-srgSRG-OS-000095-GPOS-00049
cis1.1.1.1

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
# Remediation is applicable only in certain platforms
if dpkg-query --show --showformat='${db:Status-Status}' 'linux-base' 2>/dev/null | grep -q '^installed$'; then

if LC_ALL=C grep -q -m 1 "^install cramfs" /etc/modprobe.d/cramfs.conf ; then
	
	sed -i 's#^install cramfs.*#install cramfs /bin/false#g' /etc/modprobe.d/cramfs.conf
else
	echo -e "\n# Disable per security requirements" >> /etc/modprobe.d/cramfs.conf
	echo "install cramfs /bin/false" >> /etc/modprobe.d/cramfs.conf
fi

if ! LC_ALL=C grep -q -m 1 "^blacklist cramfs$" /etc/modprobe.d/cramfs.conf ; then
	echo "blacklist cramfs" >> /etc/modprobe.d/cramfs.conf
fi

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

Rule   Disable Mounting of freevxfs   [ref]

To configure the system to prevent the freevxfs kernel module from being loaded, add the following line to the file /etc/modprobe.d/freevxfs.conf:
install freevxfs /bin/false
This entry will cause a non-zero return value during a freevxfs module installation and additionally convey the meaning of the entry to the user in form of an error message. If you would like to omit a non-zero return value and an error message, you may want to add a different line instead (both /bin/true and /bin/false are allowed by OVAL and will be accepted by the scan):
install freevxfs /bin/true
This effectively prevents usage of this uncommon filesystem.
Rationale:
Linux kernel modules which implement filesystems that are not needed by the local system should be disabled.
Severity: 
low
Rule ID:xccdf_org.ssgproject.content_rule_kernel_module_freevxfs_disabled
References:
cis-csc11, 14, 3, 9
cobit5BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.05, DSS06.06
cui3.4.6
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
cis1.1.1.2

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
# Remediation is applicable only in certain platforms
if dpkg-query --show --showformat='${db:Status-Status}' 'linux-base' 2>/dev/null | grep -q '^installed$'; then

if LC_ALL=C grep -q -m 1 "^install freevxfs" /etc/modprobe.d/freevxfs.conf ; then
	
	sed -i 's#^install freevxfs.*#install freevxfs /bin/false#g' /etc/modprobe.d/freevxfs.conf
else
	echo -e "\n# Disable per security requirements" >> /etc/modprobe.d/freevxfs.conf
	echo "install freevxfs /bin/false" >> /etc/modprobe.d/freevxfs.conf
fi

if ! LC_ALL=C grep -q -m 1 "^blacklist freevxfs$" /etc/modprobe.d/freevxfs.conf ; then
	echo "blacklist freevxfs" >> /etc/modprobe.d/freevxfs.conf
fi

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

Rule   Disable Mounting of hfs   [ref]

To configure the system to prevent the hfs kernel module from being loaded, add the following line to the file /etc/modprobe.d/hfs.conf:
install hfs /bin/false
This entry will cause a non-zero return value during a hfs module installation and additionally convey the meaning of the entry to the user in form of an error message. If you would like to omit a non-zero return value and an error message, you may want to add a different line instead (both /bin/true and /bin/false are allowed by OVAL and will be accepted by the scan):
install hfs /bin/true
This effectively prevents usage of this uncommon filesystem.
Rationale:
Linux kernel modules which implement filesystems that are not needed by the local system should be disabled.
Severity: 
low
Rule ID:xccdf_org.ssgproject.content_rule_kernel_module_hfs_disabled
References:
cis-csc11, 14, 3, 9
cobit5BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.05, DSS06.06
cui3.4.6
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
cis1.1.1.3

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
# Remediation is applicable only in certain platforms
if dpkg-query --show --showformat='${db:Status-Status}' 'linux-base' 2>/dev/null | grep -q '^installed$'; then

if LC_ALL=C grep -q -m 1 "^install hfs" /etc/modprobe.d/hfs.conf ; then
	
	sed -i 's#^install hfs.*#install hfs /bin/false#g' /etc/modprobe.d/hfs.conf
else
	echo -e "\n# Disable per security requirements" >> /etc/modprobe.d/hfs.conf
	echo "install hfs /bin/false" >> /etc/modprobe.d/hfs.conf
fi

if ! LC_ALL=C grep -q -m 1 "^blacklist hfs$" /etc/modprobe.d/hfs.conf ; then
	echo "blacklist hfs" >> /etc/modprobe.d/hfs.conf
fi

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

Rule   Disable Mounting of hfsplus   [ref]

To configure the system to prevent the hfsplus kernel module from being loaded, add the following line to the file /etc/modprobe.d/hfsplus.conf:
install hfsplus /bin/false
This entry will cause a non-zero return value during a hfsplus module installation and additionally convey the meaning of the entry to the user in form of an error message. If you would like to omit a non-zero return value and an error message, you may want to add a different line instead (both /bin/true and /bin/false are allowed by OVAL and will be accepted by the scan):
install hfsplus /bin/true
This effectively prevents usage of this uncommon filesystem.
Rationale:
Linux kernel modules which implement filesystems that are not needed by the local system should be disabled.
Severity: 
low
Rule ID:xccdf_org.ssgproject.content_rule_kernel_module_hfsplus_disabled
References:
cis-csc11, 14, 3, 9
cobit5BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.05, DSS06.06
cui3.4.6
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
cis1.1.1.4

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
# Remediation is applicable only in certain platforms
if dpkg-query --show --showformat='${db:Status-Status}' 'linux-base' 2>/dev/null | grep -q '^installed$'; then

if LC_ALL=C grep -q -m 1 "^install hfsplus" /etc/modprobe.d/hfsplus.conf ; then
	
	sed -i 's#^install hfsplus.*#install hfsplus /bin/false#g' /etc/modprobe.d/hfsplus.conf
else
	echo -e "\n# Disable per security requirements" >> /etc/modprobe.d/hfsplus.conf
	echo "install hfsplus /bin/false" >> /etc/modprobe.d/hfsplus.conf
fi

if ! LC_ALL=C grep -q -m 1 "^blacklist hfsplus$" /etc/modprobe.d/hfsplus.conf ; then
	echo "blacklist hfsplus" >> /etc/modprobe.d/hfsplus.conf
fi

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

Rule   Disable Mounting of jffs2   [ref]

To configure the system to prevent the jffs2 kernel module from being loaded, add the following line to the file /etc/modprobe.d/jffs2.conf:
install jffs2 /bin/false
This entry will cause a non-zero return value during a jffs2 module installation and additionally convey the meaning of the entry to the user in form of an error message. If you would like to omit a non-zero return value and an error message, you may want to add a different line instead (both /bin/true and /bin/false are allowed by OVAL and will be accepted by the scan):
install jffs2 /bin/true
This effectively prevents usage of this uncommon filesystem.
Rationale:
Linux kernel modules which implement filesystems that are not needed by the local system should be disabled.
Severity: 
low
Rule ID:xccdf_org.ssgproject.content_rule_kernel_module_jffs2_disabled
References:
cis-csc11, 14, 3, 9
cobit5BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.05, DSS06.06
cui3.4.6
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
cis1.1.1.5

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
# Remediation is applicable only in certain platforms
if dpkg-query --show --showformat='${db:Status-Status}' 'linux-base' 2>/dev/null | grep -q '^installed$'; then

if LC_ALL=C grep -q -m 1 "^install jffs2" /etc/modprobe.d/jffs2.conf ; then
	
	sed -i 's#^install jffs2.*#install jffs2 /bin/false#g' /etc/modprobe.d/jffs2.conf
else
	echo -e "\n# Disable per security requirements" >> /etc/modprobe.d/jffs2.conf
	echo "install jffs2 /bin/false" >> /etc/modprobe.d/jffs2.conf
fi

if ! LC_ALL=C grep -q -m 1 "^blacklist jffs2$" /etc/modprobe.d/jffs2.conf ; then
	echo "blacklist jffs2" >> /etc/modprobe.d/jffs2.conf
fi

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

Rule   Disable Modprobe Loading of USB Storage Driver   [ref]

To prevent USB storage devices from being used, configure the kernel module loading system to prevent automatic loading of the USB storage driver. To configure the system to prevent the usb-storage kernel module from being loaded, add the following line to the file /etc/modprobe.d/usb-storage.conf:
install usb-storage /bin/false
This entry will cause a non-zero return value during a usb-storage module installation and additionally convey the meaning of the entry to the user in form of an error message. If you would like to omit a non-zero return value and an error message, you may want to add a different line instead (both /bin/true and /bin/false are allowed by OVAL and will be accepted by the scan):
install usb-storage /bin/true
This will prevent the modprobe program from loading the usb-storage module, but will not prevent an administrator (or another program) from using the insmod program to load the module manually.
Rationale:
USB storage devices such as thumb drives can be used to introduce malicious software.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_kernel_module_usb-storage_disabled
References:
cis-csc1, 12, 15, 16, 5
cobit5APO13.01, DSS01.04, DSS05.03, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.10
cui3.1.21
hipaa164.308(a)(3)(i), 164.308(a)(3)(ii)(A), 164.310(d)(1), 164.310(d)(2), 164.312(a)(1), 164.312(a)(2)(iv), 164.312(b)
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
iso27001-2013A.11.2.6, A.13.1.1, A.13.2.1, 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
nistCM-7(a), CM-7(b), CM-6(a), MP-7
nist-csfPR.AC-1, PR.AC-3, PR.AC-6, PR.AC-7
os-srgSRG-OS-000114-GPOS-00059, SRG-OS-000378-GPOS-00163, SRG-OS-000480-GPOS-00227
app-srg-ctrSRG-APP-000141-CTR-000315
cis1.1.1.10
pcidss43.4.2, 3.4

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
# Remediation is applicable only in certain platforms
if dpkg-query --show --showformat='${db:Status-Status}' 'linux-base' 2>/dev/null | grep -q '^installed$'; then

if LC_ALL=C grep -q -m 1 "^install usb-storage" /etc/modprobe.d/usb-storage.conf ; then
	
	sed -i 's#^install usb-storage.*#install usb-storage /bin/false#g' /etc/modprobe.d/usb-storage.conf
else
	echo -e "\n# Disable per security requirements" >> /etc/modprobe.d/usb-storage.conf
	echo "install usb-storage /bin/false" >> /etc/modprobe.d/usb-storage.conf
fi

if ! LC_ALL=C grep -q -m 1 "^blacklist usb-storage$" /etc/modprobe.d/usb-storage.conf ; then
	echo "blacklist usb-storage" >> /etc/modprobe.d/usb-storage.conf
fi

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi
Group   Restrict Partition Mount Options   Group contains 19 rules
[ref]   System partitions can be mounted with certain options that limit what files on those partitions can do. These options are set in the /etc/fstab configuration file, and can be used to make certain types of malicious behavior more difficult.

Rule   Add nodev Option to /dev/shm   [ref]

The nodev mount option can be used to prevent creation of device files in /dev/shm. Legitimate character and block devices should not exist within temporary directories like /dev/shm. Add the nodev option to the fourth column of /etc/fstab for the line which controls mounting of /dev/shm.
Rationale:
The only legitimate location for device files is the /dev directory located on the root partition. The only exception to this is chroot jails.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_mount_option_dev_shm_nodev
References:
cis-csc11, 13, 14, 3, 8, 9
cobit5APO13.01, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.05, DSS05.06, 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.11.2.9, A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, A.8.2.1, A.8.2.2, A.8.2.3, A.8.3.1, A.8.3.3, A.9.1.2
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-7(a), CM-7(b), CM-6(a), AC-6, AC-6(1), MP-7
nist-csfPR.IP-1, PR.PT-2, PR.PT-3
os-srgSRG-OS-000368-GPOS-00154
cis1.1.2.2.2
ism1409

Reboot:false
# Remediation is applicable only in certain platforms
if ( ! ( { rpm --quiet -q kernel ;} && { rpm --quiet -q rpm-ostree ;} && { rpm --quiet -q bootc ;} && { ! rpm --quiet -q openshift-kubelet ;} && ([ -f /run/ostree-booted ] || [ -L /ostree ]) ) && ! ( [ -f /.dockerenv ] || [ -f /run/.containerenv ] ) ); then

function perform_remediation {

    


    mount_point_match_regexp="$(printf "^[[:space:]]*[^#].*[[:space:]]%s[[:space:]]" /dev/shm)"

    # If the mount point is not in /etc/fstab, get previous mount options from /etc/mtab
    if ! grep -q "$mount_point_match_regexp" /etc/fstab; then
        # runtime opts without some automatic kernel/userspace-added defaults
        previous_mount_opts=$(grep "$mount_point_match_regexp" /etc/mtab | head -1 |  awk '{print $4}' \
                    | sed -E "s/(rw|defaults|seclabel|nodev)(,|$)//g;s/,$//")
        [ "$previous_mount_opts" ] && previous_mount_opts+=","
        # In iso9660 filesystems mtab could describe a "blocksize" value, this should be reflected in
        # fstab as "block".  The next variable is to satisfy shellcheck SC2050.
        fs_type="tmpfs"
        if [  "$fs_type" == "iso9660" ] ; then
            previous_mount_opts=$(sed 's/blocksize=/block=/' <<< "$previous_mount_opts")
        fi
        echo "tmpfs /dev/shm tmpfs defaults,${previous_mount_opts}nodev 0 0" >> /etc/fstab
    # If the mount_opt option is not already in the mount point's /etc/fstab entry, add it
    elif ! grep "$mount_point_match_regexp" /etc/fstab | grep -q "nodev"; then
        previous_mount_opts=$(grep "$mount_point_match_regexp" /etc/fstab | awk '{print $4}')
        sed -i "s|\(${mount_point_match_regexp}.*${previous_mount_opts}\)|\1,nodev|" /etc/fstab
    fi


    if mkdir -p "/dev/shm"; then
        if mountpoint -q "/dev/shm"; then
            mount -o remount --target "/dev/shm"
        fi
    fi
}

perform_remediation

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

Complexity:low
Disruption:high
Reboot:false
Strategy:configure
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_dev_shm_nodev
  - no_reboot_needed

- name: 'Add nodev Option to /dev/shm: Check information associated to mountpoint'
  ansible.builtin.command: findmnt  '/dev/shm'
  register: device_name
  failed_when: device_name.rc > 1
  changed_when: false
  check_mode: false
  when: ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_dev_shm_nodev
  - no_reboot_needed

- name: 'Add nodev Option to /dev/shm: Create mount_info dictionary variable'
  set_fact:
    mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
  with_together:
  - '{{ device_name.stdout_lines[0].split() | map(''lower'') | list }}'
  - '{{ device_name.stdout_lines[1].split() | list }}'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - device_name.stdout is defined and device_name.stdout_lines is defined
  - (device_name.stdout | length > 0)
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_dev_shm_nodev
  - no_reboot_needed

- name: 'Add nodev Option to /dev/shm: If /dev/shm not mounted, craft mount_info manually'
  set_fact:
    mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
  with_together:
  - - target
    - source
    - fstype
    - options
  - - /dev/shm
    - tmpfs
    - tmpfs
    - defaults
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - ("" | length == 0)
  - device_name.stdout is defined and device_name.stdout_lines is defined
  - (device_name.stdout | length == 0)
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_dev_shm_nodev
  - no_reboot_needed

- name: 'Add nodev Option to /dev/shm: Make sure nodev option is part of the to /dev/shm
    options'
  set_fact:
    mount_info: '{{ mount_info | combine( {''options'':''''~(mount_info.options |
      default(''''))~('','' if (mount_info.options | default('''')) else '''')~''nodev''
      }) }}'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - mount_info is defined and "nodev" not in (mount_info.options | default(''))
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_dev_shm_nodev
  - no_reboot_needed

- name: 'Add nodev Option to /dev/shm: Ensure /dev/shm is mounted with nodev option'
  ansible.posix.mount:
    path: /dev/shm
    src: '{{ mount_info.source | default('''') }}'
    opts: '{{ mount_info.options | default('''') }}'
    state: mounted
    fstype: '{{ mount_info.fstype | default('''') }}'
  register: mount_result
  failed_when:
  - mount_result is failed
  - '''target is busy'' not in (mount_result.msg | default(''''))'
  - '''already mounted'' not in (mount_result.msg | default(''''))'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - mount_info is defined
  - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("" |
    length == 0)
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_dev_shm_nodev
  - no_reboot_needed

Rule   Add noexec Option to /dev/shm   [ref]

The noexec mount option can be used to prevent binaries from being executed out of /dev/shm. It can be dangerous to allow the execution of binaries from world-writable temporary storage directories such as /dev/shm. Add the noexec option to the fourth column of /etc/fstab for the line which controls mounting of /dev/shm.
Rationale:
Allowing users to execute binaries from world-writable directories such as /dev/shm can expose the system to potential compromise.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_mount_option_dev_shm_noexec
References:
cis-csc11, 13, 14, 3, 8, 9
cobit5APO13.01, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.05, DSS05.06, 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.11.2.9, A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, A.8.2.1, A.8.2.2, A.8.2.3, A.8.3.1, A.8.3.3, A.9.1.2
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-7(a), CM-7(b), CM-6(a), AC-6, AC-6(1), MP-7
nist-csfPR.IP-1, PR.PT-2, PR.PT-3
os-srgSRG-OS-000368-GPOS-00154
cis1.1.2.2.4
ism1409

Reboot:false
# Remediation is applicable only in certain platforms
if ( ! ( { rpm --quiet -q kernel ;} && { rpm --quiet -q rpm-ostree ;} && { rpm --quiet -q bootc ;} && { ! rpm --quiet -q openshift-kubelet ;} && ([ -f /run/ostree-booted ] || [ -L /ostree ]) ) && ! ( [ -f /.dockerenv ] || [ -f /run/.containerenv ] ) ); then

function perform_remediation {

    


    mount_point_match_regexp="$(printf "^[[:space:]]*[^#].*[[:space:]]%s[[:space:]]" /dev/shm)"

    # If the mount point is not in /etc/fstab, get previous mount options from /etc/mtab
    if ! grep -q "$mount_point_match_regexp" /etc/fstab; then
        # runtime opts without some automatic kernel/userspace-added defaults
        previous_mount_opts=$(grep "$mount_point_match_regexp" /etc/mtab | head -1 |  awk '{print $4}' \
                    | sed -E "s/(rw|defaults|seclabel|noexec)(,|$)//g;s/,$//")
        [ "$previous_mount_opts" ] && previous_mount_opts+=","
        # In iso9660 filesystems mtab could describe a "blocksize" value, this should be reflected in
        # fstab as "block".  The next variable is to satisfy shellcheck SC2050.
        fs_type="tmpfs"
        if [  "$fs_type" == "iso9660" ] ; then
            previous_mount_opts=$(sed 's/blocksize=/block=/' <<< "$previous_mount_opts")
        fi
        echo "tmpfs /dev/shm tmpfs defaults,${previous_mount_opts}noexec 0 0" >> /etc/fstab
    # If the mount_opt option is not already in the mount point's /etc/fstab entry, add it
    elif ! grep "$mount_point_match_regexp" /etc/fstab | grep -q "noexec"; then
        previous_mount_opts=$(grep "$mount_point_match_regexp" /etc/fstab | awk '{print $4}')
        sed -i "s|\(${mount_point_match_regexp}.*${previous_mount_opts}\)|\1,noexec|" /etc/fstab
    fi


    if mkdir -p "/dev/shm"; then
        if mountpoint -q "/dev/shm"; then
            mount -o remount --target "/dev/shm"
        fi
    fi
}

perform_remediation

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

Complexity:low
Disruption:high
Reboot:false
Strategy:configure
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_dev_shm_noexec
  - no_reboot_needed

- name: 'Add noexec Option to /dev/shm: Check information associated to mountpoint'
  ansible.builtin.command: findmnt  '/dev/shm'
  register: device_name
  failed_when: device_name.rc > 1
  changed_when: false
  check_mode: false
  when: ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_dev_shm_noexec
  - no_reboot_needed

- name: 'Add noexec Option to /dev/shm: Create mount_info dictionary variable'
  set_fact:
    mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
  with_together:
  - '{{ device_name.stdout_lines[0].split() | map(''lower'') | list }}'
  - '{{ device_name.stdout_lines[1].split() | list }}'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - device_name.stdout is defined and device_name.stdout_lines is defined
  - (device_name.stdout | length > 0)
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_dev_shm_noexec
  - no_reboot_needed

- name: 'Add noexec Option to /dev/shm: If /dev/shm not mounted, craft mount_info
    manually'
  set_fact:
    mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
  with_together:
  - - target
    - source
    - fstype
    - options
  - - /dev/shm
    - tmpfs
    - tmpfs
    - defaults
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - ("" | length == 0)
  - device_name.stdout is defined and device_name.stdout_lines is defined
  - (device_name.stdout | length == 0)
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_dev_shm_noexec
  - no_reboot_needed

- name: 'Add noexec Option to /dev/shm: Make sure noexec option is part of the to
    /dev/shm options'
  set_fact:
    mount_info: '{{ mount_info | combine( {''options'':''''~(mount_info.options |
      default(''''))~('','' if (mount_info.options | default('''')) else '''')~''noexec''
      }) }}'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - mount_info is defined and "noexec" not in (mount_info.options | default(''))
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_dev_shm_noexec
  - no_reboot_needed

- name: 'Add noexec Option to /dev/shm: Ensure /dev/shm is mounted with noexec option'
  ansible.posix.mount:
    path: /dev/shm
    src: '{{ mount_info.source | default('''') }}'
    opts: '{{ mount_info.options | default('''') }}'
    state: mounted
    fstype: '{{ mount_info.fstype | default('''') }}'
  register: mount_result
  failed_when:
  - mount_result is failed
  - '''target is busy'' not in (mount_result.msg | default(''''))'
  - '''already mounted'' not in (mount_result.msg | default(''''))'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - mount_info is defined
  - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("" |
    length == 0)
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_dev_shm_noexec
  - no_reboot_needed

Rule   Add nosuid Option to /dev/shm   [ref]

The nosuid mount option can be used to prevent execution of setuid programs in /dev/shm. The SUID and SGID permissions should not be required in these world-writable directories. Add the nosuid option to the fourth column of /etc/fstab for the line which controls mounting of /dev/shm.
Rationale:
The presence of SUID and SGID executables should be tightly controlled. Users should not be able to execute SUID or SGID binaries from temporary storage partitions.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_mount_option_dev_shm_nosuid
References:
cis-csc11, 13, 14, 3, 8, 9
cobit5APO13.01, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.05, DSS05.06, 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.11.2.9, A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, A.8.2.1, A.8.2.2, A.8.2.3, A.8.3.1, A.8.3.3, A.9.1.2
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-7(a), CM-7(b), CM-6(a), AC-6, AC-6(1), MP-7
nist-csfPR.IP-1, PR.PT-2, PR.PT-3
os-srgSRG-OS-000368-GPOS-00154
cis1.1.2.2.3
ism1409

Reboot:false
# Remediation is applicable only in certain platforms
if ( ! ( { rpm --quiet -q kernel ;} && { rpm --quiet -q rpm-ostree ;} && { rpm --quiet -q bootc ;} && { ! rpm --quiet -q openshift-kubelet ;} && ([ -f /run/ostree-booted ] || [ -L /ostree ]) ) && ! ( [ -f /.dockerenv ] || [ -f /run/.containerenv ] ) ); then

function perform_remediation {

    


    mount_point_match_regexp="$(printf "^[[:space:]]*[^#].*[[:space:]]%s[[:space:]]" /dev/shm)"

    # If the mount point is not in /etc/fstab, get previous mount options from /etc/mtab
    if ! grep -q "$mount_point_match_regexp" /etc/fstab; then
        # runtime opts without some automatic kernel/userspace-added defaults
        previous_mount_opts=$(grep "$mount_point_match_regexp" /etc/mtab | head -1 |  awk '{print $4}' \
                    | sed -E "s/(rw|defaults|seclabel|nosuid)(,|$)//g;s/,$//")
        [ "$previous_mount_opts" ] && previous_mount_opts+=","
        # In iso9660 filesystems mtab could describe a "blocksize" value, this should be reflected in
        # fstab as "block".  The next variable is to satisfy shellcheck SC2050.
        fs_type="tmpfs"
        if [  "$fs_type" == "iso9660" ] ; then
            previous_mount_opts=$(sed 's/blocksize=/block=/' <<< "$previous_mount_opts")
        fi
        echo "tmpfs /dev/shm tmpfs defaults,${previous_mount_opts}nosuid 0 0" >> /etc/fstab
    # If the mount_opt option is not already in the mount point's /etc/fstab entry, add it
    elif ! grep "$mount_point_match_regexp" /etc/fstab | grep -q "nosuid"; then
        previous_mount_opts=$(grep "$mount_point_match_regexp" /etc/fstab | awk '{print $4}')
        sed -i "s|\(${mount_point_match_regexp}.*${previous_mount_opts}\)|\1,nosuid|" /etc/fstab
    fi


    if mkdir -p "/dev/shm"; then
        if mountpoint -q "/dev/shm"; then
            mount -o remount --target "/dev/shm"
        fi
    fi
}

perform_remediation

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

Complexity:low
Disruption:high
Reboot:false
Strategy:configure
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_dev_shm_nosuid
  - no_reboot_needed

- name: 'Add nosuid Option to /dev/shm: Check information associated to mountpoint'
  ansible.builtin.command: findmnt  '/dev/shm'
  register: device_name
  failed_when: device_name.rc > 1
  changed_when: false
  check_mode: false
  when: ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_dev_shm_nosuid
  - no_reboot_needed

- name: 'Add nosuid Option to /dev/shm: Create mount_info dictionary variable'
  set_fact:
    mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
  with_together:
  - '{{ device_name.stdout_lines[0].split() | map(''lower'') | list }}'
  - '{{ device_name.stdout_lines[1].split() | list }}'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - device_name.stdout is defined and device_name.stdout_lines is defined
  - (device_name.stdout | length > 0)
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_dev_shm_nosuid
  - no_reboot_needed

- name: 'Add nosuid Option to /dev/shm: If /dev/shm not mounted, craft mount_info
    manually'
  set_fact:
    mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
  with_together:
  - - target
    - source
    - fstype
    - options
  - - /dev/shm
    - tmpfs
    - tmpfs
    - defaults
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - ("" | length == 0)
  - device_name.stdout is defined and device_name.stdout_lines is defined
  - (device_name.stdout | length == 0)
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_dev_shm_nosuid
  - no_reboot_needed

- name: 'Add nosuid Option to /dev/shm: Make sure nosuid option is part of the to
    /dev/shm options'
  set_fact:
    mount_info: '{{ mount_info | combine( {''options'':''''~(mount_info.options |
      default(''''))~('','' if (mount_info.options | default('''')) else '''')~''nosuid''
      }) }}'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - mount_info is defined and "nosuid" not in (mount_info.options | default(''))
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_dev_shm_nosuid
  - no_reboot_needed

- name: 'Add nosuid Option to /dev/shm: Ensure /dev/shm is mounted with nosuid option'
  ansible.posix.mount:
    path: /dev/shm
    src: '{{ mount_info.source | default('''') }}'
    opts: '{{ mount_info.options | default('''') }}'
    state: mounted
    fstype: '{{ mount_info.fstype | default('''') }}'
  register: mount_result
  failed_when:
  - mount_result is failed
  - '''target is busy'' not in (mount_result.msg | default(''''))'
  - '''already mounted'' not in (mount_result.msg | default(''''))'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - mount_info is defined
  - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("" |
    length == 0)
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_dev_shm_nosuid
  - no_reboot_needed

Rule   Add nodev Option to /home   [ref]

The nodev mount option can be used to prevent device files from being created in /home. Legitimate character and block devices should exist only in the /dev directory on the root partition or within chroot jails built for system services. Add the nodev option to the fourth column of /etc/fstab for the line which controls mounting of /home.
Rationale:
The only legitimate location for device files is the /dev directory located on the root partition. The only exception to this is chroot jails.
Severity: 
unknown
Rule ID:xccdf_org.ssgproject.content_rule_mount_option_home_nodev
References:
os-srgSRG-OS-000368-GPOS-00154
cis1.1.2.3.2

Reboot:false
# Remediation is applicable only in certain platforms
if ( ! ( { rpm --quiet -q kernel ;} && { rpm --quiet -q rpm-ostree ;} && { rpm --quiet -q bootc ;} && { ! rpm --quiet -q openshift-kubelet ;} && ([ -f /run/ostree-booted ] || [ -L /ostree ]) ) && ! ( [ -f /.dockerenv ] || [ -f /run/.containerenv ] ) ) && { ( findmnt --kernel "/home" > /dev/null || findmnt --fstab "/home" > /dev/null ); }; then

function perform_remediation {

    
        # the mount point /home has to be defined in /etc/fstab
        # before this remediation can be executed. In case it is not defined, the
        # remediation aborts and no changes regarding the mount point are done.
        mount_point_match_regexp="$(printf "^[[:space:]]*[^#].*[[:space:]]%s[[:space:]]" "/home")"

    grep "$mount_point_match_regexp" -q /etc/fstab \
        || { echo "The mount point '/home' is not even in /etc/fstab, so we can't set up mount options" >&2;
                echo "Not remediating, because there is no record of /home in /etc/fstab" >&2; return 1; }
    


    mount_point_match_regexp="$(printf "^[[:space:]]*[^#].*[[:space:]]%s[[:space:]]" /home)"

    # If the mount point is not in /etc/fstab, get previous mount options from /etc/mtab
    if ! grep -q "$mount_point_match_regexp" /etc/fstab; then
        # runtime opts without some automatic kernel/userspace-added defaults
        previous_mount_opts=$(grep "$mount_point_match_regexp" /etc/mtab | head -1 |  awk '{print $4}' \
                    | sed -E "s/(rw|defaults|seclabel|nodev)(,|$)//g;s/,$//")
        [ "$previous_mount_opts" ] && previous_mount_opts+=","
        # In iso9660 filesystems mtab could describe a "blocksize" value, this should be reflected in
        # fstab as "block".  The next variable is to satisfy shellcheck SC2050.
        fs_type=""
        if [  "$fs_type" == "iso9660" ] ; then
            previous_mount_opts=$(sed 's/blocksize=/block=/' <<< "$previous_mount_opts")
        fi
        echo " /home  defaults,${previous_mount_opts}nodev 0 0" >> /etc/fstab
    # If the mount_opt option is not already in the mount point's /etc/fstab entry, add it
    elif ! grep "$mount_point_match_regexp" /etc/fstab | grep -q "nodev"; then
        previous_mount_opts=$(grep "$mount_point_match_regexp" /etc/fstab | awk '{print $4}')
        sed -i "s|\(${mount_point_match_regexp}.*${previous_mount_opts}\)|\1,nodev|" /etc/fstab
    fi


    if mkdir -p "/home"; then
        if mountpoint -q "/home"; then
            mount -o remount --target "/home"
        fi
    fi
}

perform_remediation

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

Complexity:low
Disruption:high
Reboot:false
Strategy:configure
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - configure_strategy
  - high_disruption
  - low_complexity
  - mount_option_home_nodev
  - no_reboot_needed
  - unknown_severity

- name: 'Add nodev Option to /home: Check information associated to mountpoint'
  ansible.builtin.command: findmnt --fstab '/home'
  register: device_name
  failed_when: device_name.rc > 1
  changed_when: false
  check_mode: false
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/home" in ansible_mounts | map(attribute="mount") | list'
  tags:
  - configure_strategy
  - high_disruption
  - low_complexity
  - mount_option_home_nodev
  - no_reboot_needed
  - unknown_severity

- name: 'Add nodev Option to /home: Create mount_info dictionary variable'
  set_fact:
    mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
  with_together:
  - '{{ device_name.stdout_lines[0].split() | map(''lower'') | list }}'
  - '{{ device_name.stdout_lines[1].split() | list }}'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/home" in ansible_mounts | map(attribute="mount") | list'
  - device_name.stdout is defined and device_name.stdout_lines is defined
  - (device_name.stdout | length > 0)
  tags:
  - configure_strategy
  - high_disruption
  - low_complexity
  - mount_option_home_nodev
  - no_reboot_needed
  - unknown_severity

- name: 'Add nodev Option to /home: If /home not mounted, craft mount_info manually'
  set_fact:
    mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
  with_together:
  - - target
    - source
    - fstype
    - options
  - - /home
    - ''
    - ''
    - defaults
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/home" in ansible_mounts | map(attribute="mount") | list'
  - ("--fstab" | length == 0)
  - device_name.stdout is defined and device_name.stdout_lines is defined
  - (device_name.stdout | length == 0)
  tags:
  - configure_strategy
  - high_disruption
  - low_complexity
  - mount_option_home_nodev
  - no_reboot_needed
  - unknown_severity

- name: 'Add nodev Option to /home: Make sure nodev option is part of the to /home
    options'
  set_fact:
    mount_info: '{{ mount_info | combine( {''options'':''''~(mount_info.options |
      default(''''))~('','' if (mount_info.options | default('''')) else '''')~''nodev''
      }) }}'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/home" in ansible_mounts | map(attribute="mount") | list'
  - mount_info is defined and "nodev" not in (mount_info.options | default(''))
  tags:
  - configure_strategy
  - high_disruption
  - low_complexity
  - mount_option_home_nodev
  - no_reboot_needed
  - unknown_severity

- name: 'Add nodev Option to /home: Ensure /home is mounted with nodev option'
  ansible.posix.mount:
    path: /home
    src: '{{ mount_info.source | default('''') }}'
    opts: '{{ mount_info.options | default('''') }}'
    state: mounted
    fstype: '{{ mount_info.fstype | default('''') }}'
  register: mount_result
  failed_when:
  - mount_result is failed
  - '''target is busy'' not in (mount_result.msg | default(''''))'
  - '''already mounted'' not in (mount_result.msg | default(''''))'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/home" in ansible_mounts | map(attribute="mount") | list'
  - mount_info is defined
  - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab"
    | length == 0)
  tags:
  - configure_strategy
  - high_disruption
  - low_complexity
  - mount_option_home_nodev
  - no_reboot_needed
  - unknown_severity

Rule   Add nosuid Option to /home   [ref]

The nosuid mount option can be used to prevent execution of setuid programs in /home. The SUID and SGID permissions should not be required in these user data directories. Add the nosuid option to the fourth column of /etc/fstab for the line which controls mounting of /home.
Rationale:
The presence of SUID and SGID executables should be tightly controlled. Users should not be able to execute SUID or SGID binaries from user home directory partitions.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_mount_option_home_nosuid
References:
cis-csc11, 13, 14, 3, 8, 9
cobit5APO13.01, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.05, DSS05.06, 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.11.2.9, A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, A.8.2.1, A.8.2.2, A.8.2.3, A.8.3.1, A.8.3.3, A.9.1.2
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-7(a), CM-7(b), CM-6(a), AC-6, AC-6(1), MP-7
nist-csfPR.IP-1, PR.PT-2, PR.PT-3
os-srgSRG-OS-000368-GPOS-00154, SRG-OS-000480-GPOS-00227
anssiR28
cis1.1.2.3.3

Reboot:false
# Remediation is applicable only in certain platforms
if ( ! ( { rpm --quiet -q kernel ;} && { rpm --quiet -q rpm-ostree ;} && { rpm --quiet -q bootc ;} && { ! rpm --quiet -q openshift-kubelet ;} && ([ -f /run/ostree-booted ] || [ -L /ostree ]) ) && ! ( [ -f /.dockerenv ] || [ -f /run/.containerenv ] ) ) && { ( findmnt --kernel "/home" > /dev/null || findmnt --fstab "/home" > /dev/null ); }; then

function perform_remediation {

    
        # the mount point /home has to be defined in /etc/fstab
        # before this remediation can be executed. In case it is not defined, the
        # remediation aborts and no changes regarding the mount point are done.
        mount_point_match_regexp="$(printf "^[[:space:]]*[^#].*[[:space:]]%s[[:space:]]" "/home")"

    grep "$mount_point_match_regexp" -q /etc/fstab \
        || { echo "The mount point '/home' is not even in /etc/fstab, so we can't set up mount options" >&2;
                echo "Not remediating, because there is no record of /home in /etc/fstab" >&2; return 1; }
    


    mount_point_match_regexp="$(printf "^[[:space:]]*[^#].*[[:space:]]%s[[:space:]]" /home)"

    # If the mount point is not in /etc/fstab, get previous mount options from /etc/mtab
    if ! grep -q "$mount_point_match_regexp" /etc/fstab; then
        # runtime opts without some automatic kernel/userspace-added defaults
        previous_mount_opts=$(grep "$mount_point_match_regexp" /etc/mtab | head -1 |  awk '{print $4}' \
                    | sed -E "s/(rw|defaults|seclabel|nosuid)(,|$)//g;s/,$//")
        [ "$previous_mount_opts" ] && previous_mount_opts+=","
        # In iso9660 filesystems mtab could describe a "blocksize" value, this should be reflected in
        # fstab as "block".  The next variable is to satisfy shellcheck SC2050.
        fs_type=""
        if [  "$fs_type" == "iso9660" ] ; then
            previous_mount_opts=$(sed 's/blocksize=/block=/' <<< "$previous_mount_opts")
        fi
        echo " /home  defaults,${previous_mount_opts}nosuid 0 0" >> /etc/fstab
    # If the mount_opt option is not already in the mount point's /etc/fstab entry, add it
    elif ! grep "$mount_point_match_regexp" /etc/fstab | grep -q "nosuid"; then
        previous_mount_opts=$(grep "$mount_point_match_regexp" /etc/fstab | awk '{print $4}')
        sed -i "s|\(${mount_point_match_regexp}.*${previous_mount_opts}\)|\1,nosuid|" /etc/fstab
    fi


    if mkdir -p "/home"; then
        if mountpoint -q "/home"; then
            mount -o remount --target "/home"
        fi
    fi
}

perform_remediation

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

Complexity:low
Disruption:high
Reboot:false
Strategy:configure
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_home_nosuid
  - no_reboot_needed

- name: 'Add nosuid Option to /home: Check information associated to mountpoint'
  ansible.builtin.command: findmnt --fstab '/home'
  register: device_name
  failed_when: device_name.rc > 1
  changed_when: false
  check_mode: false
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/home" in ansible_mounts | map(attribute="mount") | list'
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_home_nosuid
  - no_reboot_needed

- name: 'Add nosuid Option to /home: Create mount_info dictionary variable'
  set_fact:
    mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
  with_together:
  - '{{ device_name.stdout_lines[0].split() | map(''lower'') | list }}'
  - '{{ device_name.stdout_lines[1].split() | list }}'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/home" in ansible_mounts | map(attribute="mount") | list'
  - device_name.stdout is defined and device_name.stdout_lines is defined
  - (device_name.stdout | length > 0)
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_home_nosuid
  - no_reboot_needed

- name: 'Add nosuid Option to /home: If /home not mounted, craft mount_info manually'
  set_fact:
    mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
  with_together:
  - - target
    - source
    - fstype
    - options
  - - /home
    - ''
    - ''
    - defaults
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/home" in ansible_mounts | map(attribute="mount") | list'
  - ("--fstab" | length == 0)
  - device_name.stdout is defined and device_name.stdout_lines is defined
  - (device_name.stdout | length == 0)
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_home_nosuid
  - no_reboot_needed

- name: 'Add nosuid Option to /home: Make sure nosuid option is part of the to /home
    options'
  set_fact:
    mount_info: '{{ mount_info | combine( {''options'':''''~(mount_info.options |
      default(''''))~('','' if (mount_info.options | default('''')) else '''')~''nosuid''
      }) }}'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/home" in ansible_mounts | map(attribute="mount") | list'
  - mount_info is defined and "nosuid" not in (mount_info.options | default(''))
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_home_nosuid
  - no_reboot_needed

- name: 'Add nosuid Option to /home: Ensure /home is mounted with nosuid option'
  ansible.posix.mount:
    path: /home
    src: '{{ mount_info.source | default('''') }}'
    opts: '{{ mount_info.options | default('''') }}'
    state: mounted
    fstype: '{{ mount_info.fstype | default('''') }}'
  register: mount_result
  failed_when:
  - mount_result is failed
  - '''target is busy'' not in (mount_result.msg | default(''''))'
  - '''already mounted'' not in (mount_result.msg | default(''''))'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/home" in ansible_mounts | map(attribute="mount") | list'
  - mount_info is defined
  - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab"
    | length == 0)
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_home_nosuid
  - no_reboot_needed

Rule   Add nodev Option to /tmp   [ref]

The nodev mount option can be used to prevent device files from being created in /tmp. Legitimate character and block devices should not exist within temporary directories like /tmp. Add the nodev option to the fourth column of /etc/fstab for the line which controls mounting of /tmp.
Rationale:
The only legitimate location for device files is the /dev directory located on the root partition. The only exception to this is chroot jails.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_mount_option_tmp_nodev
References:
cis-csc11, 13, 14, 3, 8, 9
cobit5APO13.01, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.05, DSS05.06, 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.11.2.9, A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, A.8.2.1, A.8.2.2, A.8.2.3, A.8.3.1, A.8.3.3, A.9.1.2
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-7(a), CM-7(b), CM-6(a), AC-6, AC-6(1), MP-7
nist-csfPR.IP-1, PR.PT-2, PR.PT-3
os-srgSRG-OS-000368-GPOS-00154
cis1.1.2.1.2

Reboot:false
# Remediation is applicable only in certain platforms
if ( ! ( { rpm --quiet -q kernel ;} && { rpm --quiet -q rpm-ostree ;} && { rpm --quiet -q bootc ;} && { ! rpm --quiet -q openshift-kubelet ;} && ([ -f /run/ostree-booted ] || [ -L /ostree ]) ) && ! ( [ -f /.dockerenv ] || [ -f /run/.containerenv ] ) ) && { ( findmnt --kernel "/tmp" > /dev/null || findmnt --fstab "/tmp" > /dev/null ); }; then

function perform_remediation {

    
        # the mount point /tmp has to be defined in /etc/fstab
        # before this remediation can be executed. In case it is not defined, the
        # remediation aborts and no changes regarding the mount point are done.
        mount_point_match_regexp="$(printf "^[[:space:]]*[^#].*[[:space:]]%s[[:space:]]" "/tmp")"

    grep "$mount_point_match_regexp" -q /etc/fstab \
        || { echo "The mount point '/tmp' is not even in /etc/fstab, so we can't set up mount options" >&2;
                echo "Not remediating, because there is no record of /tmp in /etc/fstab" >&2; return 1; }
    


    mount_point_match_regexp="$(printf "^[[:space:]]*[^#].*[[:space:]]%s[[:space:]]" /tmp)"

    # If the mount point is not in /etc/fstab, get previous mount options from /etc/mtab
    if ! grep -q "$mount_point_match_regexp" /etc/fstab; then
        # runtime opts without some automatic kernel/userspace-added defaults
        previous_mount_opts=$(grep "$mount_point_match_regexp" /etc/mtab | head -1 |  awk '{print $4}' \
                    | sed -E "s/(rw|defaults|seclabel|nodev)(,|$)//g;s/,$//")
        [ "$previous_mount_opts" ] && previous_mount_opts+=","
        # In iso9660 filesystems mtab could describe a "blocksize" value, this should be reflected in
        # fstab as "block".  The next variable is to satisfy shellcheck SC2050.
        fs_type=""
        if [  "$fs_type" == "iso9660" ] ; then
            previous_mount_opts=$(sed 's/blocksize=/block=/' <<< "$previous_mount_opts")
        fi
        echo " /tmp  defaults,${previous_mount_opts}nodev 0 0" >> /etc/fstab
    # If the mount_opt option is not already in the mount point's /etc/fstab entry, add it
    elif ! grep "$mount_point_match_regexp" /etc/fstab | grep -q "nodev"; then
        previous_mount_opts=$(grep "$mount_point_match_regexp" /etc/fstab | awk '{print $4}')
        sed -i "s|\(${mount_point_match_regexp}.*${previous_mount_opts}\)|\1,nodev|" /etc/fstab
    fi


    if mkdir -p "/tmp"; then
        if mountpoint -q "/tmp"; then
            mount -o remount --target "/tmp"
        fi
    fi
}

perform_remediation

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

Complexity:low
Disruption:high
Reboot:false
Strategy:configure
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_tmp_nodev
  - no_reboot_needed

- name: 'Add nodev Option to /tmp: Check information associated to mountpoint'
  ansible.builtin.command: findmnt --fstab '/tmp'
  register: device_name
  failed_when: device_name.rc > 1
  changed_when: false
  check_mode: false
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/tmp" in ansible_mounts | map(attribute="mount") | list'
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_tmp_nodev
  - no_reboot_needed

- name: 'Add nodev Option to /tmp: Create mount_info dictionary variable'
  set_fact:
    mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
  with_together:
  - '{{ device_name.stdout_lines[0].split() | map(''lower'') | list }}'
  - '{{ device_name.stdout_lines[1].split() | list }}'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/tmp" in ansible_mounts | map(attribute="mount") | list'
  - device_name.stdout is defined and device_name.stdout_lines is defined
  - (device_name.stdout | length > 0)
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_tmp_nodev
  - no_reboot_needed

- name: 'Add nodev Option to /tmp: If /tmp not mounted, craft mount_info manually'
  set_fact:
    mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
  with_together:
  - - target
    - source
    - fstype
    - options
  - - /tmp
    - ''
    - ''
    - defaults
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/tmp" in ansible_mounts | map(attribute="mount") | list'
  - ("--fstab" | length == 0)
  - device_name.stdout is defined and device_name.stdout_lines is defined
  - (device_name.stdout | length == 0)
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_tmp_nodev
  - no_reboot_needed

- name: 'Add nodev Option to /tmp: Make sure nodev option is part of the to /tmp options'
  set_fact:
    mount_info: '{{ mount_info | combine( {''options'':''''~(mount_info.options |
      default(''''))~('','' if (mount_info.options | default('''')) else '''')~''nodev''
      }) }}'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/tmp" in ansible_mounts | map(attribute="mount") | list'
  - mount_info is defined and "nodev" not in (mount_info.options | default(''))
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_tmp_nodev
  - no_reboot_needed

- name: 'Add nodev Option to /tmp: Ensure /tmp is mounted with nodev option'
  ansible.posix.mount:
    path: /tmp
    src: '{{ mount_info.source | default('''') }}'
    opts: '{{ mount_info.options | default('''') }}'
    state: mounted
    fstype: '{{ mount_info.fstype | default('''') }}'
  register: mount_result
  failed_when:
  - mount_result is failed
  - '''target is busy'' not in (mount_result.msg | default(''''))'
  - '''already mounted'' not in (mount_result.msg | default(''''))'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/tmp" in ansible_mounts | map(attribute="mount") | list'
  - mount_info is defined
  - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab"
    | length == 0)
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_tmp_nodev
  - no_reboot_needed

Rule   Add noexec Option to /tmp   [ref]

The noexec mount option can be used to prevent binaries from being executed out of /tmp. Add the noexec option to the fourth column of /etc/fstab for the line which controls mounting of /tmp.
Rationale:
Allowing users to execute binaries from world-writable directories such as /tmp should never be necessary in normal operation and can expose the system to potential compromise.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_mount_option_tmp_noexec
References:
cis-csc11, 13, 14, 3, 8, 9
cobit5APO13.01, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.05, DSS05.06, 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.11.2.9, A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, A.8.2.1, A.8.2.2, A.8.2.3, A.8.3.1, A.8.3.3, A.9.1.2
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-7(a), CM-7(b), CM-6(a), AC-6, AC-6(1), MP-7
nist-csfPR.IP-1, PR.PT-2, PR.PT-3
os-srgSRG-OS-000368-GPOS-00154
anssiR28
cis1.1.2.1.4

Complexity:low
Disruption:low
Reboot:false
Strategy:enable
# Remediation is applicable only in certain platforms
if ( ! ( { rpm --quiet -q kernel ;} && { rpm --quiet -q rpm-ostree ;} && { rpm --quiet -q bootc ;} && { ! rpm --quiet -q openshift-kubelet ;} && ([ -f /run/ostree-booted ] || [ -L /ostree ]) ) && ! ( [ -f /.dockerenv ] || [ -f /run/.containerenv ] ) ) && { ( findmnt --kernel "/tmp" > /dev/null || findmnt --fstab "/tmp" > /dev/null ); }; then

unit=tmp.mount
mount_option=noexec

# check whether unit is in use
unit_check=$(systemctl -q list-units $unit | grep active)

if [ "x$unit_check" == "x" ]; then
    exit 0
fi

# check whether mount option is present
current_options=$(systemctl show $unit -P Options)
option_check=$(echo $current_options | grep $mount_option | wc -l)

# add systemd drop in to add missing option
if [ $option_check == "0" ]; then
    mkdir -p /etc/systemd/system/$unit.d
    cat > /etc/systemd/system/$unit.d/mount_options.conf <<EOF
[Mount]
Options=$current_options,$mount_option
EOF

    # unit changed on disk. reload.
    systemctl daemon-reload
    
    # note: mount point is probably in use, so we cannot restart
    # the unit without getting an error, but we may be able to
    # remount the filesystem with the new option
    mount_point=$(systemctl show $unit -P Where)
    mount $mount_point -o remount,$mount_option
fi

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

Complexity:low
Disruption:high
Reboot:false
Strategy:configure
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_tmp_noexec
  - no_reboot_needed

- name: 'Add noexec Option to /tmp: Check information associated to mountpoint'
  ansible.builtin.command: findmnt --fstab '/tmp'
  register: device_name
  failed_when: device_name.rc > 1
  changed_when: false
  check_mode: false
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/tmp" in ansible_mounts | map(attribute="mount") | list'
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_tmp_noexec
  - no_reboot_needed

- name: 'Add noexec Option to /tmp: Create mount_info dictionary variable'
  set_fact:
    mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
  with_together:
  - '{{ device_name.stdout_lines[0].split() | map(''lower'') | list }}'
  - '{{ device_name.stdout_lines[1].split() | list }}'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/tmp" in ansible_mounts | map(attribute="mount") | list'
  - device_name.stdout is defined and device_name.stdout_lines is defined
  - (device_name.stdout | length > 0)
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_tmp_noexec
  - no_reboot_needed

- name: 'Add noexec Option to /tmp: If /tmp not mounted, craft mount_info manually'
  set_fact:
    mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
  with_together:
  - - target
    - source
    - fstype
    - options
  - - /tmp
    - ''
    - ''
    - defaults
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/tmp" in ansible_mounts | map(attribute="mount") | list'
  - ("--fstab" | length == 0)
  - device_name.stdout is defined and device_name.stdout_lines is defined
  - (device_name.stdout | length == 0)
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_tmp_noexec
  - no_reboot_needed

- name: 'Add noexec Option to /tmp: Make sure noexec option is part of the to /tmp
    options'
  set_fact:
    mount_info: '{{ mount_info | combine( {''options'':''''~(mount_info.options |
      default(''''))~('','' if (mount_info.options | default('''')) else '''')~''noexec''
      }) }}'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/tmp" in ansible_mounts | map(attribute="mount") | list'
  - mount_info is defined and "noexec" not in (mount_info.options | default(''))
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_tmp_noexec
  - no_reboot_needed

- name: 'Add noexec Option to /tmp: Ensure /tmp is mounted with noexec option'
  ansible.posix.mount:
    path: /tmp
    src: '{{ mount_info.source | default('''') }}'
    opts: '{{ mount_info.options | default('''') }}'
    state: mounted
    fstype: '{{ mount_info.fstype | default('''') }}'
  register: mount_result
  failed_when:
  - mount_result is failed
  - '''target is busy'' not in (mount_result.msg | default(''''))'
  - '''already mounted'' not in (mount_result.msg | default(''''))'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/tmp" in ansible_mounts | map(attribute="mount") | list'
  - mount_info is defined
  - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab"
    | length == 0)
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_tmp_noexec
  - no_reboot_needed

Rule   Add nosuid Option to /tmp   [ref]

The nosuid mount option can be used to prevent execution of setuid programs in /tmp. The SUID and SGID permissions should not be required in these world-writable directories. Add the nosuid option to the fourth column of /etc/fstab for the line which controls mounting of /tmp.
Rationale:
The presence of SUID and SGID executables should be tightly controlled. Users should not be able to execute SUID or SGID binaries from temporary storage partitions.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_mount_option_tmp_nosuid
References:
cis-csc11, 13, 14, 3, 8, 9
cobit5APO13.01, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.05, DSS05.06, 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.11.2.9, A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, A.8.2.1, A.8.2.2, A.8.2.3, A.8.3.1, A.8.3.3, A.9.1.2
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-7(a), CM-7(b), CM-6(a), AC-6, AC-6(1), MP-7
nist-csfPR.IP-1, PR.PT-2, PR.PT-3
os-srgSRG-OS-000368-GPOS-00154
anssiR28
cis1.1.2.1.3

Reboot:false
# Remediation is applicable only in certain platforms
if ( ! ( { rpm --quiet -q kernel ;} && { rpm --quiet -q rpm-ostree ;} && { rpm --quiet -q bootc ;} && { ! rpm --quiet -q openshift-kubelet ;} && ([ -f /run/ostree-booted ] || [ -L /ostree ]) ) && ! ( [ -f /.dockerenv ] || [ -f /run/.containerenv ] ) ) && { ( findmnt --kernel "/tmp" > /dev/null || findmnt --fstab "/tmp" > /dev/null ); }; then

function perform_remediation {

    
        # the mount point /tmp has to be defined in /etc/fstab
        # before this remediation can be executed. In case it is not defined, the
        # remediation aborts and no changes regarding the mount point are done.
        mount_point_match_regexp="$(printf "^[[:space:]]*[^#].*[[:space:]]%s[[:space:]]" "/tmp")"

    grep "$mount_point_match_regexp" -q /etc/fstab \
        || { echo "The mount point '/tmp' is not even in /etc/fstab, so we can't set up mount options" >&2;
                echo "Not remediating, because there is no record of /tmp in /etc/fstab" >&2; return 1; }
    


    mount_point_match_regexp="$(printf "^[[:space:]]*[^#].*[[:space:]]%s[[:space:]]" /tmp)"

    # If the mount point is not in /etc/fstab, get previous mount options from /etc/mtab
    if ! grep -q "$mount_point_match_regexp" /etc/fstab; then
        # runtime opts without some automatic kernel/userspace-added defaults
        previous_mount_opts=$(grep "$mount_point_match_regexp" /etc/mtab | head -1 |  awk '{print $4}' \
                    | sed -E "s/(rw|defaults|seclabel|nosuid)(,|$)//g;s/,$//")
        [ "$previous_mount_opts" ] && previous_mount_opts+=","
        # In iso9660 filesystems mtab could describe a "blocksize" value, this should be reflected in
        # fstab as "block".  The next variable is to satisfy shellcheck SC2050.
        fs_type=""
        if [  "$fs_type" == "iso9660" ] ; then
            previous_mount_opts=$(sed 's/blocksize=/block=/' <<< "$previous_mount_opts")
        fi
        echo " /tmp  defaults,${previous_mount_opts}nosuid 0 0" >> /etc/fstab
    # If the mount_opt option is not already in the mount point's /etc/fstab entry, add it
    elif ! grep "$mount_point_match_regexp" /etc/fstab | grep -q "nosuid"; then
        previous_mount_opts=$(grep "$mount_point_match_regexp" /etc/fstab | awk '{print $4}')
        sed -i "s|\(${mount_point_match_regexp}.*${previous_mount_opts}\)|\1,nosuid|" /etc/fstab
    fi


    if mkdir -p "/tmp"; then
        if mountpoint -q "/tmp"; then
            mount -o remount --target "/tmp"
        fi
    fi
}

perform_remediation

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

Complexity:low
Disruption:high
Reboot:false
Strategy:configure
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_tmp_nosuid
  - no_reboot_needed

- name: 'Add nosuid Option to /tmp: Check information associated to mountpoint'
  ansible.builtin.command: findmnt --fstab '/tmp'
  register: device_name
  failed_when: device_name.rc > 1
  changed_when: false
  check_mode: false
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/tmp" in ansible_mounts | map(attribute="mount") | list'
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_tmp_nosuid
  - no_reboot_needed

- name: 'Add nosuid Option to /tmp: Create mount_info dictionary variable'
  set_fact:
    mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
  with_together:
  - '{{ device_name.stdout_lines[0].split() | map(''lower'') | list }}'
  - '{{ device_name.stdout_lines[1].split() | list }}'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/tmp" in ansible_mounts | map(attribute="mount") | list'
  - device_name.stdout is defined and device_name.stdout_lines is defined
  - (device_name.stdout | length > 0)
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_tmp_nosuid
  - no_reboot_needed

- name: 'Add nosuid Option to /tmp: If /tmp not mounted, craft mount_info manually'
  set_fact:
    mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
  with_together:
  - - target
    - source
    - fstype
    - options
  - - /tmp
    - ''
    - ''
    - defaults
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/tmp" in ansible_mounts | map(attribute="mount") | list'
  - ("--fstab" | length == 0)
  - device_name.stdout is defined and device_name.stdout_lines is defined
  - (device_name.stdout | length == 0)
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_tmp_nosuid
  - no_reboot_needed

- name: 'Add nosuid Option to /tmp: Make sure nosuid option is part of the to /tmp
    options'
  set_fact:
    mount_info: '{{ mount_info | combine( {''options'':''''~(mount_info.options |
      default(''''))~('','' if (mount_info.options | default('''')) else '''')~''nosuid''
      }) }}'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/tmp" in ansible_mounts | map(attribute="mount") | list'
  - mount_info is defined and "nosuid" not in (mount_info.options | default(''))
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_tmp_nosuid
  - no_reboot_needed

- name: 'Add nosuid Option to /tmp: Ensure /tmp is mounted with nosuid option'
  ansible.posix.mount:
    path: /tmp
    src: '{{ mount_info.source | default('''') }}'
    opts: '{{ mount_info.options | default('''') }}'
    state: mounted
    fstype: '{{ mount_info.fstype | default('''') }}'
  register: mount_result
  failed_when:
  - mount_result is failed
  - '''target is busy'' not in (mount_result.msg | default(''''))'
  - '''already mounted'' not in (mount_result.msg | default(''''))'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/tmp" in ansible_mounts | map(attribute="mount") | list'
  - mount_info is defined
  - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab"
    | length == 0)
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_tmp_nosuid
  - no_reboot_needed

Rule   Add nodev Option to /var/log/audit   [ref]

The nodev mount option can be used to prevent device files from being created in /var/log/audit. Legitimate character and block devices should exist only in the /dev directory on the root partition or within chroot jails built for system services. Add the nodev option to the fourth column of /etc/fstab for the line which controls mounting of /var/log/audit.
Rationale:
The only legitimate location for device files is the /dev directory located on the root partition. The only exception to this is chroot jails.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_mount_option_var_log_audit_nodev
References:
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-7(a), CM-7(b), CM-6(a), AC-6, AC-6(1), MP-7
nist-csfPR.IP-1, PR.PT-2, PR.PT-3
osppFMT_SMF_EXT.1
os-srgSRG-OS-000368-GPOS-00154
cis1.1.2.7.2

Reboot:false
# Remediation is applicable only in certain platforms
if ( ! ( { rpm --quiet -q kernel ;} && { rpm --quiet -q rpm-ostree ;} && { rpm --quiet -q bootc ;} && { ! rpm --quiet -q openshift-kubelet ;} && ([ -f /run/ostree-booted ] || [ -L /ostree ]) ) && ! ( [ -f /.dockerenv ] || [ -f /run/.containerenv ] ) ) && { ( findmnt --kernel "/var/log/audit" > /dev/null || findmnt --fstab "/var/log/audit" > /dev/null ); }; then

function perform_remediation {

    
        # the mount point /var/log/audit has to be defined in /etc/fstab
        # before this remediation can be executed. In case it is not defined, the
        # remediation aborts and no changes regarding the mount point are done.
        mount_point_match_regexp="$(printf "^[[:space:]]*[^#].*[[:space:]]%s[[:space:]]" "/var/log/audit")"

    grep "$mount_point_match_regexp" -q /etc/fstab \
        || { echo "The mount point '/var/log/audit' is not even in /etc/fstab, so we can't set up mount options" >&2;
                echo "Not remediating, because there is no record of /var/log/audit in /etc/fstab" >&2; return 1; }
    


    mount_point_match_regexp="$(printf "^[[:space:]]*[^#].*[[:space:]]%s[[:space:]]" /var/log/audit)"

    # If the mount point is not in /etc/fstab, get previous mount options from /etc/mtab
    if ! grep -q "$mount_point_match_regexp" /etc/fstab; then
        # runtime opts without some automatic kernel/userspace-added defaults
        previous_mount_opts=$(grep "$mount_point_match_regexp" /etc/mtab | head -1 |  awk '{print $4}' \
                    | sed -E "s/(rw|defaults|seclabel|nodev)(,|$)//g;s/,$//")
        [ "$previous_mount_opts" ] && previous_mount_opts+=","
        # In iso9660 filesystems mtab could describe a "blocksize" value, this should be reflected in
        # fstab as "block".  The next variable is to satisfy shellcheck SC2050.
        fs_type=""
        if [  "$fs_type" == "iso9660" ] ; then
            previous_mount_opts=$(sed 's/blocksize=/block=/' <<< "$previous_mount_opts")
        fi
        echo " /var/log/audit  defaults,${previous_mount_opts}nodev 0 0" >> /etc/fstab
    # If the mount_opt option is not already in the mount point's /etc/fstab entry, add it
    elif ! grep "$mount_point_match_regexp" /etc/fstab | grep -q "nodev"; then
        previous_mount_opts=$(grep "$mount_point_match_regexp" /etc/fstab | awk '{print $4}')
        sed -i "s|\(${mount_point_match_regexp}.*${previous_mount_opts}\)|\1,nodev|" /etc/fstab
    fi


    if mkdir -p "/var/log/audit"; then
        if mountpoint -q "/var/log/audit"; then
            mount -o remount --target "/var/log/audit"
        fi
    fi
}

perform_remediation

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

Complexity:low
Disruption:high
Reboot:false
Strategy:configure
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_log_audit_nodev
  - no_reboot_needed

- name: 'Add nodev Option to /var/log/audit: Check information associated to mountpoint'
  ansible.builtin.command: findmnt --fstab '/var/log/audit'
  register: device_name
  failed_when: device_name.rc > 1
  changed_when: false
  check_mode: false
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list'
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_log_audit_nodev
  - no_reboot_needed

- name: 'Add nodev Option to /var/log/audit: Create mount_info dictionary variable'
  set_fact:
    mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
  with_together:
  - '{{ device_name.stdout_lines[0].split() | map(''lower'') | list }}'
  - '{{ device_name.stdout_lines[1].split() | list }}'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list'
  - device_name.stdout is defined and device_name.stdout_lines is defined
  - (device_name.stdout | length > 0)
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_log_audit_nodev
  - no_reboot_needed

- name: 'Add nodev Option to /var/log/audit: If /var/log/audit not mounted, craft
    mount_info manually'
  set_fact:
    mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
  with_together:
  - - target
    - source
    - fstype
    - options
  - - /var/log/audit
    - ''
    - ''
    - defaults
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list'
  - ("--fstab" | length == 0)
  - device_name.stdout is defined and device_name.stdout_lines is defined
  - (device_name.stdout | length == 0)
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_log_audit_nodev
  - no_reboot_needed

- name: 'Add nodev Option to /var/log/audit: Make sure nodev option is part of the
    to /var/log/audit options'
  set_fact:
    mount_info: '{{ mount_info | combine( {''options'':''''~(mount_info.options |
      default(''''))~('','' if (mount_info.options | default('''')) else '''')~''nodev''
      }) }}'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list'
  - mount_info is defined and "nodev" not in (mount_info.options | default(''))
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_log_audit_nodev
  - no_reboot_needed

- name: 'Add nodev Option to /var/log/audit: Ensure /var/log/audit is mounted with
    nodev option'
  ansible.posix.mount:
    path: /var/log/audit
    src: '{{ mount_info.source | default('''') }}'
    opts: '{{ mount_info.options | default('''') }}'
    state: mounted
    fstype: '{{ mount_info.fstype | default('''') }}'
  register: mount_result
  failed_when:
  - mount_result is failed
  - '''target is busy'' not in (mount_result.msg | default(''''))'
  - '''already mounted'' not in (mount_result.msg | default(''''))'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list'
  - mount_info is defined
  - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab"
    | length == 0)
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_log_audit_nodev
  - no_reboot_needed

Rule   Add noexec Option to /var/log/audit   [ref]

The noexec mount option can be used to prevent binaries from being executed out of /var/log/audit. Add the noexec option to the fourth column of /etc/fstab for the line which controls mounting of /var/log/audit.
Rationale:
Allowing users to execute binaries from directories containing audit log files such as /var/log/audit should never be necessary in normal operation and can expose the system to potential compromise.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_mount_option_var_log_audit_noexec
References:
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-7(a), CM-7(b), CM-6(a), AC-6, AC-6(1), MP-7
nist-csfPR.IP-1, PR.PT-2, PR.PT-3
osppFMT_SMF_EXT.1
os-srgSRG-OS-000368-GPOS-00154
cis1.1.2.7.4

Reboot:false
# Remediation is applicable only in certain platforms
if ( ! ( { rpm --quiet -q kernel ;} && { rpm --quiet -q rpm-ostree ;} && { rpm --quiet -q bootc ;} && { ! rpm --quiet -q openshift-kubelet ;} && ([ -f /run/ostree-booted ] || [ -L /ostree ]) ) && ! ( [ -f /.dockerenv ] || [ -f /run/.containerenv ] ) ) && { ( findmnt --kernel "/var/log/audit" > /dev/null || findmnt --fstab "/var/log/audit" > /dev/null ); }; then

function perform_remediation {

    
        # the mount point /var/log/audit has to be defined in /etc/fstab
        # before this remediation can be executed. In case it is not defined, the
        # remediation aborts and no changes regarding the mount point are done.
        mount_point_match_regexp="$(printf "^[[:space:]]*[^#].*[[:space:]]%s[[:space:]]" "/var/log/audit")"

    grep "$mount_point_match_regexp" -q /etc/fstab \
        || { echo "The mount point '/var/log/audit' is not even in /etc/fstab, so we can't set up mount options" >&2;
                echo "Not remediating, because there is no record of /var/log/audit in /etc/fstab" >&2; return 1; }
    


    mount_point_match_regexp="$(printf "^[[:space:]]*[^#].*[[:space:]]%s[[:space:]]" /var/log/audit)"

    # If the mount point is not in /etc/fstab, get previous mount options from /etc/mtab
    if ! grep -q "$mount_point_match_regexp" /etc/fstab; then
        # runtime opts without some automatic kernel/userspace-added defaults
        previous_mount_opts=$(grep "$mount_point_match_regexp" /etc/mtab | head -1 |  awk '{print $4}' \
                    | sed -E "s/(rw|defaults|seclabel|noexec)(,|$)//g;s/,$//")
        [ "$previous_mount_opts" ] && previous_mount_opts+=","
        # In iso9660 filesystems mtab could describe a "blocksize" value, this should be reflected in
        # fstab as "block".  The next variable is to satisfy shellcheck SC2050.
        fs_type=""
        if [  "$fs_type" == "iso9660" ] ; then
            previous_mount_opts=$(sed 's/blocksize=/block=/' <<< "$previous_mount_opts")
        fi
        echo " /var/log/audit  defaults,${previous_mount_opts}noexec 0 0" >> /etc/fstab
    # If the mount_opt option is not already in the mount point's /etc/fstab entry, add it
    elif ! grep "$mount_point_match_regexp" /etc/fstab | grep -q "noexec"; then
        previous_mount_opts=$(grep "$mount_point_match_regexp" /etc/fstab | awk '{print $4}')
        sed -i "s|\(${mount_point_match_regexp}.*${previous_mount_opts}\)|\1,noexec|" /etc/fstab
    fi


    if mkdir -p "/var/log/audit"; then
        if mountpoint -q "/var/log/audit"; then
            mount -o remount --target "/var/log/audit"
        fi
    fi
}

perform_remediation

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

Complexity:low
Disruption:high
Reboot:false
Strategy:configure
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_log_audit_noexec
  - no_reboot_needed

- name: 'Add noexec Option to /var/log/audit: Check information associated to mountpoint'
  ansible.builtin.command: findmnt --fstab '/var/log/audit'
  register: device_name
  failed_when: device_name.rc > 1
  changed_when: false
  check_mode: false
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list'
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_log_audit_noexec
  - no_reboot_needed

- name: 'Add noexec Option to /var/log/audit: Create mount_info dictionary variable'
  set_fact:
    mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
  with_together:
  - '{{ device_name.stdout_lines[0].split() | map(''lower'') | list }}'
  - '{{ device_name.stdout_lines[1].split() | list }}'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list'
  - device_name.stdout is defined and device_name.stdout_lines is defined
  - (device_name.stdout | length > 0)
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_log_audit_noexec
  - no_reboot_needed

- name: 'Add noexec Option to /var/log/audit: If /var/log/audit not mounted, craft
    mount_info manually'
  set_fact:
    mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
  with_together:
  - - target
    - source
    - fstype
    - options
  - - /var/log/audit
    - ''
    - ''
    - defaults
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list'
  - ("--fstab" | length == 0)
  - device_name.stdout is defined and device_name.stdout_lines is defined
  - (device_name.stdout | length == 0)
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_log_audit_noexec
  - no_reboot_needed

- name: 'Add noexec Option to /var/log/audit: Make sure noexec option is part of the
    to /var/log/audit options'
  set_fact:
    mount_info: '{{ mount_info | combine( {''options'':''''~(mount_info.options |
      default(''''))~('','' if (mount_info.options | default('''')) else '''')~''noexec''
      }) }}'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list'
  - mount_info is defined and "noexec" not in (mount_info.options | default(''))
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_log_audit_noexec
  - no_reboot_needed

- name: 'Add noexec Option to /var/log/audit: Ensure /var/log/audit is mounted with
    noexec option'
  ansible.posix.mount:
    path: /var/log/audit
    src: '{{ mount_info.source | default('''') }}'
    opts: '{{ mount_info.options | default('''') }}'
    state: mounted
    fstype: '{{ mount_info.fstype | default('''') }}'
  register: mount_result
  failed_when:
  - mount_result is failed
  - '''target is busy'' not in (mount_result.msg | default(''''))'
  - '''already mounted'' not in (mount_result.msg | default(''''))'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list'
  - mount_info is defined
  - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab"
    | length == 0)
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_log_audit_noexec
  - no_reboot_needed

Rule   Add nosuid Option to /var/log/audit   [ref]

The nosuid mount option can be used to prevent execution of setuid programs in /var/log/audit. The SUID and SGID permissions should not be required in directories containing audit log files. Add the nosuid option to the fourth column of /etc/fstab for the line which controls mounting of /var/log/audit.
Rationale:
The presence of SUID and SGID executables should be tightly controlled. Users should not be able to execute SUID or SGID binaries from partitions designated for audit log files.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_mount_option_var_log_audit_nosuid
References:
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-7(a), CM-7(b), CM-6(a), AC-6, AC-6(1), MP-7
nist-csfPR.IP-1, PR.PT-2, PR.PT-3
osppFMT_SMF_EXT.1
os-srgSRG-OS-000368-GPOS-00154
cis1.1.2.7.3

Reboot:false
# Remediation is applicable only in certain platforms
if ( ! ( { rpm --quiet -q kernel ;} && { rpm --quiet -q rpm-ostree ;} && { rpm --quiet -q bootc ;} && { ! rpm --quiet -q openshift-kubelet ;} && ([ -f /run/ostree-booted ] || [ -L /ostree ]) ) && ! ( [ -f /.dockerenv ] || [ -f /run/.containerenv ] ) ) && { ( findmnt --kernel "/var/log/audit" > /dev/null || findmnt --fstab "/var/log/audit" > /dev/null ); }; then

function perform_remediation {

    
        # the mount point /var/log/audit has to be defined in /etc/fstab
        # before this remediation can be executed. In case it is not defined, the
        # remediation aborts and no changes regarding the mount point are done.
        mount_point_match_regexp="$(printf "^[[:space:]]*[^#].*[[:space:]]%s[[:space:]]" "/var/log/audit")"

    grep "$mount_point_match_regexp" -q /etc/fstab \
        || { echo "The mount point '/var/log/audit' is not even in /etc/fstab, so we can't set up mount options" >&2;
                echo "Not remediating, because there is no record of /var/log/audit in /etc/fstab" >&2; return 1; }
    


    mount_point_match_regexp="$(printf "^[[:space:]]*[^#].*[[:space:]]%s[[:space:]]" /var/log/audit)"

    # If the mount point is not in /etc/fstab, get previous mount options from /etc/mtab
    if ! grep -q "$mount_point_match_regexp" /etc/fstab; then
        # runtime opts without some automatic kernel/userspace-added defaults
        previous_mount_opts=$(grep "$mount_point_match_regexp" /etc/mtab | head -1 |  awk '{print $4}' \
                    | sed -E "s/(rw|defaults|seclabel|nosuid)(,|$)//g;s/,$//")
        [ "$previous_mount_opts" ] && previous_mount_opts+=","
        # In iso9660 filesystems mtab could describe a "blocksize" value, this should be reflected in
        # fstab as "block".  The next variable is to satisfy shellcheck SC2050.
        fs_type=""
        if [  "$fs_type" == "iso9660" ] ; then
            previous_mount_opts=$(sed 's/blocksize=/block=/' <<< "$previous_mount_opts")
        fi
        echo " /var/log/audit  defaults,${previous_mount_opts}nosuid 0 0" >> /etc/fstab
    # If the mount_opt option is not already in the mount point's /etc/fstab entry, add it
    elif ! grep "$mount_point_match_regexp" /etc/fstab | grep -q "nosuid"; then
        previous_mount_opts=$(grep "$mount_point_match_regexp" /etc/fstab | awk '{print $4}')
        sed -i "s|\(${mount_point_match_regexp}.*${previous_mount_opts}\)|\1,nosuid|" /etc/fstab
    fi


    if mkdir -p "/var/log/audit"; then
        if mountpoint -q "/var/log/audit"; then
            mount -o remount --target "/var/log/audit"
        fi
    fi
}

perform_remediation

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

Complexity:low
Disruption:high
Reboot:false
Strategy:configure
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_log_audit_nosuid
  - no_reboot_needed

- name: 'Add nosuid Option to /var/log/audit: Check information associated to mountpoint'
  ansible.builtin.command: findmnt --fstab '/var/log/audit'
  register: device_name
  failed_when: device_name.rc > 1
  changed_when: false
  check_mode: false
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list'
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_log_audit_nosuid
  - no_reboot_needed

- name: 'Add nosuid Option to /var/log/audit: Create mount_info dictionary variable'
  set_fact:
    mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
  with_together:
  - '{{ device_name.stdout_lines[0].split() | map(''lower'') | list }}'
  - '{{ device_name.stdout_lines[1].split() | list }}'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list'
  - device_name.stdout is defined and device_name.stdout_lines is defined
  - (device_name.stdout | length > 0)
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_log_audit_nosuid
  - no_reboot_needed

- name: 'Add nosuid Option to /var/log/audit: If /var/log/audit not mounted, craft
    mount_info manually'
  set_fact:
    mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
  with_together:
  - - target
    - source
    - fstype
    - options
  - - /var/log/audit
    - ''
    - ''
    - defaults
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list'
  - ("--fstab" | length == 0)
  - device_name.stdout is defined and device_name.stdout_lines is defined
  - (device_name.stdout | length == 0)
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_log_audit_nosuid
  - no_reboot_needed

- name: 'Add nosuid Option to /var/log/audit: Make sure nosuid option is part of the
    to /var/log/audit options'
  set_fact:
    mount_info: '{{ mount_info | combine( {''options'':''''~(mount_info.options |
      default(''''))~('','' if (mount_info.options | default('''')) else '''')~''nosuid''
      }) }}'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list'
  - mount_info is defined and "nosuid" not in (mount_info.options | default(''))
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_log_audit_nosuid
  - no_reboot_needed

- name: 'Add nosuid Option to /var/log/audit: Ensure /var/log/audit is mounted with
    nosuid option'
  ansible.posix.mount:
    path: /var/log/audit
    src: '{{ mount_info.source | default('''') }}'
    opts: '{{ mount_info.options | default('''') }}'
    state: mounted
    fstype: '{{ mount_info.fstype | default('''') }}'
  register: mount_result
  failed_when:
  - mount_result is failed
  - '''target is busy'' not in (mount_result.msg | default(''''))'
  - '''already mounted'' not in (mount_result.msg | default(''''))'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var/log/audit" in ansible_mounts | map(attribute="mount") | list'
  - mount_info is defined
  - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab"
    | length == 0)
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_log_audit_nosuid
  - no_reboot_needed

Rule   Add nodev Option to /var/log   [ref]

The nodev mount option can be used to prevent device files from being created in /var/log. Legitimate character and block devices should exist only in the /dev directory on the root partition or within chroot jails built for system services. Add the nodev option to the fourth column of /etc/fstab for the line which controls mounting of /var/log.
Rationale:
The only legitimate location for device files is the /dev directory located on the root partition. The only exception to this is chroot jails.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_mount_option_var_log_nodev
References:
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-7(a), CM-7(b), CM-6(a), AC-6, AC-6(1), MP-7
nist-csfPR.IP-1, PR.PT-2, PR.PT-3
os-srgSRG-OS-000368-GPOS-00154
cis1.1.2.6.2

Reboot:false
# Remediation is applicable only in certain platforms
if ( ! ( { rpm --quiet -q kernel ;} && { rpm --quiet -q rpm-ostree ;} && { rpm --quiet -q bootc ;} && { ! rpm --quiet -q openshift-kubelet ;} && ([ -f /run/ostree-booted ] || [ -L /ostree ]) ) && ! ( [ -f /.dockerenv ] || [ -f /run/.containerenv ] ) ) && { ( findmnt --kernel "/var/log" > /dev/null || findmnt --fstab "/var/log" > /dev/null ); }; then

function perform_remediation {

    
        # the mount point /var/log has to be defined in /etc/fstab
        # before this remediation can be executed. In case it is not defined, the
        # remediation aborts and no changes regarding the mount point are done.
        mount_point_match_regexp="$(printf "^[[:space:]]*[^#].*[[:space:]]%s[[:space:]]" "/var/log")"

    grep "$mount_point_match_regexp" -q /etc/fstab \
        || { echo "The mount point '/var/log' is not even in /etc/fstab, so we can't set up mount options" >&2;
                echo "Not remediating, because there is no record of /var/log in /etc/fstab" >&2; return 1; }
    


    mount_point_match_regexp="$(printf "^[[:space:]]*[^#].*[[:space:]]%s[[:space:]]" /var/log)"

    # If the mount point is not in /etc/fstab, get previous mount options from /etc/mtab
    if ! grep -q "$mount_point_match_regexp" /etc/fstab; then
        # runtime opts without some automatic kernel/userspace-added defaults
        previous_mount_opts=$(grep "$mount_point_match_regexp" /etc/mtab | head -1 |  awk '{print $4}' \
                    | sed -E "s/(rw|defaults|seclabel|nodev)(,|$)//g;s/,$//")
        [ "$previous_mount_opts" ] && previous_mount_opts+=","
        # In iso9660 filesystems mtab could describe a "blocksize" value, this should be reflected in
        # fstab as "block".  The next variable is to satisfy shellcheck SC2050.
        fs_type=""
        if [  "$fs_type" == "iso9660" ] ; then
            previous_mount_opts=$(sed 's/blocksize=/block=/' <<< "$previous_mount_opts")
        fi
        echo " /var/log  defaults,${previous_mount_opts}nodev 0 0" >> /etc/fstab
    # If the mount_opt option is not already in the mount point's /etc/fstab entry, add it
    elif ! grep "$mount_point_match_regexp" /etc/fstab | grep -q "nodev"; then
        previous_mount_opts=$(grep "$mount_point_match_regexp" /etc/fstab | awk '{print $4}')
        sed -i "s|\(${mount_point_match_regexp}.*${previous_mount_opts}\)|\1,nodev|" /etc/fstab
    fi


    if mkdir -p "/var/log"; then
        if mountpoint -q "/var/log"; then
            mount -o remount --target "/var/log"
        fi
    fi
}

perform_remediation

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

Complexity:low
Disruption:high
Reboot:false
Strategy:configure
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_log_nodev
  - no_reboot_needed

- name: 'Add nodev Option to /var/log: Check information associated to mountpoint'
  ansible.builtin.command: findmnt --fstab '/var/log'
  register: device_name
  failed_when: device_name.rc > 1
  changed_when: false
  check_mode: false
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var/log" in ansible_mounts | map(attribute="mount") | list'
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_log_nodev
  - no_reboot_needed

- name: 'Add nodev Option to /var/log: Create mount_info dictionary variable'
  set_fact:
    mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
  with_together:
  - '{{ device_name.stdout_lines[0].split() | map(''lower'') | list }}'
  - '{{ device_name.stdout_lines[1].split() | list }}'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var/log" in ansible_mounts | map(attribute="mount") | list'
  - device_name.stdout is defined and device_name.stdout_lines is defined
  - (device_name.stdout | length > 0)
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_log_nodev
  - no_reboot_needed

- name: 'Add nodev Option to /var/log: If /var/log not mounted, craft mount_info manually'
  set_fact:
    mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
  with_together:
  - - target
    - source
    - fstype
    - options
  - - /var/log
    - ''
    - ''
    - defaults
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var/log" in ansible_mounts | map(attribute="mount") | list'
  - ("--fstab" | length == 0)
  - device_name.stdout is defined and device_name.stdout_lines is defined
  - (device_name.stdout | length == 0)
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_log_nodev
  - no_reboot_needed

- name: 'Add nodev Option to /var/log: Make sure nodev option is part of the to /var/log
    options'
  set_fact:
    mount_info: '{{ mount_info | combine( {''options'':''''~(mount_info.options |
      default(''''))~('','' if (mount_info.options | default('''')) else '''')~''nodev''
      }) }}'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var/log" in ansible_mounts | map(attribute="mount") | list'
  - mount_info is defined and "nodev" not in (mount_info.options | default(''))
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_log_nodev
  - no_reboot_needed

- name: 'Add nodev Option to /var/log: Ensure /var/log is mounted with nodev option'
  ansible.posix.mount:
    path: /var/log
    src: '{{ mount_info.source | default('''') }}'
    opts: '{{ mount_info.options | default('''') }}'
    state: mounted
    fstype: '{{ mount_info.fstype | default('''') }}'
  register: mount_result
  failed_when:
  - mount_result is failed
  - '''target is busy'' not in (mount_result.msg | default(''''))'
  - '''already mounted'' not in (mount_result.msg | default(''''))'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var/log" in ansible_mounts | map(attribute="mount") | list'
  - mount_info is defined
  - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab"
    | length == 0)
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_log_nodev
  - no_reboot_needed

Rule   Add noexec Option to /var/log   [ref]

The noexec mount option can be used to prevent binaries from being executed out of /var/log. Add the noexec option to the fourth column of /etc/fstab for the line which controls mounting of /var/log.
Rationale:
Allowing users to execute binaries from directories containing log files such as /var/log should never be necessary in normal operation and can expose the system to potential compromise.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_mount_option_var_log_noexec
References:
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-7(a), CM-7(b), CM-6(a), AC-6, AC-6(1), MP-7
nist-csfPR.IP-1, PR.PT-2, PR.PT-3
os-srgSRG-OS-000368-GPOS-00154
anssiR28
cis1.1.2.6.4

Reboot:false
# Remediation is applicable only in certain platforms
if ( ! ( { rpm --quiet -q kernel ;} && { rpm --quiet -q rpm-ostree ;} && { rpm --quiet -q bootc ;} && { ! rpm --quiet -q openshift-kubelet ;} && ([ -f /run/ostree-booted ] || [ -L /ostree ]) ) && ! ( [ -f /.dockerenv ] || [ -f /run/.containerenv ] ) ) && { ( findmnt --kernel "/var/log" > /dev/null || findmnt --fstab "/var/log" > /dev/null ); }; then

function perform_remediation {

    
        # the mount point /var/log has to be defined in /etc/fstab
        # before this remediation can be executed. In case it is not defined, the
        # remediation aborts and no changes regarding the mount point are done.
        mount_point_match_regexp="$(printf "^[[:space:]]*[^#].*[[:space:]]%s[[:space:]]" "/var/log")"

    grep "$mount_point_match_regexp" -q /etc/fstab \
        || { echo "The mount point '/var/log' is not even in /etc/fstab, so we can't set up mount options" >&2;
                echo "Not remediating, because there is no record of /var/log in /etc/fstab" >&2; return 1; }
    


    mount_point_match_regexp="$(printf "^[[:space:]]*[^#].*[[:space:]]%s[[:space:]]" /var/log)"

    # If the mount point is not in /etc/fstab, get previous mount options from /etc/mtab
    if ! grep -q "$mount_point_match_regexp" /etc/fstab; then
        # runtime opts without some automatic kernel/userspace-added defaults
        previous_mount_opts=$(grep "$mount_point_match_regexp" /etc/mtab | head -1 |  awk '{print $4}' \
                    | sed -E "s/(rw|defaults|seclabel|noexec)(,|$)//g;s/,$//")
        [ "$previous_mount_opts" ] && previous_mount_opts+=","
        # In iso9660 filesystems mtab could describe a "blocksize" value, this should be reflected in
        # fstab as "block".  The next variable is to satisfy shellcheck SC2050.
        fs_type=""
        if [  "$fs_type" == "iso9660" ] ; then
            previous_mount_opts=$(sed 's/blocksize=/block=/' <<< "$previous_mount_opts")
        fi
        echo " /var/log  defaults,${previous_mount_opts}noexec 0 0" >> /etc/fstab
    # If the mount_opt option is not already in the mount point's /etc/fstab entry, add it
    elif ! grep "$mount_point_match_regexp" /etc/fstab | grep -q "noexec"; then
        previous_mount_opts=$(grep "$mount_point_match_regexp" /etc/fstab | awk '{print $4}')
        sed -i "s|\(${mount_point_match_regexp}.*${previous_mount_opts}\)|\1,noexec|" /etc/fstab
    fi


    if mkdir -p "/var/log"; then
        if mountpoint -q "/var/log"; then
            mount -o remount --target "/var/log"
        fi
    fi
}

perform_remediation

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

Complexity:low
Disruption:high
Reboot:false
Strategy:configure
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_log_noexec
  - no_reboot_needed

- name: 'Add noexec Option to /var/log: Check information associated to mountpoint'
  ansible.builtin.command: findmnt --fstab '/var/log'
  register: device_name
  failed_when: device_name.rc > 1
  changed_when: false
  check_mode: false
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var/log" in ansible_mounts | map(attribute="mount") | list'
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_log_noexec
  - no_reboot_needed

- name: 'Add noexec Option to /var/log: Create mount_info dictionary variable'
  set_fact:
    mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
  with_together:
  - '{{ device_name.stdout_lines[0].split() | map(''lower'') | list }}'
  - '{{ device_name.stdout_lines[1].split() | list }}'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var/log" in ansible_mounts | map(attribute="mount") | list'
  - device_name.stdout is defined and device_name.stdout_lines is defined
  - (device_name.stdout | length > 0)
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_log_noexec
  - no_reboot_needed

- name: 'Add noexec Option to /var/log: If /var/log not mounted, craft mount_info
    manually'
  set_fact:
    mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
  with_together:
  - - target
    - source
    - fstype
    - options
  - - /var/log
    - ''
    - ''
    - defaults
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var/log" in ansible_mounts | map(attribute="mount") | list'
  - ("--fstab" | length == 0)
  - device_name.stdout is defined and device_name.stdout_lines is defined
  - (device_name.stdout | length == 0)
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_log_noexec
  - no_reboot_needed

- name: 'Add noexec Option to /var/log: Make sure noexec option is part of the to
    /var/log options'
  set_fact:
    mount_info: '{{ mount_info | combine( {''options'':''''~(mount_info.options |
      default(''''))~('','' if (mount_info.options | default('''')) else '''')~''noexec''
      }) }}'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var/log" in ansible_mounts | map(attribute="mount") | list'
  - mount_info is defined and "noexec" not in (mount_info.options | default(''))
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_log_noexec
  - no_reboot_needed

- name: 'Add noexec Option to /var/log: Ensure /var/log is mounted with noexec option'
  ansible.posix.mount:
    path: /var/log
    src: '{{ mount_info.source | default('''') }}'
    opts: '{{ mount_info.options | default('''') }}'
    state: mounted
    fstype: '{{ mount_info.fstype | default('''') }}'
  register: mount_result
  failed_when:
  - mount_result is failed
  - '''target is busy'' not in (mount_result.msg | default(''''))'
  - '''already mounted'' not in (mount_result.msg | default(''''))'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var/log" in ansible_mounts | map(attribute="mount") | list'
  - mount_info is defined
  - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab"
    | length == 0)
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_log_noexec
  - no_reboot_needed

Rule   Add nosuid Option to /var/log   [ref]

The nosuid mount option can be used to prevent execution of setuid programs in /var/log. The SUID and SGID permissions should not be required in directories containing log files. Add the nosuid option to the fourth column of /etc/fstab for the line which controls mounting of /var/log.
Rationale:
The presence of SUID and SGID executables should be tightly controlled. Users should not be able to execute SUID or SGID binaries from partitions designated for log files.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_mount_option_var_log_nosuid
References:
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-7(a), CM-7(b), CM-6(a), AC-6, AC-6(1), MP-7
nist-csfPR.IP-1, PR.PT-2, PR.PT-3
os-srgSRG-OS-000368-GPOS-00154
anssiR28
cis1.1.2.6.3

Reboot:false
# Remediation is applicable only in certain platforms
if ( ! ( { rpm --quiet -q kernel ;} && { rpm --quiet -q rpm-ostree ;} && { rpm --quiet -q bootc ;} && { ! rpm --quiet -q openshift-kubelet ;} && ([ -f /run/ostree-booted ] || [ -L /ostree ]) ) && ! ( [ -f /.dockerenv ] || [ -f /run/.containerenv ] ) ) && { ( findmnt --kernel "/var/log" > /dev/null || findmnt --fstab "/var/log" > /dev/null ); }; then

function perform_remediation {

    
        # the mount point /var/log has to be defined in /etc/fstab
        # before this remediation can be executed. In case it is not defined, the
        # remediation aborts and no changes regarding the mount point are done.
        mount_point_match_regexp="$(printf "^[[:space:]]*[^#].*[[:space:]]%s[[:space:]]" "/var/log")"

    grep "$mount_point_match_regexp" -q /etc/fstab \
        || { echo "The mount point '/var/log' is not even in /etc/fstab, so we can't set up mount options" >&2;
                echo "Not remediating, because there is no record of /var/log in /etc/fstab" >&2; return 1; }
    


    mount_point_match_regexp="$(printf "^[[:space:]]*[^#].*[[:space:]]%s[[:space:]]" /var/log)"

    # If the mount point is not in /etc/fstab, get previous mount options from /etc/mtab
    if ! grep -q "$mount_point_match_regexp" /etc/fstab; then
        # runtime opts without some automatic kernel/userspace-added defaults
        previous_mount_opts=$(grep "$mount_point_match_regexp" /etc/mtab | head -1 |  awk '{print $4}' \
                    | sed -E "s/(rw|defaults|seclabel|nosuid)(,|$)//g;s/,$//")
        [ "$previous_mount_opts" ] && previous_mount_opts+=","
        # In iso9660 filesystems mtab could describe a "blocksize" value, this should be reflected in
        # fstab as "block".  The next variable is to satisfy shellcheck SC2050.
        fs_type=""
        if [  "$fs_type" == "iso9660" ] ; then
            previous_mount_opts=$(sed 's/blocksize=/block=/' <<< "$previous_mount_opts")
        fi
        echo " /var/log  defaults,${previous_mount_opts}nosuid 0 0" >> /etc/fstab
    # If the mount_opt option is not already in the mount point's /etc/fstab entry, add it
    elif ! grep "$mount_point_match_regexp" /etc/fstab | grep -q "nosuid"; then
        previous_mount_opts=$(grep "$mount_point_match_regexp" /etc/fstab | awk '{print $4}')
        sed -i "s|\(${mount_point_match_regexp}.*${previous_mount_opts}\)|\1,nosuid|" /etc/fstab
    fi


    if mkdir -p "/var/log"; then
        if mountpoint -q "/var/log"; then
            mount -o remount --target "/var/log"
        fi
    fi
}

perform_remediation

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

Complexity:low
Disruption:high
Reboot:false
Strategy:configure
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_log_nosuid
  - no_reboot_needed

- name: 'Add nosuid Option to /var/log: Check information associated to mountpoint'
  ansible.builtin.command: findmnt --fstab '/var/log'
  register: device_name
  failed_when: device_name.rc > 1
  changed_when: false
  check_mode: false
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var/log" in ansible_mounts | map(attribute="mount") | list'
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_log_nosuid
  - no_reboot_needed

- name: 'Add nosuid Option to /var/log: Create mount_info dictionary variable'
  set_fact:
    mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
  with_together:
  - '{{ device_name.stdout_lines[0].split() | map(''lower'') | list }}'
  - '{{ device_name.stdout_lines[1].split() | list }}'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var/log" in ansible_mounts | map(attribute="mount") | list'
  - device_name.stdout is defined and device_name.stdout_lines is defined
  - (device_name.stdout | length > 0)
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_log_nosuid
  - no_reboot_needed

- name: 'Add nosuid Option to /var/log: If /var/log not mounted, craft mount_info
    manually'
  set_fact:
    mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
  with_together:
  - - target
    - source
    - fstype
    - options
  - - /var/log
    - ''
    - ''
    - defaults
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var/log" in ansible_mounts | map(attribute="mount") | list'
  - ("--fstab" | length == 0)
  - device_name.stdout is defined and device_name.stdout_lines is defined
  - (device_name.stdout | length == 0)
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_log_nosuid
  - no_reboot_needed

- name: 'Add nosuid Option to /var/log: Make sure nosuid option is part of the to
    /var/log options'
  set_fact:
    mount_info: '{{ mount_info | combine( {''options'':''''~(mount_info.options |
      default(''''))~('','' if (mount_info.options | default('''')) else '''')~''nosuid''
      }) }}'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var/log" in ansible_mounts | map(attribute="mount") | list'
  - mount_info is defined and "nosuid" not in (mount_info.options | default(''))
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_log_nosuid
  - no_reboot_needed

- name: 'Add nosuid Option to /var/log: Ensure /var/log is mounted with nosuid option'
  ansible.posix.mount:
    path: /var/log
    src: '{{ mount_info.source | default('''') }}'
    opts: '{{ mount_info.options | default('''') }}'
    state: mounted
    fstype: '{{ mount_info.fstype | default('''') }}'
  register: mount_result
  failed_when:
  - mount_result is failed
  - '''target is busy'' not in (mount_result.msg | default(''''))'
  - '''already mounted'' not in (mount_result.msg | default(''''))'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var/log" in ansible_mounts | map(attribute="mount") | list'
  - mount_info is defined
  - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab"
    | length == 0)
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_log_nosuid
  - no_reboot_needed

Rule   Add nodev Option to /var   [ref]

The nodev mount option can be used to prevent device files from being created in /var. Legitimate character and block devices should exist only in the /dev directory on the root partition or within chroot jails built for system services. Add the nodev option to the fourth column of /etc/fstab for the line which controls mounting of /var.
Rationale:
The only legitimate location for device files is the /dev directory located on the root partition. The only exception to this is chroot jails.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_mount_option_var_nodev
References:
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-7(a), CM-7(b), CM-6(a), AC-6, AC-6(1), MP-7
nist-csfPR.IP-1, PR.PT-2, PR.PT-3
os-srgSRG-OS-000368-GPOS-00154
cis1.1.2.4.2

Reboot:false
# Remediation is applicable only in certain platforms
if ( ! ( { rpm --quiet -q kernel ;} && { rpm --quiet -q rpm-ostree ;} && { rpm --quiet -q bootc ;} && { ! rpm --quiet -q openshift-kubelet ;} && ([ -f /run/ostree-booted ] || [ -L /ostree ]) ) && ! ( [ -f /.dockerenv ] || [ -f /run/.containerenv ] ) ) && { ( findmnt --kernel "/var" > /dev/null || findmnt --fstab "/var" > /dev/null ); }; then

function perform_remediation {

    
        # the mount point /var has to be defined in /etc/fstab
        # before this remediation can be executed. In case it is not defined, the
        # remediation aborts and no changes regarding the mount point are done.
        mount_point_match_regexp="$(printf "^[[:space:]]*[^#].*[[:space:]]%s[[:space:]]" "/var")"

    grep "$mount_point_match_regexp" -q /etc/fstab \
        || { echo "The mount point '/var' is not even in /etc/fstab, so we can't set up mount options" >&2;
                echo "Not remediating, because there is no record of /var in /etc/fstab" >&2; return 1; }
    


    mount_point_match_regexp="$(printf "^[[:space:]]*[^#].*[[:space:]]%s[[:space:]]" /var)"

    # If the mount point is not in /etc/fstab, get previous mount options from /etc/mtab
    if ! grep -q "$mount_point_match_regexp" /etc/fstab; then
        # runtime opts without some automatic kernel/userspace-added defaults
        previous_mount_opts=$(grep "$mount_point_match_regexp" /etc/mtab | head -1 |  awk '{print $4}' \
                    | sed -E "s/(rw|defaults|seclabel|nodev)(,|$)//g;s/,$//")
        [ "$previous_mount_opts" ] && previous_mount_opts+=","
        # In iso9660 filesystems mtab could describe a "blocksize" value, this should be reflected in
        # fstab as "block".  The next variable is to satisfy shellcheck SC2050.
        fs_type=""
        if [  "$fs_type" == "iso9660" ] ; then
            previous_mount_opts=$(sed 's/blocksize=/block=/' <<< "$previous_mount_opts")
        fi
        echo " /var  defaults,${previous_mount_opts}nodev 0 0" >> /etc/fstab
    # If the mount_opt option is not already in the mount point's /etc/fstab entry, add it
    elif ! grep "$mount_point_match_regexp" /etc/fstab | grep -q "nodev"; then
        previous_mount_opts=$(grep "$mount_point_match_regexp" /etc/fstab | awk '{print $4}')
        sed -i "s|\(${mount_point_match_regexp}.*${previous_mount_opts}\)|\1,nodev|" /etc/fstab
    fi


    if mkdir -p "/var"; then
        if mountpoint -q "/var"; then
            mount -o remount --target "/var"
        fi
    fi
}

perform_remediation

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

Complexity:low
Disruption:high
Reboot:false
Strategy:configure
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_nodev
  - no_reboot_needed

- name: 'Add nodev Option to /var: Check information associated to mountpoint'
  ansible.builtin.command: findmnt --fstab '/var'
  register: device_name
  failed_when: device_name.rc > 1
  changed_when: false
  check_mode: false
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var" in ansible_mounts | map(attribute="mount") | list'
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_nodev
  - no_reboot_needed

- name: 'Add nodev Option to /var: Create mount_info dictionary variable'
  set_fact:
    mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
  with_together:
  - '{{ device_name.stdout_lines[0].split() | map(''lower'') | list }}'
  - '{{ device_name.stdout_lines[1].split() | list }}'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var" in ansible_mounts | map(attribute="mount") | list'
  - device_name.stdout is defined and device_name.stdout_lines is defined
  - (device_name.stdout | length > 0)
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_nodev
  - no_reboot_needed

- name: 'Add nodev Option to /var: If /var not mounted, craft mount_info manually'
  set_fact:
    mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
  with_together:
  - - target
    - source
    - fstype
    - options
  - - /var
    - ''
    - ''
    - defaults
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var" in ansible_mounts | map(attribute="mount") | list'
  - ("--fstab" | length == 0)
  - device_name.stdout is defined and device_name.stdout_lines is defined
  - (device_name.stdout | length == 0)
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_nodev
  - no_reboot_needed

- name: 'Add nodev Option to /var: Make sure nodev option is part of the to /var options'
  set_fact:
    mount_info: '{{ mount_info | combine( {''options'':''''~(mount_info.options |
      default(''''))~('','' if (mount_info.options | default('''')) else '''')~''nodev''
      }) }}'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var" in ansible_mounts | map(attribute="mount") | list'
  - mount_info is defined and "nodev" not in (mount_info.options | default(''))
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_nodev
  - no_reboot_needed

- name: 'Add nodev Option to /var: Ensure /var is mounted with nodev option'
  ansible.posix.mount:
    path: /var
    src: '{{ mount_info.source | default('''') }}'
    opts: '{{ mount_info.options | default('''') }}'
    state: mounted
    fstype: '{{ mount_info.fstype | default('''') }}'
  register: mount_result
  failed_when:
  - mount_result is failed
  - '''target is busy'' not in (mount_result.msg | default(''''))'
  - '''already mounted'' not in (mount_result.msg | default(''''))'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var" in ansible_mounts | map(attribute="mount") | list'
  - mount_info is defined
  - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab"
    | length == 0)
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-MP-7
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_nodev
  - no_reboot_needed

Rule   Add nosuid Option to /var   [ref]

The nosuid mount option can be used to prevent execution of setuid programs in /var. The SUID and SGID permissions should not be required for this directory. Add the nosuid option to the fourth column of /etc/fstab for the line which controls mounting of /var.
Rationale:
The presence of SUID and SGID executables should be tightly controlled.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_mount_option_var_nosuid
References:
anssiR28
cis1.1.2.4.3

Reboot:false
# Remediation is applicable only in certain platforms
if ( ! ( { rpm --quiet -q kernel ;} && { rpm --quiet -q rpm-ostree ;} && { rpm --quiet -q bootc ;} && { ! rpm --quiet -q openshift-kubelet ;} && ([ -f /run/ostree-booted ] || [ -L /ostree ]) ) && ! ( [ -f /.dockerenv ] || [ -f /run/.containerenv ] ) ) && { ( findmnt --kernel "/var" > /dev/null || findmnt --fstab "/var" > /dev/null ); }; then

function perform_remediation {

    
        # the mount point /var has to be defined in /etc/fstab
        # before this remediation can be executed. In case it is not defined, the
        # remediation aborts and no changes regarding the mount point are done.
        mount_point_match_regexp="$(printf "^[[:space:]]*[^#].*[[:space:]]%s[[:space:]]" "/var")"

    grep "$mount_point_match_regexp" -q /etc/fstab \
        || { echo "The mount point '/var' is not even in /etc/fstab, so we can't set up mount options" >&2;
                echo "Not remediating, because there is no record of /var in /etc/fstab" >&2; return 1; }
    


    mount_point_match_regexp="$(printf "^[[:space:]]*[^#].*[[:space:]]%s[[:space:]]" /var)"

    # If the mount point is not in /etc/fstab, get previous mount options from /etc/mtab
    if ! grep -q "$mount_point_match_regexp" /etc/fstab; then
        # runtime opts without some automatic kernel/userspace-added defaults
        previous_mount_opts=$(grep "$mount_point_match_regexp" /etc/mtab | head -1 |  awk '{print $4}' \
                    | sed -E "s/(rw|defaults|seclabel|nosuid)(,|$)//g;s/,$//")
        [ "$previous_mount_opts" ] && previous_mount_opts+=","
        # In iso9660 filesystems mtab could describe a "blocksize" value, this should be reflected in
        # fstab as "block".  The next variable is to satisfy shellcheck SC2050.
        fs_type=""
        if [  "$fs_type" == "iso9660" ] ; then
            previous_mount_opts=$(sed 's/blocksize=/block=/' <<< "$previous_mount_opts")
        fi
        echo " /var  defaults,${previous_mount_opts}nosuid 0 0" >> /etc/fstab
    # If the mount_opt option is not already in the mount point's /etc/fstab entry, add it
    elif ! grep "$mount_point_match_regexp" /etc/fstab | grep -q "nosuid"; then
        previous_mount_opts=$(grep "$mount_point_match_regexp" /etc/fstab | awk '{print $4}')
        sed -i "s|\(${mount_point_match_regexp}.*${previous_mount_opts}\)|\1,nosuid|" /etc/fstab
    fi


    if mkdir -p "/var"; then
        if mountpoint -q "/var"; then
            mount -o remount --target "/var"
        fi
    fi
}

perform_remediation

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

Complexity:low
Disruption:high
Reboot:false
Strategy:configure
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_nosuid
  - no_reboot_needed

- name: 'Add nosuid Option to /var: Check information associated to mountpoint'
  ansible.builtin.command: findmnt --fstab '/var'
  register: device_name
  failed_when: device_name.rc > 1
  changed_when: false
  check_mode: false
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var" in ansible_mounts | map(attribute="mount") | list'
  tags:
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_nosuid
  - no_reboot_needed

- name: 'Add nosuid Option to /var: Create mount_info dictionary variable'
  set_fact:
    mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
  with_together:
  - '{{ device_name.stdout_lines[0].split() | map(''lower'') | list }}'
  - '{{ device_name.stdout_lines[1].split() | list }}'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var" in ansible_mounts | map(attribute="mount") | list'
  - device_name.stdout is defined and device_name.stdout_lines is defined
  - (device_name.stdout | length > 0)
  tags:
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_nosuid
  - no_reboot_needed

- name: 'Add nosuid Option to /var: If /var not mounted, craft mount_info manually'
  set_fact:
    mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
  with_together:
  - - target
    - source
    - fstype
    - options
  - - /var
    - ''
    - ''
    - defaults
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var" in ansible_mounts | map(attribute="mount") | list'
  - ("--fstab" | length == 0)
  - device_name.stdout is defined and device_name.stdout_lines is defined
  - (device_name.stdout | length == 0)
  tags:
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_nosuid
  - no_reboot_needed

- name: 'Add nosuid Option to /var: Make sure nosuid option is part of the to /var
    options'
  set_fact:
    mount_info: '{{ mount_info | combine( {''options'':''''~(mount_info.options |
      default(''''))~('','' if (mount_info.options | default('''')) else '''')~''nosuid''
      }) }}'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var" in ansible_mounts | map(attribute="mount") | list'
  - mount_info is defined and "nosuid" not in (mount_info.options | default(''))
  tags:
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_nosuid
  - no_reboot_needed

- name: 'Add nosuid Option to /var: Ensure /var is mounted with nosuid option'
  ansible.posix.mount:
    path: /var
    src: '{{ mount_info.source | default('''') }}'
    opts: '{{ mount_info.options | default('''') }}'
    state: mounted
    fstype: '{{ mount_info.fstype | default('''') }}'
  register: mount_result
  failed_when:
  - mount_result is failed
  - '''target is busy'' not in (mount_result.msg | default(''''))'
  - '''already mounted'' not in (mount_result.msg | default(''''))'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var" in ansible_mounts | map(attribute="mount") | list'
  - mount_info is defined
  - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab"
    | length == 0)
  tags:
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_nosuid
  - no_reboot_needed

Rule   Add nodev Option to /var/tmp   [ref]

The nodev mount option can be used to prevent device files from being created in /var/tmp. Legitimate character and block devices should not exist within temporary directories like /var/tmp. Add the nodev option to the fourth column of /etc/fstab for the line which controls mounting of /var/tmp.
Rationale:
The only legitimate location for device files is the /dev directory located on the root partition. The only exception to this is chroot jails.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_mount_option_var_tmp_nodev
References:
os-srgSRG-OS-000368-GPOS-00154
cis1.1.2.5.2

Reboot:false
# Remediation is applicable only in certain platforms
if ( ! ( { rpm --quiet -q kernel ;} && { rpm --quiet -q rpm-ostree ;} && { rpm --quiet -q bootc ;} && { ! rpm --quiet -q openshift-kubelet ;} && ([ -f /run/ostree-booted ] || [ -L /ostree ]) ) && ! ( [ -f /.dockerenv ] || [ -f /run/.containerenv ] ) ) && { ( findmnt --kernel "/var/tmp" > /dev/null || findmnt --fstab "/var/tmp" > /dev/null ); }; then

function perform_remediation {

    
        # the mount point /var/tmp has to be defined in /etc/fstab
        # before this remediation can be executed. In case it is not defined, the
        # remediation aborts and no changes regarding the mount point are done.
        mount_point_match_regexp="$(printf "^[[:space:]]*[^#].*[[:space:]]%s[[:space:]]" "/var/tmp")"

    grep "$mount_point_match_regexp" -q /etc/fstab \
        || { echo "The mount point '/var/tmp' is not even in /etc/fstab, so we can't set up mount options" >&2;
                echo "Not remediating, because there is no record of /var/tmp in /etc/fstab" >&2; return 1; }
    


    mount_point_match_regexp="$(printf "^[[:space:]]*[^#].*[[:space:]]%s[[:space:]]" /var/tmp)"

    # If the mount point is not in /etc/fstab, get previous mount options from /etc/mtab
    if ! grep -q "$mount_point_match_regexp" /etc/fstab; then
        # runtime opts without some automatic kernel/userspace-added defaults
        previous_mount_opts=$(grep "$mount_point_match_regexp" /etc/mtab | head -1 |  awk '{print $4}' \
                    | sed -E "s/(rw|defaults|seclabel|nodev)(,|$)//g;s/,$//")
        [ "$previous_mount_opts" ] && previous_mount_opts+=","
        # In iso9660 filesystems mtab could describe a "blocksize" value, this should be reflected in
        # fstab as "block".  The next variable is to satisfy shellcheck SC2050.
        fs_type=""
        if [  "$fs_type" == "iso9660" ] ; then
            previous_mount_opts=$(sed 's/blocksize=/block=/' <<< "$previous_mount_opts")
        fi
        echo " /var/tmp  defaults,${previous_mount_opts}nodev 0 0" >> /etc/fstab
    # If the mount_opt option is not already in the mount point's /etc/fstab entry, add it
    elif ! grep "$mount_point_match_regexp" /etc/fstab | grep -q "nodev"; then
        previous_mount_opts=$(grep "$mount_point_match_regexp" /etc/fstab | awk '{print $4}')
        sed -i "s|\(${mount_point_match_regexp}.*${previous_mount_opts}\)|\1,nodev|" /etc/fstab
    fi


    if mkdir -p "/var/tmp"; then
        if mountpoint -q "/var/tmp"; then
            mount -o remount --target "/var/tmp"
        fi
    fi
}

perform_remediation

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

Complexity:low
Disruption:high
Reboot:false
Strategy:configure
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_tmp_nodev
  - no_reboot_needed

- name: 'Add nodev Option to /var/tmp: Check information associated to mountpoint'
  ansible.builtin.command: findmnt --fstab '/var/tmp'
  register: device_name
  failed_when: device_name.rc > 1
  changed_when: false
  check_mode: false
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list'
  tags:
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_tmp_nodev
  - no_reboot_needed

- name: 'Add nodev Option to /var/tmp: Create mount_info dictionary variable'
  set_fact:
    mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
  with_together:
  - '{{ device_name.stdout_lines[0].split() | map(''lower'') | list }}'
  - '{{ device_name.stdout_lines[1].split() | list }}'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list'
  - device_name.stdout is defined and device_name.stdout_lines is defined
  - (device_name.stdout | length > 0)
  tags:
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_tmp_nodev
  - no_reboot_needed

- name: 'Add nodev Option to /var/tmp: If /var/tmp not mounted, craft mount_info manually'
  set_fact:
    mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
  with_together:
  - - target
    - source
    - fstype
    - options
  - - /var/tmp
    - ''
    - ''
    - defaults
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list'
  - ("--fstab" | length == 0)
  - device_name.stdout is defined and device_name.stdout_lines is defined
  - (device_name.stdout | length == 0)
  tags:
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_tmp_nodev
  - no_reboot_needed

- name: 'Add nodev Option to /var/tmp: Make sure nodev option is part of the to /var/tmp
    options'
  set_fact:
    mount_info: '{{ mount_info | combine( {''options'':''''~(mount_info.options |
      default(''''))~('','' if (mount_info.options | default('''')) else '''')~''nodev''
      }) }}'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list'
  - mount_info is defined and "nodev" not in (mount_info.options | default(''))
  tags:
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_tmp_nodev
  - no_reboot_needed

- name: 'Add nodev Option to /var/tmp: Ensure /var/tmp is mounted with nodev option'
  ansible.posix.mount:
    path: /var/tmp
    src: '{{ mount_info.source | default('''') }}'
    opts: '{{ mount_info.options | default('''') }}'
    state: mounted
    fstype: '{{ mount_info.fstype | default('''') }}'
  register: mount_result
  failed_when:
  - mount_result is failed
  - '''target is busy'' not in (mount_result.msg | default(''''))'
  - '''already mounted'' not in (mount_result.msg | default(''''))'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list'
  - mount_info is defined
  - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab"
    | length == 0)
  tags:
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_tmp_nodev
  - no_reboot_needed

Rule   Add noexec Option to /var/tmp   [ref]

The noexec mount option can be used to prevent binaries from being executed out of /var/tmp. Add the noexec option to the fourth column of /etc/fstab for the line which controls mounting of /var/tmp.
Rationale:
Allowing users to execute binaries from world-writable directories such as /var/tmp should never be necessary in normal operation and can expose the system to potential compromise.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_mount_option_var_tmp_noexec
References:
os-srgSRG-OS-000368-GPOS-00154
anssiR28
cis1.1.2.5.4

Reboot:false
# Remediation is applicable only in certain platforms
if ( ! ( { rpm --quiet -q kernel ;} && { rpm --quiet -q rpm-ostree ;} && { rpm --quiet -q bootc ;} && { ! rpm --quiet -q openshift-kubelet ;} && ([ -f /run/ostree-booted ] || [ -L /ostree ]) ) && ! ( [ -f /.dockerenv ] || [ -f /run/.containerenv ] ) ) && { ( findmnt --kernel "/var/tmp" > /dev/null || findmnt --fstab "/var/tmp" > /dev/null ); }; then

function perform_remediation {

    
        # the mount point /var/tmp has to be defined in /etc/fstab
        # before this remediation can be executed. In case it is not defined, the
        # remediation aborts and no changes regarding the mount point are done.
        mount_point_match_regexp="$(printf "^[[:space:]]*[^#].*[[:space:]]%s[[:space:]]" "/var/tmp")"

    grep "$mount_point_match_regexp" -q /etc/fstab \
        || { echo "The mount point '/var/tmp' is not even in /etc/fstab, so we can't set up mount options" >&2;
                echo "Not remediating, because there is no record of /var/tmp in /etc/fstab" >&2; return 1; }
    


    mount_point_match_regexp="$(printf "^[[:space:]]*[^#].*[[:space:]]%s[[:space:]]" /var/tmp)"

    # If the mount point is not in /etc/fstab, get previous mount options from /etc/mtab
    if ! grep -q "$mount_point_match_regexp" /etc/fstab; then
        # runtime opts without some automatic kernel/userspace-added defaults
        previous_mount_opts=$(grep "$mount_point_match_regexp" /etc/mtab | head -1 |  awk '{print $4}' \
                    | sed -E "s/(rw|defaults|seclabel|noexec)(,|$)//g;s/,$//")
        [ "$previous_mount_opts" ] && previous_mount_opts+=","
        # In iso9660 filesystems mtab could describe a "blocksize" value, this should be reflected in
        # fstab as "block".  The next variable is to satisfy shellcheck SC2050.
        fs_type=""
        if [  "$fs_type" == "iso9660" ] ; then
            previous_mount_opts=$(sed 's/blocksize=/block=/' <<< "$previous_mount_opts")
        fi
        echo " /var/tmp  defaults,${previous_mount_opts}noexec 0 0" >> /etc/fstab
    # If the mount_opt option is not already in the mount point's /etc/fstab entry, add it
    elif ! grep "$mount_point_match_regexp" /etc/fstab | grep -q "noexec"; then
        previous_mount_opts=$(grep "$mount_point_match_regexp" /etc/fstab | awk '{print $4}')
        sed -i "s|\(${mount_point_match_regexp}.*${previous_mount_opts}\)|\1,noexec|" /etc/fstab
    fi


    if mkdir -p "/var/tmp"; then
        if mountpoint -q "/var/tmp"; then
            mount -o remount --target "/var/tmp"
        fi
    fi
}

perform_remediation

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

Complexity:low
Disruption:high
Reboot:false
Strategy:configure
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_tmp_noexec
  - no_reboot_needed

- name: 'Add noexec Option to /var/tmp: Check information associated to mountpoint'
  ansible.builtin.command: findmnt --fstab '/var/tmp'
  register: device_name
  failed_when: device_name.rc > 1
  changed_when: false
  check_mode: false
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list'
  tags:
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_tmp_noexec
  - no_reboot_needed

- name: 'Add noexec Option to /var/tmp: Create mount_info dictionary variable'
  set_fact:
    mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
  with_together:
  - '{{ device_name.stdout_lines[0].split() | map(''lower'') | list }}'
  - '{{ device_name.stdout_lines[1].split() | list }}'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list'
  - device_name.stdout is defined and device_name.stdout_lines is defined
  - (device_name.stdout | length > 0)
  tags:
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_tmp_noexec
  - no_reboot_needed

- name: 'Add noexec Option to /var/tmp: If /var/tmp not mounted, craft mount_info
    manually'
  set_fact:
    mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
  with_together:
  - - target
    - source
    - fstype
    - options
  - - /var/tmp
    - ''
    - ''
    - defaults
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list'
  - ("--fstab" | length == 0)
  - device_name.stdout is defined and device_name.stdout_lines is defined
  - (device_name.stdout | length == 0)
  tags:
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_tmp_noexec
  - no_reboot_needed

- name: 'Add noexec Option to /var/tmp: Make sure noexec option is part of the to
    /var/tmp options'
  set_fact:
    mount_info: '{{ mount_info | combine( {''options'':''''~(mount_info.options |
      default(''''))~('','' if (mount_info.options | default('''')) else '''')~''noexec''
      }) }}'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list'
  - mount_info is defined and "noexec" not in (mount_info.options | default(''))
  tags:
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_tmp_noexec
  - no_reboot_needed

- name: 'Add noexec Option to /var/tmp: Ensure /var/tmp is mounted with noexec option'
  ansible.posix.mount:
    path: /var/tmp
    src: '{{ mount_info.source | default('''') }}'
    opts: '{{ mount_info.options | default('''') }}'
    state: mounted
    fstype: '{{ mount_info.fstype | default('''') }}'
  register: mount_result
  failed_when:
  - mount_result is failed
  - '''target is busy'' not in (mount_result.msg | default(''''))'
  - '''already mounted'' not in (mount_result.msg | default(''''))'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list'
  - mount_info is defined
  - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab"
    | length == 0)
  tags:
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_tmp_noexec
  - no_reboot_needed

Rule   Add nosuid Option to /var/tmp   [ref]

The nosuid mount option can be used to prevent execution of setuid programs in /var/tmp. The SUID and SGID permissions should not be required in these world-writable directories. Add the nosuid option to the fourth column of /etc/fstab for the line which controls mounting of /var/tmp.
Rationale:
The presence of SUID and SGID executables should be tightly controlled. Users should not be able to execute SUID or SGID binaries from temporary storage partitions.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_mount_option_var_tmp_nosuid
References:
os-srgSRG-OS-000368-GPOS-00154
anssiR28
cis1.1.2.5.3

Reboot:false
# Remediation is applicable only in certain platforms
if ( ! ( { rpm --quiet -q kernel ;} && { rpm --quiet -q rpm-ostree ;} && { rpm --quiet -q bootc ;} && { ! rpm --quiet -q openshift-kubelet ;} && ([ -f /run/ostree-booted ] || [ -L /ostree ]) ) && ! ( [ -f /.dockerenv ] || [ -f /run/.containerenv ] ) ) && { ( findmnt --kernel "/var/tmp" > /dev/null || findmnt --fstab "/var/tmp" > /dev/null ); }; then

function perform_remediation {

    
        # the mount point /var/tmp has to be defined in /etc/fstab
        # before this remediation can be executed. In case it is not defined, the
        # remediation aborts and no changes regarding the mount point are done.
        mount_point_match_regexp="$(printf "^[[:space:]]*[^#].*[[:space:]]%s[[:space:]]" "/var/tmp")"

    grep "$mount_point_match_regexp" -q /etc/fstab \
        || { echo "The mount point '/var/tmp' is not even in /etc/fstab, so we can't set up mount options" >&2;
                echo "Not remediating, because there is no record of /var/tmp in /etc/fstab" >&2; return 1; }
    


    mount_point_match_regexp="$(printf "^[[:space:]]*[^#].*[[:space:]]%s[[:space:]]" /var/tmp)"

    # If the mount point is not in /etc/fstab, get previous mount options from /etc/mtab
    if ! grep -q "$mount_point_match_regexp" /etc/fstab; then
        # runtime opts without some automatic kernel/userspace-added defaults
        previous_mount_opts=$(grep "$mount_point_match_regexp" /etc/mtab | head -1 |  awk '{print $4}' \
                    | sed -E "s/(rw|defaults|seclabel|nosuid)(,|$)//g;s/,$//")
        [ "$previous_mount_opts" ] && previous_mount_opts+=","
        # In iso9660 filesystems mtab could describe a "blocksize" value, this should be reflected in
        # fstab as "block".  The next variable is to satisfy shellcheck SC2050.
        fs_type=""
        if [  "$fs_type" == "iso9660" ] ; then
            previous_mount_opts=$(sed 's/blocksize=/block=/' <<< "$previous_mount_opts")
        fi
        echo " /var/tmp  defaults,${previous_mount_opts}nosuid 0 0" >> /etc/fstab
    # If the mount_opt option is not already in the mount point's /etc/fstab entry, add it
    elif ! grep "$mount_point_match_regexp" /etc/fstab | grep -q "nosuid"; then
        previous_mount_opts=$(grep "$mount_point_match_regexp" /etc/fstab | awk '{print $4}')
        sed -i "s|\(${mount_point_match_regexp}.*${previous_mount_opts}\)|\1,nosuid|" /etc/fstab
    fi


    if mkdir -p "/var/tmp"; then
        if mountpoint -q "/var/tmp"; then
            mount -o remount --target "/var/tmp"
        fi
    fi
}

perform_remediation

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

Complexity:low
Disruption:high
Reboot:false
Strategy:configure
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_tmp_nosuid
  - no_reboot_needed

- name: 'Add nosuid Option to /var/tmp: Check information associated to mountpoint'
  ansible.builtin.command: findmnt --fstab '/var/tmp'
  register: device_name
  failed_when: device_name.rc > 1
  changed_when: false
  check_mode: false
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list'
  tags:
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_tmp_nosuid
  - no_reboot_needed

- name: 'Add nosuid Option to /var/tmp: Create mount_info dictionary variable'
  set_fact:
    mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
  with_together:
  - '{{ device_name.stdout_lines[0].split() | map(''lower'') | list }}'
  - '{{ device_name.stdout_lines[1].split() | list }}'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list'
  - device_name.stdout is defined and device_name.stdout_lines is defined
  - (device_name.stdout | length > 0)
  tags:
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_tmp_nosuid
  - no_reboot_needed

- name: 'Add nosuid Option to /var/tmp: If /var/tmp not mounted, craft mount_info
    manually'
  set_fact:
    mount_info: '{{ mount_info|default({})|combine({item.0: item.1}) }}'
  with_together:
  - - target
    - source
    - fstype
    - options
  - - /var/tmp
    - ''
    - ''
    - defaults
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list'
  - ("--fstab" | length == 0)
  - device_name.stdout is defined and device_name.stdout_lines is defined
  - (device_name.stdout | length == 0)
  tags:
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_tmp_nosuid
  - no_reboot_needed

- name: 'Add nosuid Option to /var/tmp: Make sure nosuid option is part of the to
    /var/tmp options'
  set_fact:
    mount_info: '{{ mount_info | combine( {''options'':''''~(mount_info.options |
      default(''''))~('','' if (mount_info.options | default('''')) else '''')~''nosuid''
      }) }}'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list'
  - mount_info is defined and "nosuid" not in (mount_info.options | default(''))
  tags:
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_tmp_nosuid
  - no_reboot_needed

- name: 'Add nosuid Option to /var/tmp: Ensure /var/tmp is mounted with nosuid option'
  ansible.posix.mount:
    path: /var/tmp
    src: '{{ mount_info.source | default('''') }}'
    opts: '{{ mount_info.options | default('''') }}'
    state: mounted
    fstype: '{{ mount_info.fstype | default('''') }}'
  register: mount_result
  failed_when:
  - mount_result is failed
  - '''target is busy'' not in (mount_result.msg | default(''''))'
  - '''already mounted'' not in (mount_result.msg | default(''''))'
  when:
  - ( not ( "kernel" in ansible_facts.packages and "rpm-ostree" in ansible_facts.packages
    and "bootc" in ansible_facts.packages and not "openshift-kubelet" in ansible_facts.packages
    and "ostree" in ansible_proc_cmdline ) and not ( ansible_virtualization_type in
    ["docker", "lxc", "openvz", "podman", "container"] ) )
  - '"/var/tmp" in ansible_mounts | map(attribute="mount") | list'
  - mount_info is defined
  - (device_name.stdout is defined and (device_name.stdout | length > 0)) or ("--fstab"
    | length == 0)
  tags:
  - configure_strategy
  - high_disruption
  - low_complexity
  - medium_severity
  - mount_option_var_tmp_nosuid
  - no_reboot_needed
Group   Restrict Programs from Dangerous Execution Patterns   Group contains 2 groups and 8 rules
[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 4 rules
[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 dump backtraces   [ref]

The ProcessSizeMax option in [Coredump] section of /etc/systemd/coredump.conf or in a drop-in file under /etc/systemd/coredump.conf.d/ specifies the maximum size in bytes of a core which will be processed. Core dumps exceeding this size may be stored, but the backtrace will not be generated.
Warning:  If the /etc/systemd/coredump.conf file or a drop-in file under /etc/systemd/coredump.conf.d/ does not already contain the [Coredump] section, the value will not be configured correctly.
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 or system operators trying to debug problems. Enabling core dumps on production systems is not recommended, however there may be overriding operational requirements to enable advanced debugging. Permitting temporary enablement of core dumps during such situations should be reviewed through local needs and policy.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_coredump_disable_backtraces
References:
nistCM-6
pcidssReq-3.2
os-srgSRG-OS-000480-GPOS-00227
cis1.5.12
pcidss43.3.1.1, 3.3.1, 3.3

Complexity:low
Disruption:low
Reboot:false
Strategy:restrict
# Remediation is applicable only in certain platforms
if dpkg-query --show --showformat='${db:Status-Status}' 'linux-base' 2>/dev/null | grep -q '^installed$' && { dpkg-query --show --showformat='${db:Status-Status}' 'systemd' 2>/dev/null | grep -q '^installed$'; }; then

found=false

# set value in all files if they contain section or key
for f in $(echo -n "/etc/systemd/coredump.conf.d/complianceascode_hardening.conf /etc/systemd/coredump.conf.d/*.conf /etc/systemd/coredump.conf"); do
    if [ ! -e "$f" ]; then
        continue
    fi

    # find key in section and change value
    if grep -qzosP "(?m)^[[:space:]]*\[Coredump\]([^\n\[]*\n+)+?[[:space:]]*ProcessSizeMax" "$f"; then
        if ! grep -qzosP "(?m)^[[:space:]]*ProcessSizeMax[[:space:]]*=[[:space:]]*0" "$f"; then

            sed -i "/^[[:space:]]*ProcessSizeMax/s/\([[:blank:]]*=[[:blank:]]*\).*/\10/" "$f"

        fi

        found=true

    # find section and add key = value to it
    elif grep -qs "^[[:space:]]*\[Coredump\]" "$f"; then

            sed -i "/^[[:space:]]*\[Coredump\]/a ProcessSizeMax=0" "$f"

            found=true
    fi
done

# if section not in any file, append section with key = value to FIRST file in files parameter
if ! $found ; then
    file=$(echo "/etc/systemd/coredump.conf.d/complianceascode_hardening.conf /etc/systemd/coredump.conf.d/*.conf /etc/systemd/coredump.conf" | cut -f1 -d ' ')
    mkdir -p "$(dirname "$file")"

    echo -e "[Coredump]\nProcessSizeMax=0" >> "$file"

fi

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

Complexity:low
Disruption:low
Reboot:false
Strategy:restrict
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - NIST-800-53-CM-6
  - PCI-DSS-Req-3.2
  - PCI-DSSv4-3.3
  - PCI-DSSv4-3.3.1
  - PCI-DSSv4-3.3.1.1
  - coredump_disable_backtraces
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

- name: Disable core dump backtraces - Search for a section in files
  ansible.builtin.find:
    paths: '{{item.path}}'
    patterns: '{{item.pattern}}'
    contains: ^\s*\[Coredump\]
    read_whole_file: true
    use_regex: true
  register: systemd_dropin_files_with_section
  loop:
  - path: '{{ ''/etc/systemd/coredump.conf'' | dirname }}'
    pattern: '{{ ''/etc/systemd/coredump.conf'' | basename | regex_escape }}'
  - path: /etc/systemd/coredump.conf.d
    pattern: .*\.conf
  when:
  - '"linux-base" in ansible_facts.packages'
  - '"systemd" in ansible_facts.packages'
  tags:
  - NIST-800-53-CM-6
  - PCI-DSS-Req-3.2
  - PCI-DSSv4-3.3
  - PCI-DSSv4-3.3.1
  - PCI-DSSv4-3.3.1.1
  - coredump_disable_backtraces
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

- name: Disable core dump backtraces - Count number of files which contain the correct
    section
  ansible.builtin.set_fact:
    count_of_systemd_dropin_files_with_section: '{{systemd_dropin_files_with_section.results
      | map(attribute=''matched'') | list | map(''int'') | sum}}'
  when:
  - '"linux-base" in ansible_facts.packages'
  - '"systemd" in ansible_facts.packages'
  tags:
  - NIST-800-53-CM-6
  - PCI-DSS-Req-3.2
  - PCI-DSSv4-3.3
  - PCI-DSSv4-3.3.1
  - PCI-DSSv4-3.3.1.1
  - coredump_disable_backtraces
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

- name: Disable core dump backtraces - Add missing configuration to correct section
  community.general.ini_file:
    path: '{{item}}'
    section: Coredump
    option: ProcessSizeMax
    value: '0'
    state: present
    no_extra_spaces: true
  when:
  - '"linux-base" in ansible_facts.packages'
  - '"systemd" in ansible_facts.packages'
  - count_of_systemd_dropin_files_with_section | int > 0
  loop: '{{systemd_dropin_files_with_section.results | sum(attribute=''files'', start=[])
    | map(attribute=''path'') | list }}'
  tags:
  - NIST-800-53-CM-6
  - PCI-DSS-Req-3.2
  - PCI-DSSv4-3.3
  - PCI-DSSv4-3.3.1
  - PCI-DSSv4-3.3.1.1
  - coredump_disable_backtraces
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

- name: Disable core dump backtraces - Add configuration to new remediation file
  community.general.ini_file:
    path: /etc/systemd/coredump.conf.d/complianceascode_hardening.conf
    section: Coredump
    option: ProcessSizeMax
    value: '0'
    state: present
    no_extra_spaces: true
    create: true
  when:
  - '"linux-base" in ansible_facts.packages'
  - '"systemd" in ansible_facts.packages'
  - count_of_systemd_dropin_files_with_section | int == 0
  tags:
  - NIST-800-53-CM-6
  - PCI-DSS-Req-3.2
  - PCI-DSSv4-3.3
  - PCI-DSSv4-3.3.1
  - PCI-DSSv4-3.3.1.1
  - coredump_disable_backtraces
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

Rule   Disable storing core dump   [ref]

The Storage option in [Coredump] section of /etc/systemd/coredump.conf or a drop-in file in /etc/systemd/coredump.conf.d/*.conf can be set to none to disable storing core dumps permanently.
Warning:  If the /etc/systemd/coredump.conf file or a drop-in file under /etc/systemd/coredump.conf.d/ does not already contain the [Coredump] section, the value will not be configured correctly.
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 or system operators trying to debug problems. Enabling core dumps on production systems is not recommended, however there may be overriding operational requirements to enable advanced debugging. Permitting temporary enablement of core dumps during such situations should be reviewed through local needs and policy.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_coredump_disable_storage
References:
nistCM-6
pcidssReq-3.2
os-srgSRG-OS-000480-GPOS-00227
cis1.5.13
pcidss43.3.1.1, 3.3.1, 3.3

Complexity:low
Disruption:low
Reboot:false
Strategy:restrict
# Remediation is applicable only in certain platforms
if dpkg-query --show --showformat='${db:Status-Status}' 'linux-base' 2>/dev/null | grep -q '^installed$' && { dpkg-query --show --showformat='${db:Status-Status}' 'systemd' 2>/dev/null | grep -q '^installed$'; }; then

found=false

# set value in all files if they contain section or key
for f in $(echo -n "/etc/systemd/coredump.conf.d/complianceascode_hardening.conf /etc/systemd/coredump.conf.d/*.conf /etc/systemd/coredump.conf"); do
    if [ ! -e "$f" ]; then
        continue
    fi

    # find key in section and change value
    if grep -qzosP "(?m)^[[:space:]]*\[Coredump\]([^\n\[]*\n+)+?[[:space:]]*Storage" "$f"; then
        if ! grep -qzosP "(?m)^[[:space:]]*Storage[[:space:]]*=[[:space:]]*none" "$f"; then

            sed -i "/^[[:space:]]*Storage/s/\([[:blank:]]*=[[:blank:]]*\).*/\1none/" "$f"

        fi

        found=true

    # find section and add key = value to it
    elif grep -qs "^[[:space:]]*\[Coredump\]" "$f"; then

            sed -i "/^[[:space:]]*\[Coredump\]/a Storage=none" "$f"

            found=true
    fi
done

# if section not in any file, append section with key = value to FIRST file in files parameter
if ! $found ; then
    file=$(echo "/etc/systemd/coredump.conf.d/complianceascode_hardening.conf /etc/systemd/coredump.conf.d/*.conf /etc/systemd/coredump.conf" | cut -f1 -d ' ')
    mkdir -p "$(dirname "$file")"

    echo -e "[Coredump]\nStorage=none" >> "$file"

fi

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

Complexity:low
Disruption:low
Reboot:false
Strategy:restrict
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - NIST-800-53-CM-6
  - PCI-DSS-Req-3.2
  - PCI-DSSv4-3.3
  - PCI-DSSv4-3.3.1
  - PCI-DSSv4-3.3.1.1
  - coredump_disable_storage
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

- name: Disable storing core dump - Search for a section in files
  ansible.builtin.find:
    paths: '{{item.path}}'
    patterns: '{{item.pattern}}'
    contains: ^\s*\[Coredump\]
    read_whole_file: true
    use_regex: true
  register: systemd_dropin_files_with_section
  loop:
  - path: '{{ ''/etc/systemd/coredump.conf'' | dirname }}'
    pattern: '{{ ''/etc/systemd/coredump.conf'' | basename | regex_escape }}'
  - path: /etc/systemd/coredump.conf.d
    pattern: .*\.conf
  when:
  - '"linux-base" in ansible_facts.packages'
  - '"systemd" in ansible_facts.packages'
  tags:
  - NIST-800-53-CM-6
  - PCI-DSS-Req-3.2
  - PCI-DSSv4-3.3
  - PCI-DSSv4-3.3.1
  - PCI-DSSv4-3.3.1.1
  - coredump_disable_storage
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

- name: Disable storing core dump - Count number of files which contain the correct
    section
  ansible.builtin.set_fact:
    count_of_systemd_dropin_files_with_section: '{{systemd_dropin_files_with_section.results
      | map(attribute=''matched'') | list | map(''int'') | sum}}'
  when:
  - '"linux-base" in ansible_facts.packages'
  - '"systemd" in ansible_facts.packages'
  tags:
  - NIST-800-53-CM-6
  - PCI-DSS-Req-3.2
  - PCI-DSSv4-3.3
  - PCI-DSSv4-3.3.1
  - PCI-DSSv4-3.3.1.1
  - coredump_disable_storage
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

- name: Disable storing core dump - Add missing configuration to correct section
  community.general.ini_file:
    path: '{{item}}'
    section: Coredump
    option: Storage
    value: none
    state: present
    no_extra_spaces: true
  when:
  - '"linux-base" in ansible_facts.packages'
  - '"systemd" in ansible_facts.packages'
  - count_of_systemd_dropin_files_with_section | int > 0
  loop: '{{systemd_dropin_files_with_section.results | sum(attribute=''files'', start=[])
    | map(attribute=''path'') | list }}'
  tags:
  - NIST-800-53-CM-6
  - PCI-DSS-Req-3.2
  - PCI-DSSv4-3.3
  - PCI-DSSv4-3.3.1
  - PCI-DSSv4-3.3.1.1
  - coredump_disable_storage
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

- name: Disable storing core dump - Add configuration to new remediation file
  community.general.ini_file:
    path: /etc/systemd/coredump.conf.d/complianceascode_hardening.conf
    section: Coredump
    option: Storage
    value: none
    state: present
    no_extra_spaces: true
    create: true
  when:
  - '"linux-base" in ansible_facts.packages'
  - '"systemd" in ansible_facts.packages'
  - count_of_systemd_dropin_files_with_section | int == 0
  tags:
  - NIST-800-53-CM-6
  - PCI-DSS-Req-3.2
  - PCI-DSSv4-3.3
  - PCI-DSSv4-3.3.1
  - PCI-DSSv4-3.3.1.1
  - coredump_disable_storage
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

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
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
cis1.5.11
pcidss43.3.1.1, 3.3.1, 3.3

# Remediation is applicable only in certain platforms
if dpkg-query --show --showformat='${db:Status-Status}' 'linux-base' 2>/dev/null | grep -q '^installed$' && { dpkg-query --show --showformat='${db:Status-Status}' 'libpam-runtime' 2>/dev/null | grep -q '^installed$'; }; then

SECURITY_LIMITS_FILE="/etc/security/limits.conf"
DROPIN_DIR="/etc/security/limits.d"
DROPIN_FILE="$DROPIN_DIR/10-ssg-hardening.conf"
REGEX_CORRECT_VALUE="^\s*\*\s+hard\s+core\s+0\s*$"

# Remove bad configuration in drop-ins
if [ -d "$DROPIN_DIR" ]; then
    for override in "$DROPIN_DIR"/*.conf; do
        if [ -f "$override" ] && ! grep -qE "$REGEX_CORRECT_VALUE" "$override"; then
            sed -ir -E '/^[[:space:]]*\*[[:space:]]+hard[[:space:]]+core[[:space:]]+/ s/^/#/' "$override"
        fi
    done
fi

if [ -d "$DROPIN_DIR" ] && grep -qEr "$REGEX_CORRECT_VALUE" "$DROPIN_DIR"; then
    exit 0
elif [ ! -d "$DROPIN_DIR" ] && grep -qE "$REGEX_CORRECT_VALUE" "$SECURITY_LIMITS_FILE"; then
    exit 0
else
    mkdir -p "$DROPIN_DIR"
    echo "*     hard   core    0" >> $DROPIN_FILE
fi

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

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
  - PCI-DSSv4-3.3.1
  - PCI-DSSv4-3.3.1.1
  - disable_users_coredumps
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

- name: Disable Core Dumps for All Users - Set dirs, files and regex variables
  ansible.builtin.set_fact:
    limits_dropin_dir: /etc/security/limits.d
    limits_dropin_file: /etc/security/limits.d/10-ssg-hardening.conf
    limits_main_file: /etc/security/limits.conf
    limits_correct_regex: ^\s*\*\s+hard\s+core\s+0\s*$
  when:
  - '"linux-base" in ansible_facts.packages'
  - '"libpam-runtime" in ansible_facts.packages'
  tags:
  - NIST-800-53-CM-6
  - NIST-800-53-SC-7(10)
  - PCI-DSSv4-3.3
  - PCI-DSSv4-3.3.1
  - PCI-DSSv4-3.3.1.1
  - disable_users_coredumps
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

- name: Disable Core Dumps for All Users - Find valid drop-ins for core limit
  ansible.builtin.find:
    paths: '{{ limits_dropin_dir }}'
    patterns: '*.conf'
    contains: '{{ limits_correct_regex }}'
    file_type: file
  register: valid_dropins
  failed_when: false
  when:
  - '"linux-base" in ansible_facts.packages'
  - '"libpam-runtime" in ansible_facts.packages'
  tags:
  - NIST-800-53-CM-6
  - NIST-800-53-SC-7(10)
  - PCI-DSSv4-3.3
  - PCI-DSSv4-3.3.1
  - PCI-DSSv4-3.3.1.1
  - disable_users_coredumps
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

- name: Disable Core Dumps for All Users - Find all drop-ins with any core limit
  ansible.builtin.find:
    paths: '{{ limits_dropin_dir }}'
    patterns: '*.conf'
    contains: ^\s*\*\s+hard\s+core\s+
    file_type: file
  register: all_dropins
  failed_when: false
  when:
  - '"linux-base" in ansible_facts.packages'
  - '"libpam-runtime" in ansible_facts.packages'
  tags:
  - NIST-800-53-CM-6
  - NIST-800-53-SC-7(10)
  - PCI-DSSv4-3.3
  - PCI-DSSv4-3.3.1
  - PCI-DSSv4-3.3.1.1
  - disable_users_coredumps
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

- name: Disable Core Dumps for All Users - Get invalid drop-ins
  ansible.builtin.set_fact:
    invalid_dropins: '{{ all_dropins.files | rejectattr(''path'', ''in'', valid_dropins.files
      | map(attribute=''path'') | list) | map(attribute=''path'') | list }}'
  when:
  - '"linux-base" in ansible_facts.packages'
  - '"libpam-runtime" in ansible_facts.packages'
  tags:
  - NIST-800-53-CM-6
  - NIST-800-53-SC-7(10)
  - PCI-DSSv4-3.3
  - PCI-DSSv4-3.3.1
  - PCI-DSSv4-3.3.1.1
  - disable_users_coredumps
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

- name: Disable Core Dumps for All Users - Comment invalid * hard core lines in drop-ins
  ansible.builtin.replace:
    path: '{{ item }}'
    regexp: (^\s*\*\s+hard\s+core\s+.*$)
    replace: '#\1'
  loop: '{{ invalid_dropins }}'
  when:
  - '"linux-base" in ansible_facts.packages'
  - '"libpam-runtime" in ansible_facts.packages'
  - invalid_dropins | length > 0
  tags:
  - NIST-800-53-CM-6
  - NIST-800-53-SC-7(10)
  - PCI-DSSv4-3.3
  - PCI-DSSv4-3.3.1
  - PCI-DSSv4-3.3.1.1
  - disable_users_coredumps
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

- name: Disable Core Dumps for All Users - Check if main limits.conf contains correct
    core limit
  ansible.builtin.find:
    paths: /etc/security
    patterns: limits.conf
    contains: '{{ limits_correct_regex }}'
    file_type: file
  register: main_valid
  failed_when: false
  when:
  - '"linux-base" in ansible_facts.packages'
  - '"libpam-runtime" in ansible_facts.packages'
  - not (valid_dropins.matched | default(0) > 0)
  tags:
  - NIST-800-53-CM-6
  - NIST-800-53-SC-7(10)
  - PCI-DSSv4-3.3
  - PCI-DSSv4-3.3.1
  - PCI-DSSv4-3.3.1.1
  - disable_users_coredumps
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

- name: Disable Core Dumps for All Users - Set fact if configuration is valid
  ansible.builtin.set_fact:
    core_limit_valid: '{{ (valid_dropins.matched | default(0)) > 0 or (main_valid.matched
      | default(0)) > 0 }}'
  when:
  - '"linux-base" in ansible_facts.packages'
  - '"libpam-runtime" in ansible_facts.packages'
  tags:
  - NIST-800-53-CM-6
  - NIST-800-53-SC-7(10)
  - PCI-DSSv4-3.3
  - PCI-DSSv4-3.3.1
  - PCI-DSSv4-3.3.1.1
  - disable_users_coredumps
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

- name: Disable Core Dumps for All Users - Ensure drop-in directory exists
  ansible.builtin.file:
    path: '{{ limits_dropin_dir }}'
    state: directory
  when:
  - '"linux-base" in ansible_facts.packages'
  - '"libpam-runtime" in ansible_facts.packages'
  - not core_limit_valid
  tags:
  - NIST-800-53-CM-6
  - NIST-800-53-SC-7(10)
  - PCI-DSSv4-3.3
  - PCI-DSSv4-3.3.1
  - PCI-DSSv4-3.3.1.1
  - disable_users_coredumps
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

- name: Disable Core Dumps for All Users - Deploy 10-ssg-hardening.conf drop-in with
    correct core limit
  ansible.builtin.copy:
    dest: '{{ limits_dropin_file }}'
    content: |
      *     hard   core    0
  when:
  - '"linux-base" in ansible_facts.packages'
  - '"libpam-runtime" in ansible_facts.packages'
  - not core_limit_valid
  tags:
  - NIST-800-53-CM-6
  - NIST-800-53-SC-7(10)
  - PCI-DSSv4-3.3
  - PCI-DSSv4-3.3.1
  - PCI-DSSv4-3.3.1.1
  - disable_users_coredumps
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

Rule   Disable Core Dumps for SUID programs   [ref]

To set the runtime status of the fs.suid_dumpable kernel parameter, run the following command:
$ sudo sysctl -w fs.suid_dumpable=0
To make sure that the setting is persistent, add the following line to a file in the directory /etc/sysctl.d:
fs.suid_dumpable = 0
Rationale:
The core dump of a setuid program is more likely to contain sensitive data, as the program itself runs with greater privileges than the user who initiated execution of the program. Disabling the ability for any setuid program to write a core file decreases the risk of unauthorized access of such data.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_sysctl_fs_suid_dumpable
References:
hipaa164.308(a)(1)(ii)(D), 164.308(a)(3), 164.308(a)(4), 164.310(b), 164.310(c), 164.312(a), 164.312(e)
nistSI-11(a), SI-11(b)
anssiR14
cis1.5.4
pcidss43.3.1.1, 3.3.1, 3.3

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
# Remediation is applicable only in certain platforms
if dpkg-query --show --showformat='${db:Status-Status}' 'linux-base' 2>/dev/null | grep -q '^installed$'; then

# Comment out any occurrences of fs.suid_dumpable from /etc/sysctl.d/*.conf files

for f in /etc/sysctl.d/*.conf /run/sysctl.d/*.conf /usr/local/lib/sysctl.d/*.conf /usr/lib/sysctl.d/*.conf; do


  # skip systemd-sysctl symlink (/etc/sysctl.d/99-sysctl.conf -> /etc/sysctl.conf)
  if [[ "$(readlink -f "$f")" == "/etc/sysctl.conf" ]]; then continue; fi

  matching_list=$(grep -P '^(?!#).*[\s]*fs.suid_dumpable.*$' $f | uniq )
  if ! test -z "$matching_list"; then
    while IFS= read -r entry; do
      escaped_entry=$(sed -e 's|/|\\/|g' <<< "$entry")
      # comment out "fs.suid_dumpable" matches to preserve user data
      sed -i --follow-symlinks "s/^${escaped_entry}$/# &/g" $f
    done <<< "$matching_list"
  fi
done

#
# Set sysctl config file which to save the desired value
#

SYSCONFIG_FILE="/etc/sysctl.conf"


#
# Set runtime for fs.suid_dumpable
#
if ! /bin/false ; then
    /sbin/sysctl -q -n -w fs.suid_dumpable="0"
fi

#
# If fs.suid_dumpable present in /etc/sysctl.conf, change value to "0"
#	else, add "fs.suid_dumpable = 0" to /etc/sysctl.conf
#

# 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' <<< "^fs.suid_dumpable")

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

# 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 "^fs.suid_dumpable\\>" "${SYSCONFIG_FILE}"; then
    escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
    LC_ALL=C sed -i --follow-symlinks "s/^fs.suid_dumpable\\>.*/$escaped_formatted_output/gi" "${SYSCONFIG_FILE}"
else
    if [[ -s "${SYSCONFIG_FILE}" ]] && [[ -n "$(tail -c 1 -- "${SYSCONFIG_FILE}" || true)" ]]; then
        LC_ALL=C sed -i --follow-symlinks '$a'\\ "${SYSCONFIG_FILE}"
    fi
    printf '%s\n' "$formatted_output" >> "${SYSCONFIG_FILE}"
fi

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

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - NIST-800-53-SI-11(a)
  - NIST-800-53-SI-11(b)
  - PCI-DSSv4-3.3
  - PCI-DSSv4-3.3.1
  - PCI-DSSv4-3.3.1.1
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_fs_suid_dumpable

- name: Disable Core Dumps for SUID programs - Set fact for sysctl paths
  ansible.builtin.set_fact:
    sysctl_paths:
    - /etc/sysctl.d/
    - /run/sysctl.d/
    - /usr/local/lib/sysctl.d/
    - /usr/lib/sysctl.d/
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-53-SI-11(a)
  - NIST-800-53-SI-11(b)
  - PCI-DSSv4-3.3
  - PCI-DSSv4-3.3.1
  - PCI-DSSv4-3.3.1.1
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_fs_suid_dumpable

- name: Disable Core Dumps for SUID programs - Find all files that contain fs.suid_dumpable
  ansible.builtin.shell:
    cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
      -HP '^\s*fs.suid_dumpable\s*=\s*.*$'
  register: find_all_values
  check_mode: false
  changed_when: false
  failed_when: false
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-53-SI-11(a)
  - NIST-800-53-SI-11(b)
  - PCI-DSSv4-3.3
  - PCI-DSSv4-3.3.1
  - PCI-DSSv4-3.3.1.1
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_fs_suid_dumpable

- name: Disable Core Dumps for SUID programs - Find all files that set fs.suid_dumpable
    to correct value
  ansible.builtin.shell:
    cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
      -HP '^\s*fs.suid_dumpable\s*=\s*0$'
  register: find_correct_value
  check_mode: false
  changed_when: false
  failed_when: false
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-53-SI-11(a)
  - NIST-800-53-SI-11(b)
  - PCI-DSSv4-3.3
  - PCI-DSSv4-3.3.1
  - PCI-DSSv4-3.3.1.1
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_fs_suid_dumpable

- name: Disable Core Dumps for SUID programs - Comment out any occurrences of fs.suid_dumpable
    from config files
  ansible.builtin.replace:
    path: '{{ item | split(":") | first }}'
    regexp: ^[\s]*fs.suid_dumpable
    replace: '#fs.suid_dumpable'
  loop: '{{ find_all_values.stdout_lines }}'
  when:
  - '"linux-base" in ansible_facts.packages'
  - find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
    | length > find_correct_value.stdout_lines | length
  tags:
  - NIST-800-53-SI-11(a)
  - NIST-800-53-SI-11(b)
  - PCI-DSSv4-3.3
  - PCI-DSSv4-3.3.1
  - PCI-DSSv4-3.3.1.1
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_fs_suid_dumpable

- name: Disable Core Dumps for SUID programs - Ensure sysctl fs.suid_dumpable is set
    to 0
  ansible.posix.sysctl:
    name: fs.suid_dumpable
    value: '0'
    sysctl_file: /etc/sysctl.conf
    state: present
    reload: true
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-53-SI-11(a)
  - NIST-800-53-SI-11(b)
  - PCI-DSSv4-3.3
  - PCI-DSSv4-3.3.1
  - PCI-DSSv4-3.3.1.1
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_fs_suid_dumpable
Group   Enable ExecShield   Group contains 2 rules
[ref]   ExecShield describes kernel features that provide protection against exploitation of memory corruption errors such as buffer overflows. These features include random placement of the stack and other memory regions, prevention of execution in memory that should only hold data, and special handling of text buffers. These protections are enabled by default on 32-bit systems and controlled through sysctl variables kernel.exec-shield and kernel.randomize_va_space. On the latest 64-bit systems, kernel.exec-shield cannot be enabled or disabled with sysctl.

Rule   Restrict Exposed Kernel Pointer Addresses Access   [ref]

To set the runtime status of the kernel.kptr_restrict kernel parameter, run the following command:
$ sudo sysctl -w kernel.kptr_restrict=1
         
To make sure that the setting is persistent, add the following line to a file in the directory /etc/sysctl.d:
kernel.kptr_restrict = 1
         
Rationale:
Exposing kernel pointers (through procfs or seq_printf()) exposes kernel writeable structures which may contain functions pointers. If a write vulnerability occurs in the kernel, allowing write access to any of this structure, the kernel can be compromised. This option disallow any program without the CAP_SYSLOG capability to get the addresses of kernel pointers by replacing them with 0.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_sysctl_kernel_kptr_restrict
References:
nerc-cipCIP-002-5 R1.1, CIP-002-5 R1.2, CIP-003-8 R5.1.1, CIP-003-8 R5.3, CIP-004-6 4.1, CIP-004-6 4.2, CIP-004-6 R2.2.3, CIP-004-6 R2.2.4, CIP-004-6 R2.3, CIP-004-6 R4, CIP-005-6 R1, CIP-005-6 R1.1, CIP-005-6 R1.2, CIP-007-3 R3, CIP-007-3 R3.1, CIP-007-3 R5.1, CIP-007-3 R5.1.2, CIP-007-3 R5.1.3, CIP-007-3 R5.2.1, CIP-007-3 R5.2.3, CIP-007-3 R8.4, CIP-009-6 R.1.1, CIP-009-6 R4
nistSC-30, SC-30(2), SC-30(5), CM-6(a)
osppFMT_SMF_EXT.1
os-srgSRG-OS-000132-GPOS-00067, SRG-OS-000433-GPOS-00192, SRG-OS-000480-GPOS-00227
anssiR9
cis1.5.8
ism1409

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
# Remediation is applicable only in certain platforms
if dpkg-query --show --showformat='${db:Status-Status}' 'linux-base' 2>/dev/null | grep -q '^installed$'; then

# Comment out any occurrences of kernel.kptr_restrict from /etc/sysctl.d/*.conf files

for f in /etc/sysctl.d/*.conf /run/sysctl.d/*.conf /usr/local/lib/sysctl.d/*.conf /usr/lib/sysctl.d/*.conf; do


  # skip systemd-sysctl symlink (/etc/sysctl.d/99-sysctl.conf -> /etc/sysctl.conf)
  if [[ "$(readlink -f "$f")" == "/etc/sysctl.conf" ]]; then continue; fi

  matching_list=$(grep -P '^(?!#).*[\s]*kernel.kptr_restrict.*$' $f | uniq )
  if ! test -z "$matching_list"; then
    while IFS= read -r entry; do
      escaped_entry=$(sed -e 's|/|\\/|g' <<< "$entry")
      # comment out "kernel.kptr_restrict" matches to preserve user data
      sed -i --follow-symlinks "s/^${escaped_entry}$/# &/g" $f
    done <<< "$matching_list"
  fi
done

#
# Set sysctl config file which to save the desired value
#

SYSCONFIG_FILE="/etc/sysctl.conf"

sysctl_kernel_kptr_restrict_value='1'


#
# Set runtime for kernel.kptr_restrict
#
if ! /bin/false ; then
    /sbin/sysctl -q -n -w kernel.kptr_restrict="$sysctl_kernel_kptr_restrict_value"
fi

#
# If kernel.kptr_restrict present in /etc/sysctl.conf, change value to appropriate value
#	else, add "kernel.kptr_restrict = value" to /etc/sysctl.conf
#

# 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' <<< "^kernel.kptr_restrict")

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

# 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 "^kernel.kptr_restrict\\>" "${SYSCONFIG_FILE}"; then
    escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
    LC_ALL=C sed -i --follow-symlinks "s/^kernel.kptr_restrict\\>.*/$escaped_formatted_output/gi" "${SYSCONFIG_FILE}"
else
    if [[ -s "${SYSCONFIG_FILE}" ]] && [[ -n "$(tail -c 1 -- "${SYSCONFIG_FILE}" || true)" ]]; then
        LC_ALL=C sed -i --follow-symlinks '$a'\\ "${SYSCONFIG_FILE}"
    fi
    printf '%s\n' "$formatted_output" >> "${SYSCONFIG_FILE}"
fi

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

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - NIST-800-53-CM-6(a)
  - NIST-800-53-SC-30
  - NIST-800-53-SC-30(2)
  - NIST-800-53-SC-30(5)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_kernel_kptr_restrict
- name: XCCDF Value sysctl_kernel_kptr_restrict_value # promote to variable
  set_fact:
    sysctl_kernel_kptr_restrict_value: !!str 1
  tags:
    - always

- name: Restrict Exposed Kernel Pointer Addresses Access - Set fact for sysctl paths
  ansible.builtin.set_fact:
    sysctl_paths:
    - /etc/sysctl.d/
    - /run/sysctl.d/
    - /usr/local/lib/sysctl.d/
    - /usr/lib/sysctl.d/
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-53-CM-6(a)
  - NIST-800-53-SC-30
  - NIST-800-53-SC-30(2)
  - NIST-800-53-SC-30(5)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_kernel_kptr_restrict

- name: Restrict Exposed Kernel Pointer Addresses Access - Find all files that contain
    kernel.kptr_restrict
  ansible.builtin.shell:
    cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
      -HP '^\s*kernel.kptr_restrict\s*=\s*.*$'
  register: find_all_values
  check_mode: false
  changed_when: false
  failed_when: false
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-53-CM-6(a)
  - NIST-800-53-SC-30
  - NIST-800-53-SC-30(2)
  - NIST-800-53-SC-30(5)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_kernel_kptr_restrict

- name: Restrict Exposed Kernel Pointer Addresses Access - Find all files that set
    kernel.kptr_restrict to correct value
  ansible.builtin.shell:
    cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
      -HP '^\s*kernel.kptr_restrict\s*=\s*{{ sysctl_kernel_kptr_restrict_value }}$'
  register: find_correct_value
  check_mode: false
  changed_when: false
  failed_when: false
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-53-CM-6(a)
  - NIST-800-53-SC-30
  - NIST-800-53-SC-30(2)
  - NIST-800-53-SC-30(5)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_kernel_kptr_restrict

- name: Restrict Exposed Kernel Pointer Addresses Access - Comment out any occurrences
    of kernel.kptr_restrict from config files
  ansible.builtin.replace:
    path: '{{ item | split(":") | first }}'
    regexp: ^[\s]*kernel.kptr_restrict
    replace: '#kernel.kptr_restrict'
  loop: '{{ find_all_values.stdout_lines }}'
  when:
  - '"linux-base" in ansible_facts.packages'
  - find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
    | length > find_correct_value.stdout_lines | length
  tags:
  - NIST-800-53-CM-6(a)
  - NIST-800-53-SC-30
  - NIST-800-53-SC-30(2)
  - NIST-800-53-SC-30(5)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_kernel_kptr_restrict

- name: Restrict Exposed Kernel Pointer Addresses Access - Ensure sysctl kernel.kptr_restrict
    is set
  ansible.posix.sysctl:
    name: kernel.kptr_restrict
    value: '{{ sysctl_kernel_kptr_restrict_value }}'
    sysctl_file: /etc/sysctl.conf
    state: present
    reload: true
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-53-CM-6(a)
  - NIST-800-53-SC-30
  - NIST-800-53-SC-30(2)
  - NIST-800-53-SC-30(5)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_kernel_kptr_restrict

Rule   Enable Randomized Layout of Virtual Address Space   [ref]

To set the runtime status of the kernel.randomize_va_space kernel parameter, run the following command:
$ sudo sysctl -w kernel.randomize_va_space=2
To make sure that the setting is persistent, add the following line to a file in the directory /etc/sysctl.d:
kernel.randomize_va_space = 2
Rationale:
Address space layout randomization (ASLR) makes it more difficult for an attacker to predict the location of attack code they have introduced into a process's address space during an attempt at exploitation. Additionally, ASLR makes it more difficult for an attacker to know the location of existing code in order to re-purpose it using return oriented programming (ROP) techniques.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_sysctl_kernel_randomize_va_space
References:
cui3.1.7
hipaa164.308(a)(1)(ii)(D), 164.308(a)(3), 164.308(a)(4), 164.310(b), 164.310(c), 164.312(a), 164.312(e)
nerc-cipCIP-002-5 R1.1, CIP-002-5 R1.2, CIP-003-8 R5.1.1, CIP-003-8 R5.3, CIP-004-6 4.1, CIP-004-6 4.2, CIP-004-6 R2.2.3, CIP-004-6 R2.2.4, CIP-004-6 R2.3, CIP-004-6 R4, CIP-005-6 R1, CIP-005-6 R1.1, CIP-005-6 R1.2, CIP-007-3 R3, CIP-007-3 R3.1, CIP-007-3 R5.1, CIP-007-3 R5.1.2, CIP-007-3 R5.1.3, CIP-007-3 R5.2.1, CIP-007-3 R5.2.3, CIP-007-3 R8.4, CIP-009-6 R.1.1, CIP-009-6 R4
nistSC-30, SC-30(2), CM-6(a)
pcidssReq-2.2.1
os-srgSRG-OS-000433-GPOS-00193, SRG-OS-000480-GPOS-00227
app-srg-ctrSRG-APP-000450-CTR-001105
anssiR9
cis1.5.9
ism1409
pcidss43.3.1.1, 3.3.1, 3.3

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
# Remediation is applicable only in certain platforms
if dpkg-query --show --showformat='${db:Status-Status}' 'linux-base' 2>/dev/null | grep -q '^installed$'; then

# Comment out any occurrences of kernel.randomize_va_space from /etc/sysctl.d/*.conf files

for f in /etc/sysctl.d/*.conf /run/sysctl.d/*.conf /usr/local/lib/sysctl.d/*.conf /usr/lib/sysctl.d/*.conf; do


  # skip systemd-sysctl symlink (/etc/sysctl.d/99-sysctl.conf -> /etc/sysctl.conf)
  if [[ "$(readlink -f "$f")" == "/etc/sysctl.conf" ]]; then continue; fi

  matching_list=$(grep -P '^(?!#).*[\s]*kernel.randomize_va_space.*$' $f | uniq )
  if ! test -z "$matching_list"; then
    while IFS= read -r entry; do
      escaped_entry=$(sed -e 's|/|\\/|g' <<< "$entry")
      # comment out "kernel.randomize_va_space" matches to preserve user data
      sed -i --follow-symlinks "s/^${escaped_entry}$/# &/g" $f
    done <<< "$matching_list"
  fi
done

#
# Set sysctl config file which to save the desired value
#

SYSCONFIG_FILE="/etc/sysctl.conf"


#
# Set runtime for kernel.randomize_va_space
#
if ! /bin/false ; then
    /sbin/sysctl -q -n -w kernel.randomize_va_space="2"
fi

#
# If kernel.randomize_va_space present in /etc/sysctl.conf, change value to "2"
#	else, add "kernel.randomize_va_space = 2" to /etc/sysctl.conf
#

# 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' <<< "^kernel.randomize_va_space")

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

# If the key exists, change it. Otherwise, add it to the config_file.
# We search for the key string followed by a word boundary (matched by \>),
# so if we search for 'setting', 'setting2' won't match.
if LC_ALL=C grep -q -m 1 -i -e "^kernel.randomize_va_space\\>" "${SYSCONFIG_FILE}"; then
    escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
    LC_ALL=C sed -i --follow-symlinks "s/^kernel.randomize_va_space\\>.*/$escaped_formatted_output/gi" "${SYSCONFIG_FILE}"
else
    if [[ -s "${SYSCONFIG_FILE}" ]] && [[ -n "$(tail -c 1 -- "${SYSCONFIG_FILE}" || true)" ]]; then
        LC_ALL=C sed -i --follow-symlinks '$a'\\ "${SYSCONFIG_FILE}"
    fi
    printf '%s\n' "$formatted_output" >> "${SYSCONFIG_FILE}"
fi

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

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - NIST-800-171-3.1.7
  - NIST-800-53-CM-6(a)
  - NIST-800-53-SC-30
  - NIST-800-53-SC-30(2)
  - PCI-DSS-Req-2.2.1
  - PCI-DSSv4-3.3
  - PCI-DSSv4-3.3.1
  - PCI-DSSv4-3.3.1.1
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_kernel_randomize_va_space

- name: Enable Randomized Layout of Virtual Address Space - Set fact for sysctl paths
  ansible.builtin.set_fact:
    sysctl_paths:
    - /etc/sysctl.d/
    - /run/sysctl.d/
    - /usr/local/lib/sysctl.d/
    - /usr/lib/sysctl.d/
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.7
  - NIST-800-53-CM-6(a)
  - NIST-800-53-SC-30
  - NIST-800-53-SC-30(2)
  - PCI-DSS-Req-2.2.1
  - PCI-DSSv4-3.3
  - PCI-DSSv4-3.3.1
  - PCI-DSSv4-3.3.1.1
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_kernel_randomize_va_space

- name: Enable Randomized Layout of Virtual Address Space - Find all files that contain
    kernel.randomize_va_space
  ansible.builtin.shell:
    cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
      -HP '^\s*kernel.randomize_va_space\s*=\s*.*$'
  register: find_all_values
  check_mode: false
  changed_when: false
  failed_when: false
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.7
  - NIST-800-53-CM-6(a)
  - NIST-800-53-SC-30
  - NIST-800-53-SC-30(2)
  - PCI-DSS-Req-2.2.1
  - PCI-DSSv4-3.3
  - PCI-DSSv4-3.3.1
  - PCI-DSSv4-3.3.1.1
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_kernel_randomize_va_space

- name: Enable Randomized Layout of Virtual Address Space - Find all files that set
    kernel.randomize_va_space to correct value
  ansible.builtin.shell:
    cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
      -HP '^\s*kernel.randomize_va_space\s*=\s*2$'
  register: find_correct_value
  check_mode: false
  changed_when: false
  failed_when: false
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.7
  - NIST-800-53-CM-6(a)
  - NIST-800-53-SC-30
  - NIST-800-53-SC-30(2)
  - PCI-DSS-Req-2.2.1
  - PCI-DSSv4-3.3
  - PCI-DSSv4-3.3.1
  - PCI-DSSv4-3.3.1.1
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_kernel_randomize_va_space

- name: Enable Randomized Layout of Virtual Address Space - Comment out any occurrences
    of kernel.randomize_va_space from config files
  ansible.builtin.replace:
    path: '{{ item | split(":") | first }}'
    regexp: ^[\s]*kernel.randomize_va_space
    replace: '#kernel.randomize_va_space'
  loop: '{{ find_all_values.stdout_lines }}'
  when:
  - '"linux-base" in ansible_facts.packages'
  - find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
    | length > find_correct_value.stdout_lines | length
  tags:
  - NIST-800-171-3.1.7
  - NIST-800-53-CM-6(a)
  - NIST-800-53-SC-30
  - NIST-800-53-SC-30(2)
  - PCI-DSS-Req-2.2.1
  - PCI-DSSv4-3.3
  - PCI-DSSv4-3.3.1
  - PCI-DSSv4-3.3.1.1
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_kernel_randomize_va_space

- name: Enable Randomized Layout of Virtual Address Space - Ensure sysctl kernel.randomize_va_space
    is set to 2
  ansible.posix.sysctl:
    name: kernel.randomize_va_space
    value: '2'
    sysctl_file: /etc/sysctl.conf
    state: present
    reload: true
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.7
  - NIST-800-53-CM-6(a)
  - NIST-800-53-SC-30
  - NIST-800-53-SC-30(2)
  - PCI-DSS-Req-2.2.1
  - PCI-DSSv4-3.3
  - PCI-DSSv4-3.3.1
  - PCI-DSSv4-3.3.1.1
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_kernel_randomize_va_space

Rule   Restrict Access to Kernel Message Buffer   [ref]

To set the runtime status of the kernel.dmesg_restrict kernel parameter, run the following command:
$ sudo sysctl -w kernel.dmesg_restrict=1
To make sure that the setting is persistent, add the following line to a file in the directory /etc/sysctl.d:
kernel.dmesg_restrict = 1
Rationale:
Unprivileged access to the kernel syslog can expose sensitive kernel address information.
Severity: 
low
Rule ID:xccdf_org.ssgproject.content_rule_sysctl_kernel_dmesg_restrict
References:
cui3.1.5
hipaa164.308(a)(1)(ii)(D), 164.308(a)(3), 164.308(a)(4), 164.310(b), 164.310(c), 164.312(a), 164.312(e)
nistSI-11(a), SI-11(b)
osppFMT_SMF_EXT.1
os-srgSRG-OS-000132-GPOS-00067, SRG-OS-000138-GPOS-00069
app-srg-ctrSRG-APP-000243-CTR-000600
anssiR9
cis1.5.5
ism1546

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
# Remediation is applicable only in certain platforms
if dpkg-query --show --showformat='${db:Status-Status}' 'linux-base' 2>/dev/null | grep -q '^installed$'; then

# Comment out any occurrences of kernel.dmesg_restrict from /etc/sysctl.d/*.conf files

for f in /etc/sysctl.d/*.conf /run/sysctl.d/*.conf /usr/local/lib/sysctl.d/*.conf /usr/lib/sysctl.d/*.conf; do


  # skip systemd-sysctl symlink (/etc/sysctl.d/99-sysctl.conf -> /etc/sysctl.conf)
  if [[ "$(readlink -f "$f")" == "/etc/sysctl.conf" ]]; then continue; fi

  matching_list=$(grep -P '^(?!#).*[\s]*kernel.dmesg_restrict.*$' $f | uniq )
  if ! test -z "$matching_list"; then
    while IFS= read -r entry; do
      escaped_entry=$(sed -e 's|/|\\/|g' <<< "$entry")
      # comment out "kernel.dmesg_restrict" matches to preserve user data
      sed -i --follow-symlinks "s/^${escaped_entry}$/# &/g" $f
    done <<< "$matching_list"
  fi
done

#
# Set sysctl config file which to save the desired value
#

SYSCONFIG_FILE="/etc/sysctl.conf"


#
# Set runtime for kernel.dmesg_restrict
#
if ! /bin/false ; then
    /sbin/sysctl -q -n -w kernel.dmesg_restrict="1"
fi

#
# If kernel.dmesg_restrict present in /etc/sysctl.conf, change value to "1"
#	else, add "kernel.dmesg_restrict = 1" to /etc/sysctl.conf
#

# 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' <<< "^kernel.dmesg_restrict")

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

# If the key exists, change it. Otherwise, add it to the config_file.
# We search for the key string followed by a word boundary (matched by \>),
# so if we search for 'setting', 'setting2' won't match.
if LC_ALL=C grep -q -m 1 -i -e "^kernel.dmesg_restrict\\>" "${SYSCONFIG_FILE}"; then
    escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
    LC_ALL=C sed -i --follow-symlinks "s/^kernel.dmesg_restrict\\>.*/$escaped_formatted_output/gi" "${SYSCONFIG_FILE}"
else
    if [[ -s "${SYSCONFIG_FILE}" ]] && [[ -n "$(tail -c 1 -- "${SYSCONFIG_FILE}" || true)" ]]; then
        LC_ALL=C sed -i --follow-symlinks '$a'\\ "${SYSCONFIG_FILE}"
    fi
    printf '%s\n' "$formatted_output" >> "${SYSCONFIG_FILE}"
fi

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

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - NIST-800-171-3.1.5
  - NIST-800-53-SI-11(a)
  - NIST-800-53-SI-11(b)
  - disable_strategy
  - low_complexity
  - low_severity
  - medium_disruption
  - reboot_required
  - sysctl_kernel_dmesg_restrict

- name: Restrict Access to Kernel Message Buffer - Set fact for sysctl paths
  ansible.builtin.set_fact:
    sysctl_paths:
    - /etc/sysctl.d/
    - /run/sysctl.d/
    - /usr/local/lib/sysctl.d/
    - /usr/lib/sysctl.d/
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.5
  - NIST-800-53-SI-11(a)
  - NIST-800-53-SI-11(b)
  - disable_strategy
  - low_complexity
  - low_severity
  - medium_disruption
  - reboot_required
  - sysctl_kernel_dmesg_restrict

- name: Restrict Access to Kernel Message Buffer - Find all files that contain kernel.dmesg_restrict
  ansible.builtin.shell:
    cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
      -HP '^\s*kernel.dmesg_restrict\s*=\s*.*$'
  register: find_all_values
  check_mode: false
  changed_when: false
  failed_when: false
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.5
  - NIST-800-53-SI-11(a)
  - NIST-800-53-SI-11(b)
  - disable_strategy
  - low_complexity
  - low_severity
  - medium_disruption
  - reboot_required
  - sysctl_kernel_dmesg_restrict

- name: Restrict Access to Kernel Message Buffer - Find all files that set kernel.dmesg_restrict
    to correct value
  ansible.builtin.shell:
    cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
      -HP '^\s*kernel.dmesg_restrict\s*=\s*1$'
  register: find_correct_value
  check_mode: false
  changed_when: false
  failed_when: false
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.5
  - NIST-800-53-SI-11(a)
  - NIST-800-53-SI-11(b)
  - disable_strategy
  - low_complexity
  - low_severity
  - medium_disruption
  - reboot_required
  - sysctl_kernel_dmesg_restrict

- name: Restrict Access to Kernel Message Buffer - Comment out any occurrences of
    kernel.dmesg_restrict from config files
  ansible.builtin.replace:
    path: '{{ item | split(":") | first }}'
    regexp: ^[\s]*kernel.dmesg_restrict
    replace: '#kernel.dmesg_restrict'
  loop: '{{ find_all_values.stdout_lines }}'
  when:
  - '"linux-base" in ansible_facts.packages'
  - find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
    | length > find_correct_value.stdout_lines | length
  tags:
  - NIST-800-171-3.1.5
  - NIST-800-53-SI-11(a)
  - NIST-800-53-SI-11(b)
  - disable_strategy
  - low_complexity
  - low_severity
  - medium_disruption
  - reboot_required
  - sysctl_kernel_dmesg_restrict

- name: Restrict Access to Kernel Message Buffer - Ensure sysctl kernel.dmesg_restrict
    is set to 1
  ansible.posix.sysctl:
    name: kernel.dmesg_restrict
    value: '1'
    sysctl_file: /etc/sysctl.conf
    state: present
    reload: true
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.5
  - NIST-800-53-SI-11(a)
  - NIST-800-53-SI-11(b)
  - disable_strategy
  - low_complexity
  - low_severity
  - medium_disruption
  - reboot_required
  - sysctl_kernel_dmesg_restrict

Rule   Restrict usage of ptrace to descendant processes   [ref]

To set the runtime status of the kernel.yama.ptrace_scope kernel parameter, run the following command:
$ sudo sysctl -w kernel.yama.ptrace_scope=1
To make sure that the setting is persistent, add the following line to a file in the directory /etc/sysctl.d:
kernel.yama.ptrace_scope = 1
Rationale:
Unrestricted usage of ptrace allows compromised binaries to run ptrace on another processes of the user. Like this, the attacker can steal sensitive information from the target processes (e.g. SSH sessions, web browser, ...) without any additional assistance from the user (i.e. without resorting to phishing).
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_sysctl_kernel_yama_ptrace_scope
References:
nistSC-7(10)
osppFMT_SMF_EXT.1
os-srgSRG-OS-000132-GPOS-00067, SRG-OS-000480-GPOS-00227
anssiR11
cis1.5.3, 1.5.10
ism1409

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
# Remediation is applicable only in certain platforms
if dpkg-query --show --showformat='${db:Status-Status}' 'linux-base' 2>/dev/null | grep -q '^installed$'; then

# Comment out any occurrences of kernel.yama.ptrace_scope from /etc/sysctl.d/*.conf files

for f in /etc/sysctl.d/*.conf /run/sysctl.d/*.conf /usr/local/lib/sysctl.d/*.conf /usr/lib/sysctl.d/*.conf; do


  # skip systemd-sysctl symlink (/etc/sysctl.d/99-sysctl.conf -> /etc/sysctl.conf)
  if [[ "$(readlink -f "$f")" == "/etc/sysctl.conf" ]]; then continue; fi

  matching_list=$(grep -P '^(?!#).*[\s]*kernel.yama.ptrace_scope.*$' $f | uniq )
  if ! test -z "$matching_list"; then
    while IFS= read -r entry; do
      escaped_entry=$(sed -e 's|/|\\/|g' <<< "$entry")
      # comment out "kernel.yama.ptrace_scope" matches to preserve user data
      sed -i --follow-symlinks "s/^${escaped_entry}$/# &/g" $f
    done <<< "$matching_list"
  fi
done

#
# Set sysctl config file which to save the desired value
#

SYSCONFIG_FILE="/etc/sysctl.conf"


#
# Set runtime for kernel.yama.ptrace_scope
#
if ! /bin/false ; then
    /sbin/sysctl -q -n -w kernel.yama.ptrace_scope="1"
fi

#
# If kernel.yama.ptrace_scope present in /etc/sysctl.conf, change value to "1"
#	else, add "kernel.yama.ptrace_scope = 1" to /etc/sysctl.conf
#

# 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' <<< "^kernel.yama.ptrace_scope")

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

# If the key exists, change it. Otherwise, add it to the config_file.
# We search for the key string followed by a word boundary (matched by \>),
# so if we search for 'setting', 'setting2' won't match.
if LC_ALL=C grep -q -m 1 -i -e "^kernel.yama.ptrace_scope\\>" "${SYSCONFIG_FILE}"; then
    escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
    LC_ALL=C sed -i --follow-symlinks "s/^kernel.yama.ptrace_scope\\>.*/$escaped_formatted_output/gi" "${SYSCONFIG_FILE}"
else
    if [[ -s "${SYSCONFIG_FILE}" ]] && [[ -n "$(tail -c 1 -- "${SYSCONFIG_FILE}" || true)" ]]; then
        LC_ALL=C sed -i --follow-symlinks '$a'\\ "${SYSCONFIG_FILE}"
    fi
    printf '%s\n' "$formatted_output" >> "${SYSCONFIG_FILE}"
fi

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

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - NIST-800-53-SC-7(10)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_kernel_yama_ptrace_scope

- name: Restrict usage of ptrace to descendant processes - Set fact for sysctl paths
  ansible.builtin.set_fact:
    sysctl_paths:
    - /etc/sysctl.d/
    - /run/sysctl.d/
    - /usr/local/lib/sysctl.d/
    - /usr/lib/sysctl.d/
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-53-SC-7(10)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_kernel_yama_ptrace_scope

- name: Restrict usage of ptrace to descendant processes - Find all files that contain
    kernel.yama.ptrace_scope
  ansible.builtin.shell:
    cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
      -HP '^\s*kernel.yama.ptrace_scope\s*=\s*.*$'
  register: find_all_values
  check_mode: false
  changed_when: false
  failed_when: false
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-53-SC-7(10)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_kernel_yama_ptrace_scope

- name: Restrict usage of ptrace to descendant processes - Find all files that set
    kernel.yama.ptrace_scope to correct value
  ansible.builtin.shell:
    cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
      -HP '^\s*kernel.yama.ptrace_scope\s*=\s*1$'
  register: find_correct_value
  check_mode: false
  changed_when: false
  failed_when: false
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-53-SC-7(10)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_kernel_yama_ptrace_scope

- name: Restrict usage of ptrace to descendant processes - Comment out any occurrences
    of kernel.yama.ptrace_scope from config files
  ansible.builtin.replace:
    path: '{{ item | split(":") | first }}'
    regexp: ^[\s]*kernel.yama.ptrace_scope
    replace: '#kernel.yama.ptrace_scope'
  loop: '{{ find_all_values.stdout_lines }}'
  when:
  - '"linux-base" in ansible_facts.packages'
  - find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
    | length > find_correct_value.stdout_lines | length
  tags:
  - NIST-800-53-SC-7(10)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_kernel_yama_ptrace_scope

- name: Restrict usage of ptrace to descendant processes - Ensure sysctl kernel.yama.ptrace_scope
    is set to 1
  ansible.posix.sysctl:
    name: kernel.yama.ptrace_scope
    value: '1'
    sysctl_file: /etc/sysctl.conf
    state: present
    reload: true
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-53-SC-7(10)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_kernel_yama_ptrace_scope
Red Hat and Red Hat Enterprise Linux are either registered trademarks or trademarks of Red Hat, Inc. in the United States and other countries. All other names are registered trademarks or trademarks of their respective companies.