Guide to the Secure Configuration of Ubuntu 24.04

with profile DRAFT - CIS Ubuntu Linux 24.04 LTS Benchmark for Level 1 - Workstation
This profile defines a baseline that aligns to the "Level 1 - Workstation" configuration from the Center for Internet Security® Ubuntu Linux 24.04 LTS Benchmark™, v1.0.0, released 2024-08-26. This profile includes Center for Internet Security® Ubuntu Linux 24.04 LTS Benchmark™ content.
This guide presents a catalog of security-relevant configuration settings for Ubuntu 24.04. 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 TitleDRAFT - CIS Ubuntu Linux 24.04 LTS Benchmark for Level 1 - Workstation
Profile IDxccdf_org.ssgproject.content_profile_cis_level1_workstation

CPE Platforms

  • cpe:/o:canonical:ubuntu_linux:24.04::~~lts~~~

Revision History

Current version: 0.1.76

  • draft (as of 2024-11-29)

Table of Contents

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

Checklist

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

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

Rule   Install AIDE   [ref]

The aide package can be installed with the following command:
$ apt-get install aide
Rationale:
The AIDE package must be installed if it is to be available for integrity checking.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_package_aide_installed
References:
cis-csc1, 11, 12, 13, 14, 15, 16, 2, 3, 5, 7, 8, 9
cjis5.10.1.3
cobit5APO01.06, BAI01.06, BAI02.01, BAI03.05, BAI06.01, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS01.03, DSS03.05, DSS04.07, DSS05.02, DSS05.03, DSS05.05, DSS05.07, DSS06.02, DSS06.06
disaCCI-002696, CCI-001744
isa-62443-20094.3.4.3.2, 4.3.4.3.3, 4.3.4.4.4
isa-62443-2013SR 3.1, SR 3.3, SR 3.4, SR 3.8, SR 4.1, SR 6.2, SR 7.6
ism1034, 1288, 1341, 1417
iso27001-2013A.11.2.4, A.12.1.2, A.12.2.1, A.12.4.1, A.12.5.1, A.12.6.2, A.14.1.2, A.14.1.3, A.14.2.2, A.14.2.3, A.14.2.4, A.14.2.7, A.15.2.1, A.8.2.3
nistCM-6(a)
nist-csfDE.CM-1, DE.CM-7, PR.DS-1, PR.DS-6, PR.DS-8, PR.IP-1, PR.IP-3
pcidssReq-11.5
os-srgSRG-OS-000445-GPOS-00199
anssiR76, R79
cis6.3.1
pcidss411.5.2

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

class install_aide {
  package { 'aide':
    ensure => 'installed',
  }
}

Complexity:low
Disruption:low
Reboot:false
Strategy:enable
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - CJIS-5.10.1.3
  - NIST-800-53-CM-6(a)
  - PCI-DSS-Req-11.5
  - PCI-DSSv4-11.5.2
  - enable_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - package_aide_installed

- name: Ensure aide is installed
  package:
    name: aide
    state: present
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - CJIS-5.10.1.3
  - NIST-800-53-CM-6(a)
  - PCI-DSS-Req-11.5
  - PCI-DSSv4-11.5.2
  - enable_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - package_aide_installed


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

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

DEBIAN_FRONTEND=noninteractive apt-get install -y "aide"

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

Rule   Build and Test AIDE Database   [ref]

Run the following command to generate a new database:
$ sudo aideinit
By default, the database will be written to the file /var/lib/aide/aide.db.new. Storing the database, the configuration file /etc/aide.conf, and the binary /usr/bin/aide (or hashes of these files), in a secure location (such as on read-only media) provides additional assurance about their integrity. The newly-generated database can be installed as follows:
$ sudo cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db
To initiate a manual check, run the following command:
$ sudo /usr/bin/aide --check
If this check produces any unexpected output, investigate.
Rationale:
For AIDE to be effective, an initial database of "known-good" information about files must be captured and it should be able to be verified against the installed files.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_aide_build_database
References:
cis-csc1, 11, 12, 13, 14, 15, 16, 2, 3, 5, 7, 8, 9
cjis5.10.1.3
cobit5APO01.06, BAI01.06, BAI02.01, BAI03.05, BAI06.01, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS01.03, DSS03.05, DSS04.07, DSS05.02, DSS05.03, DSS05.05, DSS05.07, DSS06.02, DSS06.06
disaCCI-002696, CCI-001744
isa-62443-20094.3.4.3.2, 4.3.4.3.3, 4.3.4.4.4
isa-62443-2013SR 3.1, SR 3.3, SR 3.4, SR 3.8, SR 4.1, SR 6.2, SR 7.6
iso27001-2013A.11.2.4, A.12.1.2, A.12.2.1, A.12.4.1, A.12.5.1, A.12.6.2, A.14.1.2, A.14.1.3, A.14.2.2, A.14.2.3, A.14.2.4, A.14.2.7, A.15.2.1, A.8.2.3
nistCM-6(a)
nist-csfDE.CM-1, DE.CM-7, PR.DS-1, PR.DS-6, PR.DS-8, PR.IP-1, PR.IP-3
pcidssReq-11.5
os-srgSRG-OS-000445-GPOS-00199
anssiR76, R79
cis6.3.1
pcidss411.5.2

Complexity:low
Disruption:low
Reboot:false
Strategy:restrict
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - CJIS-5.10.1.3
  - NIST-800-53-CM-6(a)
  - PCI-DSS-Req-11.5
  - PCI-DSSv4-11.5.2
  - aide_build_database
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

- name: Build and Test AIDE Database - Ensure AIDE Is Installed
  ansible.builtin.apt:
    name: aide
    state: present
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - CJIS-5.10.1.3
  - NIST-800-53-CM-6(a)
  - PCI-DSS-Req-11.5
  - PCI-DSSv4-11.5.2
  - aide_build_database
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

- name: Build and Test AIDE Database - Check if DB Path in /etc/aide/aide.conf Is
    Already Set
  ansible.builtin.lineinfile:
    path: /etc/aide/aide.conf
    regexp: ^#?(\s*)(database=)(.*)$
    state: absent
  check_mode: true
  changed_when: false
  register: database_replace
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - CJIS-5.10.1.3
  - NIST-800-53-CM-6(a)
  - PCI-DSS-Req-11.5
  - PCI-DSSv4-11.5.2
  - aide_build_database
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

- name: Build and Test AIDE Database - Check if DB Out Path in /etc/aide/aide.conf
    Is Already Set
  ansible.builtin.lineinfile:
    path: /etc/aide/aide.conf
    regexp: ^#?(\s*)(database_out=)(.*)$
    state: absent
  check_mode: true
  changed_when: false
  register: database_out_replace
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - CJIS-5.10.1.3
  - NIST-800-53-CM-6(a)
  - PCI-DSS-Req-11.5
  - PCI-DSSv4-11.5.2
  - aide_build_database
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

- name: Build and Test AIDE Database - Fix DB Path in Config File if Necessary
  ansible.builtin.lineinfile:
    path: /etc/aide/aide.conf
    regexp: ^#?(\s*)(database)(\s*)=(\s*)(.*)$
    line: \2\3=\4file:/var/lib/aide/aide.db
    backrefs: true
  when:
  - '"linux-base" in ansible_facts.packages'
  - database_replace.found > 0
  tags:
  - CJIS-5.10.1.3
  - NIST-800-53-CM-6(a)
  - PCI-DSS-Req-11.5
  - PCI-DSSv4-11.5.2
  - aide_build_database
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

- name: Build and Test AIDE Database - Fix DB Out Path in Config File if Necessary
  ansible.builtin.lineinfile:
    path: /etc/aide/aide.conf
    regexp: ^#?(\s*)(database_out)(\s*)=(\s*)(.*)$
    line: \2\3=\4file:/var/lib/aide/aide.db.new
    backrefs: true
  when:
  - '"linux-base" in ansible_facts.packages'
  - database_out_replace.found > 0
  tags:
  - CJIS-5.10.1.3
  - NIST-800-53-CM-6(a)
  - PCI-DSS-Req-11.5
  - PCI-DSSv4-11.5.2
  - aide_build_database
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

- name: Build and Test AIDE Database - Ensure the Default DB Path is Added
  ansible.builtin.lineinfile:
    path: /etc/aide/aide.conf
    line: database=file:/var/lib/aide/aide.db
    create: true
  when:
  - '"linux-base" in ansible_facts.packages'
  - database_replace.found == 0
  tags:
  - CJIS-5.10.1.3
  - NIST-800-53-CM-6(a)
  - PCI-DSS-Req-11.5
  - PCI-DSSv4-11.5.2
  - aide_build_database
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

- name: Build and Test AIDE Database - Ensure the Default Out Path is Added
  ansible.builtin.lineinfile:
    path: /etc/aide/aide.conf
    line: database_out=file:/var/lib/aide/aide.db.new
    create: true
  when:
  - '"linux-base" in ansible_facts.packages'
  - database_out_replace.found == 0
  tags:
  - CJIS-5.10.1.3
  - NIST-800-53-CM-6(a)
  - PCI-DSS-Req-11.5
  - PCI-DSSv4-11.5.2
  - aide_build_database
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

- name: Build and Test AIDE Database - Build and Test AIDE Database
  ansible.builtin.command: /usr/sbin/aideinit -y -f
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - CJIS-5.10.1.3
  - NIST-800-53-CM-6(a)
  - PCI-DSS-Req-11.5
  - PCI-DSSv4-11.5.2
  - aide_build_database
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

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

DEBIAN_FRONTEND=noninteractive apt-get install -y "aide"

AIDE_CONFIG=/etc/aide/aide.conf
DEFAULT_DB_PATH=/var/lib/aide/aide.db

# Fix db path in the config file, if necessary
if ! grep -q '^database=file:' ${AIDE_CONFIG}; then
    # replace_or_append gets confused by 'database=file' as a key, so should not be used.
    #replace_or_append "${AIDE_CONFIG}" '^database=file' "${DEFAULT_DB_PATH}" '@CCENUM@' '%s:%s'
    echo "database=file:${DEFAULT_DB_PATH}" >> ${AIDE_CONFIG}
fi

# Fix db out path in the config file, if necessary
if ! grep -q '^database_out=file:' ${AIDE_CONFIG}; then
    echo "database_out=file:${DEFAULT_DB_PATH}.new" >> ${AIDE_CONFIG}
fi

/usr/sbin/aideinit -y -f

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi
Group   Disk Partitioning   Group contains 1 rule
[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 /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
disaCCI-000366
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   GNOME Desktop Environment   Group contains 3 groups and 6 rules
[ref]   GNOME is a graphical desktop environment bundled with many Linux distributions that allow users to easily interact with the operating system graphically rather than textually. The GNOME Graphical Display Manager (GDM) provides login, logout, and user switching contexts as well as display server management.

GNOME is developed by the GNOME Project and is considered the default Red Hat Graphical environment.

For more information on GNOME and the GNOME Project, see https://www.gnome.org.
Group   Configure GNOME Login Screen   Group contains 2 rules

Rule   Disable the GNOME3 Login User List   [ref]

In the default graphical environment, users logging directly into the system are greeted with a login screen that displays all known users. This functionality should be disabled by setting disable-user-list to true.

To disable, add or edit disable-user-list to /etc/dconf/db/gdm.d/00-security-settings. For example:
[org/gnome/login-screen]
disable-user-list=true
Once the setting has been added, add a lock to /etc/dconf/db/gdm.d/locks/00-security-settings-lock to prevent user modification. For example:
/org/gnome/login-screen/disable-user-list
After the settings have been set, run dconf update.
Rationale:
Leaving the user list enabled is a security risk since it allows anyone with physical access to the system to quickly enumerate known user accounts without logging in.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_dconf_gnome_disable_user_list
References:
disaCCI-000366
nistCM-6(a), AC-23
os-srgSRG-OS-000480-GPOS-00227
cis1.7.3

# Remediation is applicable only in certain platforms
if dpkg-query --show --showformat='${db:Status-Status}\n' 'gdm3' 2>/dev/null | grep -q installed && { [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; }; then

mkdir -p /etc/dconf/profile
dconf_profile_path=/etc/dconf/profile/user

[[ -s "${dconf_profile_path}" ]] || echo > "${dconf_profile_path}"

if ! grep -Pzq "(?s)^\s*user-db:user.*\n\s*system-db:local" "${dconf_profile_path}"; then
    sed -i --follow-symlinks "1s/^/user-db:user\nsystem-db:local\n/" "${dconf_profile_path}"
fi

# Make sure the corresponding directories exist
mkdir -p /etc/dconf/db/local.d

# Make sure permissions allow regular users to read dconf settings.
# Also define the umask to avoid `dconf update` changing permissions.
chmod -R u=rwX,go=rX /etc/dconf/profile
(umask 0022 && dconf update)
mkdir -p /etc/dconf/profile
dconf_profile_path=/etc/dconf/profile/gdm

[[ -s "${dconf_profile_path}" ]] || echo > "${dconf_profile_path}"

if ! grep -Pzq "(?s)^\s*user-db:user.*\n\s*system-db:gdm" "${dconf_profile_path}"; then
    sed -i --follow-symlinks "1s/^/user-db:user\nsystem-db:gdm\n/" "${dconf_profile_path}"
fi

# Make sure the corresponding directories exist
mkdir -p /etc/dconf/db/gdm.d

# Make sure permissions allow regular users to read dconf settings.
# Also define the umask to avoid `dconf update` changing permissions.
chmod -R u=rwX,go=rX /etc/dconf/profile
(umask 0022 && dconf update)


# Check for setting in any of the DConf db directories
# If files contain ibus or distro, ignore them.
# The assignment assumes that individual filenames don't contain :
readarray -t SETTINGSFILES < <(grep -r "\\[org/gnome/login-screen\\]" "/etc/dconf/db/" \
                                | grep -v 'distro\|ibus\|gdm.d' | cut -d":" -f1)
DCONFFILE="/etc/dconf/db/gdm.d/00-security-settings"
DBDIR="/etc/dconf/db/gdm.d"

mkdir -p "${DBDIR}"

# Comment out the configurations in databases different from the target one
if [ "${#SETTINGSFILES[@]}" -ne 0 ]
then
    if grep -q "^\\s*disable-user-list\\s*=" "${SETTINGSFILES[@]}"
    then
        
        sed -Ei "s/(^\s*)disable-user-list(\s*=)/#\1disable-user-list\2/g" "${SETTINGSFILES[@]}"
    fi
fi

[ ! -z "${DCONFFILE}" ] && echo "" >> "${DCONFFILE}"
if ! grep -q "\\[org/gnome/login-screen\\]" "${DCONFFILE}"
then
    printf '%s\n' "[org/gnome/login-screen]" >> ${DCONFFILE}
fi

escaped_value="$(sed -e 's/\\/\\\\/g' <<< "true")"
if grep -q "^\\s*disable-user-list\\s*=" "${DCONFFILE}"
then
        sed -i "s/\\s*disable-user-list\\s*=\\s*.*/disable-user-list=${escaped_value}/g" "${DCONFFILE}"
    else
        sed -i "\\|\\[org/gnome/login-screen\\]|a\\disable-user-list=${escaped_value}" "${DCONFFILE}"
fi
# Make sure permissions allow regular users to read dconf settings.
# Also define the umask to avoid `dconf update` changing permissions.
chmod -R u=rwX,go=rX /etc/dconf/db
(umask 0022 && dconf update)
# Check for setting in any of the DConf db directories
LOCKFILES=$(grep -r "^/org/gnome/login-screen/disable-user-list$" "/etc/dconf/db/" \
            | grep -v 'distro\|ibus\|gdm.d' | grep ":" | cut -d":" -f1)
LOCKSFOLDER="/etc/dconf/db/gdm.d/locks"

mkdir -p "${LOCKSFOLDER}"

# Comment out the configurations in databases different from the target one
if [[ ! -z "${LOCKFILES}" ]]
then
    sed -i -E "s|^/org/gnome/login-screen/disable-user-list$|#&|" "${LOCKFILES[@]}"
fi

if ! grep -qr "^/org/gnome/login-screen/disable-user-list$" /etc/dconf/db/gdm.d/
then
    echo "/org/gnome/login-screen/disable-user-list" >> "/etc/dconf/db/gdm.d/locks/00-security-settings-lock"
fi
# Make sure permissions allow regular users to read dconf settings.
# Also define the umask to avoid `dconf update` changing permissions.
chmod -R u=rwX,go=rX /etc/dconf/db
(umask 0022 && dconf update)

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

Rule   Disable XDMCP in GDM   [ref]

XDMCP is an unencrypted protocol, and therefore, presents a security risk, see e.g. XDMCP Gnome docs. To disable XDMCP support in Gnome, set Enable to false under the [xdmcp] configuration section in /etc/gdm/custom.conf. For example:
[xdmcp]
Enable=false
Rationale:
XDMCP provides unencrypted remote access through the Gnome Display Manager (GDM) which does not provide for the confidentiality and integrity of user passwords or the remote session. If a privileged user were to login using XDMCP, the privileged user password could be compromised due to typed XEvents and keystrokes will traversing over the network in clear text.
Severity: 
high
Rule ID:xccdf_org.ssgproject.content_rule_gnome_gdm_disable_xdmcp
References:
cis1.7.10

# Remediation is applicable only in certain platforms
if dpkg-query --show --showformat='${db:Status-Status}\n' 'gdm3' 2>/dev/null | grep -q installed; then

# Try find '[xdmcp]' and 'Enable' in '/etc/gdm3/custom.conf', if it exists, set
# to 'false', if it isn't here, add it, if '[xdmcp]' doesn't exist, add it there
if grep -qzosP '[[:space:]]*\[xdmcp]([^\n\[]*\n+)+?[[:space:]]*Enable' '/etc/gdm3/custom.conf'; then
    
    sed -i "s/Enable[^(\n)]*/Enable=false/" '/etc/gdm3/custom.conf'
elif grep -qs '[[:space:]]*\[xdmcp]' '/etc/gdm3/custom.conf'; then
    sed -i "/[[:space:]]*\[xdmcp]/a Enable=false" '/etc/gdm3/custom.conf'
else
    if test -d "/etc/gdm3"; then
        printf '%s\n' '[xdmcp]' "Enable=false" >> '/etc/gdm3/custom.conf'
    else
        echo "Config file directory '/etc/gdm3' doesnt exist, not remediating, assuming non-applicability." >&2
    fi
fi

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi
Group   GNOME Media Settings   Group contains 1 rule
[ref]   GNOME media settings that apply to the graphical interface.

Rule   Disable GNOME3 Automount running   [ref]

The system's default desktop environment, GNOME3, will mount devices and removable media (such as DVDs, CDs and USB flash drives) whenever they are inserted into the system. To disable autorun-never within GNOME3, add or set autorun-never to true in /etc/dconf/db/local.d/00-security-settings. For example:
[org/gnome/desktop/media-handling]
autorun-never=true
Once the settings have been added, add a lock to /etc/dconf/db/local.d/locks/00-security-settings-lock to prevent user modification. For example:
/org/gnome/desktop/media-handling/autorun-never
After the settings have been set, run dconf update.
Rationale:
Automatically mounting file systems permits easy introduction of unknown devices, thereby facilitating malicious activity. Disabling automatic mount running in GNOME3 can prevent the introduction of malware via removable media. It will, however, also prevent desktop users from legitimate use of removable media.
Severity: 
low
Rule ID:xccdf_org.ssgproject.content_rule_dconf_gnome_disable_autorun
References:
cis-csc12, 16
cobit5APO13.01, DSS01.04, DSS05.03, DSS05.04, DSS05.05, DSS05.07, DSS06.03
cui3.1.7
disaCCI-000366, CCI-001764, CCI-001958, CCI-000778
isa-62443-20094.3.3.2.2, 4.3.3.5.2, 4.3.3.6.6, 4.3.3.7.2, 4.3.3.7.4
isa-62443-2013SR 1.1, SR 1.13, SR 1.2, SR 1.4, SR 1.5, SR 1.9, SR 2.1, SR 2.6
iso27001-2013A.11.2.6, A.13.1.1, A.13.2.1, A.6.2.1, A.6.2.2, A.7.1.1, A.9.2.1
nistCM-7(a), CM-7(b), CM-6(a)
nist-csfPR.AC-3, PR.AC-6
os-srgSRG-OS-000114-GPOS-00059, SRG-OS-000378-GPOS-00163, SRG-OS-000480-GPOS-00227
cis1.7.8, 1.7.9

# Remediation is applicable only in certain platforms
if dpkg-query --show --showformat='${db:Status-Status}\n' 'gdm3' 2>/dev/null | grep -q installed && { [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; }; then

mkdir -p /etc/dconf/profile
dconf_profile_path=/etc/dconf/profile/user

[[ -s "${dconf_profile_path}" ]] || echo > "${dconf_profile_path}"

if ! grep -Pzq "(?s)^\s*user-db:user.*\n\s*system-db:local" "${dconf_profile_path}"; then
    sed -i --follow-symlinks "1s/^/user-db:user\nsystem-db:local\n/" "${dconf_profile_path}"
fi

# Make sure the corresponding directories exist
mkdir -p /etc/dconf/db/local.d

# Make sure permissions allow regular users to read dconf settings.
# Also define the umask to avoid `dconf update` changing permissions.
chmod -R u=rwX,go=rX /etc/dconf/profile
(umask 0022 && dconf update)
mkdir -p /etc/dconf/profile
dconf_profile_path=/etc/dconf/profile/gdm

[[ -s "${dconf_profile_path}" ]] || echo > "${dconf_profile_path}"

if ! grep -Pzq "(?s)^\s*user-db:user.*\n\s*system-db:gdm" "${dconf_profile_path}"; then
    sed -i --follow-symlinks "1s/^/user-db:user\nsystem-db:gdm\n/" "${dconf_profile_path}"
fi

# Make sure the corresponding directories exist
mkdir -p /etc/dconf/db/gdm.d

# Make sure permissions allow regular users to read dconf settings.
# Also define the umask to avoid `dconf update` changing permissions.
chmod -R u=rwX,go=rX /etc/dconf/profile
(umask 0022 && dconf update)


# Check for setting in any of the DConf db directories
# If files contain ibus or distro, ignore them.
# The assignment assumes that individual filenames don't contain :
readarray -t SETTINGSFILES < <(grep -r "\\[org/gnome/desktop/media-handling\\]" "/etc/dconf/db/" \
                                | grep -v 'distro\|ibus\|local.d' | cut -d":" -f1)
DCONFFILE="/etc/dconf/db/local.d/00-security-settings"
DBDIR="/etc/dconf/db/local.d"

mkdir -p "${DBDIR}"

# Comment out the configurations in databases different from the target one
if [ "${#SETTINGSFILES[@]}" -ne 0 ]
then
    if grep -q "^\\s*autorun-never\\s*=" "${SETTINGSFILES[@]}"
    then
        
        sed -Ei "s/(^\s*)autorun-never(\s*=)/#\1autorun-never\2/g" "${SETTINGSFILES[@]}"
    fi
fi

[ ! -z "${DCONFFILE}" ] && echo "" >> "${DCONFFILE}"
if ! grep -q "\\[org/gnome/desktop/media-handling\\]" "${DCONFFILE}"
then
    printf '%s\n' "[org/gnome/desktop/media-handling]" >> ${DCONFFILE}
fi

escaped_value="$(sed -e 's/\\/\\\\/g' <<< "true")"
if grep -q "^\\s*autorun-never\\s*=" "${DCONFFILE}"
then
        sed -i "s/\\s*autorun-never\\s*=\\s*.*/autorun-never=${escaped_value}/g" "${DCONFFILE}"
    else
        sed -i "\\|\\[org/gnome/desktop/media-handling\\]|a\\autorun-never=${escaped_value}" "${DCONFFILE}"
fi
# Make sure permissions allow regular users to read dconf settings.
# Also define the umask to avoid `dconf update` changing permissions.
chmod -R u=rwX,go=rX /etc/dconf/db
(umask 0022 && dconf update)
# Check for setting in any of the DConf db directories
LOCKFILES=$(grep -r "^/org/gnome/desktop/media-handling/autorun-never$" "/etc/dconf/db/" \
            | grep -v 'distro\|ibus\|local.d' | grep ":" | cut -d":" -f1)
LOCKSFOLDER="/etc/dconf/db/local.d/locks"

mkdir -p "${LOCKSFOLDER}"

# Comment out the configurations in databases different from the target one
if [[ ! -z "${LOCKFILES}" ]]
then
    sed -i -E "s|^/org/gnome/desktop/media-handling/autorun-never$|#&|" "${LOCKFILES[@]}"
fi

if ! grep -qr "^/org/gnome/desktop/media-handling/autorun-never$" /etc/dconf/db/local.d/
then
    echo "/org/gnome/desktop/media-handling/autorun-never" >> "/etc/dconf/db/local.d/locks/00-security-settings-lock"
fi
# Make sure permissions allow regular users to read dconf settings.
# Also define the umask to avoid `dconf update` changing permissions.
chmod -R u=rwX,go=rX /etc/dconf/db
(umask 0022 && dconf update)

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi
Group   Configure GNOME Screen Locking   Group contains 3 rules
[ref]   In the default GNOME3 desktop, the screen can be locked by selecting the user name in the far right corner of the main panel and selecting Lock.

The following sections detail commands to enforce idle activation of the screensaver, screen locking, a blank-screen screensaver, and an idle activation time.

Because users should be trained to lock the screen when they step away from the computer, the automatic locking feature is only meant as a backup.

The root account can be screen-locked; however, the root account should never be used to log into an X Windows environment and should only be used to for direct login via console in emergency circumstances.

For more information about enforcing preferences in the GNOME3 environment using the DConf configuration system, see http://wiki.gnome.org/dconf and the man page dconf(1).

Rule   Set GNOME3 Screensaver Inactivity Timeout   [ref]

The idle time-out value for inactivity in the GNOME3 desktop is configured via the idle-delay setting must be set under an appropriate configuration file(s) in the /etc/dconf/db/local.d directory and locked in /etc/dconf/db/local.d/locks directory to prevent user modification.

For example, to configure the system for a 15 minute delay, add the following to /etc/dconf/db/local.d/00-security-settings:
[org/gnome/desktop/session]
idle-delay=uint32 900
Rationale:
A session time-out lock is a temporary action taken when a user stops work and moves away from the immediate physical vicinity of the information system but does not logout because of the temporary nature of the absence. Rather than relying on the user to manually lock their operating system session prior to vacating the vicinity, GNOME3 can be configured to identify when a user's session has idled and take action to initiate a session lock.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_dconf_gnome_screensaver_idle_delay
References:
cis-csc1, 12, 15, 16
cjis5.5.5
cobit5DSS05.04, DSS05.10, DSS06.10
cui3.1.10
disaCCI-000057, CCI-000060
isa-62443-20094.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9
isa-62443-2013SR 1.1, SR 1.10, SR 1.2, SR 1.5, SR 1.7, SR 1.8, SR 1.9
iso27001-2013A.18.1.4, A.9.2.1, A.9.2.4, A.9.3.1, A.9.4.2, A.9.4.3
nistAC-11(a), CM-6(a)
nist-csfPR.AC-7
pcidssReq-8.1.8
os-srgSRG-OS-000029-GPOS-00010, SRG-OS-000031-GPOS-00012
cis1.7.4, 1.7.5
pcidss48.2.8, 8.2

# Remediation is applicable only in certain platforms
if dpkg-query --show --showformat='${db:Status-Status}\n' 'gdm3' 2>/dev/null | grep -q installed && { [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; }; then

mkdir -p /etc/dconf/profile
dconf_profile_path=/etc/dconf/profile/user

[[ -s "${dconf_profile_path}" ]] || echo > "${dconf_profile_path}"

if ! grep -Pzq "(?s)^\s*user-db:user.*\n\s*system-db:local" "${dconf_profile_path}"; then
    sed -i --follow-symlinks "1s/^/user-db:user\nsystem-db:local\n/" "${dconf_profile_path}"
fi

# Make sure the corresponding directories exist
mkdir -p /etc/dconf/db/local.d

# Make sure permissions allow regular users to read dconf settings.
# Also define the umask to avoid `dconf update` changing permissions.
chmod -R u=rwX,go=rX /etc/dconf/profile
(umask 0022 && dconf update)
mkdir -p /etc/dconf/profile
dconf_profile_path=/etc/dconf/profile/gdm

[[ -s "${dconf_profile_path}" ]] || echo > "${dconf_profile_path}"

if ! grep -Pzq "(?s)^\s*user-db:user.*\n\s*system-db:gdm" "${dconf_profile_path}"; then
    sed -i --follow-symlinks "1s/^/user-db:user\nsystem-db:gdm\n/" "${dconf_profile_path}"
fi

# Make sure the corresponding directories exist
mkdir -p /etc/dconf/db/gdm.d

# Make sure permissions allow regular users to read dconf settings.
# Also define the umask to avoid `dconf update` changing permissions.
chmod -R u=rwX,go=rX /etc/dconf/profile
(umask 0022 && dconf update)


inactivity_timeout_value='900'


# Check for setting in any of the DConf db directories
# If files contain ibus or distro, ignore them.
# The assignment assumes that individual filenames don't contain :
readarray -t SETTINGSFILES < <(grep -r "\\[org/gnome/desktop/session\\]" "/etc/dconf/db/" \
                                | grep -v 'distro\|ibus\|local.d' | cut -d":" -f1)
DCONFFILE="/etc/dconf/db/local.d/00-security-settings"
DBDIR="/etc/dconf/db/local.d"

mkdir -p "${DBDIR}"

# Comment out the configurations in databases different from the target one
if [ "${#SETTINGSFILES[@]}" -ne 0 ]
then
    if grep -q "^\\s*idle-delay\\s*=" "${SETTINGSFILES[@]}"
    then
        
        sed -Ei "s/(^\s*)idle-delay(\s*=)/#\1idle-delay\2/g" "${SETTINGSFILES[@]}"
    fi
fi

[ ! -z "${DCONFFILE}" ] && echo "" >> "${DCONFFILE}"
if ! grep -q "\\[org/gnome/desktop/session\\]" "${DCONFFILE}"
then
    printf '%s\n' "[org/gnome/desktop/session]" >> ${DCONFFILE}
fi

escaped_value="$(sed -e 's/\\/\\\\/g' <<< "uint32 ${inactivity_timeout_value}")"
if grep -q "^\\s*idle-delay\\s*=" "${DCONFFILE}"
then
        sed -i "s/\\s*idle-delay\\s*=\\s*.*/idle-delay=${escaped_value}/g" "${DCONFFILE}"
    else
        sed -i "\\|\\[org/gnome/desktop/session\\]|a\\idle-delay=${escaped_value}" "${DCONFFILE}"
fi
# Make sure permissions allow regular users to read dconf settings.
# Also define the umask to avoid `dconf update` changing permissions.
chmod -R u=rwX,go=rX /etc/dconf/db
(umask 0022 && dconf update)

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

Rule   Set GNOME3 Screensaver Lock Delay After Activation Period   [ref]

To activate the locking delay of the screensaver in the GNOME3 desktop when the screensaver is activated, add or set lock-delay to uint32 5 in /etc/dconf/db/local.d/00-security-settings. For example:
[org/gnome/desktop/screensaver]
lock-delay=uint32 5
         
After the settings have been set, run dconf update.
Rationale:
A session lock is a temporary action taken when a user stops work and moves away from the immediate physical vicinity of the information system but does not want to logout because of the temporary nature of the absense.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_dconf_gnome_screensaver_lock_delay
References:
cis-csc1, 12, 15, 16
cobit5DSS05.04, DSS05.10, DSS06.10
cui3.1.10
disaCCI-000057
isa-62443-20094.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9
isa-62443-2013SR 1.1, SR 1.10, SR 1.2, SR 1.5, SR 1.7, SR 1.8, SR 1.9
iso27001-2013A.18.1.4, A.9.2.1, A.9.2.4, A.9.3.1, A.9.4.2, A.9.4.3
nistAC-11(a), CM-6(a)
nist-csfPR.AC-7
pcidssReq-8.1.8
os-srgSRG-OS-000029-GPOS-00010, SRG-OS-000031-GPOS-00012
cis1.7.4, 1.7.5
pcidss48.2.8, 8.2

# Remediation is applicable only in certain platforms
if dpkg-query --show --showformat='${db:Status-Status}\n' 'gdm3' 2>/dev/null | grep -q installed && { [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; }; then

mkdir -p /etc/dconf/profile
dconf_profile_path=/etc/dconf/profile/user

[[ -s "${dconf_profile_path}" ]] || echo > "${dconf_profile_path}"

if ! grep -Pzq "(?s)^\s*user-db:user.*\n\s*system-db:local" "${dconf_profile_path}"; then
    sed -i --follow-symlinks "1s/^/user-db:user\nsystem-db:local\n/" "${dconf_profile_path}"
fi

# Make sure the corresponding directories exist
mkdir -p /etc/dconf/db/local.d

# Make sure permissions allow regular users to read dconf settings.
# Also define the umask to avoid `dconf update` changing permissions.
chmod -R u=rwX,go=rX /etc/dconf/profile
(umask 0022 && dconf update)
mkdir -p /etc/dconf/profile
dconf_profile_path=/etc/dconf/profile/gdm

[[ -s "${dconf_profile_path}" ]] || echo > "${dconf_profile_path}"

if ! grep -Pzq "(?s)^\s*user-db:user.*\n\s*system-db:gdm" "${dconf_profile_path}"; then
    sed -i --follow-symlinks "1s/^/user-db:user\nsystem-db:gdm\n/" "${dconf_profile_path}"
fi

# Make sure the corresponding directories exist
mkdir -p /etc/dconf/db/gdm.d

# Make sure permissions allow regular users to read dconf settings.
# Also define the umask to avoid `dconf update` changing permissions.
chmod -R u=rwX,go=rX /etc/dconf/profile
(umask 0022 && dconf update)


var_screensaver_lock_delay='5'


# Check for setting in any of the DConf db directories
# If files contain ibus or distro, ignore them.
# The assignment assumes that individual filenames don't contain :
readarray -t SETTINGSFILES < <(grep -r "\\[org/gnome/desktop/screensaver\\]" "/etc/dconf/db/" \
                                | grep -v 'distro\|ibus\|local.d' | cut -d":" -f1)
DCONFFILE="/etc/dconf/db/local.d/00-security-settings"
DBDIR="/etc/dconf/db/local.d"

mkdir -p "${DBDIR}"

# Comment out the configurations in databases different from the target one
if [ "${#SETTINGSFILES[@]}" -ne 0 ]
then
    if grep -q "^\\s*lock-delay\\s*=" "${SETTINGSFILES[@]}"
    then
        
        sed -Ei "s/(^\s*)lock-delay(\s*=)/#\1lock-delay\2/g" "${SETTINGSFILES[@]}"
    fi
fi

[ ! -z "${DCONFFILE}" ] && echo "" >> "${DCONFFILE}"
if ! grep -q "\\[org/gnome/desktop/screensaver\\]" "${DCONFFILE}"
then
    printf '%s\n' "[org/gnome/desktop/screensaver]" >> ${DCONFFILE}
fi

escaped_value="$(sed -e 's/\\/\\\\/g' <<< "uint32 ${var_screensaver_lock_delay}")"
if grep -q "^\\s*lock-delay\\s*=" "${DCONFFILE}"
then
        sed -i "s/\\s*lock-delay\\s*=\\s*.*/lock-delay=${escaped_value}/g" "${DCONFFILE}"
    else
        sed -i "\\|\\[org/gnome/desktop/screensaver\\]|a\\lock-delay=${escaped_value}" "${DCONFFILE}"
fi
# Make sure permissions allow regular users to read dconf settings.
# Also define the umask to avoid `dconf update` changing permissions.
chmod -R u=rwX,go=rX /etc/dconf/db
(umask 0022 && dconf update)

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

Rule   Enable GNOME3 Screensaver Lock After Idle Period   [ref]

To activate locking of the screensaver in the GNOME3 desktop when it is activated, add or set lock-enabled to true in /etc/dconf/db/local.d/00-security-settings. For example:
[org/gnome/desktop/screensaver]
lock-enabled=true
Once the settings have been added, add a lock to /etc/dconf/db/local.d/locks/00-security-settings-lock to prevent user modification. For example:
/org/gnome/desktop/screensaver/lock-enabled
After the settings have been set, run dconf update.
Rationale:
A session lock is a temporary action taken when a user stops work and moves away from the immediate physical vicinity of the information system but does not want to logout because of the temporary nature of the absense.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_dconf_gnome_screensaver_lock_enabled
References:
cis-csc1, 12, 15, 16
cjis5.5.5
cobit5DSS05.04, DSS05.10, DSS06.10
cui3.1.10
disaCCI-000057, CCI-000056
isa-62443-20094.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9
isa-62443-2013SR 1.1, SR 1.10, SR 1.2, SR 1.5, SR 1.7, SR 1.8, SR 1.9
iso27001-2013A.18.1.4, A.9.2.1, A.9.2.4, A.9.3.1, A.9.4.2, A.9.4.3
nistCM-6(a)
nist-csfPR.AC-7
pcidssReq-8.1.8
os-srgSRG-OS-000028-GPOS-00009, SRG-OS-000030-GPOS-00011
cis1.7.4, 1.7.5
pcidss48.2.8, 8.2

# Remediation is applicable only in certain platforms
if dpkg-query --show --showformat='${db:Status-Status}\n' 'gdm3' 2>/dev/null | grep -q installed && { [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; }; then

mkdir -p /etc/dconf/profile
dconf_profile_path=/etc/dconf/profile/user

[[ -s "${dconf_profile_path}" ]] || echo > "${dconf_profile_path}"

if ! grep -Pzq "(?s)^\s*user-db:user.*\n\s*system-db:local" "${dconf_profile_path}"; then
    sed -i --follow-symlinks "1s/^/user-db:user\nsystem-db:local\n/" "${dconf_profile_path}"
fi

# Make sure the corresponding directories exist
mkdir -p /etc/dconf/db/local.d

# Make sure permissions allow regular users to read dconf settings.
# Also define the umask to avoid `dconf update` changing permissions.
chmod -R u=rwX,go=rX /etc/dconf/profile
(umask 0022 && dconf update)
mkdir -p /etc/dconf/profile
dconf_profile_path=/etc/dconf/profile/gdm

[[ -s "${dconf_profile_path}" ]] || echo > "${dconf_profile_path}"

if ! grep -Pzq "(?s)^\s*user-db:user.*\n\s*system-db:gdm" "${dconf_profile_path}"; then
    sed -i --follow-symlinks "1s/^/user-db:user\nsystem-db:gdm\n/" "${dconf_profile_path}"
fi

# Make sure the corresponding directories exist
mkdir -p /etc/dconf/db/gdm.d

# Make sure permissions allow regular users to read dconf settings.
# Also define the umask to avoid `dconf update` changing permissions.
chmod -R u=rwX,go=rX /etc/dconf/profile
(umask 0022 && dconf update)



# Check for setting in any of the DConf db directories
# If files contain ibus or distro, ignore them.
# The assignment assumes that individual filenames don't contain :
readarray -t SETTINGSFILES < <(grep -r "\\[org/gnome/desktop/screensaver\\]" "/etc/dconf/db/" \
                                | grep -v 'distro\|ibus\|local.d' | cut -d":" -f1)
DCONFFILE="/etc/dconf/db/local.d/00-security-settings"
DBDIR="/etc/dconf/db/local.d"

mkdir -p "${DBDIR}"

# Comment out the configurations in databases different from the target one
if [ "${#SETTINGSFILES[@]}" -ne 0 ]
then
    if grep -q "^\\s*lock-enabled\\s*=" "${SETTINGSFILES[@]}"
    then
        
        sed -Ei "s/(^\s*)lock-enabled(\s*=)/#\1lock-enabled\2/g" "${SETTINGSFILES[@]}"
    fi
fi

[ ! -z "${DCONFFILE}" ] && echo "" >> "${DCONFFILE}"
if ! grep -q "\\[org/gnome/desktop/screensaver\\]" "${DCONFFILE}"
then
    printf '%s\n' "[org/gnome/desktop/screensaver]" >> ${DCONFFILE}
fi

escaped_value="$(sed -e 's/\\/\\\\/g' <<< "true")"
if grep -q "^\\s*lock-enabled\\s*=" "${DCONFFILE}"
then
        sed -i "s/\\s*lock-enabled\\s*=\\s*.*/lock-enabled=${escaped_value}/g" "${DCONFFILE}"
    else
        sed -i "\\|\\[org/gnome/desktop/screensaver\\]|a\\lock-enabled=${escaped_value}" "${DCONFFILE}"
fi
# Make sure permissions allow regular users to read dconf settings.
# Also define the umask to avoid `dconf update` changing permissions.
chmod -R u=rwX,go=rX /etc/dconf/db
(umask 0022 && dconf update)
# Check for setting in any of the DConf db directories
LOCKFILES=$(grep -r "^/org/gnome/desktop/screensaver/lock-enabled$" "/etc/dconf/db/" \
            | grep -v 'distro\|ibus\|local.d' | grep ":" | cut -d":" -f1)
LOCKSFOLDER="/etc/dconf/db/local.d/locks"

mkdir -p "${LOCKSFOLDER}"

# Comment out the configurations in databases different from the target one
if [[ ! -z "${LOCKFILES}" ]]
then
    sed -i -E "s|^/org/gnome/desktop/screensaver/lock-enabled$|#&|" "${LOCKFILES[@]}"
fi

if ! grep -qr "^/org/gnome/desktop/screensaver/lock-enabled$" /etc/dconf/db/local.d/
then
    echo "/org/gnome/desktop/screensaver/lock-enabled" >> "/etc/dconf/db/local.d/locks/00-security-settings-lock"
fi
# Make sure permissions allow regular users to read dconf settings.
# Also define the umask to avoid `dconf update` changing permissions.
chmod -R u=rwX,go=rX /etc/dconf/db
(umask 0022 && dconf update)

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi
Group   Sudo   Group contains 4 rules
[ref]   Sudo, which stands for "su 'do'", provides the ability to delegate authority to certain users, groups of users, or system administrators. When configured for system users and/or groups, Sudo can allow a user or group to execute privileged commands that normally only root is allowed to execute.

For more information on Sudo and addition Sudo configuration options, see https://www.sudo.ws.

Rule   Install sudo Package   [ref]

The sudo package can be installed with the following command:
$ apt-get install sudo
Rationale:
sudo is a program designed to allow a system administrator to give limited root privileges to users and log root activity. The basic philosophy is to give as few privileges as possible but still allow system users to get their work done.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_package_sudo_installed
References:
disaCCI-002235
ism1382, 1384, 1386
nistCM-6(a)
osppFMT_MOF_EXT.1
os-srgSRG-OS-000324-GPOS-00125
anssiR33
cis5.2.1
pcidss42.2.6, 2.2

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

class install_sudo {
  package { 'sudo':
    ensure => 'installed',
  }
}

Complexity:low
Disruption:low
Reboot:false
Strategy:enable
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - NIST-800-53-CM-6(a)
  - PCI-DSSv4-2.2
  - PCI-DSSv4-2.2.6
  - enable_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - package_sudo_installed

- name: Ensure sudo is installed
  package:
    name: sudo
    state: present
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-53-CM-6(a)
  - PCI-DSSv4-2.2
  - PCI-DSSv4-2.2.6
  - enable_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - package_sudo_installed


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

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

DEBIAN_FRONTEND=noninteractive apt-get install -y "sudo"

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

Rule   Ensure Sudo Logfile Exists - sudo logfile   [ref]

A custom log sudo file can be configured with the 'logfile' tag. This rule configures a sudo custom logfile at the default location suggested by CIS, which uses /var/log/sudo.log.
Rationale:
A sudo log file simplifies auditing of sudo commands.
Severity: 
low
Rule ID:xccdf_org.ssgproject.content_rule_sudo_custom_logfile
References:
pcidssReq-10.2.5
cis5.2.3
pcidss42.2.6, 2.2

Complexity:low
Disruption:low
Reboot:false
Strategy:restrict
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - PCI-DSS-Req-10.2.5
  - PCI-DSSv4-2.2
  - PCI-DSSv4-2.2.6
  - low_complexity
  - low_disruption
  - low_severity
  - no_reboot_needed
  - restrict_strategy
  - sudo_custom_logfile
- name: XCCDF Value var_sudo_logfile # promote to variable
  set_fact:
    var_sudo_logfile: !!str /var/log/sudo.log
  tags:
    - always

- name: Ensure logfile is enabled with the appropriate value in /etc/sudoers
  lineinfile:
    path: /etc/sudoers
    regexp: ^[\s]*Defaults\s(.*)\blogfile=[-]?.+\b(.*)$
    line: Defaults \1logfile={{ var_sudo_logfile }}\2
    validate: /usr/sbin/visudo -cf %s
    backrefs: true
  register: edit_sudoers_logfile_option
  when: '"sudo" in ansible_facts.packages'
  tags:
  - PCI-DSS-Req-10.2.5
  - PCI-DSSv4-2.2
  - PCI-DSSv4-2.2.6
  - low_complexity
  - low_disruption
  - low_severity
  - no_reboot_needed
  - restrict_strategy
  - sudo_custom_logfile

- name: Enable logfile option with appropriate value in /etc/sudoers
  lineinfile:
    path: /etc/sudoers
    line: Defaults logfile={{ var_sudo_logfile }}
    validate: /usr/sbin/visudo -cf %s
  when:
  - '"sudo" in ansible_facts.packages'
  - edit_sudoers_logfile_option is defined and not edit_sudoers_logfile_option.changed
  tags:
  - PCI-DSS-Req-10.2.5
  - PCI-DSSv4-2.2
  - PCI-DSSv4-2.2.6
  - low_complexity
  - low_disruption
  - low_severity
  - no_reboot_needed
  - restrict_strategy
  - sudo_custom_logfile

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

var_sudo_logfile='/var/log/sudo.log'


if /usr/sbin/visudo -qcf /etc/sudoers; then
    cp /etc/sudoers /etc/sudoers.bak
    if ! grep -P '^[\s]*Defaults[\s]*\blogfile\s*=\s*(?:"?([^",\s]+)"?)\b.*$' /etc/sudoers; then
        # sudoers file doesn't define Option logfile
        echo "Defaults logfile=${var_sudo_logfile}" >> /etc/sudoers
    else
        # sudoers file defines Option logfile, remediate if appropriate value is not set
        if ! grep -P "^[\s]*Defaults.*\blogfile=${var_sudo_logfile}\b.*$" /etc/sudoers; then
            
            escaped_variable=${var_sudo_logfile//$'/'/$'\/'}
            sed -Ei "s/(^[\s]*Defaults.*\blogfile=)[-]?.+(\b.*$)/\1$escaped_variable\2/" /etc/sudoers
        fi
    fi
    
    # Check validity of sudoers and cleanup bak
    if /usr/sbin/visudo -qcf /etc/sudoers; then
        rm -f /etc/sudoers.bak
    else
        echo "Fail to validate remediated /etc/sudoers, reverting to original file."
        mv /etc/sudoers.bak /etc/sudoers
        false
    fi
else
    echo "Skipping remediation, /etc/sudoers failed to validate"
    false
fi

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

Rule   Ensure Users Re-Authenticate for Privilege Escalation - sudo !authenticate   [ref]

The sudo !authenticate option, when specified, allows a user to execute commands using sudo without having to authenticate. This should be disabled by making sure that the !authenticate option does not exist in /etc/sudoers configuration file or any sudo configuration snippets in /etc/sudoers.d/.
Rationale:
Without re-authentication, users may access resources or perform tasks for which they do not have authorization.

When operating systems provide the capability to escalate a functional capability, it is critical that the user re-authenticate.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_sudo_remove_no_authenticate
References:
cis-csc1, 12, 15, 16, 5
cobit5DSS05.04, DSS05.10, DSS06.03, DSS06.10
disaCCI-004895
isa-62443-20094.3.3.5.1, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9
isa-62443-2013SR 1.1, SR 1.10, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.7, SR 1.8, SR 1.9
iso27001-2013A.18.1.4, A.9.2.1, A.9.2.2, A.9.2.3, A.9.2.4, A.9.2.6, A.9.3.1, A.9.4.2, A.9.4.3
nistIA-11, CM-6(a)
nist-csfPR.AC-1, PR.AC-7
os-srgSRG-OS-000373-GPOS-00156, SRG-OS-000373-GPOS-00157, SRG-OS-000373-GPOS-00158
cis5.2.5

Complexity:low
Disruption:low
Reboot:false
Strategy:restrict
- name: Find /etc/sudoers.d/ files
  ansible.builtin.find:
    paths:
    - /etc/sudoers.d/
  register: sudoers
  tags:
  - NIST-800-53-CM-6(a)
  - NIST-800-53-IA-11
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy
  - sudo_remove_no_authenticate

- name: Remove lines containing !authenticate from sudoers files
  ansible.builtin.replace:
    regexp: (^(?!#).*[\s]+\!authenticate.*$)
    replace: '# \g<1>'
    path: '{{ item.path }}'
    validate: /usr/sbin/visudo -cf %s
  with_items:
  - path: /etc/sudoers
  - '{{ sudoers.files }}'
  tags:
  - NIST-800-53-CM-6(a)
  - NIST-800-53-IA-11
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy
  - sudo_remove_no_authenticate

Complexity:low
Disruption:low
Reboot:false
Strategy:restrict

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

    /usr/sbin/visudo -cf $f &> /dev/null || echo "Fail to validate $f with visudo"
  fi
done

Rule   Require Re-Authentication When Using the sudo Command   [ref]

The sudo timestamp_timeout tag sets the amount of time sudo password prompt waits. The default timestamp_timeout value is 5 minutes. The timestamp_timeout should be configured by making sure that the timestamp_timeout tag exists in /etc/sudoers configuration file or any sudo configuration snippets in /etc/sudoers.d/. If the value is set to an integer less than 0, the user's time stamp will not expire and the user will not have to re-authenticate for privileged actions until the user's session is terminated.
Rationale:
Without re-authentication, users may access resources or perform tasks for which they do not have authorization.

When operating systems provide the capability to escalate a functional capability, it is critical that the user re-authenticate.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_sudo_require_reauthentication
References:
disaCCI-004895
nistIA-11
os-srgSRG-OS-000373-GPOS-00156, SRG-OS-000373-GPOS-00157, SRG-OS-000373-GPOS-00158
cis5.2.6
pcidss42.2.6, 2.2

Complexity:low
Disruption:low
Reboot:false
Strategy:restrict
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - NIST-800-53-IA-11
  - PCI-DSSv4-2.2
  - PCI-DSSv4-2.2.6
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy
  - sudo_require_reauthentication
- name: XCCDF Value var_sudo_timestamp_timeout # promote to variable
  set_fact:
    var_sudo_timestamp_timeout: !!str 15
  tags:
    - always

- name: Require Re-Authentication When Using the sudo Command - Find /etc/sudoers.d/*
    files containing 'Defaults timestamp_timeout'
  ansible.builtin.find:
    path: /etc/sudoers.d
    patterns: '*'
    contains: ^[\s]*Defaults\s.*\btimestamp_timeout[\s]*=.*
  register: sudoers_d_defaults_timestamp_timeout
  when: '"sudo" in ansible_facts.packages'
  tags:
  - NIST-800-53-IA-11
  - PCI-DSSv4-2.2
  - PCI-DSSv4-2.2.6
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy
  - sudo_require_reauthentication

- name: Require Re-Authentication When Using the sudo Command - Remove 'Defaults timestamp_timeout'
    from /etc/sudoers.d/* files
  ansible.builtin.lineinfile:
    path: '{{ item.path }}'
    regexp: ^[\s]*Defaults\s.*\btimestamp_timeout[\s]*=.*
    state: absent
  with_items: '{{ sudoers_d_defaults_timestamp_timeout.files }}'
  when: '"sudo" in ansible_facts.packages'
  tags:
  - NIST-800-53-IA-11
  - PCI-DSSv4-2.2
  - PCI-DSSv4-2.2.6
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy
  - sudo_require_reauthentication

- name: Require Re-Authentication When Using the sudo Command - Ensure timestamp_timeout
    has the appropriate value in /etc/sudoers
  ansible.builtin.lineinfile:
    path: /etc/sudoers
    regexp: ^[\s]*Defaults\s(.*)\btimestamp_timeout[\s]*=[\s]*[-]?\w+\b(.*)$
    line: Defaults \1timestamp_timeout={{ var_sudo_timestamp_timeout }}\2
    validate: /usr/sbin/visudo -cf %s
    backrefs: true
  register: edit_sudoers_timestamp_timeout_option
  when: '"sudo" in ansible_facts.packages'
  tags:
  - NIST-800-53-IA-11
  - PCI-DSSv4-2.2
  - PCI-DSSv4-2.2.6
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy
  - sudo_require_reauthentication

- name: Require Re-Authentication When Using the sudo Command - Enable timestamp_timeout
    option with correct value in /etc/sudoers
  ansible.builtin.lineinfile:
    path: /etc/sudoers
    line: Defaults timestamp_timeout={{ var_sudo_timestamp_timeout }}
    validate: /usr/sbin/visudo -cf %s
  when:
  - '"sudo" in ansible_facts.packages'
  - |
    edit_sudoers_timestamp_timeout_option is defined and not edit_sudoers_timestamp_timeout_option.changed
  tags:
  - NIST-800-53-IA-11
  - PCI-DSSv4-2.2
  - PCI-DSSv4-2.2.6
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy
  - sudo_require_reauthentication

- name: Require Re-Authentication When Using the sudo Command - Remove timestamp_timeout
    wrong values in /etc/sudoers
  ansible.builtin.lineinfile:
    path: /etc/sudoers
    regexp: ^[\s]*Defaults\s.*\btimestamp_timeout[\s]*=[\s]*(?!{{ var_sudo_timestamp_timeout
      }}\b)[-]?\w+\b.*$
    state: absent
    validate: /usr/sbin/visudo -cf %s
  when: '"sudo" in ansible_facts.packages'
  tags:
  - NIST-800-53-IA-11
  - PCI-DSSv4-2.2
  - PCI-DSSv4-2.2.6
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy
  - sudo_require_reauthentication

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

var_sudo_timestamp_timeout='15'


if grep -Px '^[\s]*Defaults.*timestamp_timeout[\s]*=.*' /etc/sudoers.d/*; then
    find /etc/sudoers.d/ -type f -exec sed -Ei "/^[[:blank:]]*Defaults.*timestamp_timeout[[:blank:]]*=.*/d" {} \;
fi

if /usr/sbin/visudo -qcf /etc/sudoers; then
    cp /etc/sudoers /etc/sudoers.bak
    if ! grep -P '^[\s]*Defaults.*timestamp_timeout[\s]*=[\s]*[-]?\w+.*$' /etc/sudoers; then
        # sudoers file doesn't define Option timestamp_timeout
        echo "Defaults timestamp_timeout=${var_sudo_timestamp_timeout}" >> /etc/sudoers
    else
        # sudoers file defines Option timestamp_timeout, remediate wrong values if present
        if grep -qP "^[\s]*Defaults\s.*\btimestamp_timeout[\s]*=[\s]*(?!${var_sudo_timestamp_timeout}\b)[-]?\w+\b.*$" /etc/sudoers; then
            sed -Ei "s/(^[[:blank:]]*Defaults.*timestamp_timeout[[:blank:]]*=)[[:blank:]]*[-]?\w+(.*$)/\1${var_sudo_timestamp_timeout}\2/" /etc/sudoers
        fi
    fi
    
    # Check validity of sudoers and cleanup bak
    if /usr/sbin/visudo -qcf /etc/sudoers; then
        rm -f /etc/sudoers.bak
    else
        echo "Fail to validate remediated /etc/sudoers, reverting to original file."
        mv /etc/sudoers.bak /etc/sudoers
        false
    fi
else
    echo "Skipping remediation, /etc/sudoers failed to validate"
    false
fi

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi
Group   Account and Access Control   Group contains 9 groups and 38 rules
[ref]   In traditional Unix security, if an attacker gains shell access to a certain login account, they can perform any action or access any file to which that account has access. Therefore, making it more difficult for unauthorized people to gain shell access to accounts, particularly to privileged accounts, is a necessary part of securing a system. This section introduces mechanisms for restricting access to accounts under Ubuntu 24.04.
Group   Warning Banners for System Accesses   Group contains 1 group and 13 rules
[ref]   Each system should expose as little information about itself as possible.

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

Many organizations implement security policies that require a system banner provide notice of the system's ownership, provide warning to unauthorized users, and remind authorized users of their consent to monitoring.
Group   Implement a GUI Warning Banner   Group contains 2 rules

Rule   Enable GNOME3 Login Warning Banner   [ref]

In the default graphical environment, displaying a login warning banner in the GNOME Display Manager's login screen can be enabled on the login screen by setting banner-message-enable to true.

To enable, add or edit banner-message-enable to /etc/dconf/db/gdm.d/00-security-settings. For example:
[org/gnome/login-screen]
banner-message-enable=true
Once the setting has been added, add a lock to /etc/dconf/db/gdm.d/locks/00-security-settings-lock to prevent user modification. For example:
/org/gnome/login-screen/banner-message-enable
After the settings have been set, run dconf update. The banner text must also be set.
Rationale:
Display of a standardized and approved use notification before granting access to the operating system ensures privacy and security notification verbiage used is consistent with applicable federal laws, Executive Orders, directives, policies, regulations, standards, and guidance.

For U.S. Government systems, system use notifications are required only for access via login interfaces with human users and are not required when such human interfaces do not exist.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_dconf_gnome_banner_enabled
References:
cis-csc1, 12, 15, 16
cobit5DSS05.04, DSS05.10, DSS06.10
cui3.1.9
disaCCI-001387, CCI-001384, CCI-000048, CCI-001386, CCI-001388, CCI-001385
isa-62443-20094.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9
isa-62443-2013SR 1.1, SR 1.10, SR 1.2, SR 1.5, SR 1.7, SR 1.8, SR 1.9
iso27001-2013A.18.1.4, A.9.2.1, A.9.2.4, A.9.3.1, A.9.4.2, A.9.4.3
nistAC-8(a), AC-8(b), AC-8(c)
nist-csfPR.AC-7
os-srgSRG-OS-000023-GPOS-00006, SRG-OS-000228-GPOS-00088
cis1.7.2

# Remediation is applicable only in certain platforms
if dpkg-query --show --showformat='${db:Status-Status}\n' 'gdm3' 2>/dev/null | grep -q installed; then

mkdir -p /etc/dconf/profile
dconf_profile_path=/etc/dconf/profile/user

[[ -s "${dconf_profile_path}" ]] || echo > "${dconf_profile_path}"

if ! grep -Pzq "(?s)^\s*user-db:user.*\n\s*system-db:local" "${dconf_profile_path}"; then
    sed -i --follow-symlinks "1s/^/user-db:user\nsystem-db:local\n/" "${dconf_profile_path}"
fi

# Make sure the corresponding directories exist
mkdir -p /etc/dconf/db/local.d

# Make sure permissions allow regular users to read dconf settings.
# Also define the umask to avoid `dconf update` changing permissions.
chmod -R u=rwX,go=rX /etc/dconf/profile
(umask 0022 && dconf update)
mkdir -p /etc/dconf/profile
dconf_profile_path=/etc/dconf/profile/gdm

[[ -s "${dconf_profile_path}" ]] || echo > "${dconf_profile_path}"

if ! grep -Pzq "(?s)^\s*user-db:user.*\n\s*system-db:gdm" "${dconf_profile_path}"; then
    sed -i --follow-symlinks "1s/^/user-db:user\nsystem-db:gdm\n/" "${dconf_profile_path}"
fi

# Make sure the corresponding directories exist
mkdir -p /etc/dconf/db/gdm.d

# Make sure permissions allow regular users to read dconf settings.
# Also define the umask to avoid `dconf update` changing permissions.
chmod -R u=rwX,go=rX /etc/dconf/profile
(umask 0022 && dconf update)
# Duplicate the setting also in 'greeter.dconf-defaults' for consistency with
# 'dconf_gnome_login_banner_text' and better alignment with STIG V1R1.
if [ -e "/etc/gdm3/greeter.dconf-defaults" ] ; then
    
    LC_ALL=C sed -i "/^\s*banner\-message\-enable/Id" "/etc/gdm3/greeter.dconf-defaults"
else
    touch "/etc/gdm3/greeter.dconf-defaults"
fi
# make sure file has newline at the end
sed -i -e '$a\' "/etc/gdm3/greeter.dconf-defaults"

cp "/etc/gdm3/greeter.dconf-defaults" "/etc/gdm3/greeter.dconf-defaults.bak"
# Insert after the line matching the regex '\[org/gnome/login-screen\]'
line_number="$(LC_ALL=C grep -n "\[org/gnome/login-screen\]" "/etc/gdm3/greeter.dconf-defaults.bak" | LC_ALL=C sed 's/:.*//g')"
if [ -z "$line_number" ]; then
    # There was no match of '\[org/gnome/login-screen\]', insert at
    # the end of the file.
    printf '%s\n' "banner-message-enable=true" >> "/etc/gdm3/greeter.dconf-defaults"
else
    head -n "$(( line_number ))" "/etc/gdm3/greeter.dconf-defaults.bak" > "/etc/gdm3/greeter.dconf-defaults"
    printf '%s\n' "banner-message-enable=true" >> "/etc/gdm3/greeter.dconf-defaults"
    tail -n "+$(( line_number + 1 ))" "/etc/gdm3/greeter.dconf-defaults.bak" >> "/etc/gdm3/greeter.dconf-defaults"
fi
# Clean up after ourselves.
rm "/etc/gdm3/greeter.dconf-defaults.bak"


# Check for setting in any of the DConf db directories
# If files contain ibus or distro, ignore them.
# The assignment assumes that individual filenames don't contain :
readarray -t SETTINGSFILES < <(grep -r "\\[org/gnome/login-screen\\]" "/etc/dconf/db/" \
                                | grep -v 'distro\|ibus\|gdm.d' | cut -d":" -f1)
DCONFFILE="/etc/dconf/db/gdm.d/00-security-settings"
DBDIR="/etc/dconf/db/gdm.d"

mkdir -p "${DBDIR}"

# Comment out the configurations in databases different from the target one
if [ "${#SETTINGSFILES[@]}" -ne 0 ]
then
    if grep -q "^\\s*banner-message-enable\\s*=" "${SETTINGSFILES[@]}"
    then
        
        sed -Ei "s/(^\s*)banner-message-enable(\s*=)/#\1banner-message-enable\2/g" "${SETTINGSFILES[@]}"
    fi
fi

[ ! -z "${DCONFFILE}" ] && echo "" >> "${DCONFFILE}"
if ! grep -q "\\[org/gnome/login-screen\\]" "${DCONFFILE}"
then
    printf '%s\n' "[org/gnome/login-screen]" >> ${DCONFFILE}
fi

escaped_value="$(sed -e 's/\\/\\\\/g' <<< "true")"
if grep -q "^\\s*banner-message-enable\\s*=" "${DCONFFILE}"
then
        sed -i "s/\\s*banner-message-enable\\s*=\\s*.*/banner-message-enable=${escaped_value}/g" "${DCONFFILE}"
    else
        sed -i "\\|\\[org/gnome/login-screen\\]|a\\banner-message-enable=${escaped_value}" "${DCONFFILE}"
fi
# Make sure permissions allow regular users to read dconf settings.
# Also define the umask to avoid `dconf update` changing permissions.
chmod -R u=rwX,go=rX /etc/dconf/db
(umask 0022 && dconf update)
# Check for setting in any of the DConf db directories
LOCKFILES=$(grep -r "^/org/gnome/login-screen/banner-message-enable$" "/etc/dconf/db/" \
            | grep -v 'distro\|ibus\|gdm.d' | grep ":" | cut -d":" -f1)
LOCKSFOLDER="/etc/dconf/db/gdm.d/locks"

mkdir -p "${LOCKSFOLDER}"

# Comment out the configurations in databases different from the target one
if [[ ! -z "${LOCKFILES}" ]]
then
    sed -i -E "s|^/org/gnome/login-screen/banner-message-enable$|#&|" "${LOCKFILES[@]}"
fi

if ! grep -qr "^/org/gnome/login-screen/banner-message-enable$" /etc/dconf/db/gdm.d/
then
    echo "/org/gnome/login-screen/banner-message-enable" >> "/etc/dconf/db/gdm.d/locks/00-security-settings-lock"
fi
# Make sure permissions allow regular users to read dconf settings.
# Also define the umask to avoid `dconf update` changing permissions.
chmod -R u=rwX,go=rX /etc/dconf/db
(umask 0022 && dconf update)

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

Rule   Ensure Local Login Warning Banner Is Configured Properly   [ref]

To configure the system local login warning banner edit the /etc/issue file. The contents of this file is displayed to users prior to login to local terminals. 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_issue_cis
References:
cis1.6.2

Complexity:low
Disruption:low
Reboot:false
Strategy:restrict
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - banner_etc_issue_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 Local Login Warning Banner Is Configured Properly - Copy using inline
    content
  ansible.builtin.copy:
    content: '{{ cis_banner_text }}'
    dest: /etc/issue
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - banner_etc_issue_cis
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

Complexity:low
Disruption:low
Reboot:false
Strategy:restrict
# Remediation is applicable only in certain platforms
if 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/issue"

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

Rule   Ensure Remote Login Warning Banner Is Configured Properly   [ref]

To configure the system remote login warning banner edit the /etc/issue.net file. The contents of this file is displayed to users prior to login from remote connections. 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_issue_net_cis
References:
cis1.6.3

Complexity:low
Disruption:low
Reboot:false
Strategy:restrict
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - banner_etc_issue_net_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 Remote Login Warning Banner Is Configured Properly - Copy using inline
    content
  ansible.builtin.copy:
    content: '{{ cis_banner_text }}'
    dest: /etc/issue.net
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - banner_etc_issue_net_cis
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

Complexity:low
Disruption:low
Reboot:false
Strategy:restrict
# Remediation is applicable only in certain platforms
if 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/issue.net"

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

Rule   Verify Group Ownership of System Login Banner   [ref]

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

Complexity:low
Disruption:low
Reboot:false
Strategy:configure
- name: Test for existence /etc/issue
  stat:
    path: /etc/issue
  register: file_exists
  tags:
  - configure_strategy
  - file_groupowner_etc_issue
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed

- name: Ensure group owner 0 on /etc/issue
  file:
    path: /etc/issue
    group: '0'
  when: file_exists.stat is defined and file_exists.stat.exists
  tags:
  - configure_strategy
  - file_groupowner_etc_issue
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed

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

Rule   Verify Group Ownership of System Login Banner for Remote Connections   [ref]

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

Complexity:low
Disruption:low
Reboot:false
Strategy:configure
- name: Test for existence /etc/issue.net
  stat:
    path: /etc/issue.net
  register: file_exists
  tags:
  - PCI-DSSv4-1.2
  - PCI-DSSv4-1.2.8
  - configure_strategy
  - file_groupowner_etc_issue_net
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed

- name: Ensure group owner 0 on /etc/issue.net
  file:
    path: /etc/issue.net
    group: '0'
  when: file_exists.stat is defined and file_exists.stat.exists
  tags:
  - PCI-DSSv4-1.2
  - PCI-DSSv4-1.2.8
  - configure_strategy
  - file_groupowner_etc_issue_net
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed

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

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

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

Complexity:low
Disruption:low
Reboot:false
Strategy:configure
- name: Test for existence /etc/motd
  stat:
    path: /etc/motd
  register: file_exists
  tags:
  - configure_strategy
  - file_groupowner_etc_motd
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed

- name: Ensure group owner 0 on /etc/motd
  file:
    path: /etc/motd
    group: '0'
  when: file_exists.stat is defined and file_exists.stat.exists
  tags:
  - configure_strategy
  - file_groupowner_etc_motd
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed

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

Rule   Verify ownership of System Login Banner   [ref]

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

Complexity:low
Disruption:low
Reboot:false
Strategy:configure
- name: Test for existence /etc/issue
  stat:
    path: /etc/issue
  register: file_exists
  tags:
  - configure_strategy
  - file_owner_etc_issue
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed

- name: Ensure owner 0 on /etc/issue
  file:
    path: /etc/issue
    owner: '0'
  when: file_exists.stat is defined and file_exists.stat.exists
  tags:
  - configure_strategy
  - file_owner_etc_issue
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed

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

Rule   Verify ownership of System Login Banner for Remote Connections   [ref]

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

Complexity:low
Disruption:low
Reboot:false
Strategy:configure
- name: Test for existence /etc/issue.net
  stat:
    path: /etc/issue.net
  register: file_exists
  tags:
  - PCI-DSSv4-1.2
  - PCI-DSSv4-1.2.8
  - configure_strategy
  - file_owner_etc_issue_net
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed

- name: Ensure owner 0 on /etc/issue.net
  file:
    path: /etc/issue.net
    owner: '0'
  when: file_exists.stat is defined and file_exists.stat.exists
  tags:
  - PCI-DSSv4-1.2
  - PCI-DSSv4-1.2.8
  - configure_strategy
  - file_owner_etc_issue_net
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed

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

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

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

Complexity:low
Disruption:low
Reboot:false
Strategy:configure
- name: Test for existence /etc/motd
  stat:
    path: /etc/motd
  register: file_exists
  tags:
  - configure_strategy
  - file_owner_etc_motd
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed

- name: Ensure owner 0 on /etc/motd
  file:
    path: /etc/motd
    owner: '0'
  when: file_exists.stat is defined and file_exists.stat.exists
  tags:
  - configure_strategy
  - file_owner_etc_motd
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed

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

Rule   Verify permissions on System Login Banner   [ref]

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

Complexity:low
Disruption:low
Reboot:false
Strategy:configure
- name: Test for existence /etc/issue
  stat:
    path: /etc/issue
  register: file_exists
  tags:
  - configure_strategy
  - file_permissions_etc_issue
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed

- name: Ensure permission u-xs,g-xws,o-xwt on /etc/issue
  file:
    path: /etc/issue
    mode: u-xs,g-xws,o-xwt
  when: file_exists.stat is defined and file_exists.stat.exists
  tags:
  - configure_strategy
  - file_permissions_etc_issue
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed

Complexity:low
Disruption:low
Reboot:false
Strategy:configure




chmod u-xs,g-xws,o-xwt /etc/issue

Rule   Verify permissions on System Login Banner for Remote Connections   [ref]

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

Complexity:low
Disruption:low
Reboot:false
Strategy:configure
- name: Test for existence /etc/issue.net
  stat:
    path: /etc/issue.net
  register: file_exists
  tags:
  - PCI-DSSv4-1.2
  - PCI-DSSv4-1.2.8
  - configure_strategy
  - file_permissions_etc_issue_net
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed

- name: Ensure permission u-xs,g-xws,o-xwt on /etc/issue.net
  file:
    path: /etc/issue.net
    mode: u-xs,g-xws,o-xwt
  when: file_exists.stat is defined and file_exists.stat.exists
  tags:
  - PCI-DSSv4-1.2
  - PCI-DSSv4-1.2.8
  - configure_strategy
  - file_permissions_etc_issue_net
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed

Complexity:low
Disruption:low
Reboot:false
Strategy:configure




chmod u-xs,g-xws,o-xwt /etc/issue.net

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

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

Complexity:low
Disruption:low
Reboot:false
Strategy:configure
- name: Test for existence /etc/motd
  stat:
    path: /etc/motd
  register: file_exists
  tags:
  - configure_strategy
  - file_permissions_etc_motd
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed

- name: Ensure permission u-xs,g-xws,o-xwt on /etc/motd
  file:
    path: /etc/motd
    mode: u-xs,g-xws,o-xwt
  when: file_exists.stat is defined and file_exists.stat.exists
  tags:
  - configure_strategy
  - file_permissions_etc_motd
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed

Complexity:low
Disruption:low
Reboot:false
Strategy:configure




chmod u-xs,g-xws,o-xwt /etc/motd
Group   Protect Accounts by Restricting Password-Based Login   Group contains 4 groups and 17 rules
[ref]   Conventionally, Unix shell accounts are accessed by providing a username and password to a login program, which tests these values for correctness using the /etc/passwd and /etc/shadow files. Password-based login is vulnerable to guessing of weak passwords, and to sniffing and man-in-the-middle attacks against passwords entered over a network or at an insecure console. Therefore, mechanisms for accessing accounts by entering usernames and passwords should be restricted to those which are operationally necessary.
Group   Set Account Expiration Parameters   Group contains 3 rules

Rule   Ensure shadow Group is Empty   [ref]

The shadow group allows system programs which require access the ability to read the /etc/shadow file. No users should be assigned to the shadow group.
Warning:  This rule remediation will ensure the group membership is empty in /etc/group. To avoid any disruption the remediation won't change the primary group of users in /etc/passwd if any user has the shadow GID as primary group.
Rationale:
Any users assigned to the shadow group would be granted read access to the /etc/shadow file. If attackers can gain read access to the /etc/shadow file, they can easily run a password cracking program against the hashed passwords to break them. Other security information that is stored in the /etc/shadow file (such as expiration) could also be useful to subvert additional user accounts.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_ensure_shadow_group_empty
References:
pcidssReq-8.2.1
cis7.2.4
pcidss48.3.2, 8.3


sed -ri 's/(^shadow:[^:]*:[^:]*:)([^:]+$)/\1/' /etc/group
Group   Set Password Expiration Parameters   Group contains 3 rules
[ref]   The file /etc/login.defs controls several password-related settings. Programs such as passwd, su, and login consult /etc/login.defs to determine behavior with regard to password aging, expiration warnings, and length. See the man page login.defs(5) for more information.

Users should be forced to change their passwords, in order to decrease the utility of compromised passwords. However, the need to change passwords often should be balanced against the risk that users will reuse or write down passwords if forced to change them too often. Forcing password changes every 90-360 days, depending on the environment, is recommended. Set the appropriate value as PASS_MAX_DAYS and apply it to existing accounts with the -M flag.

The PASS_MIN_DAYS (-m) setting prevents password changes for 7 days after the first change, to discourage password cycling. If you use this setting, train users to contact an administrator for an emergency password change in case a new password becomes compromised. The PASS_WARN_AGE (-W) setting gives users 7 days of warnings at login time that their passwords are about to expire.

For example, for each existing human user USER, expiration parameters could be adjusted to a 180 day maximum password age, 7 day minimum password age, and 7 day warning period with the following command:
$ sudo chage -M 180 -m 7 -W 7 USER

Rule   Set Existing Passwords Maximum Age   [ref]

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

Complexity:low
Disruption:low
Reboot:false
Strategy:restrict

var_accounts_maximum_age_login_defs='365'


while IFS= read -r i; do
    
    chage -M $var_accounts_maximum_age_login_defs $i

done <   <(awk -v var="$var_accounts_maximum_age_login_defs" -F: '(/^[^:]+:[^!*]/ && ($5 > var || $5 == "")) {print $1}' /etc/shadow)
Group   Verify Proper Storage and Existence of Password Hashes   Group contains 4 rules
[ref]   By default, password hashes for local accounts are stored in the second field (colon-separated) in /etc/shadow. This file should be readable only by processes running with root credentials, preventing users from casually accessing others' password hashes and attempting to crack them. However, it remains possible to misconfigure the system and store password hashes in world-readable files such as /etc/passwd, or to even store passwords themselves in plaintext on the system. Using system-provided tools for password change/creation should allow administrators to avoid such misconfiguration.

Rule   Verify All Account Password Hashes are Shadowed   [ref]

If any password hashes are stored in /etc/passwd (in the second field, instead of an x or *), the cause of this misconfiguration should be investigated. The account should have its password reset and the hash should be properly stored, or the account should be deleted entirely.
Rationale:
The hashes for all user account passwords should be stored in the file /etc/shadow and never in /etc/passwd, which is readable by all users.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_accounts_password_all_shadowed
References:
cis-csc1, 12, 15, 16, 5
cjis5.5.2
cobit5DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.10
cui3.5.10
isa-62443-20094.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.2, 4.3.3.7.4
isa-62443-2013SR 1.1, SR 1.10, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.7, SR 1.8, SR 1.9, SR 2.1
ism1410
iso27001-2013A.18.1.4, A.7.1.1, A.9.2.1, A.9.2.2, A.9.2.3, A.9.2.4, A.9.2.6, A.9.3.1, A.9.4.2, A.9.4.3
nistIA-5(h), CM-6(a)
nist-csfPR.AC-1, PR.AC-6, PR.AC-7
pcidssReq-8.2.1
cis7.2.1
pcidss48.3.2, 8.3

Rule   Ensure all users last password change date is in the past   [ref]

All users should have a password change date in the past.
Warning:  Automatic remediation is not available, in order to avoid any system disruption.
Rationale:
If a user recorded password change date is in the future then they could bypass any set password expiration.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_accounts_password_last_change_is_in_past
References:
cis5.4.1.6
pcidss48.3.5, 8.3

Rule   All GIDs referenced in /etc/passwd must be defined in /etc/group   [ref]

Add a group to the system for each GID referenced without a corresponding group.
Rationale:
If a user is assigned the Group Identifier (GID) of a group not existing on the system, and a group with the Group Identifier (GID) is subsequently created, the user may have unintended rights to any files associated with the group.
Severity: 
low
Rule ID:xccdf_org.ssgproject.content_rule_gid_passwd_group_same
References:
cis-csc1, 12, 15, 16, 5
cjis5.5.2
cobit5DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.10
disaCCI-000764
isa-62443-20094.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.2, 4.3.3.7.4
isa-62443-2013SR 1.1, SR 1.10, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.7, SR 1.8, SR 1.9, SR 2.1
iso27001-2013A.18.1.4, A.7.1.1, A.9.2.1, A.9.2.2, A.9.2.3, A.9.2.4, A.9.2.6, A.9.3.1, A.9.4.2, A.9.4.3
nerc-cipCIP-003-8 R5.1.1, CIP-003-8 R5.3, CIP-004-6 R2.2.3, CIP-004-6 R2.3, CIP-007-3 R5.1, CIP-007-3 R5.1.2, CIP-007-3 R5.2, CIP-007-3 R5.3.1, CIP-007-3 R5.3.2, CIP-007-3 R5.3.3
nistIA-2, CM-6(a)
nist-csfPR.AC-1, PR.AC-6, PR.AC-7
pcidssReq-8.5.a
os-srgSRG-OS-000104-GPOS-00051
cis7.2.3
pcidss48.2.2, 8.2

Rule   Ensure There Are No Accounts With Blank or Null Passwords   [ref]

Check the "/etc/shadow" file for blank passwords with the following command:
$ sudo awk -F: '!$2 {print $1}' /etc/shadow
If the command returns any results, this is a finding. Configure all accounts on the system to have a password or lock the account with the following commands: Perform a password reset:
$ sudo passwd [username]
Lock an account:
$ sudo passwd -l [username]
Warning:  Note that this rule is not applicable for systems running within a container. Having user with empty password within a container is not considered a risk, because it should not be possible to directly login into a container anyway.
Rationale:
If an account has an empty password, anyone could log in and run commands with the privileges of that account. Accounts with empty passwords should never be used in operational environments.
Severity: 
high
Rule ID:xccdf_org.ssgproject.content_rule_no_empty_passwords_etc_shadow
References:
disaCCI-000366
nistCM-6(b), CM-6.1(iv)
os-srgSRG-OS-000480-GPOS-00227
cis7.2.2
pcidss42.2.2, 2.2

Complexity:low
Disruption:low
Reboot:false
Strategy:restrict
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - NIST-800-53-CM-6(b)
  - NIST-800-53-CM-6.1(iv)
  - PCI-DSSv4-2.2
  - PCI-DSSv4-2.2.2
  - high_severity
  - low_complexity
  - low_disruption
  - no_empty_passwords_etc_shadow
  - no_reboot_needed
  - restrict_strategy

- name: Collect users with no password
  command: |
    awk -F: '!$2 {print $1}' /etc/shadow
  register: users_nopasswd
  changed_when: false
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-53-CM-6(b)
  - NIST-800-53-CM-6.1(iv)
  - PCI-DSSv4-2.2
  - PCI-DSSv4-2.2.2
  - high_severity
  - low_complexity
  - low_disruption
  - no_empty_passwords_etc_shadow
  - no_reboot_needed
  - restrict_strategy

- name: Lock users with no password
  command: |
    passwd -l {{ item }}
  with_items: '{{ users_nopasswd.stdout_lines }}'
  when:
  - '"linux-base" in ansible_facts.packages'
  - users_nopasswd is not skipped and users_nopasswd.stdout_lines | length > 0
  tags:
  - NIST-800-53-CM-6(b)
  - NIST-800-53-CM-6.1(iv)
  - PCI-DSSv4-2.2
  - PCI-DSSv4-2.2.2
  - high_severity
  - low_complexity
  - low_disruption
  - no_empty_passwords_etc_shadow
  - no_reboot_needed
  - restrict_strategy

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

readarray -t users_with_empty_pass < <(sudo awk -F: '!$2 {print $1}' /etc/shadow)

for user_with_empty_pass in "${users_with_empty_pass[@]}"
do
    passwd -l $user_with_empty_pass
done

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

Rule   Verify Only Root Has UID 0   [ref]

If any account other than root has a UID of 0, this misconfiguration should be investigated and the accounts other than root should be removed or have their UID changed.
If the account is associated with system commands or applications the UID should be changed to one greater than "0" but less than "1000." Otherwise assign a UID greater than "1000" that has not already been assigned.
Rationale:
An account has root authority if it has a UID of 0. Multiple accounts with a UID of 0 afford more opportunity for potential intruders to guess a password for a privileged account. Proper configuration of sudo is recommended to afford multiple system administrators access to root privileges in an accountable manner.
Severity: 
high
Rule ID:xccdf_org.ssgproject.content_rule_accounts_no_uid_except_zero
References:
cis-csc1, 12, 13, 14, 15, 16, 18, 3, 5
cobit5APO01.06, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.02, DSS06.03, DSS06.10
cui3.1.1, 3.1.5
disaCCI-000366
isa-62443-20094.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4
isa-62443-2013SR 1.1, SR 1.10, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 5.2
iso27001-2013A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.18.1.4, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.1, A.9.2.2, A.9.2.3, A.9.2.4, A.9.2.6, A.9.3.1, A.9.4.1, A.9.4.2, A.9.4.3, A.9.4.4, A.9.4.5
nerc-cipCIP-003-8 R5.1.1, CIP-003-8 R5.3, CIP-004-6 R2.2.3, CIP-004-6 R2.3, CIP-007-3 R5.1, CIP-007-3 R5.1.2, CIP-007-3 R5.2, CIP-007-3 R5.3.1, CIP-007-3 R5.3.2, CIP-007-3 R5.3.3
nistIA-2, AC-6(5), IA-4(b)
nist-csfPR.AC-1, PR.AC-4, PR.AC-6, PR.AC-7, PR.DS-5
pcidssReq-8.5
os-srgSRG-OS-000480-GPOS-00227
cis5.4.2.1
pcidss48.2.1, 8.2

Complexity:low
Disruption:low
Reboot:false
Strategy:restrict
- name: Get all /etc/passwd file entries
  getent:
    database: passwd
    split: ':'
  tags:
  - NIST-800-171-3.1.1
  - NIST-800-171-3.1.5
  - NIST-800-53-AC-6(5)
  - NIST-800-53-IA-2
  - NIST-800-53-IA-4(b)
  - PCI-DSS-Req-8.5
  - PCI-DSSv4-8.2
  - PCI-DSSv4-8.2.1
  - accounts_no_uid_except_zero
  - high_severity
  - low_complexity
  - low_disruption
  - no_reboot_needed
  - restrict_strategy

- name: Lock the password of the user accounts other than root with uid 0
  command: passwd -l {{ item.key }}
  loop: '{{ getent_passwd | dict2items | rejectattr(''key'', ''search'', ''root'')
    | list }}'
  when: item.value.1  == '0'
  tags:
  - NIST-800-171-3.1.1
  - NIST-800-171-3.1.5
  - NIST-800-53-AC-6(5)
  - NIST-800-53-IA-2
  - NIST-800-53-IA-4(b)
  - PCI-DSS-Req-8.5
  - PCI-DSSv4-8.2
  - PCI-DSSv4-8.2.1
  - accounts_no_uid_except_zero
  - high_severity
  - low_complexity
  - low_disruption
  - no_reboot_needed
  - restrict_strategy

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

Rule   Ensure the Group Used by pam_wheel.so Module Exists on System and is Empty   [ref]

Ensure that the group sugroup referenced by var_pam_wheel_group_for_su variable and used as value for the pam_wheel.so group option exists and has no members. This empty group used by pam_wheel.so in /etc/pam.d/su ensures that no user can run commands with altered privileges through the su command.
Warning:  Note that this rule just ensures the group exists and has no members. This rule does not configure pam_wheel.so module. The pam_wheel.so module configuration is accomplished by use_pam_wheel_group_for_su rule.
Rationale:
The su program allows to run commands with a substitute user and group ID. It is commonly used to run commands as the root user. Limiting access to such command is considered a good security practice.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_ensure_pam_wheel_group_empty
References:
cis5.2.7
pcidss42.2.6, 2.2

Complexity:low
Disruption:low
Reboot:false
Strategy:restrict
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - PCI-DSSv4-2.2
  - PCI-DSSv4-2.2.6
  - ensure_pam_wheel_group_empty
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy
- name: XCCDF Value var_pam_wheel_group_for_su # promote to variable
  set_fact:
    var_pam_wheel_group_for_su: !!str sugroup
  tags:
    - always

- name: Ensure the Group Used by pam_wheel.so Module Exists on System and is Empty
    - Ensure {{ var_pam_wheel_group_for_su }} Group Exists
  ansible.builtin.group:
    name: '{{ var_pam_wheel_group_for_su }}'
    state: present
  when: '"libpam-runtime" in ansible_facts.packages'
  tags:
  - PCI-DSSv4-2.2
  - PCI-DSSv4-2.2.6
  - ensure_pam_wheel_group_empty
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

- name: Ensure the Group Used by pam_wheel.so Module Exists on System and is Empty
    - Ensure {{ var_pam_wheel_group_for_su }} Group is Empty
  ansible.builtin.lineinfile:
    path: /etc/group
    regexp: ^({{ var_pam_wheel_group_for_su }}:[^:]+:[0-9]+:).*$
    line: \1
    backrefs: true
  when: '"libpam-runtime" in ansible_facts.packages'
  tags:
  - PCI-DSSv4-2.2
  - PCI-DSSv4-2.2.6
  - ensure_pam_wheel_group_empty
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

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

var_pam_wheel_group_for_su='sugroup'


if ! grep -q "^${var_pam_wheel_group_for_su}:[^:]*:[^:]*:[^:]*" /etc/group; then
    groupadd ${var_pam_wheel_group_for_su}
fi

# group must be empty
gpasswd -M '' ${var_pam_wheel_group_for_su}

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

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

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

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

Complexity:low
Disruption:medium
Reboot:false
Strategy:restrict
- name: Ensure that System Accounts Do Not Run a Shell Upon Login - Get All Local
    Users From /etc/passwd
  ansible.builtin.getent:
    database: passwd
    split: ':'
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-6(b)
  - NIST-800-53-CM-6.1(iv)
  - PCI-DSSv4-8.2
  - PCI-DSSv4-8.2.2
  - low_complexity
  - medium_disruption
  - medium_severity
  - no_reboot_needed
  - no_shelllogin_for_systemaccounts
  - restrict_strategy

- name: Ensure that System Accounts Do Not Run a Shell Upon Login - Create local_users
    Variable From getent_passwd Facts
  ansible.builtin.set_fact:
    local_users: '{{ ansible_facts.getent_passwd | dict2items }}'
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-6(b)
  - NIST-800-53-CM-6.1(iv)
  - PCI-DSSv4-8.2
  - PCI-DSSv4-8.2.2
  - low_complexity
  - medium_disruption
  - medium_severity
  - no_reboot_needed
  - no_shelllogin_for_systemaccounts
  - restrict_strategy

- name: Ensure that System Accounts Do Not Run a Shell Upon Login -  Disable Login
    Shell for System Accounts
  ansible.builtin.user:
    name: '{{ item.key }}'
    shell: /sbin/nologin
  loop: '{{ local_users }}'
  when:
  - item.key not in ['root']
  - item.value[1]|int < 1000
  - item.value[5] not in ['/sbin/shutdown', '/sbin/halt', '/bin/sync']
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-6(b)
  - NIST-800-53-CM-6.1(iv)
  - PCI-DSSv4-8.2
  - PCI-DSSv4-8.2.2
  - low_complexity
  - medium_disruption
  - medium_severity
  - no_reboot_needed
  - no_shelllogin_for_systemaccounts
  - restrict_strategy

Complexity:low
Disruption:medium
Reboot:false
Strategy:restrict

readarray -t systemaccounts < <(awk -F: '($3 < 1000 && $3 != root \
  && $7 != "\/sbin\/shutdown" && $7 != "\/sbin\/halt" && $7 != "\/bin\/sync") \
  { print $1 }' /etc/passwd)

for systemaccount in "${systemaccounts[@]}"; do
    usermod -s /sbin/nologin "$systemaccount"
done

Rule   Enforce Usage of pam_wheel with Group Parameter for su Authentication   [ref]

To ensure that only users who are members of the group set in the group option of pam_wheel.so module can run commands with altered privileges through the su command, make sure that the following line exists in the file /etc/pam.d/su:
auth required pam_wheel.so use_uid group=sugroup
         
Warning:  Note that ensure_pam_wheel_group_empty rule complements this requirement by ensuring the referenced group exists and has no members.
Rationale:
The su program allows to run commands with a substitute user and group ID. It is commonly used to run commands as the root user. Limiting access to such command is considered a good security practice.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_use_pam_wheel_group_for_su
References:
cis5.2.7
pcidss42.2.6, 2.2

Complexity:low
Disruption:low
Reboot:false
Strategy:restrict
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - PCI-DSSv4-2.2
  - PCI-DSSv4-2.2.6
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy
  - use_pam_wheel_group_for_su
- name: XCCDF Value var_pam_wheel_group_for_su # promote to variable
  set_fact:
    var_pam_wheel_group_for_su: !!str sugroup
  tags:
    - always

- name: Enforce Usage of pam_wheel with Group Parameter for su Authentication - Add
    the group to the /etc/pam.d/su file
  ansible.builtin.lineinfile:
    path: /etc/pam.d/su
    state: present
    regexp: ^[\s]*#[\s]*auth[\s]+required[\s]+pam_wheel\.so[\s]+use_uid group=$
    line: auth             required        pam_wheel.so use_uid group={{ var_pam_wheel_group_for_su
      }}
  when: '"libpam-runtime" in ansible_facts.packages'
  tags:
  - PCI-DSSv4-2.2
  - PCI-DSSv4-2.2.6
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy
  - use_pam_wheel_group_for_su

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

var_pam_wheel_group_for_su='sugroup'


PAM_CONF=/etc/pam.d/su

pamstr=$(grep -P '^auth\s+required\s+pam_wheel\.so\s+(?=[^#]*\buse_uid\b)(?=[^#]*\bgroup=)' ${PAM_CONF})
if [ -z "$pamstr" ]; then
    sed -Ei '/^auth\b.*\brequired\b.*\bpam_wheel\.so/d' ${PAM_CONF} # remove any remaining uncommented pam_wheel.so line
    sed -Ei "/^auth\s+sufficient\s+pam_rootok\.so.*$/a auth             required        pam_wheel.so use_uid group=${var_pam_wheel_group_for_su}" ${PAM_CONF}
else
    group_val=$(echo -n "$pamstr" | grep -Eo '\bgroup=[_a-z][-0-9_a-z]*' | cut -d '=' -f 2)
    if [ -z "${group_val}" ] || [ ${group_val} != ${var_pam_wheel_group_for_su} ]; then
        sed -Ei "s/(^auth\s+required\s+pam_wheel.so\s+[^#]*group=)[_a-z][-0-9_a-z]*/\1${var_pam_wheel_group_for_su}/" ${PAM_CONF}
    fi
fi

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

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

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

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

Change the group name or delete groups, so each has a unique name.
Warning:  Automatic remediation of this control is not available due to the unique requirements of each system.
Rationale:
To assure accountability and prevent unauthenticated access, groups must be identified uniquely to prevent potential misuse and compromise of the system.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_group_unique_name
References:
cis7.2.8
pcidss48.2.1, 8.2
Group   Secure Session Configuration Files for Login Accounts   Group contains 1 group and 8 rules
[ref]   When a user logs into a Unix account, the system configures the user's session by reading a number of files. Many of these files are located in the user's home directory, and may have weak permissions as a result of user error or misconfiguration. If an attacker can modify or even read certain types of account configuration information, they can often gain full access to the affected user's account. Therefore, it is important to test and correct configuration file permissions for interactive accounts, particularly those of privileged users such as root or system administrators.
Group   Ensure that Users Have Sensible Umask Values   Group contains 3 rules
[ref]   The umask setting controls the default permissions for the creation of new files. With a default umask setting of 077, files and directories created by users will not be readable by any other user on the system. Users who wish to make specific files group- or world-readable can accomplish this by using the chmod command. Additionally, users can make all their files readable to their group by default by setting a umask of 027 in their shell configuration files. If default per-user groups exist (that is, if every user has a default group whose name is the same as that user's username and whose only member is the user), then it may even be safe for users to select a umask of 007, making it very easy to intentionally share files with groups of which the user is a member.

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

To ensure the default umask for users of the Bash shell is set properly, add or correct the umask setting in /etc/bash.bashrc to read as follows:
umask 027
         
Rationale:
The umask value influences the permissions assigned to files when they are created. A misconfigured umask value could result in files with excessive permissions that can be read or written to by unauthorized users.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_accounts_umask_etc_bashrc
References:
cis-csc18
cobit5APO13.01, BAI03.01, BAI03.02, BAI03.03
disaCCI-000366
isa-62443-20094.3.4.3.3
iso27001-2013A.14.1.1, A.14.2.1, A.14.2.5, A.6.1.5
nerc-cipCIP-003-8 R5.1.1, CIP-003-8 R5.3, CIP-004-6 R2.3, CIP-007-3 R2.1, CIP-007-3 R2.2, CIP-007-3 R2.3, CIP-007-3 R5.1, CIP-007-3 R5.1.1, CIP-007-3 R5.1.2
nistAC-6(1), CM-6(a)
nist-csfPR.IP-2
os-srgSRG-OS-000480-GPOS-00228, SRG-OS-000480-GPOS-00227
anssiR36
cis5.4.3.3

Complexity:low
Disruption:low
Reboot:false
Strategy:restrict
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - accounts_umask_etc_bashrc
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy
- name: XCCDF Value var_accounts_user_umask # promote to variable
  set_fact:
    var_accounts_user_umask: !!str 027
  tags:
    - always

- name: Check if umask in /etc/bash.bashrc is already set
  ansible.builtin.lineinfile:
    path: /etc/bash.bashrc
    regexp: ^[^#]*\bumask\s+\d+$
    state: absent
  check_mode: true
  changed_when: false
  register: umask_replace
  when: '"bash" in ansible_facts.packages'
  tags:
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - accounts_umask_etc_bashrc
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

- name: Replace user umask in /etc/bash.bashrc
  ansible.builtin.replace:
    path: /etc/bash.bashrc
    regexp: ^([^#]*\b)umask\s+\d+$
    replace: \g<1>umask {{ var_accounts_user_umask }}
  when:
  - '"bash" in ansible_facts.packages'
  - umask_replace.found > 0
  tags:
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - accounts_umask_etc_bashrc
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

- name: Ensure the Default umask is Appended Correctly
  ansible.builtin.lineinfile:
    create: true
    path: /etc/bash.bashrc
    line: umask {{ var_accounts_user_umask }}
  when:
  - '"bash" in ansible_facts.packages'
  - umask_replace.found == 0
  tags:
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - accounts_umask_etc_bashrc
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

# Remediation is applicable only in certain platforms
if dpkg-query --show --showformat='${db:Status-Status}\n' 'bash' 2>/dev/null | grep -q installed; then

var_accounts_user_umask='027'






grep -q "^[^#]*\bumask" /etc/bash.bashrc && \
  sed -i -E -e "s/^([^#]*\bumask)[[:space:]]+[[:digit:]]+/\1 $var_accounts_user_umask/g" /etc/bash.bashrc
if ! [ $? -eq 0 ]; then
    echo "umask $var_accounts_user_umask" >> /etc/bash.bashrc
fi

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

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

To ensure the default umask controlled by /etc/profile is set properly, add or correct the umask setting in /etc/profile to read as follows:
umask 027
         
Note that /etc/profile also reads scrips within /etc/profile.d directory. These scripts are also valid files to set umask value. Therefore, they should also be considered during the check and properly remediated, if necessary.
Rationale:
The umask value influences the permissions assigned to files when they are created. A misconfigured umask value could result in files with excessive permissions that can be read or written to by unauthorized users.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_accounts_umask_etc_profile
References:
cis-csc18
cobit5APO13.01, BAI03.01, BAI03.02, BAI03.03
disaCCI-000366
isa-62443-20094.3.4.3.3
iso27001-2013A.14.1.1, A.14.2.1, A.14.2.5, A.6.1.5
nerc-cipCIP-003-8 R5.1.1, CIP-003-8 R5.3, CIP-004-6 R2.3, CIP-007-3 R2.1, CIP-007-3 R2.2, CIP-007-3 R2.3, CIP-007-3 R5.1, CIP-007-3 R5.1.1, CIP-007-3 R5.1.2
nistAC-6(1), CM-6(a)
nist-csfPR.IP-2
os-srgSRG-OS-000480-GPOS-00228, SRG-OS-000480-GPOS-00227
anssiR36
cis5.4.3.3

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

- name: Ensure the Default Umask is Set Correctly in /etc/profile - Locate Profile
    Configuration Files Where umask Is Defined
  ansible.builtin.find:
    paths:
    - /etc/profile.d
    patterns:
    - sh.local
    - '*.sh'
    contains: ^[\s]*umask\s+\d+
  register: result_profile_d_files
  tags:
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - accounts_umask_etc_profile
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

- name: Ensure the Default Umask is Set Correctly in /etc/profile - Replace Existing
    umask Value in Files From /etc/profile.d
  ansible.builtin.replace:
    path: '{{ item.path }}'
    regexp: ^(\s*)umask\s+\d+
    replace: \1umask {{ var_accounts_user_umask }}
  loop: '{{ result_profile_d_files.files }}'
  register: result_umask_replaced_profile_d
  when: result_profile_d_files.matched
  tags:
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - accounts_umask_etc_profile
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

- name: Ensure the Default Umask is Set Correctly in /etc/profile - Ensure umask Is
    Set in /etc/profile if Not Already Set Elsewhere
  ansible.builtin.lineinfile:
    create: true
    mode: 420
    path: /etc/profile
    line: umask {{ var_accounts_user_umask }}
  when: not result_profile_d_files.matched
  tags:
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - accounts_umask_etc_profile
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

- name: Ensure the Default Umask is Set Correctly in /etc/profile - Ensure umask Value
    For All Existing umask Definition in /etc/profile
  ansible.builtin.replace:
    path: /etc/profile
    regexp: ^(\s*)umask\s+\d+
    replace: \1umask {{ var_accounts_user_umask }}
  register: result_umask_replaced_profile
  tags:
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - accounts_umask_etc_profile
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

Complexity:low
Disruption:low
Reboot:false
Strategy:restrict

var_accounts_user_umask='027'


readarray -t profile_files < <(find /etc/profile.d/ -type f -name '*.sh' -or -name 'sh.local')

for file in "${profile_files[@]}" /etc/profile; do
  grep -qE '^[^#]*umask' "$file" && sed -i -E "s/^(\s*umask\s*)[0-7]+/\1$var_accounts_user_umask/g" "$file"
done

if ! grep -qrE '^[^#]*umask' /etc/profile*; then
  echo "umask $var_accounts_user_umask" >> /etc/profile
fi

Rule   Set Interactive Session Timeout   [ref]

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

Complexity:low
Disruption:low
Reboot:false
Strategy:restrict
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - NIST-800-171-3.1.11
  - NIST-800-53-AC-12
  - NIST-800-53-AC-2(5)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-SC-10
  - PCI-DSSv4-8.6
  - PCI-DSSv4-8.6.1
  - accounts_tmout
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy
- name: XCCDF Value var_accounts_tmout # promote to variable
  set_fact:
    var_accounts_tmout: !!str 900
  tags:
    - always

- name: Correct any occurrence of TMOUT in /etc/profile
  replace:
    path: /etc/profile
    regexp: ^[^#].*TMOUT=.*
    replace: typeset -xr TMOUT={{ var_accounts_tmout }}
  register: profile_replaced
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.11
  - NIST-800-53-AC-12
  - NIST-800-53-AC-2(5)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-SC-10
  - PCI-DSSv4-8.6
  - PCI-DSSv4-8.6.1
  - accounts_tmout
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

- name: Set Interactive Session Timeout
  lineinfile:
    path: /etc/profile.d/tmout.sh
    create: true
    regexp: TMOUT=
    line: typeset -xr TMOUT={{ var_accounts_tmout }}
    state: present
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.11
  - NIST-800-53-AC-12
  - NIST-800-53-AC-2(5)
  - NIST-800-53-CM-6(a)
  - NIST-800-53-SC-10
  - PCI-DSSv4-8.6
  - PCI-DSSv4-8.6.1
  - accounts_tmout
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

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

var_accounts_tmout='900'


# if 0, no occurence of tmout found, if 1, occurence found
tmout_found=0

for f in /etc/bash.bashrc /etc/profile /etc/profile.d/*.sh; do
    if grep --silent '^\s*TMOUT' $f; then
        sed -i -E "s/^(\s*)TMOUT\s*=\s*(\w|\$)*(.*)$/\1TMOUT=$var_accounts_tmout\3/g" $f
        tmout_found=1
        if ! grep --silent '^\s*readonly TMOUT' $f ; then
            echo "readonly TMOUT" >> $f
        fi
        if ! grep --silent '^\s*export TMOUT' $f ; then
            echo "export TMOUT" >> $f
        fi
    fi
done

if [ $tmout_found -eq 0 ]; then
        echo -e "\n# Set TMOUT to $var_accounts_tmout per security requirements" >> /etc/profile.d/tmout.sh
        echo "TMOUT=$var_accounts_tmout" >> /etc/profile.d/tmout.sh
        echo "readonly TMOUT" >> /etc/profile.d/tmout.sh
        echo "export TMOUT" >> /etc/profile.d/tmout.sh
fi

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

Rule   All Interactive Users Home Directories Must Exist   [ref]

Create home directories to all local interactive users that currently do not have a home directory assigned. Use the following commands to create the user home directory assigned in /etc/passwd:
$ sudo mkdir /home/USER
        
Rationale:
If a local interactive user has a home directory defined that does not exist, the user may be given access to the / directory as the current working directory upon logon. This could create a Denial of Service because the user would not be able to access their logon configuration files, and it may give them visibility to system files they normally would not be able to access.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_accounts_user_interactive_home_directory_exists
References:
disaCCI-000366
os-srgSRG-OS-000480-GPOS-00227
cis7.2.9

Complexity:low
Disruption:low
Reboot:false
Strategy:restrict
- name: Get all local users from /etc/passwd
  ansible.builtin.getent:
    database: passwd
    split: ':'
  tags:
  - accounts_user_interactive_home_directory_exists
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

- name: Create local_users variable from the getent output
  ansible.builtin.set_fact:
    local_users: '{{ ansible_facts.getent_passwd|dict2items }}'
  tags:
  - accounts_user_interactive_home_directory_exists
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

- name: Ensure interactive users have a home directory exists
  ansible.builtin.user:
    name: '{{ item.key }}'
    create_home: true
  loop: '{{ local_users }}'
  when:
  - item.value[2]|int >= 1000
  - item.value[2]|int != 65534
  tags:
  - accounts_user_interactive_home_directory_exists
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

Complexity:low
Disruption:low
Reboot:false
Strategy:restrict

for user in $(awk -F':' '{ if ($3 >= 1000 && $3 != 65534) print $1}' /etc/passwd); do
    mkhomedir_helper $user 0077;
done

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

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

Complexity:low
Disruption:low
Reboot:false
Strategy:restrict
- name: Get all local users from /etc/passwd
  ansible.builtin.getent:
    database: passwd
    split: ':'
  tags:
  - file_groupownership_home_directories
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

- name: Create local_users variable from the getent output
  ansible.builtin.set_fact:
    local_users: '{{ ansible_facts.getent_passwd|dict2items }}'
  tags:
  - file_groupownership_home_directories
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

- name: Test for existence of home directories to avoid creating them, but only fixing
    group ownership
  ansible.builtin.stat:
    path: '{{ item.value[4] }}'
  register: path_exists
  loop: '{{ local_users }}'
  when:
  - item.value[1]|int >= 1000
  - item.value[1]|int != 65534
  tags:
  - file_groupownership_home_directories
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

- name: Ensure interactive local users are the group-owners of their respective home
    directories
  ansible.builtin.file:
    path: '{{ item.0.value[4] }}'
    group: '{{ item.0.value[2] }}'
  loop: '{{ local_users|zip(path_exists.results)|list }}'
  when: item.1.stat is defined and item.1.stat.exists
  tags:
  - file_groupownership_home_directories
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

Complexity:low
Disruption:low
Reboot:false
Strategy:restrict

awk -F':' '{ if ($3 >= 1000 && $3 != 65534) system("chgrp -f " $4" "$6) }' /etc/passwd

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

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

Complexity:low
Disruption:low
Reboot:false
Strategy:restrict
- name: Get all local users from /etc/passwd
  ansible.builtin.getent:
    database: passwd
    split: ':'
  tags:
  - file_ownership_home_directories
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

- name: Create local_users variable from the getent output
  ansible.builtin.set_fact:
    local_users: '{{ ansible_facts.getent_passwd|dict2items }}'
  tags:
  - file_ownership_home_directories
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

- name: Test for existence of home directories to avoid creating them, but only fixing
    ownership
  ansible.builtin.stat:
    path: '{{ item.value[4] }}'
  register: path_exists
  loop: '{{ local_users }}'
  when:
  - item.value[1]|int >= 1000
  - item.value[1]|int != 65534
  tags:
  - file_ownership_home_directories
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

- name: Ensure interactive local users are the owners of their respective home directories
  ansible.builtin.file:
    path: '{{ item.0.value[4] }}'
    owner: '{{ item.0.value[1] }}'
  loop: '{{ local_users|zip(path_exists.results)|list }}'
  when: item.1.stat is defined and item.1.stat.exists
  tags:
  - file_ownership_home_directories
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

Complexity:low
Disruption:low
Reboot:false
Strategy:restrict

awk -F':' '{ if ($3 >= 1000 && $3 != 65534) system("chown -f " $3" "$6) }' /etc/passwd

Rule   All Interactive User Home Directories Must Have mode 0750 Or Less Permissive   [ref]

Change the mode of interactive users home directories to 0750. To change the mode of interactive users home directory, use the following command:
$ sudo chmod 0750 /home/USER
        
Rationale:
Excessive permissions on local interactive user home directories may allow unauthorized access to user files by other users.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_file_permissions_home_directories
References:
disaCCI-000366
os-srgSRG-OS-000480-GPOS-00227
cis7.2.9

Complexity:low
Disruption:low
Reboot:false
Strategy:restrict
- name: Get all local users from /etc/passwd
  ansible.builtin.getent:
    database: passwd
    split: ':'
  tags:
  - file_permissions_home_directories
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

- name: Create local_users variable from the getent output
  ansible.builtin.set_fact:
    local_users: '{{ ansible_facts.getent_passwd|dict2items }}'
  tags:
  - file_permissions_home_directories
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

- name: Test for existence home directories to avoid creating them.
  ansible.builtin.stat:
    path: '{{ item.value[4] }}'
  register: path_exists
  loop: '{{ local_users }}'
  when:
  - item.value[1]|int >= 1000
  - item.value[1]|int != 65534
  - item.value[4] != "/"
  tags:
  - file_permissions_home_directories
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

- name: Ensure interactive local users have proper permissions on their respective
    home directories
  ansible.builtin.file:
    path: '{{ item.0.value[4] }}'
    mode: u-s,g-w-s,o=-
    follow: false
    recurse: false
  loop: '{{ local_users|zip(path_exists.results)|list }}'
  when: item.1.stat is defined and item.1.stat.exists
  tags:
  - file_permissions_home_directories
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy

Complexity:low
Disruption:low
Reboot:false
Strategy:restrict

for home_dir in $(awk -F':' '{ if ($3 >= 1000 && $3 != 65534 && $6 != "/") print $6 }' /etc/passwd); do
    # Only update the permissions when necessary. This will avoid changing the inode timestamp when
    # the permission is already defined as expected, therefore not impacting in possible integrity
    # check systems that also check inodes timestamps.
    find "$home_dir" -maxdepth 0 -perm /7027 \! -type l -exec chmod u-s,g-w-s,o=- {} \;
done
Group   AppArmor   Group contains 2 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   All AppArmor Profiles are in enforce or complain mode   [ref]

AppArmor profiles define what resources applications are able to access. To set all profiles to either enforce or complain mode run the following command to set all profiles to enforce mode:
$ sudo aa-enforce /etc/apparmor.d/*
run the following command to set all profiles to complain mode:
$ sudo aa-complain /etc/apparmor.d/*
To list unconfined processes run the following command:
$ sudo apparmor_status | grep processes
Any unconfined processes may need to have a profile created or activated for them and then be restarted.
Rationale:
Security configuration requirements vary from site to site. Some sites may mandate a policy that is stricter than the default policy, which is perfectly acceptable. This recommendation is intended to ensure that any policies that exist on the system are activated.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_all_apparmor_profiles_in_enforce_complain_mode
References:
cis1.3.1.3

# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ] && { ( [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ] && dpkg-query --show --showformat='${db:Status-Status}\n' 'apparmor' 2>/dev/null | grep -q installed ); }; then

var_apparmor_mode='enforce'


# make sure apparmor-utils is installed for aa-complain and aa-enforce
DEBIAN_FRONTEND=noninteractive apt-get install -y "apparmor-utils"

# Reload all AppArmor profiles
apparmor_parser -q -r /etc/apparmor.d/

# Set the mode
APPARMOR_MODE="$var_apparmor_mode"

if [ "$APPARMOR_MODE" = "enforce" ]
then
  
  # Set all profiles to enforce mode except disabled profiles
  find /etc/apparmor.d -maxdepth 1 ! -type d -exec bash -c '[[ -e "/etc/apparmor.d/disable/$(basename "$1")" ]] || aa-enforce "$1"' _ {} \;
  
fi

if [ "$APPARMOR_MODE" = "complain" ]
then
  
  # Load all not-loaded profiles into complain mode
  apparmor_parser -a --Complain /etc/apparmor.d/
  echo "***WARNING***: This remediation will not downgrade any existing AppArmor profiles."
  
fi


UNCONFINED=$(aa-status | grep "processes are unconfined" | awk '{print $1;}')
if [ $UNCONFINED -ne 0 ];

then
  echo -e "***WARNING***: There are some unconfined processes:"
  echo -e "----------------------------"
  echo "The may need to have a profile created or activated for them and then be restarted."
  for PROCESS in "${UNCONFINED[@]}"
  do
      echo "$PROCESS"
  done
  echo -e "----------------------------"
  echo "The may need to have a profile created or activated for them and then be restarted."
fi

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

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 GRUB_CMDLINE_LINUX 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 GRUB_CMDLINE_LINUX parameters line
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 GRUB_CMDLINE_LINUX 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 GRUB_CMDLINE_LINUX parameters line
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 Ubuntu 24.04 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
disaCCI-000366
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
- 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: Test for existence /boot/grub/grub.cfg
  stat:
    path: /boot/grub/grub.cfg
  register: file_exists
  when:
  - '"/boot/efi" not in ansible_mounts | map(attribute="mount") | list'
  - '"grub2-common" in ansible_facts.packages'
  - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
  tags:
  - CJIS-5.5.2.2
  - NIST-800-171-3.4.5
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - PCI-DSS-Req-7.1
  - PCI-DSSv4-2.2
  - PCI-DSSv4-2.2.6
  - configure_strategy
  - file_owner_grub2_cfg
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed

- name: Ensure owner 0 on /boot/grub/grub.cfg
  file:
    path: /boot/grub/grub.cfg
    owner: '0'
  when:
  - '"/boot/efi" not in ansible_mounts | map(attribute="mount") | list'
  - '"grub2-common" in ansible_facts.packages'
  - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
  - file_exists.stat is defined and file_exists.stat.exists
  tags:
  - CJIS-5.5.2.2
  - NIST-800-171-3.4.5
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - PCI-DSS-Req-7.1
  - PCI-DSSv4-2.2
  - PCI-DSSv4-2.2.6
  - configure_strategy
  - file_owner_grub2_cfg
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed

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

chown 0 /boot/grub/grub.cfg

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

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
disaCCI-000225
hipaa164.308(a)(1)(ii)(B), 164.308(a)(7)(i), 164.308(a)(7)(ii)(A), 164.310(a)(1), 164.310(a)(2)(i), 164.310(a)(2)(ii), 164.310(a)(2)(iii), 164.310(b), 164.310(c), 164.310(d)(1), 164.310(d)(2)(iii)
isa-62443-20094.3.3.7.3
isa-62443-2013SR 2.1, SR 5.2
iso27001-2013A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5
nistCM-6(a), AC-6(1)
nist-csfPR.AC-4, PR.DS-5
anssiR29
cis1.4.2
pcidss42.2.6, 2.2

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
  stat:
    path: /boot/grub/grub.cfg
  register: file_exists
  when:
  - '"/boot/efi" not in ansible_mounts | map(attribute="mount") | list'
  - '"grub2-common" in ansible_facts.packages'
  - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
  tags:
  - NIST-800-171-3.4.5
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - PCI-DSSv4-2.2
  - 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
  file:
    path: /boot/grub/grub.cfg
    mode: u-xs,g-xwrs,o-xwrt
  when:
  - '"/boot/efi" not in ansible_mounts | map(attribute="mount") | list'
  - '"grub2-common" in ansible_facts.packages'
  - ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
  - file_exists.stat is defined and file_exists.stat.exists
  tags:
  - NIST-800-171-3.4.5
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - PCI-DSSv4-2.2
  - PCI-DSSv4-2.2.6
  - configure_strategy
  - file_permissions_grub2_cfg
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed

Complexity:low
Disruption:low
Reboot:false
Strategy:configure
# Remediation is applicable only in certain platforms
if [ ! -d /sys/firmware/efi ] && dpkg-query --show --showformat='${db:Status-Status}\n' 'grub2-common' 2>/dev/null | grep -q installed && { [ ! -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

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-mkpasswd-pbkdf2
When prompted, enter the password that was selected.

Using the hash from the output, modify the /etc/grub.d/40_custom file with the following content:
set superusers="boot"
password_pbkdf2 boot grub.pbkdf2.sha512.VeryLongString
NOTE: the bootloader superuser account and password MUST differ from the root account and password. Once the superuser password has been added, update the grub.cfg file by running:
update-grub 
Warning:  To prevent hard-coded passwords, automatic remediation of this control is not available. Remediation must be automated as a component of machine provisioning, or followed manually as outlined above. Also, do NOT manually add the superuser account and password to the grub.cfg file as the grub2-mkconfig command overwrites this file.
Rationale:
Password protection on the boot loader configuration ensures users with physical access cannot trivially alter important bootloader settings. These include which kernel to use, and whether to enter single-user mode.
Severity: 
high
Rule ID:xccdf_org.ssgproject.content_rule_grub2_password
References:
cis-csc1, 11, 12, 14, 15, 16, 18, 3, 5
cobit5DSS05.02, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.06, DSS06.10
cui3.4.5
disaCCI-000213
hipaa164.308(a)(1)(ii)(B), 164.308(a)(7)(i), 164.308(a)(7)(ii)(A), 164.310(a)(1), 164.310(a)(2)(i), 164.310(a)(2)(ii), 164.310(a)(2)(iii), 164.310(b), 164.310(c), 164.310(d)(1), 164.310(d)(2)(iii)
isa-62443-20094.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4
isa-62443-2013SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7
iso27001-2013A.18.1.4, A.6.1.2, A.7.1.1, A.9.1.2, A.9.2.1, A.9.2.2, A.9.2.3, A.9.2.4, A.9.2.6, A.9.3.1, A.9.4.1, A.9.4.2, A.9.4.3, A.9.4.4, A.9.4.5
nistCM-6(a)
nist-csfPR.AC-1, PR.AC-4, PR.AC-6, PR.AC-7, PR.PT-3
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-mkpasswd-pbkdf2
When prompted, enter the password that was selected.

Using the hash from the output, modify the /etc/grub.d/40_custom file with the following content:
set superusers="boot"
password_pbkdf2 boot grub.pbkdf2.sha512.VeryLongString
NOTE: the bootloader superuser account and password MUST differ from the root account and password. Once the superuser password has been added, update the grub.cfg file by running:
update-grub 
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
disaCCI-000213
hipaa164.308(a)(1)(ii)(B), 164.308(a)(7)(i), 164.308(a)(7)(ii)(A), 164.310(a)(1), 164.310(a)(2)(i), 164.310(a)(2)(ii), 164.310(a)(2)(iii), 164.310(b), 164.310(c), 164.310(d)(1), 164.310(d)(2)(iii)
isa-62443-20094.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4
isa-62443-2013SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7
iso27001-2013A.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   Configure Syslog   Group contains 2 groups and 7 rules
[ref]   The syslog service has been the default Unix logging mechanism for many years. It has a number of downsides, including inconsistent log format, lack of authentication for received messages, and lack of authentication, encryption, or reliable transport for messages sent over a network. However, due to its long history, syslog is a de facto standard which is supported by almost all Unix applications.

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

Rule   Install systemd-journal-remote Package   [ref]

Journald (via systemd-journal-remote ) supports the ability to send log events it gathers to a remote log host or to receive messages from remote hosts, thus enabling centralised log management.
Rationale:
Storing log data on a remote host protects log integrity from local attacks. If an attacker gains root access on the local system, they could tamper with or remove log data that is stored on the local system.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_package_systemd-journal-remote_installed
References:
os-srgSRG-OS-000479-GPOS-00224
cis6.1.2.1.1

Complexity:low
Disruption:low
Reboot:false
Strategy:enable
include install_systemd-journal-remote

class install_systemd-journal-remote {
  package { 'systemd-journal-remote':
    ensure => 'installed',
  }
}

Complexity:low
Disruption:low
Reboot:false
Strategy:enable
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - enable_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - package_systemd-journal-remote_installed

- name: Ensure systemd-journal-remote is installed
  package:
    name: systemd-journal-remote
    state: present
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - enable_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - package_systemd-journal-remote_installed


[[packages]]
name = "systemd-journal-remote"
version = "*"

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

DEBIAN_FRONTEND=noninteractive apt-get install -y "systemd-journal-remote"

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

Rule   Enable systemd-journald Service   [ref]

The systemd-journald service is an essential component of systemd. The systemd-journald service can be enabled with the following command:
$ sudo systemctl enable systemd-journald.service
Rationale:
In the event of a system failure, Ubuntu 24.04 must preserve any information necessary to determine cause of failure and any information necessary to return to operations with least disruption to system processes.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_service_systemd-journald_enabled
References:
disaCCI-001665
nistSC-24
os-srgSRG-OS-000269-GPOS-00103
cis6.1.1.1

Complexity:low
Disruption:low
Reboot:false
Strategy:enable
include enable_systemd-journald

class enable_systemd-journald {
  service {'systemd-journald':
    enable => true,
    ensure => 'running',
  }
}

Complexity:low
Disruption:low
Reboot:false
Strategy:enable
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - NIST-800-53-SC-24
  - enable_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - service_systemd-journald_enabled

- name: Enable systemd-journald Service - Enable service systemd-journald
  block:

  - name: Gather the package facts
    package_facts:
      manager: auto

  - name: Enable systemd-journald Service - Enable Service systemd-journald
    ansible.builtin.systemd:
      name: systemd-journald
      enabled: true
      state: started
      masked: false
    when:
    - '"systemd" in ansible_facts.packages'
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-53-SC-24
  - enable_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - service_systemd-journald_enabled


[customizations.services]
enabled = ["systemd-journald"]

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

SYSTEMCTL_EXEC='/usr/bin/systemctl'
"$SYSTEMCTL_EXEC" unmask 'systemd-journald.service'
"$SYSTEMCTL_EXEC" start 'systemd-journald.service'
"$SYSTEMCTL_EXEC" enable 'systemd-journald.service'

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

Rule   Disable systemd-journal-remote Socket   [ref]

Journald supports the ability to receive messages from remote hosts, thus acting as a log server. Clients should not receive data from other hosts. NOTE: The same package, systemd-journal-remote , is used for both sending logs to remote hosts and receiving incoming logs. With regards to receiving logs, there are two Systemd unit files; systemd-journal-remote.socket and systemd-journal-remote.service.
Rationale:
If a client is configured to also receive data, thus turning it into a server, the client system is acting outside it's operational boundary.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_socket_systemd-journal-remote_disabled
References:
cis6.1.2.1.4

Complexity:low
Disruption:low
Reboot:false
Strategy:disable
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - disable_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - socket_systemd-journal-remote_disabled

- name: Disable systemd-journal-remote Socket - Collect systemd Socket Units Present
    in the System
  ansible.builtin.command:
    cmd: systemctl -q list-unit-files --type socket
  register: result_systemd_unit_files
  changed_when: false
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - disable_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - socket_systemd-journal-remote_disabled

- name: Disable systemd-journal-remote Socket - Ensure systemd-journal-remote.socket
    is Masked
  ansible.builtin.systemd:
    name: systemd-journal-remote.socket
    state: stopped
    enabled: false
    masked: true
  when:
  - '"linux-base" in ansible_facts.packages'
  - result_systemd_unit_files.stdout_lines is search("systemd-journal-remote.socket")
  tags:
  - disable_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - socket_systemd-journal-remote_disabled

Complexity:low
Disruption:low
Reboot:false
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

SOCKET_NAME="systemd-journal-remote.socket"
SYSTEMCTL_EXEC='/usr/bin/systemctl'

if "$SYSTEMCTL_EXEC" -q list-unit-files --type socket | grep -q "$SOCKET_NAME"; then
    "$SYSTEMCTL_EXEC" stop "$SOCKET_NAME"
    "$SYSTEMCTL_EXEC" mask "$SOCKET_NAME"
fi

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi
Group   Configure rsyslogd to Accept Remote Messages If Acting as a Log Server   Group contains 1 rule
[ref]   By default, rsyslog does not listen over the network for log messages. If needed, modules can be enabled to allow the rsyslog daemon to receive messages from other systems and for the system thus to act as a log server. If the system is not a log server, then lines concerning these modules should remain commented out.

Rule   Ensure rsyslog Does Not Accept Remote Messages Unless Acting As Log Server   [ref]

The rsyslog daemon should not accept remote messages unless the system acts as a log server. To ensure that it is not listening on the network, ensure any of the following lines are not found in rsyslog configuration files. If using legacy syntax:
$ModLoad imtcp
$InputTCPServerRun port
$ModLoad imudp
$UDPServerRun port
$ModLoad imrelp
$InputRELPServerRun port
        
If using RainerScript syntax:
module(load="imtcp")
module(load="imudp")
input(type="imtcp" port="514")
input(type="imudp" port="514")
Rationale:
Any process which receives messages from the network incurs some risk of receiving malicious messages. This risk can be eliminated for rsyslog by configuring it not to listen on the network.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_rsyslog_nolisten
References:
cis-csc1, 11, 12, 13, 14, 15, 16, 18, 3, 4, 5, 6, 8, 9
cobit5APO01.06, APO11.04, APO13.01, BAI03.05, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS01.05, DSS03.01, DSS05.02, DSS05.04, DSS05.07, DSS06.02, MEA02.01
disaCCI-000366
isa-62443-20094.2.3.4, 4.3.3.3.9, 4.3.3.4, 4.3.3.5.8, 4.3.4.3.2, 4.3.4.3.3, 4.3.4.4.7, 4.4.2.1, 4.4.2.2, 4.4.2.4, 4.4.3.3
isa-62443-2013SR 2.10, SR 2.11, SR 2.12, SR 2.8, SR 2.9, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 7.1, SR 7.6
ism0988, 1405
iso27001-2013A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.12.1.1, A.12.1.2, A.12.4.1, A.12.4.2, A.12.4.3, A.12.4.4, A.12.5.1, A.12.6.2, A.12.7.1, A.13.1.1, A.13.1.2, A.13.1.3, A.13.2.1, A.13.2.2, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.14.2.2, A.14.2.3, A.14.2.4, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5
nistCM-7(a), CM-7(b), CM-6(a)
nist-csfDE.AE-1, ID.AM-3, PR.AC-5, PR.DS-5, PR.IP-1, PR.PT-1, PR.PT-4
os-srgSRG-OS-000480-GPOS-00227
cis6.1.3.7

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

- name: Ensure rsyslog Does Not Accept Remote Messages Unless Acting As Log Server
    - Define Rsyslog Config Lines Regex in Legacy Syntax
  ansible.builtin.set_fact:
    rsyslog_listen_legacy_regex: ^\s*\$(((Input(TCP|RELP)|UDP)ServerRun)|ModLoad\s+(imtcp|imudp|imrelp))
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - configure_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - rsyslog_nolisten

- name: Ensure rsyslog Does Not Accept Remote Messages Unless Acting As Log Server
    - Search for Legacy Config Lines in Rsyslog Main Config File
  ansible.builtin.find:
    paths: /etc
    pattern: rsyslog.conf
    contains: '{{ rsyslog_listen_legacy_regex }}'
  register: rsyslog_listen_legacy_main_file
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - configure_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - rsyslog_nolisten

- name: Ensure rsyslog Does Not Accept Remote Messages Unless Acting As Log Server
    - Search for Legacy Config Lines in Rsyslog Include Files
  ansible.builtin.find:
    paths: /etc/rsyslog.d/
    pattern: '*.conf'
    contains: '{{ rsyslog_listen_legacy_regex }}'
  register: rsyslog_listen_legacy_include_files
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - configure_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - rsyslog_nolisten

- name: Ensure rsyslog Does Not Accept Remote Messages Unless Acting As Log Server
    - Assemble List of Config Files With Listen Lines in Legacy Syntax
  ansible.builtin.set_fact:
    rsyslog_legacy_remote_listen_files: '{{ rsyslog_listen_legacy_main_file.files
      | map(attribute=''path'') | list + rsyslog_listen_legacy_include_files.files
      | map(attribute=''path'') | list }}'
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - configure_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - rsyslog_nolisten

- name: Ensure rsyslog Does Not Accept Remote Messages Unless Acting As Log Server
    - Comment Listen Config Lines Wherever Defined Using Legacy Syntax
  ansible.builtin.replace:
    path: '{{ item }}'
    regexp: '{{ rsyslog_listen_legacy_regex }}'
    replace: '# \1'
  loop: '{{ rsyslog_legacy_remote_listen_files }}'
  register: rsyslog_listen_legacy_comment
  when:
  - '"linux-base" in ansible_facts.packages'
  - rsyslog_legacy_remote_listen_files | length > 0
  tags:
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - configure_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - rsyslog_nolisten

- name: Ensure rsyslog Does Not Accept Remote Messages Unless Acting As Log Server
    - Define Rsyslog Config Lines Regex in RainerScript Syntax
  ansible.builtin.set_fact:
    rsyslog_listen_rainer_regex: ^\s*(module|input)\((load|type)="(imtcp|imudp)".*$
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - configure_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - rsyslog_nolisten

- name: Ensure rsyslog Does Not Accept Remote Messages Unless Acting As Log Server
    - Search for RainerScript Config Lines in Rsyslog Main Config File
  ansible.builtin.find:
    paths: /etc
    pattern: rsyslog.conf
    contains: '{{ rsyslog_listen_rainer_regex }}'
  register: rsyslog_rainer_remote_main_file
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - configure_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - rsyslog_nolisten

- name: Ensure rsyslog Does Not Accept Remote Messages Unless Acting As Log Server
    - Search for RainerScript Config Lines in Rsyslog Include Files
  ansible.builtin.find:
    paths: /etc/rsyslog.d/
    pattern: '*.conf'
    contains: '{{ rsyslog_listen_rainer_regex }}'
  register: rsyslog_rainer_remote_include_files
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - configure_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - rsyslog_nolisten

- name: Ensure rsyslog Does Not Accept Remote Messages Unless Acting As Log Server
    - Assemble List of Config Files With Listen Lines in RainerScript
  ansible.builtin.set_fact:
    rsyslog_rainer_remote_listen_files: '{{ rsyslog_rainer_remote_main_file.files
      | map(attribute=''path'') | list + rsyslog_rainer_remote_include_files.files
      | map(attribute=''path'') | list }}'
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - configure_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - rsyslog_nolisten

- name: Ensure rsyslog Does Not Accept Remote Messages Unless Acting As Log Server
    - Comment Listen Config Lines Wherever Defined Using RainerScript
  ansible.builtin.replace:
    path: '{{ item }}'
    regexp: '{{ rsyslog_listen_rainer_regex }}'
    replace: '# \1'
  loop: '{{ rsyslog_rainer_remote_listen_files }}'
  register: rsyslog_listen_rainer_comment
  when:
  - '"linux-base" in ansible_facts.packages'
  - rsyslog_rainer_remote_listen_files | length > 0
  tags:
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - configure_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - rsyslog_nolisten

- name: Ensure rsyslog Does Not Accept Remote Messages Unless Acting As Log Server
    - Restart Rsyslog if Any Line Were Commented Out
  ansible.builtin.service:
    name: rsyslog
    state: restarted
  when:
  - '"linux-base" in ansible_facts.packages'
  - rsyslog_listen_legacy_comment is changed or rsyslog_listen_rainer_comment is changed
  tags:
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - configure_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - rsyslog_nolisten

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

legacy_regex='^\s*\$(((Input(TCP|RELP)|UDP)ServerRun)|ModLoad\s+(imtcp|imudp|imrelp))'
rainer_regex='^\s*(module|input)\((load|type)="(imtcp|imudp)".*$'

readarray -t legacy_targets < <(grep -l -E -r "${legacy_regex[@]}" /etc/rsyslog.conf /etc/rsyslog.d/)
readarray -t rainer_targets < <(grep -l -E -r "${rainer_regex[@]}" /etc/rsyslog.conf /etc/rsyslog.d/)

config_changed=false
if [ ${#legacy_targets[@]} -gt 0 ]; then
    for target in "${legacy_targets[@]}"; do
        sed -E -i "/$legacy_regex/ s/^/# /" "$target"
    done
    config_changed=true
fi

if [ ${#rainer_targets[@]} -gt 0 ]; then
    for target in "${rainer_targets[@]}"; do
        sed -E -i "/$rainer_regex/ s/^/# /" "$target"
    done
    config_changed=true
fi

if $config_changed; then
    systemctl restart rsyslog.service
fi

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

Rule   Ensure rsyslog is Installed   [ref]

Rsyslog is installed by default. The rsyslog package can be installed with the following command:
 $ apt-get install rsyslog
Rationale:
The rsyslog package provides the rsyslog daemon, which provides system logging services.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_package_rsyslog_installed
References:
cis-csc1, 14, 15, 16, 3, 5, 6
cobit5APO11.04, BAI03.05, DSS05.04, DSS05.07, MEA02.01
disaCCI-000366, CCI-000154, CCI-001851
hipaa164.312(a)(2)(ii)
isa-62443-20094.3.3.3.9, 4.3.3.5.8, 4.3.4.4.7, 4.4.2.1, 4.4.2.2, 4.4.2.4
isa-62443-2013SR 2.10, SR 2.11, SR 2.12, SR 2.8, SR 2.9
iso27001-2013A.12.4.1, A.12.4.2, A.12.4.3, A.12.4.4, A.12.7.1
nistCM-6(a)
nist-csfPR.PT-1
os-srgSRG-OS-000479-GPOS-00224, SRG-OS-000051-GPOS-00024, SRG-OS-000480-GPOS-00227
cis6.1.3.1

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

class install_rsyslog {
  package { 'rsyslog':
    ensure => 'installed',
  }
}

Complexity:low
Disruption:low
Reboot:false
Strategy:enable
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - NIST-800-53-CM-6(a)
  - enable_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - package_rsyslog_installed

- name: Ensure rsyslog is installed
  package:
    name: rsyslog
    state: present
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-53-CM-6(a)
  - enable_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - package_rsyslog_installed


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

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

DEBIAN_FRONTEND=noninteractive apt-get install -y "rsyslog"

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

Rule   Enable rsyslog Service   [ref]

The rsyslog service provides syslog-style logging by default on Ubuntu 24.04. The rsyslog service can be enabled with the following command:
$ sudo systemctl enable rsyslog.service
Rationale:
The rsyslog service must be running in order to provide logging services, which are essential to system administration.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_service_rsyslog_enabled
References:
cis-csc1, 12, 13, 14, 15, 16, 2, 3, 5, 6, 7, 8, 9
cobit5APO10.01, APO10.03, APO10.04, APO10.05, APO11.04, APO13.01, BAI03.05, BAI04.04, DSS01.03, DSS03.05, DSS05.02, DSS05.04, DSS05.05, DSS05.07, MEA01.01, MEA01.02, MEA01.03, MEA01.04, MEA01.05, MEA02.01
disaCCI-000366
hipaa164.312(a)(2)(ii)
isa-62443-20094.3.2.6.7, 4.3.3.3.9, 4.3.3.5.8, 4.3.4.4.7, 4.4.2.1, 4.4.2.2, 4.4.2.4
isa-62443-2013SR 2.10, SR 2.11, SR 2.12, SR 2.8, SR 2.9, SR 6.1, SR 6.2, SR 7.1, SR 7.2
iso27001-2013A.12.1.3, A.12.4.1, A.12.4.2, A.12.4.3, A.12.4.4, A.12.7.1, A.14.2.7, A.15.2.1, A.15.2.2, A.17.2.1
nistCM-6(a), AU-4(1)
nist-csfDE.CM-1, DE.CM-3, DE.CM-7, ID.SC-4, PR.DS-4, PR.PT-1
os-srgSRG-OS-000480-GPOS-00227
cis6.1.3.2

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

class enable_rsyslog {
  service {'rsyslog':
    enable => true,
    ensure => 'running',
  }
}

Complexity:low
Disruption:low
Reboot:false
Strategy:enable
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - NIST-800-53-AU-4(1)
  - NIST-800-53-CM-6(a)
  - enable_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - service_rsyslog_enabled

- name: Enable rsyslog Service - Enable service rsyslog
  block:

  - name: Gather the package facts
    package_facts:
      manager: auto

  - name: Enable rsyslog Service - Enable Service rsyslog
    ansible.builtin.systemd:
      name: rsyslog
      enabled: true
      state: started
      masked: false
    when:
    - '"rsyslog" in ansible_facts.packages'
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-53-AU-4(1)
  - NIST-800-53-CM-6(a)
  - enable_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - service_rsyslog_enabled


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

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

SYSTEMCTL_EXEC='/usr/bin/systemctl'
"$SYSTEMCTL_EXEC" unmask 'rsyslog.service'
"$SYSTEMCTL_EXEC" start 'rsyslog.service'
"$SYSTEMCTL_EXEC" enable 'rsyslog.service'

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

Rule   Ensure rsyslog Default File Permissions Configured   [ref]

rsyslog will create logfiles that do not already exist on the system. This settings controls what permissions will be applied to these newly created files.
Rationale:
It is important to ensure that log files have the correct permissions to ensure that sensitive data is archived and protected.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_rsyslog_filecreatemode
References:
cis6.1.3.4

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

- name: Ensure rsyslog Default File Permissions Configured - Search for $FileCreateMode
    Parameter in rsyslog Main Config File
  ansible.builtin.find:
    paths: /etc
    pattern: rsyslog.conf
    contains: ^\s*\$FileCreateMode\s*\d+
  register: rsyslog_main_file_with_filecreatemode
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - configure_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - rsyslog_filecreatemode

- name: Ensure rsyslog Default File Permissions Configured - Search for $FileCreateMode
    Parameter in rsyslog Include Files
  ansible.builtin.find:
    paths: /etc/rsyslog.d/
    pattern: '*.conf'
    contains: ^\s*\$FileCreateMode\s*\d+
  register: rsyslog_includes_with_filecreatemode
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - configure_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - rsyslog_filecreatemode

- name: Ensure rsyslog Default File Permissions Configured - Assemble List of rsyslog
    Configuration Files with $FileCreateMode Parameter
  ansible.builtin.set_fact:
    rsyslog_filecreatemode_files: '{{ rsyslog_main_file_with_filecreatemode.files
      | map(attribute=''path'') | list + rsyslog_includes_with_filecreatemode.files
      | map(attribute=''path'') | list }}'
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - configure_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - rsyslog_filecreatemode

- name: Ensure rsyslog Default File Permissions Configured - Remove $FileCreateMode
    Parameter from Multiple Files to Avoid Conflicts
  ansible.builtin.lineinfile:
    path: '{{ item }}'
    regexp: \$FileCreateMode.*
    state: absent
  register: result_rsyslog_filecreatemode_removed
  loop: '{{ rsyslog_filecreatemode_files }}'
  when:
  - '"linux-base" in ansible_facts.packages'
  - rsyslog_filecreatemode_files | length > 1
  tags:
  - configure_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - rsyslog_filecreatemode

- name: Ensure rsyslog Default File Permissions Configured - Add $FileCreateMode Parameter
    and Expected Value
  ansible.builtin.lineinfile:
    path: /etc/rsyslog.d/99-rsyslog_filecreatemode.conf
    line: $FileCreateMode 0640
    mode: 416
    create: true
  when:
  - '"linux-base" in ansible_facts.packages'
  - rsyslog_filecreatemode_files | length == 0 or result_rsyslog_filecreatemode_removed
    is not skipped
  tags:
  - configure_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - rsyslog_filecreatemode

- name: Ensure rsyslog Default File Permissions Configured - Ensure Correct Value
    of Existing $FileCreateMode Parameter
  ansible.builtin.lineinfile:
    path: '{{ item }}'
    regexp: ^\$FileCreateMode
    line: $FileCreateMode 0640
  loop: '{{ rsyslog_filecreatemode_files }}'
  when:
  - '"linux-base" in ansible_facts.packages'
  - rsyslog_filecreatemode_files | length == 1
  tags:
  - configure_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - rsyslog_filecreatemode

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

readarray -t targets < <(grep -H '^\s*$FileCreateMode' /etc/rsyslog.conf /etc/rsyslog.d/*)

# if $FileCreateMode set in multiple places
if [ ${#targets[@]} -gt 1 ]; then
    # delete all and create new entry with expected value
    sed -i '/^\s*$FileCreateMode/d' /etc/rsyslog.conf /etc/rsyslog.d/*
    echo '$FileCreateMode 0640' > /etc/rsyslog.d/99-rsyslog_filecreatemode.conf
# if $FileCreateMode set in only one place
elif [ "${#targets[@]}" -eq 1 ]; then
    filename=$(echo "${targets[0]}" | cut -d':' -f1)
    value=$(echo "${targets[0]}" | cut -d' ' -f2)
    #convert to decimal and bitwise or operation
    result=$((8#$value | 416))
    # if more permissive than expected, then set it to 0640
    if [ $result -ne 416 ]; then
        # if value is wrong remove it
        sed -i '/^\s*$FileCreateMode/d' $filename
        echo '$FileCreateMode 0640' > $filename
    fi
else
    echo '$FileCreateMode 0640' > /etc/rsyslog.d/99-rsyslog_filecreatemode.conf
fi

systemctl restart rsyslog.service

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi
Group   Network Configuration and Firewalls   Group contains 10 groups and 45 rules
[ref]   Most systems must be connected to a network of some sort, and this brings with it the substantial risk of network attack. This section discusses the security impact of decisions about networking which must be made when configuring a system.

This section also discusses firewalls, network access controls, and other network security frameworks, which allow system-level rules to be written that can limit an attackers' ability to connect to your system. These rules can specify that network traffic should be allowed or denied from certain IP addresses, hosts, and networks. The rules can also specify which of the system's network services are available to particular hosts or networks.
Group   iptables and ip6tables   Group contains 2 groups and 7 rules
[ref]   A host-based firewall called netfilter is included as part of the Linux kernel distributed with the system. It is activated by default. This firewall is controlled by the program iptables, and the entire capability is frequently referred to by this name. An analogous program called ip6tables handles filtering for IPv6.

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

This section provides basic information about strengthening the iptables and ip6tables configurations included with the system. For more complete information that may allow the construction of a sophisticated ruleset tailored to your environment, please consult the references at the end of this section.
Group   Inspect and Activate Default Rules   Group contains 1 rule
[ref]   View the currently-enforced iptables rules by running the command:
$ sudo iptables -nL --line-numbers
The command is analogous for ip6tables.

If the firewall does not appear to be active (i.e., no rules appear), activate it and ensure that it starts at boot by issuing the following commands (and analogously for ip6tables):
$ sudo service iptables restart
The default iptables rules are:
Chain INPUT (policy ACCEPT)
num  target     prot opt source       destination
1    ACCEPT     all  --  0.0.0.0/0    0.0.0.0/0    state RELATED,ESTABLISHED 
2    ACCEPT     icmp --  0.0.0.0/0    0.0.0.0/0
3    ACCEPT     all  --  0.0.0.0/0    0.0.0.0/0
4    ACCEPT     tcp  --  0.0.0.0/0    0.0.0.0/0    state NEW tcp dpt:22 
5    REJECT     all  --  0.0.0.0/0    0.0.0.0/0    reject-with icmp-host-prohibited 

Chain FORWARD (policy ACCEPT)
num  target     prot opt source       destination
1    REJECT     all  --  0.0.0.0/0    0.0.0.0/0    reject-with icmp-host-prohibited 

Chain OUTPUT (policy ACCEPT)
num  target     prot opt source       destination
The ip6tables default rules are essentially the same.

Rule   Set configuration for loopback traffic   [ref]

Configure the loopback interface to accept traffic. Configure all other interfaces to deny traffic to the loopback network.
Warning:  Changing firewall settings while connected over network can result in being locked out of the system.
Rationale:
Loopback traffic is generated between processes on machine and is typically critical to operation of the system. The loopback interface is the only place that loopback network traffic should be seen, all other interfaces should ignore traffic on this network as an anti-spoofing measure.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_set_loopback_traffic
References:
pcidssReq-1.3
cis4.4.2.2
pcidss41.4.1, 1.4

- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - PCI-DSS-Req-1.3
  - PCI-DSSv4-1.4
  - PCI-DSSv4-1.4.1
  - medium_severity
  - set_loopback_traffic

- name: Allow incoming traffic on the loopback interface
  ansible.builtin.iptables:
    chain: INPUT
    in_interface: lo
    jump: ACCEPT
  when: ( not ( "nftables" in ansible_facts.packages ) and not ( "ufw" in ansible_facts.packages
    ) and "iptables" in ansible_facts.packages )
  tags:
  - PCI-DSS-Req-1.3
  - PCI-DSSv4-1.4
  - PCI-DSSv4-1.4.1
  - medium_severity
  - set_loopback_traffic

- name: Allow outgoing traffic on the loopback interface
  ansible.builtin.iptables:
    chain: OUTPUT
    out_interface: lo
    jump: ACCEPT
  when: ( not ( "nftables" in ansible_facts.packages ) and not ( "ufw" in ansible_facts.packages
    ) and "iptables" in ansible_facts.packages )
  tags:
  - PCI-DSS-Req-1.3
  - PCI-DSSv4-1.4
  - PCI-DSSv4-1.4.1
  - medium_severity
  - set_loopback_traffic

- name: Drop incoming traffic from the localhost
  ansible.builtin.iptables:
    chain: INPUT
    source: 127.0.0.0/8
    jump: DROP
  when: ( not ( "nftables" in ansible_facts.packages ) and not ( "ufw" in ansible_facts.packages
    ) and "iptables" in ansible_facts.packages )
  tags:
  - PCI-DSS-Req-1.3
  - PCI-DSSv4-1.4
  - PCI-DSSv4-1.4.1
  - medium_severity
  - set_loopback_traffic

# Remediation is applicable only in certain platforms
if ( ! ( dpkg-query --show --showformat='${db:Status-Status}\n' 'nftables' 2>/dev/null | grep -q installed ) && ! ( dpkg-query --show --showformat='${db:Status-Status}\n' 'ufw' 2>/dev/null | grep -q installed ) && dpkg-query --show --showformat='${db:Status-Status}\n' 'iptables' 2>/dev/null | grep -q installed ); then

iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
iptables -A INPUT -s 127.0.0.0/8 -j DROP

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi
Group   Strengthen the Default Ruleset   Group contains 2 rules
[ref]   The default rules can be strengthened. The system scripts that activate the firewall rules expect them to be defined in the configuration files iptables and ip6tables in the directory /etc/sysconfig. Many of the lines in these files are similar to the command line arguments that would be provided to the programs /sbin/iptables or /sbin/ip6tables - but some are quite different.

The following recommendations describe how to strengthen the default ruleset configuration file. An alternative to editing this configuration file is to create a shell script that makes calls to the iptables program to load in rules, and then invokes service iptables save to write those loaded rules to /etc/sysconfig/iptables.

The following alterations can be made directly to /etc/sysconfig/iptables and /etc/sysconfig/ip6tables. Instructions apply to both unless otherwise noted. Language and address conventions for regular iptables are used throughout this section; configuration for ip6tables will be either analogous or explicitly covered.
Warning:  The program system-config-securitylevel allows additional services to penetrate the default firewall rules and automatically adjusts /etc/sysconfig/iptables. This program is only useful if the default ruleset meets your security requirements. Otherwise, this program should not be used to make changes to the firewall configuration because it re-writes the saved configuration file.

Rule   Ensure iptables Firewall Rules Exist for All Open Ports   [ref]

Any ports that have been opened on non-loopback addresses need firewall rules to govern traffic.
Warning:  Changing firewall settings while connected over network can result in being locked out of the system.
Rationale:
Without a firewall rule configured for open ports default firewall policy will drop all packets to these ports.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_iptables_rules_for_open_ports
References:
cis4.4.2.4

Rule   Set Default iptables Policy for Incoming Packets   [ref]

To set the default policy to DROP (instead of ACCEPT) for the built-in INPUT chain which processes incoming packets, add or correct the following line in /etc/sysconfig/iptables:
:INPUT DROP [0:0]
Rationale:
In iptables the default policy is applied only after all the applicable rules in the table are examined for a match. Setting the default policy to DROP implements proper design for a firewall, i.e. any packets which are not explicitly permitted should not be accepted.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_set_iptables_default_rule
References:
cis-csc11, 14, 3, 9
cobit5BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.05, DSS06.06
isa-62443-20094.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3
isa-62443-2013SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 7.6
iso27001-2013A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, A.9.1.2
nistCA-3(5), CM-7(b), SC-7(23), CM-6(a)
nist-csfPR.IP-1, PR.PT-3
cis4.4.2.1

# Remediation is applicable only in certain platforms
if dpkg-query --show --showformat='${db:Status-Status}\n' 'iptables' 2>/dev/null | grep -q installed && { ( ! ( dpkg-query --show --showformat='${db:Status-Status}\n' 'nftables' 2>/dev/null | grep -q installed ) && ! ( dpkg-query --show --showformat='${db:Status-Status}\n' 'ufw' 2>/dev/null | grep -q installed ) ); }; then

sed -i 's/^:INPUT ACCEPT.*/:INPUT DROP [0:0]/g' /etc/sysconfig/iptables

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

Rule   Install iptables-persistent Package   [ref]

The iptables-persistent package can be installed with the following command:
$ apt-get install iptables-persistent
Rationale:
A method of configuring and maintaining firewall rules is necessary to configure a Host Based Firewall.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_package_iptables-persistent_installed
References:
cis4.4.1.1

Complexity:low
Disruption:low
Reboot:false
Strategy:enable
include install_iptables-persistent

class install_iptables-persistent {
  package { 'iptables-persistent':
    ensure => 'installed',
  }
}

Complexity:low
Disruption:low
Reboot:false
Strategy:enable
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - enable_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - package_iptables-persistent_installed

- name: Ensure iptables-persistent is installed
  package:
    name: iptables-persistent
    state: present
  when: '"iptables" in ansible_facts.packages'
  tags:
  - enable_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - package_iptables-persistent_installed


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

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

DEBIAN_FRONTEND=noninteractive apt-get install -y "iptables-persistent"

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

Rule   Install iptables Package   [ref]

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

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

class install_iptables {
  package { 'iptables':
    ensure => 'installed',
  }
}

Complexity:low
Disruption:low
Reboot:false
Strategy:enable
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - NIST-800-53-CM-6(a)
  - PCI-DSS-Req-1.4.1
  - enable_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - package_iptables_installed

- name: Ensure iptables is installed
  package:
    name: iptables
    state: present
  when: ( "linux-base" in ansible_facts.packages )
  tags:
  - NIST-800-53-CM-6(a)
  - PCI-DSS-Req-1.4.1
  - enable_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - package_iptables_installed


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

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

DEBIAN_FRONTEND=noninteractive apt-get install -y "iptables"

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

Rule   Remove iptables-persistent Package   [ref]

The iptables-persistent package can be removed with the following command:
$ apt-get remove iptables-persistent
Rationale:
Running both ufw and the services included in the iptables-persistent package may lead to conflict.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_package_iptables-persistent_removed
References:
cis4.2.2

Complexity:low
Disruption:low
Reboot:false
Strategy:disable
include remove_iptables-persistent

class remove_iptables-persistent {
  package { 'iptables-persistent':
    ensure => 'purged',
  }
}

Complexity:low
Disruption:low
Reboot:false
Strategy:disable
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - disable_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - package_iptables-persistent_removed

- name: Ensure iptables-persistent is removed
  package:
    name: iptables-persistent
    state: absent
  when: '"ufw" in ansible_facts.packages'
  tags:
  - disable_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - package_iptables-persistent_removed

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

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

DEBIAN_FRONTEND=noninteractive apt-get remove -y "iptables-persistent"

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

Rule   Ensure iptables are flushed   [ref]

nftables is a replacement for iptables, ip6tables, ebtables and arptables
Rationale:
It is possible to mix iptables and nftables. However, this increases complexity and also the chance to introduce errors. For simplicity flush out all iptables rules, and ensure it is not loaded.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_ensure_iptables_are_flushed
References:
cis4.3.3
Group   IPv6   Group contains 1 group and 7 rules
[ref]   The system includes support for Internet Protocol version 6. A major and often-mentioned improvement over IPv4 is its enormous increase in the number of available addresses. Another important feature is its support for automatic configuration of many network settings.
Group   Configure IPv6 Settings if Necessary   Group contains 7 rules
[ref]   A major feature of IPv6 is the extent to which systems implementing it can automatically configure their networking devices using information from the network. From a security perspective, manually configuring important configuration information is preferable to accepting it from the network in an unauthenticated fashion.

Rule   Configure Accepting Router Advertisements on All IPv6 Interfaces   [ref]

To set the runtime status of the net.ipv6.conf.all.accept_ra kernel parameter, run the following command:
$ sudo sysctl -w net.ipv6.conf.all.accept_ra=0
To make sure that the setting is persistent, add the following line to a file in the directory /etc/sysctl.d:
net.ipv6.conf.all.accept_ra = 0
Rationale:
An illicit router advertisement message could result in a man-in-the-middle attack.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_sysctl_net_ipv6_conf_all_accept_ra
References:
cis-csc11, 14, 3, 9
cobit5BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.05, DSS06.06
cui3.1.20
disaCCI-000366
isa-62443-20094.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3
isa-62443-2013SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 7.6
iso27001-2013A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, A.9.1.2
nistCM-7(a), CM-7(b), CM-6(a)
nist-csfPR.IP-1, PR.PT-3
os-srgSRG-OS-000480-GPOS-00227
cis3.3.11

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv6_conf_all_accept_ra

- name: List /etc/sysctl.d/*.conf files
  find:
    paths:
    - /etc/sysctl.d/
    - /run/sysctl.d/
    - /usr/local/lib/sysctl.d/
    contains: ^[\s]*net.ipv6.conf.all.accept_ra.*$
    patterns: '*.conf'
    file_type: any
  register: find_sysctl_d
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv6_conf_all_accept_ra

- name: Comment out any occurrences of net.ipv6.conf.all.accept_ra from config files
  replace:
    path: '{{ item.path }}'
    regexp: ^[\s]*net.ipv6.conf.all.accept_ra
    replace: '#net.ipv6.conf.all.accept_ra'
  loop: '{{ find_sysctl_d.files }}'
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv6_conf_all_accept_ra
- name: XCCDF Value sysctl_net_ipv6_conf_all_accept_ra_value # promote to variable
  set_fact:
    sysctl_net_ipv6_conf_all_accept_ra_value: !!str 0
  tags:
    - always

- name: Ensure sysctl net.ipv6.conf.all.accept_ra is set
  sysctl:
    name: net.ipv6.conf.all.accept_ra
    value: '{{ sysctl_net_ipv6_conf_all_accept_ra_value }}'
    sysctl_file: /etc/sysctl.conf
    state: present
    reload: true
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv6_conf_all_accept_ra

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 net.ipv6.conf.all.accept_ra from /etc/sysctl.d/*.conf files

for f in /etc/sysctl.d/*.conf /run/sysctl.d/*.conf /usr/local/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]*net.ipv6.conf.all.accept_ra.*$' $f | uniq )
  if ! test -z "$matching_list"; then
    while IFS= read -r entry; do
      escaped_entry=$(sed -e 's|/|\\/|g' <<< "$entry")
      # comment out "net.ipv6.conf.all.accept_ra" 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_net_ipv6_conf_all_accept_ra_value='0'


#
# Set runtime for net.ipv6.conf.all.accept_ra
#
if [[ "$OSCAP_BOOTC_BUILD" != "YES" ]] ; then
    /sbin/sysctl -q -n -w net.ipv6.conf.all.accept_ra="$sysctl_net_ipv6_conf_all_accept_ra_value"
fi

#
# If net.ipv6.conf.all.accept_ra present in /etc/sysctl.conf, change value to appropriate value
#	else, add "net.ipv6.conf.all.accept_ra = 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' <<< "^net.ipv6.conf.all.accept_ra")

# shellcheck disable=SC2059
printf -v formatted_output "%s = %s" "$stripped_key" "$sysctl_net_ipv6_conf_all_accept_ra_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 "^net.ipv6.conf.all.accept_ra\\>" "${SYSCONFIG_FILE}"; then
    escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
    LC_ALL=C sed -i --follow-symlinks "s/^net.ipv6.conf.all.accept_ra\\>.*/$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

Rule   Disable Accepting ICMP Redirects for All IPv6 Interfaces   [ref]

To set the runtime status of the net.ipv6.conf.all.accept_redirects kernel parameter, run the following command:
$ sudo sysctl -w net.ipv6.conf.all.accept_redirects=0
To make sure that the setting is persistent, add the following line to a file in the directory /etc/sysctl.d:
net.ipv6.conf.all.accept_redirects = 0
Rationale:
An illicit ICMP redirect message could result in a man-in-the-middle attack.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_sysctl_net_ipv6_conf_all_accept_redirects
References:
cis-csc11, 14, 3, 9
cobit5BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.05, DSS06.06
cui3.1.20
disaCCI-000366
isa-62443-20094.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3
isa-62443-2013SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 7.6
iso27001-2013A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, A.9.1.2
nistCM-7(a), CM-7(b), CM-6(a), CM-6(b), CM-6.1(iv)
nist-csfPR.IP-1, PR.PT-3
os-srgSRG-OS-000480-GPOS-00227
anssiR13
cis3.3.5

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-6(b)
  - NIST-800-53-CM-6.1(iv)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv6_conf_all_accept_redirects

- name: List /etc/sysctl.d/*.conf files
  find:
    paths:
    - /etc/sysctl.d/
    - /run/sysctl.d/
    - /usr/local/lib/sysctl.d/
    contains: ^[\s]*net.ipv6.conf.all.accept_redirects.*$
    patterns: '*.conf'
    file_type: any
  register: find_sysctl_d
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-6(b)
  - NIST-800-53-CM-6.1(iv)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv6_conf_all_accept_redirects

- name: Comment out any occurrences of net.ipv6.conf.all.accept_redirects from config
    files
  replace:
    path: '{{ item.path }}'
    regexp: ^[\s]*net.ipv6.conf.all.accept_redirects
    replace: '#net.ipv6.conf.all.accept_redirects'
  loop: '{{ find_sysctl_d.files }}'
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-6(b)
  - NIST-800-53-CM-6.1(iv)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv6_conf_all_accept_redirects
- name: XCCDF Value sysctl_net_ipv6_conf_all_accept_redirects_value # promote to variable
  set_fact:
    sysctl_net_ipv6_conf_all_accept_redirects_value: !!str 0
  tags:
    - always

- name: Ensure sysctl net.ipv6.conf.all.accept_redirects is set
  sysctl:
    name: net.ipv6.conf.all.accept_redirects
    value: '{{ sysctl_net_ipv6_conf_all_accept_redirects_value }}'
    sysctl_file: /etc/sysctl.conf
    state: present
    reload: true
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-6(b)
  - NIST-800-53-CM-6.1(iv)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv6_conf_all_accept_redirects

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 net.ipv6.conf.all.accept_redirects from /etc/sysctl.d/*.conf files

for f in /etc/sysctl.d/*.conf /run/sysctl.d/*.conf /usr/local/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]*net.ipv6.conf.all.accept_redirects.*$' $f | uniq )
  if ! test -z "$matching_list"; then
    while IFS= read -r entry; do
      escaped_entry=$(sed -e 's|/|\\/|g' <<< "$entry")
      # comment out "net.ipv6.conf.all.accept_redirects" 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_net_ipv6_conf_all_accept_redirects_value='0'


#
# Set runtime for net.ipv6.conf.all.accept_redirects
#
if [[ "$OSCAP_BOOTC_BUILD" != "YES" ]] ; then
    /sbin/sysctl -q -n -w net.ipv6.conf.all.accept_redirects="$sysctl_net_ipv6_conf_all_accept_redirects_value"
fi

#
# If net.ipv6.conf.all.accept_redirects present in /etc/sysctl.conf, change value to appropriate value
#	else, add "net.ipv6.conf.all.accept_redirects = 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' <<< "^net.ipv6.conf.all.accept_redirects")

# shellcheck disable=SC2059
printf -v formatted_output "%s = %s" "$stripped_key" "$sysctl_net_ipv6_conf_all_accept_redirects_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 "^net.ipv6.conf.all.accept_redirects\\>" "${SYSCONFIG_FILE}"; then
    escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
    LC_ALL=C sed -i --follow-symlinks "s/^net.ipv6.conf.all.accept_redirects\\>.*/$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

Rule   Disable Kernel Parameter for Accepting Source-Routed Packets on all IPv6 Interfaces   [ref]

To set the runtime status of the net.ipv6.conf.all.accept_source_route kernel parameter, run the following command:
$ sudo sysctl -w net.ipv6.conf.all.accept_source_route=0
To make sure that the setting is persistent, add the following line to a file in the directory /etc/sysctl.d:
net.ipv6.conf.all.accept_source_route = 0
Rationale:
Source-routed packets allow the source of the packet to suggest routers forward the packet along a different path than configured on the router, which can be used to bypass network security measures. This requirement applies only to the forwarding of source-routerd traffic, such as when IPv6 forwarding is enabled and the system is functioning as a router.

Accepting source-routed packets in the IPv6 protocol has few legitimate uses. It should be disabled unless it is absolutely required.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_sysctl_net_ipv6_conf_all_accept_source_route
References:
cis-csc1, 12, 13, 14, 15, 16, 18, 4, 6, 8, 9
cobit5APO01.06, APO13.01, DSS01.05, DSS03.01, DSS05.02, DSS05.04, DSS05.07, DSS06.02
cui3.1.20
disaCCI-000366
isa-62443-20094.2.3.4, 4.3.3.4, 4.4.3.3
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.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.12.1.1, A.12.1.2, A.13.1.1, A.13.1.2, A.13.1.3, A.13.2.1, A.13.2.2, 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-7(a), CM-7(b), CM-6(a)
nist-csfDE.AE-1, ID.AM-3, PR.AC-5, PR.DS-5, PR.PT-4
os-srgSRG-OS-000480-GPOS-00227
anssiR13
cis3.3.8

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv6_conf_all_accept_source_route

- name: List /etc/sysctl.d/*.conf files
  find:
    paths:
    - /etc/sysctl.d/
    - /run/sysctl.d/
    - /usr/local/lib/sysctl.d/
    contains: ^[\s]*net.ipv6.conf.all.accept_source_route.*$
    patterns: '*.conf'
    file_type: any
  register: find_sysctl_d
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv6_conf_all_accept_source_route

- name: Comment out any occurrences of net.ipv6.conf.all.accept_source_route from
    config files
  replace:
    path: '{{ item.path }}'
    regexp: ^[\s]*net.ipv6.conf.all.accept_source_route
    replace: '#net.ipv6.conf.all.accept_source_route'
  loop: '{{ find_sysctl_d.files }}'
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv6_conf_all_accept_source_route
- name: XCCDF Value sysctl_net_ipv6_conf_all_accept_source_route_value # promote to variable
  set_fact:
    sysctl_net_ipv6_conf_all_accept_source_route_value: !!str 0
  tags:
    - always

- name: Ensure sysctl net.ipv6.conf.all.accept_source_route is set
  sysctl:
    name: net.ipv6.conf.all.accept_source_route
    value: '{{ sysctl_net_ipv6_conf_all_accept_source_route_value }}'
    sysctl_file: /etc/sysctl.conf
    state: present
    reload: true
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv6_conf_all_accept_source_route

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 net.ipv6.conf.all.accept_source_route from /etc/sysctl.d/*.conf files

for f in /etc/sysctl.d/*.conf /run/sysctl.d/*.conf /usr/local/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]*net.ipv6.conf.all.accept_source_route.*$' $f | uniq )
  if ! test -z "$matching_list"; then
    while IFS= read -r entry; do
      escaped_entry=$(sed -e 's|/|\\/|g' <<< "$entry")
      # comment out "net.ipv6.conf.all.accept_source_route" 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_net_ipv6_conf_all_accept_source_route_value='0'


#
# Set runtime for net.ipv6.conf.all.accept_source_route
#
if [[ "$OSCAP_BOOTC_BUILD" != "YES" ]] ; then
    /sbin/sysctl -q -n -w net.ipv6.conf.all.accept_source_route="$sysctl_net_ipv6_conf_all_accept_source_route_value"
fi

#
# If net.ipv6.conf.all.accept_source_route present in /etc/sysctl.conf, change value to appropriate value
#	else, add "net.ipv6.conf.all.accept_source_route = 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' <<< "^net.ipv6.conf.all.accept_source_route")

# shellcheck disable=SC2059
printf -v formatted_output "%s = %s" "$stripped_key" "$sysctl_net_ipv6_conf_all_accept_source_route_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 "^net.ipv6.conf.all.accept_source_route\\>" "${SYSCONFIG_FILE}"; then
    escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
    LC_ALL=C sed -i --follow-symlinks "s/^net.ipv6.conf.all.accept_source_route\\>.*/$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

Rule   Disable Kernel Parameter for IPv6 Forwarding   [ref]

To set the runtime status of the net.ipv6.conf.all.forwarding kernel parameter, run the following command:
$ sudo sysctl -w net.ipv6.conf.all.forwarding=0
To make sure that the setting is persistent, add the following line to a file in the directory /etc/sysctl.d:
net.ipv6.conf.all.forwarding = 0
Rationale:
IP forwarding permits the kernel to forward packets from one network interface to another. The ability to forward packets between two networks is only appropriate for systems acting as routers.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_sysctl_net_ipv6_conf_all_forwarding
References:
cis-csc1, 11, 12, 13, 14, 15, 16, 2, 3, 7, 8, 9
cobit5APO13.01, BAI04.04, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS01.03, DSS03.05, DSS05.02, DSS05.05, DSS05.07, DSS06.06
disaCCI-000366
isa-62443-20094.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3
isa-62443-2013SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 6.2, SR 7.1, SR 7.2, SR 7.6
iso27001-2013A.12.1.2, A.12.1.3, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, A.17.2.1, A.9.1.2
nistCM-7(a), CM-7(b), CM-6(a), CM-6(b), CM-6.1(iv)
nist-csfDE.CM-1, PR.DS-4, PR.IP-1, PR.PT-3
os-srgSRG-OS-000480-GPOS-00227
cis3.3.1

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-CM-6(b)
  - NIST-800-53-CM-6.1(iv)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv6_conf_all_forwarding

- name: List /etc/sysctl.d/*.conf files
  find:
    paths:
    - /etc/sysctl.d/
    - /run/sysctl.d/
    - /usr/local/lib/sysctl.d/
    contains: ^[\s]*net.ipv6.conf.all.forwarding.*$
    patterns: '*.conf'
    file_type: any
  register: find_sysctl_d
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-6(b)
  - NIST-800-53-CM-6.1(iv)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv6_conf_all_forwarding

- name: Comment out any occurrences of net.ipv6.conf.all.forwarding from config files
  replace:
    path: '{{ item.path }}'
    regexp: ^[\s]*net.ipv6.conf.all.forwarding
    replace: '#net.ipv6.conf.all.forwarding'
  loop: '{{ find_sysctl_d.files }}'
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-6(b)
  - NIST-800-53-CM-6.1(iv)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv6_conf_all_forwarding
- name: XCCDF Value sysctl_net_ipv6_conf_all_forwarding_value # promote to variable
  set_fact:
    sysctl_net_ipv6_conf_all_forwarding_value: !!str 0
  tags:
    - always

- name: Ensure sysctl net.ipv6.conf.all.forwarding is set
  sysctl:
    name: net.ipv6.conf.all.forwarding
    value: '{{ sysctl_net_ipv6_conf_all_forwarding_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-CM-6(b)
  - NIST-800-53-CM-6.1(iv)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv6_conf_all_forwarding

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 net.ipv6.conf.all.forwarding from /etc/sysctl.d/*.conf files

for f in /etc/sysctl.d/*.conf /run/sysctl.d/*.conf /usr/local/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]*net.ipv6.conf.all.forwarding.*$' $f | uniq )
  if ! test -z "$matching_list"; then
    while IFS= read -r entry; do
      escaped_entry=$(sed -e 's|/|\\/|g' <<< "$entry")
      # comment out "net.ipv6.conf.all.forwarding" 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_net_ipv6_conf_all_forwarding_value='0'


#
# Set runtime for net.ipv6.conf.all.forwarding
#
if [[ "$OSCAP_BOOTC_BUILD" != "YES" ]] ; then
    /sbin/sysctl -q -n -w net.ipv6.conf.all.forwarding="$sysctl_net_ipv6_conf_all_forwarding_value"
fi

#
# If net.ipv6.conf.all.forwarding present in /etc/sysctl.conf, change value to appropriate value
#	else, add "net.ipv6.conf.all.forwarding = 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' <<< "^net.ipv6.conf.all.forwarding")

# shellcheck disable=SC2059
printf -v formatted_output "%s = %s" "$stripped_key" "$sysctl_net_ipv6_conf_all_forwarding_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 "^net.ipv6.conf.all.forwarding\\>" "${SYSCONFIG_FILE}"; then
    escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
    LC_ALL=C sed -i --follow-symlinks "s/^net.ipv6.conf.all.forwarding\\>.*/$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

Rule   Disable Accepting Router Advertisements on all IPv6 Interfaces by Default   [ref]

To set the runtime status of the net.ipv6.conf.default.accept_ra kernel parameter, run the following command:
$ sudo sysctl -w net.ipv6.conf.default.accept_ra=0
To make sure that the setting is persistent, add the following line to a file in the directory /etc/sysctl.d:
net.ipv6.conf.default.accept_ra = 0
Rationale:
An illicit router advertisement message could result in a man-in-the-middle attack.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_sysctl_net_ipv6_conf_default_accept_ra
References:
cis-csc11, 14, 3, 9
cobit5BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.05, DSS06.06
cui3.1.20
disaCCI-000366
isa-62443-20094.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3
isa-62443-2013SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 7.6
iso27001-2013A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, A.9.1.2
nistCM-7(a), CM-7(b), CM-6(a)
nist-csfPR.IP-1, PR.PT-3
os-srgSRG-OS-000480-GPOS-00227
cis3.3.11

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv6_conf_default_accept_ra

- name: List /etc/sysctl.d/*.conf files
  find:
    paths:
    - /etc/sysctl.d/
    - /run/sysctl.d/
    - /usr/local/lib/sysctl.d/
    contains: ^[\s]*net.ipv6.conf.default.accept_ra.*$
    patterns: '*.conf'
    file_type: any
  register: find_sysctl_d
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv6_conf_default_accept_ra

- name: Comment out any occurrences of net.ipv6.conf.default.accept_ra from config
    files
  replace:
    path: '{{ item.path }}'
    regexp: ^[\s]*net.ipv6.conf.default.accept_ra
    replace: '#net.ipv6.conf.default.accept_ra'
  loop: '{{ find_sysctl_d.files }}'
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv6_conf_default_accept_ra
- name: XCCDF Value sysctl_net_ipv6_conf_default_accept_ra_value # promote to variable
  set_fact:
    sysctl_net_ipv6_conf_default_accept_ra_value: !!str 0
  tags:
    - always

- name: Ensure sysctl net.ipv6.conf.default.accept_ra is set
  sysctl:
    name: net.ipv6.conf.default.accept_ra
    value: '{{ sysctl_net_ipv6_conf_default_accept_ra_value }}'
    sysctl_file: /etc/sysctl.conf
    state: present
    reload: true
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv6_conf_default_accept_ra

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 net.ipv6.conf.default.accept_ra from /etc/sysctl.d/*.conf files

for f in /etc/sysctl.d/*.conf /run/sysctl.d/*.conf /usr/local/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]*net.ipv6.conf.default.accept_ra.*$' $f | uniq )
  if ! test -z "$matching_list"; then
    while IFS= read -r entry; do
      escaped_entry=$(sed -e 's|/|\\/|g' <<< "$entry")
      # comment out "net.ipv6.conf.default.accept_ra" 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_net_ipv6_conf_default_accept_ra_value='0'


#
# Set runtime for net.ipv6.conf.default.accept_ra
#
if [[ "$OSCAP_BOOTC_BUILD" != "YES" ]] ; then
    /sbin/sysctl -q -n -w net.ipv6.conf.default.accept_ra="$sysctl_net_ipv6_conf_default_accept_ra_value"
fi

#
# If net.ipv6.conf.default.accept_ra present in /etc/sysctl.conf, change value to appropriate value
#	else, add "net.ipv6.conf.default.accept_ra = 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' <<< "^net.ipv6.conf.default.accept_ra")

# shellcheck disable=SC2059
printf -v formatted_output "%s = %s" "$stripped_key" "$sysctl_net_ipv6_conf_default_accept_ra_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 "^net.ipv6.conf.default.accept_ra\\>" "${SYSCONFIG_FILE}"; then
    escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
    LC_ALL=C sed -i --follow-symlinks "s/^net.ipv6.conf.default.accept_ra\\>.*/$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

Rule   Disable Kernel Parameter for Accepting ICMP Redirects by Default on IPv6 Interfaces   [ref]

To set the runtime status of the net.ipv6.conf.default.accept_redirects kernel parameter, run the following command:
$ sudo sysctl -w net.ipv6.conf.default.accept_redirects=0
To make sure that the setting is persistent, add the following line to a file in the directory /etc/sysctl.d:
net.ipv6.conf.default.accept_redirects = 0
Rationale:
An illicit ICMP redirect message could result in a man-in-the-middle attack.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_sysctl_net_ipv6_conf_default_accept_redirects
References:
cis-csc11, 14, 3, 9
cobit5BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.05, DSS06.06
cui3.1.20
disaCCI-000366
isa-62443-20094.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3
isa-62443-2013SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 7.6
iso27001-2013A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, A.9.1.2
nistCM-7(a), CM-7(b), CM-6(a)
nist-csfPR.IP-1, PR.PT-3
os-srgSRG-OS-000480-GPOS-00227
anssiR13
cis3.3.5

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv6_conf_default_accept_redirects

- name: List /etc/sysctl.d/*.conf files
  find:
    paths:
    - /etc/sysctl.d/
    - /run/sysctl.d/
    - /usr/local/lib/sysctl.d/
    contains: ^[\s]*net.ipv6.conf.default.accept_redirects.*$
    patterns: '*.conf'
    file_type: any
  register: find_sysctl_d
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv6_conf_default_accept_redirects

- name: Comment out any occurrences of net.ipv6.conf.default.accept_redirects from
    config files
  replace:
    path: '{{ item.path }}'
    regexp: ^[\s]*net.ipv6.conf.default.accept_redirects
    replace: '#net.ipv6.conf.default.accept_redirects'
  loop: '{{ find_sysctl_d.files }}'
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv6_conf_default_accept_redirects
- name: XCCDF Value sysctl_net_ipv6_conf_default_accept_redirects_value # promote to variable
  set_fact:
    sysctl_net_ipv6_conf_default_accept_redirects_value: !!str 0
  tags:
    - always

- name: Ensure sysctl net.ipv6.conf.default.accept_redirects is set
  sysctl:
    name: net.ipv6.conf.default.accept_redirects
    value: '{{ sysctl_net_ipv6_conf_default_accept_redirects_value }}'
    sysctl_file: /etc/sysctl.conf
    state: present
    reload: true
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv6_conf_default_accept_redirects

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 net.ipv6.conf.default.accept_redirects from /etc/sysctl.d/*.conf files

for f in /etc/sysctl.d/*.conf /run/sysctl.d/*.conf /usr/local/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]*net.ipv6.conf.default.accept_redirects.*$' $f | uniq )
  if ! test -z "$matching_list"; then
    while IFS= read -r entry; do
      escaped_entry=$(sed -e 's|/|\\/|g' <<< "$entry")
      # comment out "net.ipv6.conf.default.accept_redirects" 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_net_ipv6_conf_default_accept_redirects_value='0'


#
# Set runtime for net.ipv6.conf.default.accept_redirects
#
if [[ "$OSCAP_BOOTC_BUILD" != "YES" ]] ; then
    /sbin/sysctl -q -n -w net.ipv6.conf.default.accept_redirects="$sysctl_net_ipv6_conf_default_accept_redirects_value"
fi

#
# If net.ipv6.conf.default.accept_redirects present in /etc/sysctl.conf, change value to appropriate value
#	else, add "net.ipv6.conf.default.accept_redirects = 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' <<< "^net.ipv6.conf.default.accept_redirects")

# shellcheck disable=SC2059
printf -v formatted_output "%s = %s" "$stripped_key" "$sysctl_net_ipv6_conf_default_accept_redirects_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 "^net.ipv6.conf.default.accept_redirects\\>" "${SYSCONFIG_FILE}"; then
    escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
    LC_ALL=C sed -i --follow-symlinks "s/^net.ipv6.conf.default.accept_redirects\\>.*/$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

Rule   Disable Kernel Parameter for Accepting Source-Routed Packets on IPv6 Interfaces by Default   [ref]

To set the runtime status of the net.ipv6.conf.default.accept_source_route kernel parameter, run the following command:
$ sudo sysctl -w net.ipv6.conf.default.accept_source_route=0
To make sure that the setting is persistent, add the following line to a file in the directory /etc/sysctl.d:
net.ipv6.conf.default.accept_source_route = 0
Rationale:
Source-routed packets allow the source of the packet to suggest routers forward the packet along a different path than configured on the router, which can be used to bypass network security measures. This requirement applies only to the forwarding of source-routerd traffic, such as when IPv6 forwarding is enabled and the system is functioning as a router. Accepting source-routed packets in the IPv6 protocol has few legitimate uses. It should be disabled unless it is absolutely required.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_sysctl_net_ipv6_conf_default_accept_source_route
References:
cis-csc1, 12, 13, 14, 15, 16, 18, 4, 6, 8, 9
cobit5APO01.06, APO13.01, DSS01.05, DSS03.01, DSS05.02, DSS05.04, DSS05.07, DSS06.02
cui3.1.20
disaCCI-000366
isa-62443-20094.2.3.4, 4.3.3.4, 4.4.3.3
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.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.12.1.1, A.12.1.2, A.13.1.1, A.13.1.2, A.13.1.3, A.13.2.1, A.13.2.2, 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-7(a), CM-7(b), CM-6(a), CM-6(b), CM-6.1(iv)
nist-csfDE.AE-1, ID.AM-3, PR.AC-5, PR.DS-5, PR.PT-4
pcidssReq-1.4.3
os-srgSRG-OS-000480-GPOS-00227
anssiR13
cis3.3.8
pcidss41.4.2, 1.4

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-6(b)
  - NIST-800-53-CM-6.1(iv)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - PCI-DSS-Req-1.4.3
  - PCI-DSSv4-1.4
  - PCI-DSSv4-1.4.2
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv6_conf_default_accept_source_route

- name: List /etc/sysctl.d/*.conf files
  find:
    paths:
    - /etc/sysctl.d/
    - /run/sysctl.d/
    - /usr/local/lib/sysctl.d/
    contains: ^[\s]*net.ipv6.conf.default.accept_source_route.*$
    patterns: '*.conf'
    file_type: any
  register: find_sysctl_d
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-6(b)
  - NIST-800-53-CM-6.1(iv)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - PCI-DSS-Req-1.4.3
  - PCI-DSSv4-1.4
  - PCI-DSSv4-1.4.2
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv6_conf_default_accept_source_route

- name: Comment out any occurrences of net.ipv6.conf.default.accept_source_route from
    config files
  replace:
    path: '{{ item.path }}'
    regexp: ^[\s]*net.ipv6.conf.default.accept_source_route
    replace: '#net.ipv6.conf.default.accept_source_route'
  loop: '{{ find_sysctl_d.files }}'
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-6(b)
  - NIST-800-53-CM-6.1(iv)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - PCI-DSS-Req-1.4.3
  - PCI-DSSv4-1.4
  - PCI-DSSv4-1.4.2
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv6_conf_default_accept_source_route
- name: XCCDF Value sysctl_net_ipv6_conf_default_accept_source_route_value # promote to variable
  set_fact:
    sysctl_net_ipv6_conf_default_accept_source_route_value: !!str 0
  tags:
    - always

- name: Ensure sysctl net.ipv6.conf.default.accept_source_route is set
  sysctl:
    name: net.ipv6.conf.default.accept_source_route
    value: '{{ sysctl_net_ipv6_conf_default_accept_source_route_value }}'
    sysctl_file: /etc/sysctl.conf
    state: present
    reload: true
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-6(b)
  - NIST-800-53-CM-6.1(iv)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - PCI-DSS-Req-1.4.3
  - PCI-DSSv4-1.4
  - PCI-DSSv4-1.4.2
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv6_conf_default_accept_source_route

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 net.ipv6.conf.default.accept_source_route from /etc/sysctl.d/*.conf files

for f in /etc/sysctl.d/*.conf /run/sysctl.d/*.conf /usr/local/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]*net.ipv6.conf.default.accept_source_route.*$' $f | uniq )
  if ! test -z "$matching_list"; then
    while IFS= read -r entry; do
      escaped_entry=$(sed -e 's|/|\\/|g' <<< "$entry")
      # comment out "net.ipv6.conf.default.accept_source_route" 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_net_ipv6_conf_default_accept_source_route_value='0'


#
# Set runtime for net.ipv6.conf.default.accept_source_route
#
if [[ "$OSCAP_BOOTC_BUILD" != "YES" ]] ; then
    /sbin/sysctl -q -n -w net.ipv6.conf.default.accept_source_route="$sysctl_net_ipv6_conf_default_accept_source_route_value"
fi

#
# If net.ipv6.conf.default.accept_source_route present in /etc/sysctl.conf, change value to appropriate value
#	else, add "net.ipv6.conf.default.accept_source_route = 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' <<< "^net.ipv6.conf.default.accept_source_route")

# shellcheck disable=SC2059
printf -v formatted_output "%s = %s" "$stripped_key" "$sysctl_net_ipv6_conf_default_accept_source_route_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 "^net.ipv6.conf.default.accept_source_route\\>" "${SYSCONFIG_FILE}"; then
    escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
    LC_ALL=C sed -i --follow-symlinks "s/^net.ipv6.conf.default.accept_source_route\\>.*/$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
Group   Kernel Parameters Which Affect Networking   Group contains 2 groups and 16 rules
[ref]   The sysctl utility is used to set parameters which affect the operation of the Linux kernel. Kernel parameters which affect networking and have security implications are described here.
Group   Network Related Kernel Runtime Parameters for Hosts and Routers   Group contains 13 rules
[ref]   Certain kernel parameters should be set for systems which are acting as either hosts or routers to improve the system's ability defend against certain types of IPv4 protocol attacks.

Rule   Disable Accepting ICMP Redirects for All IPv4 Interfaces   [ref]

To set the runtime status of the net.ipv4.conf.all.accept_redirects kernel parameter, run the following command:
$ sudo sysctl -w net.ipv4.conf.all.accept_redirects=0
To make sure that the setting is persistent, add the following line to a file in the directory /etc/sysctl.d:
net.ipv4.conf.all.accept_redirects = 0
Rationale:
ICMP redirect messages are used by routers to inform hosts that a more direct route exists for a particular destination. These messages modify the host's route table and are unauthenticated. An illicit ICMP redirect message could result in a man-in-the-middle attack.
This feature of the IPv4 protocol has few legitimate uses. It should be disabled unless absolutely required."
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_sysctl_net_ipv4_conf_all_accept_redirects
References:
cis-csc1, 11, 12, 13, 14, 15, 16, 2, 3, 7, 8, 9
cjis5.10.1.1
cobit5APO13.01, BAI04.04, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS01.03, DSS03.05, DSS05.02, DSS05.05, DSS05.07, DSS06.06
cui3.1.20
disaCCI-000366
isa-62443-20094.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3
isa-62443-2013SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 6.2, SR 7.1, SR 7.2, SR 7.6
iso27001-2013A.12.1.2, A.12.1.3, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, A.17.2.1, A.9.1.2
nistCM-7(a), CM-7(b), CM-6(a), SC-7(a)
nist-csfDE.CM-1, PR.DS-4, PR.IP-1, PR.PT-3
os-srgSRG-OS-000480-GPOS-00227
anssiR12
cis3.3.5

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - CJIS-5.10.1.1
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-7(a)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_conf_all_accept_redirects

- name: List /etc/sysctl.d/*.conf files
  find:
    paths:
    - /etc/sysctl.d/
    - /run/sysctl.d/
    - /usr/local/lib/sysctl.d/
    contains: ^[\s]*net.ipv4.conf.all.accept_redirects.*$
    patterns: '*.conf'
    file_type: any
  register: find_sysctl_d
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - CJIS-5.10.1.1
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-7(a)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_conf_all_accept_redirects

- name: Comment out any occurrences of net.ipv4.conf.all.accept_redirects from config
    files
  replace:
    path: '{{ item.path }}'
    regexp: ^[\s]*net.ipv4.conf.all.accept_redirects
    replace: '#net.ipv4.conf.all.accept_redirects'
  loop: '{{ find_sysctl_d.files }}'
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - CJIS-5.10.1.1
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-7(a)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_conf_all_accept_redirects
- name: XCCDF Value sysctl_net_ipv4_conf_all_accept_redirects_value # promote to variable
  set_fact:
    sysctl_net_ipv4_conf_all_accept_redirects_value: !!str 0
  tags:
    - always

- name: Ensure sysctl net.ipv4.conf.all.accept_redirects is set
  sysctl:
    name: net.ipv4.conf.all.accept_redirects
    value: '{{ sysctl_net_ipv4_conf_all_accept_redirects_value }}'
    sysctl_file: /etc/sysctl.conf
    state: present
    reload: true
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - CJIS-5.10.1.1
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-7(a)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_conf_all_accept_redirects

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 net.ipv4.conf.all.accept_redirects from /etc/sysctl.d/*.conf files

for f in /etc/sysctl.d/*.conf /run/sysctl.d/*.conf /usr/local/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]*net.ipv4.conf.all.accept_redirects.*$' $f | uniq )
  if ! test -z "$matching_list"; then
    while IFS= read -r entry; do
      escaped_entry=$(sed -e 's|/|\\/|g' <<< "$entry")
      # comment out "net.ipv4.conf.all.accept_redirects" 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_net_ipv4_conf_all_accept_redirects_value='0'


#
# Set runtime for net.ipv4.conf.all.accept_redirects
#
if [[ "$OSCAP_BOOTC_BUILD" != "YES" ]] ; then
    /sbin/sysctl -q -n -w net.ipv4.conf.all.accept_redirects="$sysctl_net_ipv4_conf_all_accept_redirects_value"
fi

#
# If net.ipv4.conf.all.accept_redirects present in /etc/sysctl.conf, change value to appropriate value
#	else, add "net.ipv4.conf.all.accept_redirects = 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' <<< "^net.ipv4.conf.all.accept_redirects")

# shellcheck disable=SC2059
printf -v formatted_output "%s = %s" "$stripped_key" "$sysctl_net_ipv4_conf_all_accept_redirects_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 "^net.ipv4.conf.all.accept_redirects\\>" "${SYSCONFIG_FILE}"; then
    escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
    LC_ALL=C sed -i --follow-symlinks "s/^net.ipv4.conf.all.accept_redirects\\>.*/$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

Rule   Disable Kernel Parameter for Accepting Source-Routed Packets on all IPv4 Interfaces   [ref]

To set the runtime status of the net.ipv4.conf.all.accept_source_route kernel parameter, run the following command:
$ sudo sysctl -w net.ipv4.conf.all.accept_source_route=0
To make sure that the setting is persistent, add the following line to a file in the directory /etc/sysctl.d:
net.ipv4.conf.all.accept_source_route = 0
Rationale:
Source-routed packets allow the source of the packet to suggest routers forward the packet along a different path than configured on the router, which can be used to bypass network security measures. This requirement applies only to the forwarding of source-routerd traffic, such as when IPv4 forwarding is enabled and the system is functioning as a router.

Accepting source-routed packets in the IPv4 protocol has few legitimate uses. It should be disabled unless it is absolutely required.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_sysctl_net_ipv4_conf_all_accept_source_route
References:
cis-csc1, 11, 12, 13, 14, 15, 16, 18, 2, 3, 4, 6, 7, 8, 9
cobit5APO01.06, APO13.01, BAI04.04, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS01.03, DSS01.05, DSS03.01, DSS03.05, DSS05.02, DSS05.04, DSS05.05, DSS05.07, DSS06.02, DSS06.06
cui3.1.20
disaCCI-000366
isa-62443-20094.2.3.4, 4.3.3.4, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3, 4.4.3.3
isa-62443-2013SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 6.2, SR 7.1, SR 7.2, SR 7.6
iso27001-2013A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.12.1.1, A.12.1.2, A.12.1.3, A.12.5.1, A.12.6.2, A.13.1.1, A.13.1.2, A.13.1.3, A.13.2.1, A.13.2.2, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.14.2.2, A.14.2.3, A.14.2.4, A.17.2.1, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5
nerc-cipCIP-007-3 R4, CIP-007-3 R4.1, CIP-007-3 R4.2, CIP-007-3 R5.1
nistCM-7(a), CM-7(b), SC-5, CM-6(a), SC-7(a)
nist-csfDE.AE-1, DE.CM-1, ID.AM-3, PR.AC-5, PR.DS-4, PR.DS-5, PR.IP-1, PR.PT-3, PR.PT-4
os-srgSRG-OS-000480-GPOS-00227
anssiR12
cis3.3.8

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-5
  - NIST-800-53-SC-7(a)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_conf_all_accept_source_route

- name: List /etc/sysctl.d/*.conf files
  find:
    paths:
    - /etc/sysctl.d/
    - /run/sysctl.d/
    - /usr/local/lib/sysctl.d/
    contains: ^[\s]*net.ipv4.conf.all.accept_source_route.*$
    patterns: '*.conf'
    file_type: any
  register: find_sysctl_d
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-5
  - NIST-800-53-SC-7(a)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_conf_all_accept_source_route

- name: Comment out any occurrences of net.ipv4.conf.all.accept_source_route from
    config files
  replace:
    path: '{{ item.path }}'
    regexp: ^[\s]*net.ipv4.conf.all.accept_source_route
    replace: '#net.ipv4.conf.all.accept_source_route'
  loop: '{{ find_sysctl_d.files }}'
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-5
  - NIST-800-53-SC-7(a)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_conf_all_accept_source_route
- name: XCCDF Value sysctl_net_ipv4_conf_all_accept_source_route_value # promote to variable
  set_fact:
    sysctl_net_ipv4_conf_all_accept_source_route_value: !!str 0
  tags:
    - always

- name: Ensure sysctl net.ipv4.conf.all.accept_source_route is set
  sysctl:
    name: net.ipv4.conf.all.accept_source_route
    value: '{{ sysctl_net_ipv4_conf_all_accept_source_route_value }}'
    sysctl_file: /etc/sysctl.conf
    state: present
    reload: true
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-5
  - NIST-800-53-SC-7(a)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_conf_all_accept_source_route

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 net.ipv4.conf.all.accept_source_route from /etc/sysctl.d/*.conf files

for f in /etc/sysctl.d/*.conf /run/sysctl.d/*.conf /usr/local/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]*net.ipv4.conf.all.accept_source_route.*$' $f | uniq )
  if ! test -z "$matching_list"; then
    while IFS= read -r entry; do
      escaped_entry=$(sed -e 's|/|\\/|g' <<< "$entry")
      # comment out "net.ipv4.conf.all.accept_source_route" 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_net_ipv4_conf_all_accept_source_route_value='0'


#
# Set runtime for net.ipv4.conf.all.accept_source_route
#
if [[ "$OSCAP_BOOTC_BUILD" != "YES" ]] ; then
    /sbin/sysctl -q -n -w net.ipv4.conf.all.accept_source_route="$sysctl_net_ipv4_conf_all_accept_source_route_value"
fi

#
# If net.ipv4.conf.all.accept_source_route present in /etc/sysctl.conf, change value to appropriate value
#	else, add "net.ipv4.conf.all.accept_source_route = 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' <<< "^net.ipv4.conf.all.accept_source_route")

# shellcheck disable=SC2059
printf -v formatted_output "%s = %s" "$stripped_key" "$sysctl_net_ipv4_conf_all_accept_source_route_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 "^net.ipv4.conf.all.accept_source_route\\>" "${SYSCONFIG_FILE}"; then
    escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
    LC_ALL=C sed -i --follow-symlinks "s/^net.ipv4.conf.all.accept_source_route\\>.*/$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

Rule   Enable Kernel Parameter to Log Martian Packets on all IPv4 Interfaces   [ref]

To set the runtime status of the net.ipv4.conf.all.log_martians kernel parameter, run the following command:
$ sudo sysctl -w net.ipv4.conf.all.log_martians=1
To make sure that the setting is persistent, add the following line to a file in the directory /etc/sysctl.d:
net.ipv4.conf.all.log_martians = 1
Rationale:
The presence of "martian" packets (which have impossible addresses) as well as spoofed packets, source-routed packets, and redirects could be a sign of nefarious network activity. Logging these packets enables this activity to be detected.
Severity: 
unknown
Rule ID:xccdf_org.ssgproject.content_rule_sysctl_net_ipv4_conf_all_log_martians
References:
cis-csc1, 11, 12, 13, 14, 15, 16, 2, 3, 7, 8, 9
cobit5APO13.01, BAI04.04, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS01.03, DSS01.04, DSS03.05, DSS05.02, DSS05.03, DSS05.05, DSS05.07, DSS06.06
cui3.1.20
disaCCI-000366
isa-62443-20094.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3
isa-62443-2013SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 6.2, SR 7.1, SR 7.2, SR 7.6
iso27001-2013A.11.2.6, A.12.1.2, A.12.1.3, A.12.5.1, A.12.6.2, A.13.1.1, A.13.2.1, A.14.1.3, A.14.2.2, A.14.2.3, A.14.2.4, A.17.2.1, A.6.2.1, A.6.2.2, A.9.1.2
nistCM-7(a), CM-7(b), SC-5(3)(a)
nist-csfDE.CM-1, PR.AC-3, PR.DS-4, PR.IP-1, PR.PT-3, PR.PT-4
os-srgSRG-OS-000480-GPOS-00227
cis3.3.9

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-5(3)(a)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - reboot_required
  - sysctl_net_ipv4_conf_all_log_martians
  - unknown_severity

- name: List /etc/sysctl.d/*.conf files
  find:
    paths:
    - /etc/sysctl.d/
    - /run/sysctl.d/
    - /usr/local/lib/sysctl.d/
    contains: ^[\s]*net.ipv4.conf.all.log_martians.*$
    patterns: '*.conf'
    file_type: any
  register: find_sysctl_d
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-5(3)(a)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - reboot_required
  - sysctl_net_ipv4_conf_all_log_martians
  - unknown_severity

- name: Comment out any occurrences of net.ipv4.conf.all.log_martians from config
    files
  replace:
    path: '{{ item.path }}'
    regexp: ^[\s]*net.ipv4.conf.all.log_martians
    replace: '#net.ipv4.conf.all.log_martians'
  loop: '{{ find_sysctl_d.files }}'
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-5(3)(a)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - reboot_required
  - sysctl_net_ipv4_conf_all_log_martians
  - unknown_severity
- name: XCCDF Value sysctl_net_ipv4_conf_all_log_martians_value # promote to variable
  set_fact:
    sysctl_net_ipv4_conf_all_log_martians_value: !!str 1
  tags:
    - always

- name: Ensure sysctl net.ipv4.conf.all.log_martians is set
  sysctl:
    name: net.ipv4.conf.all.log_martians
    value: '{{ sysctl_net_ipv4_conf_all_log_martians_value }}'
    sysctl_file: /etc/sysctl.conf
    state: present
    reload: true
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-5(3)(a)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - reboot_required
  - sysctl_net_ipv4_conf_all_log_martians
  - unknown_severity

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 net.ipv4.conf.all.log_martians from /etc/sysctl.d/*.conf files

for f in /etc/sysctl.d/*.conf /run/sysctl.d/*.conf /usr/local/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]*net.ipv4.conf.all.log_martians.*$' $f | uniq )
  if ! test -z "$matching_list"; then
    while IFS= read -r entry; do
      escaped_entry=$(sed -e 's|/|\\/|g' <<< "$entry")
      # comment out "net.ipv4.conf.all.log_martians" 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_net_ipv4_conf_all_log_martians_value='1'


#
# Set runtime for net.ipv4.conf.all.log_martians
#
if [[ "$OSCAP_BOOTC_BUILD" != "YES" ]] ; then
    /sbin/sysctl -q -n -w net.ipv4.conf.all.log_martians="$sysctl_net_ipv4_conf_all_log_martians_value"
fi

#
# If net.ipv4.conf.all.log_martians present in /etc/sysctl.conf, change value to appropriate value
#	else, add "net.ipv4.conf.all.log_martians = 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' <<< "^net.ipv4.conf.all.log_martians")

# shellcheck disable=SC2059
printf -v formatted_output "%s = %s" "$stripped_key" "$sysctl_net_ipv4_conf_all_log_martians_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 "^net.ipv4.conf.all.log_martians\\>" "${SYSCONFIG_FILE}"; then
    escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
    LC_ALL=C sed -i --follow-symlinks "s/^net.ipv4.conf.all.log_martians\\>.*/$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

Rule   Enable Kernel Parameter to Use Reverse Path Filtering on all IPv4 Interfaces   [ref]

To set the runtime status of the net.ipv4.conf.all.rp_filter kernel parameter, run the following command:
$ sudo sysctl -w net.ipv4.conf.all.rp_filter=1
To make sure that the setting is persistent, add the following line to a file in the directory /etc/sysctl.d:
net.ipv4.conf.all.rp_filter = 1
Rationale:
Enabling reverse path filtering drops packets with source addresses that should not have been able to be received on the interface they were received on. It should not be used on systems which are routers for complicated networks, but is helpful for end hosts and routers serving small networks.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_sysctl_net_ipv4_conf_all_rp_filter
References:
cis-csc1, 12, 13, 14, 15, 16, 18, 2, 4, 6, 7, 8, 9
cobit5APO01.06, APO13.01, BAI04.04, DSS01.03, DSS01.05, DSS03.01, DSS03.05, DSS05.02, DSS05.04, DSS05.07, DSS06.02
cui3.1.20
disaCCI-000366
isa-62443-20094.2.3.4, 4.3.3.4, 4.4.3.3
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 6.2, SR 7.1, SR 7.2, SR 7.6
iso27001-2013A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.12.1.1, A.12.1.2, A.12.1.3, A.13.1.1, A.13.1.2, A.13.1.3, A.13.2.1, A.13.2.2, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.17.2.1, 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-7(a), CM-7(b), CM-6(a), SC-7(a)
nist-csfDE.AE-1, DE.CM-1, ID.AM-3, PR.AC-5, PR.DS-4, PR.DS-5, PR.PT-4
pcidssReq-1.4.3
os-srgSRG-OS-000480-GPOS-00227
anssiR12
cis3.3.7
pcidss41.4.3, 1.4

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-7(a)
  - PCI-DSS-Req-1.4.3
  - PCI-DSSv4-1.4
  - PCI-DSSv4-1.4.3
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_conf_all_rp_filter

- name: List /etc/sysctl.d/*.conf files
  find:
    paths:
    - /etc/sysctl.d/
    - /run/sysctl.d/
    - /usr/local/lib/sysctl.d/
    contains: ^[\s]*net.ipv4.conf.all.rp_filter.*$
    patterns: '*.conf'
    file_type: any
  register: find_sysctl_d
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-7(a)
  - PCI-DSS-Req-1.4.3
  - PCI-DSSv4-1.4
  - PCI-DSSv4-1.4.3
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_conf_all_rp_filter

- name: Comment out any occurrences of net.ipv4.conf.all.rp_filter from config files
  replace:
    path: '{{ item.path }}'
    regexp: ^[\s]*net.ipv4.conf.all.rp_filter
    replace: '#net.ipv4.conf.all.rp_filter'
  loop: '{{ find_sysctl_d.files }}'
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-7(a)
  - PCI-DSS-Req-1.4.3
  - PCI-DSSv4-1.4
  - PCI-DSSv4-1.4.3
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_conf_all_rp_filter
- name: XCCDF Value sysctl_net_ipv4_conf_all_rp_filter_value # promote to variable
  set_fact:
    sysctl_net_ipv4_conf_all_rp_filter_value: !!str 1
  tags:
    - always

- name: Ensure sysctl net.ipv4.conf.all.rp_filter is set
  sysctl:
    name: net.ipv4.conf.all.rp_filter
    value: '{{ sysctl_net_ipv4_conf_all_rp_filter_value }}'
    sysctl_file: /etc/sysctl.conf
    state: present
    reload: true
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-7(a)
  - PCI-DSS-Req-1.4.3
  - PCI-DSSv4-1.4
  - PCI-DSSv4-1.4.3
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_conf_all_rp_filter

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 net.ipv4.conf.all.rp_filter from /etc/sysctl.d/*.conf files

for f in /etc/sysctl.d/*.conf /run/sysctl.d/*.conf /usr/local/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]*net.ipv4.conf.all.rp_filter.*$' $f | uniq )
  if ! test -z "$matching_list"; then
    while IFS= read -r entry; do
      escaped_entry=$(sed -e 's|/|\\/|g' <<< "$entry")
      # comment out "net.ipv4.conf.all.rp_filter" 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_net_ipv4_conf_all_rp_filter_value='1'


#
# Set runtime for net.ipv4.conf.all.rp_filter
#
if [[ "$OSCAP_BOOTC_BUILD" != "YES" ]] ; then
    /sbin/sysctl -q -n -w net.ipv4.conf.all.rp_filter="$sysctl_net_ipv4_conf_all_rp_filter_value"
fi

#
# If net.ipv4.conf.all.rp_filter present in /etc/sysctl.conf, change value to appropriate value
#	else, add "net.ipv4.conf.all.rp_filter = 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' <<< "^net.ipv4.conf.all.rp_filter")

# shellcheck disable=SC2059
printf -v formatted_output "%s = %s" "$stripped_key" "$sysctl_net_ipv4_conf_all_rp_filter_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 "^net.ipv4.conf.all.rp_filter\\>" "${SYSCONFIG_FILE}"; then
    escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
    LC_ALL=C sed -i --follow-symlinks "s/^net.ipv4.conf.all.rp_filter\\>.*/$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

Rule   Disable Kernel Parameter for Accepting Secure ICMP Redirects on all IPv4 Interfaces   [ref]

To set the runtime status of the net.ipv4.conf.all.secure_redirects kernel parameter, run the following command:
$ sudo sysctl -w net.ipv4.conf.all.secure_redirects=0
To make sure that the setting is persistent, add the following line to a file in the directory /etc/sysctl.d:
net.ipv4.conf.all.secure_redirects = 0
Rationale:
Accepting "secure" ICMP redirects (from those gateways listed as default gateways) has few legitimate uses. It should be disabled unless it is absolutely required.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_sysctl_net_ipv4_conf_all_secure_redirects
References:
cis-csc1, 11, 12, 13, 14, 15, 16, 18, 2, 3, 4, 6, 7, 8, 9
cobit5APO01.06, APO13.01, BAI04.04, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS01.03, DSS01.05, DSS03.01, DSS03.05, DSS05.02, DSS05.04, DSS05.05, DSS05.07, DSS06.02, DSS06.06
cui3.1.20
disaCCI-001503, CCI-001551
isa-62443-20094.2.3.4, 4.3.3.4, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3, 4.4.3.3
isa-62443-2013SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 6.2, SR 7.1, SR 7.2, SR 7.6
iso27001-2013A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.12.1.1, A.12.1.2, A.12.1.3, A.12.5.1, A.12.6.2, A.13.1.1, A.13.1.2, A.13.1.3, A.13.2.1, A.13.2.2, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.14.2.2, A.14.2.3, A.14.2.4, A.17.2.1, 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-7(a), CM-7(b), CM-6(a), SC-7(a)
nist-csfDE.AE-1, DE.CM-1, ID.AM-3, PR.AC-5, PR.DS-4, PR.DS-5, PR.IP-1, PR.PT-3, PR.PT-4
pcidssReq-1.4.3
os-srgSRG-OS-000480-GPOS-00227
anssiR12
cis3.3.6
pcidss41.4.3, 1.4

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-7(a)
  - PCI-DSS-Req-1.4.3
  - PCI-DSSv4-1.4
  - PCI-DSSv4-1.4.3
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_conf_all_secure_redirects

- name: List /etc/sysctl.d/*.conf files
  find:
    paths:
    - /etc/sysctl.d/
    - /run/sysctl.d/
    - /usr/local/lib/sysctl.d/
    contains: ^[\s]*net.ipv4.conf.all.secure_redirects.*$
    patterns: '*.conf'
    file_type: any
  register: find_sysctl_d
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-7(a)
  - PCI-DSS-Req-1.4.3
  - PCI-DSSv4-1.4
  - PCI-DSSv4-1.4.3
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_conf_all_secure_redirects

- name: Comment out any occurrences of net.ipv4.conf.all.secure_redirects from config
    files
  replace:
    path: '{{ item.path }}'
    regexp: ^[\s]*net.ipv4.conf.all.secure_redirects
    replace: '#net.ipv4.conf.all.secure_redirects'
  loop: '{{ find_sysctl_d.files }}'
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-7(a)
  - PCI-DSS-Req-1.4.3
  - PCI-DSSv4-1.4
  - PCI-DSSv4-1.4.3
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_conf_all_secure_redirects
- name: XCCDF Value sysctl_net_ipv4_conf_all_secure_redirects_value # promote to variable
  set_fact:
    sysctl_net_ipv4_conf_all_secure_redirects_value: !!str 0
  tags:
    - always

- name: Ensure sysctl net.ipv4.conf.all.secure_redirects is set
  sysctl:
    name: net.ipv4.conf.all.secure_redirects
    value: '{{ sysctl_net_ipv4_conf_all_secure_redirects_value }}'
    sysctl_file: /etc/sysctl.conf
    state: present
    reload: true
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-7(a)
  - PCI-DSS-Req-1.4.3
  - PCI-DSSv4-1.4
  - PCI-DSSv4-1.4.3
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_conf_all_secure_redirects

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 net.ipv4.conf.all.secure_redirects from /etc/sysctl.d/*.conf files

for f in /etc/sysctl.d/*.conf /run/sysctl.d/*.conf /usr/local/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]*net.ipv4.conf.all.secure_redirects.*$' $f | uniq )
  if ! test -z "$matching_list"; then
    while IFS= read -r entry; do
      escaped_entry=$(sed -e 's|/|\\/|g' <<< "$entry")
      # comment out "net.ipv4.conf.all.secure_redirects" 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_net_ipv4_conf_all_secure_redirects_value='0'


#
# Set runtime for net.ipv4.conf.all.secure_redirects
#
if [[ "$OSCAP_BOOTC_BUILD" != "YES" ]] ; then
    /sbin/sysctl -q -n -w net.ipv4.conf.all.secure_redirects="$sysctl_net_ipv4_conf_all_secure_redirects_value"
fi

#
# If net.ipv4.conf.all.secure_redirects present in /etc/sysctl.conf, change value to appropriate value
#	else, add "net.ipv4.conf.all.secure_redirects = 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' <<< "^net.ipv4.conf.all.secure_redirects")

# shellcheck disable=SC2059
printf -v formatted_output "%s = %s" "$stripped_key" "$sysctl_net_ipv4_conf_all_secure_redirects_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 "^net.ipv4.conf.all.secure_redirects\\>" "${SYSCONFIG_FILE}"; then
    escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
    LC_ALL=C sed -i --follow-symlinks "s/^net.ipv4.conf.all.secure_redirects\\>.*/$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

Rule   Disable Kernel Parameter for Accepting ICMP Redirects by Default on IPv4 Interfaces   [ref]

To set the runtime status of the net.ipv4.conf.default.accept_redirects kernel parameter, run the following command:
$ sudo sysctl -w net.ipv4.conf.default.accept_redirects=0
To make sure that the setting is persistent, add the following line to a file in the directory /etc/sysctl.d:
net.ipv4.conf.default.accept_redirects = 0
Rationale:
ICMP redirect messages are used by routers to inform hosts that a more direct route exists for a particular destination. These messages modify the host's route table and are unauthenticated. An illicit ICMP redirect message could result in a man-in-the-middle attack.
This feature of the IPv4 protocol has few legitimate uses. It should be disabled unless absolutely required.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_sysctl_net_ipv4_conf_default_accept_redirects
References:
cis-csc1, 11, 12, 13, 14, 15, 16, 18, 2, 3, 4, 6, 7, 8, 9
cjis5.10.1.1
cobit5APO01.06, APO13.01, BAI04.04, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS01.03, DSS01.05, DSS03.01, DSS03.05, DSS05.02, DSS05.04, DSS05.05, DSS05.07, DSS06.02, DSS06.06
cui3.1.20
disaCCI-000366
isa-62443-20094.2.3.4, 4.3.3.4, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3, 4.4.3.3
isa-62443-2013SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 6.2, SR 7.1, SR 7.2, SR 7.6
iso27001-2013A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.12.1.1, A.12.1.2, A.12.1.3, A.12.5.1, A.12.6.2, A.13.1.1, A.13.1.2, A.13.1.3, A.13.2.1, A.13.2.2, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.14.2.2, A.14.2.3, A.14.2.4, A.17.2.1, 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-7(a), CM-7(b), CM-6(a), SC-7(a)
nist-csfDE.AE-1, DE.CM-1, ID.AM-3, PR.AC-5, PR.DS-4, PR.DS-5, PR.IP-1, PR.PT-3, PR.PT-4
pcidssReq-1.4.3
os-srgSRG-OS-000480-GPOS-00227
anssiR12
cis3.3.5
pcidss41.4.3, 1.4

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - CJIS-5.10.1.1
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-7(a)
  - PCI-DSS-Req-1.4.3
  - PCI-DSSv4-1.4
  - PCI-DSSv4-1.4.3
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_conf_default_accept_redirects

- name: List /etc/sysctl.d/*.conf files
  find:
    paths:
    - /etc/sysctl.d/
    - /run/sysctl.d/
    - /usr/local/lib/sysctl.d/
    contains: ^[\s]*net.ipv4.conf.default.accept_redirects.*$
    patterns: '*.conf'
    file_type: any
  register: find_sysctl_d
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - CJIS-5.10.1.1
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-7(a)
  - PCI-DSS-Req-1.4.3
  - PCI-DSSv4-1.4
  - PCI-DSSv4-1.4.3
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_conf_default_accept_redirects

- name: Comment out any occurrences of net.ipv4.conf.default.accept_redirects from
    config files
  replace:
    path: '{{ item.path }}'
    regexp: ^[\s]*net.ipv4.conf.default.accept_redirects
    replace: '#net.ipv4.conf.default.accept_redirects'
  loop: '{{ find_sysctl_d.files }}'
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - CJIS-5.10.1.1
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-7(a)
  - PCI-DSS-Req-1.4.3
  - PCI-DSSv4-1.4
  - PCI-DSSv4-1.4.3
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_conf_default_accept_redirects
- name: XCCDF Value sysctl_net_ipv4_conf_default_accept_redirects_value # promote to variable
  set_fact:
    sysctl_net_ipv4_conf_default_accept_redirects_value: !!str 0
  tags:
    - always

- name: Ensure sysctl net.ipv4.conf.default.accept_redirects is set
  sysctl:
    name: net.ipv4.conf.default.accept_redirects
    value: '{{ sysctl_net_ipv4_conf_default_accept_redirects_value }}'
    sysctl_file: /etc/sysctl.conf
    state: present
    reload: true
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - CJIS-5.10.1.1
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-7(a)
  - PCI-DSS-Req-1.4.3
  - PCI-DSSv4-1.4
  - PCI-DSSv4-1.4.3
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_conf_default_accept_redirects

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 net.ipv4.conf.default.accept_redirects from /etc/sysctl.d/*.conf files

for f in /etc/sysctl.d/*.conf /run/sysctl.d/*.conf /usr/local/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]*net.ipv4.conf.default.accept_redirects.*$' $f | uniq )
  if ! test -z "$matching_list"; then
    while IFS= read -r entry; do
      escaped_entry=$(sed -e 's|/|\\/|g' <<< "$entry")
      # comment out "net.ipv4.conf.default.accept_redirects" 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_net_ipv4_conf_default_accept_redirects_value='0'


#
# Set runtime for net.ipv4.conf.default.accept_redirects
#
if [[ "$OSCAP_BOOTC_BUILD" != "YES" ]] ; then
    /sbin/sysctl -q -n -w net.ipv4.conf.default.accept_redirects="$sysctl_net_ipv4_conf_default_accept_redirects_value"
fi

#
# If net.ipv4.conf.default.accept_redirects present in /etc/sysctl.conf, change value to appropriate value
#	else, add "net.ipv4.conf.default.accept_redirects = 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' <<< "^net.ipv4.conf.default.accept_redirects")

# shellcheck disable=SC2059
printf -v formatted_output "%s = %s" "$stripped_key" "$sysctl_net_ipv4_conf_default_accept_redirects_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 "^net.ipv4.conf.default.accept_redirects\\>" "${SYSCONFIG_FILE}"; then
    escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
    LC_ALL=C sed -i --follow-symlinks "s/^net.ipv4.conf.default.accept_redirects\\>.*/$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

Rule   Disable Kernel Parameter for Accepting Source-Routed Packets on IPv4 Interfaces by Default   [ref]

To set the runtime status of the net.ipv4.conf.default.accept_source_route kernel parameter, run the following command:
$ sudo sysctl -w net.ipv4.conf.default.accept_source_route=0
To make sure that the setting is persistent, add the following line to a file in the directory /etc/sysctl.d:
net.ipv4.conf.default.accept_source_route = 0
Rationale:
Source-routed packets allow the source of the packet to suggest routers forward the packet along a different path than configured on the router, which can be used to bypass network security measures.
Accepting source-routed packets in the IPv4 protocol has few legitimate uses. It should be disabled unless it is absolutely required, such as when IPv4 forwarding is enabled and the system is legitimately functioning as a router.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_sysctl_net_ipv4_conf_default_accept_source_route
References:
cis-csc1, 11, 12, 13, 14, 15, 16, 18, 2, 3, 4, 6, 7, 8, 9
cjis5.10.1.1
cobit5APO01.06, APO13.01, BAI04.04, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS01.03, DSS01.05, DSS03.01, DSS03.05, DSS05.02, DSS05.04, DSS05.05, DSS05.07, DSS06.02, DSS06.06
cui3.1.20
disaCCI-000366
isa-62443-20094.2.3.4, 4.3.3.4, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3, 4.4.3.3
isa-62443-2013SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 6.2, SR 7.1, SR 7.2, SR 7.6
iso27001-2013A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.12.1.1, A.12.1.2, A.12.1.3, A.12.5.1, A.12.6.2, A.13.1.1, A.13.1.2, A.13.1.3, A.13.2.1, A.13.2.2, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.14.2.2, A.14.2.3, A.14.2.4, A.17.2.1, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5
nerc-cipCIP-007-3 R4, CIP-007-3 R4.1, CIP-007-3 R4.2, CIP-007-3 R5.1
nistCM-7(a), CM-7(b), SC-5, SC-7(a)
nist-csfDE.AE-1, DE.CM-1, ID.AM-3, PR.AC-5, PR.DS-4, PR.DS-5, PR.IP-1, PR.PT-3, PR.PT-4
os-srgSRG-OS-000480-GPOS-00227
anssiR12
cis3.3.8

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - CJIS-5.10.1.1
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-5
  - NIST-800-53-SC-7(a)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_conf_default_accept_source_route

- name: List /etc/sysctl.d/*.conf files
  find:
    paths:
    - /etc/sysctl.d/
    - /run/sysctl.d/
    - /usr/local/lib/sysctl.d/
    contains: ^[\s]*net.ipv4.conf.default.accept_source_route.*$
    patterns: '*.conf'
    file_type: any
  register: find_sysctl_d
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - CJIS-5.10.1.1
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-5
  - NIST-800-53-SC-7(a)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_conf_default_accept_source_route

- name: Comment out any occurrences of net.ipv4.conf.default.accept_source_route from
    config files
  replace:
    path: '{{ item.path }}'
    regexp: ^[\s]*net.ipv4.conf.default.accept_source_route
    replace: '#net.ipv4.conf.default.accept_source_route'
  loop: '{{ find_sysctl_d.files }}'
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - CJIS-5.10.1.1
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-5
  - NIST-800-53-SC-7(a)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_conf_default_accept_source_route
- name: XCCDF Value sysctl_net_ipv4_conf_default_accept_source_route_value # promote to variable
  set_fact:
    sysctl_net_ipv4_conf_default_accept_source_route_value: !!str 0
  tags:
    - always

- name: Ensure sysctl net.ipv4.conf.default.accept_source_route is set
  sysctl:
    name: net.ipv4.conf.default.accept_source_route
    value: '{{ sysctl_net_ipv4_conf_default_accept_source_route_value }}'
    sysctl_file: /etc/sysctl.conf
    state: present
    reload: true
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - CJIS-5.10.1.1
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-5
  - NIST-800-53-SC-7(a)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_conf_default_accept_source_route

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 net.ipv4.conf.default.accept_source_route from /etc/sysctl.d/*.conf files

for f in /etc/sysctl.d/*.conf /run/sysctl.d/*.conf /usr/local/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]*net.ipv4.conf.default.accept_source_route.*$' $f | uniq )
  if ! test -z "$matching_list"; then
    while IFS= read -r entry; do
      escaped_entry=$(sed -e 's|/|\\/|g' <<< "$entry")
      # comment out "net.ipv4.conf.default.accept_source_route" 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_net_ipv4_conf_default_accept_source_route_value='0'


#
# Set runtime for net.ipv4.conf.default.accept_source_route
#
if [[ "$OSCAP_BOOTC_BUILD" != "YES" ]] ; then
    /sbin/sysctl -q -n -w net.ipv4.conf.default.accept_source_route="$sysctl_net_ipv4_conf_default_accept_source_route_value"
fi

#
# If net.ipv4.conf.default.accept_source_route present in /etc/sysctl.conf, change value to appropriate value
#	else, add "net.ipv4.conf.default.accept_source_route = 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' <<< "^net.ipv4.conf.default.accept_source_route")

# shellcheck disable=SC2059
printf -v formatted_output "%s = %s" "$stripped_key" "$sysctl_net_ipv4_conf_default_accept_source_route_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 "^net.ipv4.conf.default.accept_source_route\\>" "${SYSCONFIG_FILE}"; then
    escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
    LC_ALL=C sed -i --follow-symlinks "s/^net.ipv4.conf.default.accept_source_route\\>.*/$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

Rule   Enable Kernel Paremeter to Log Martian Packets on all IPv4 Interfaces by Default   [ref]

To set the runtime status of the net.ipv4.conf.default.log_martians kernel parameter, run the following command:
$ sudo sysctl -w net.ipv4.conf.default.log_martians=1
To make sure that the setting is persistent, add the following line to a file in the directory /etc/sysctl.d:
net.ipv4.conf.default.log_martians = 1
Rationale:
The presence of "martian" packets (which have impossible addresses) as well as spoofed packets, source-routed packets, and redirects could be a sign of nefarious network activity. Logging these packets enables this activity to be detected.
Severity: 
unknown
Rule ID:xccdf_org.ssgproject.content_rule_sysctl_net_ipv4_conf_default_log_martians
References:
cis-csc1, 11, 12, 13, 14, 15, 16, 2, 3, 7, 8, 9
cobit5APO13.01, BAI04.04, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS01.03, DSS01.04, DSS03.05, DSS05.02, DSS05.03, DSS05.05, DSS05.07, DSS06.06
cui3.1.20
disaCCI-000366
isa-62443-20094.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3
isa-62443-2013SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 6.2, SR 7.1, SR 7.2, SR 7.6
iso27001-2013A.11.2.6, A.12.1.2, A.12.1.3, A.12.5.1, A.12.6.2, A.13.1.1, A.13.2.1, A.14.1.3, A.14.2.2, A.14.2.3, A.14.2.4, A.17.2.1, A.6.2.1, A.6.2.2, A.9.1.2
nistCM-7(a), CM-7(b), SC-5(3)(a)
nist-csfDE.CM-1, PR.AC-3, PR.DS-4, PR.IP-1, PR.PT-3, PR.PT-4
os-srgSRG-OS-000480-GPOS-00227
cis3.3.9

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-5(3)(a)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - reboot_required
  - sysctl_net_ipv4_conf_default_log_martians
  - unknown_severity

- name: List /etc/sysctl.d/*.conf files
  find:
    paths:
    - /etc/sysctl.d/
    - /run/sysctl.d/
    - /usr/local/lib/sysctl.d/
    contains: ^[\s]*net.ipv4.conf.default.log_martians.*$
    patterns: '*.conf'
    file_type: any
  register: find_sysctl_d
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-5(3)(a)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - reboot_required
  - sysctl_net_ipv4_conf_default_log_martians
  - unknown_severity

- name: Comment out any occurrences of net.ipv4.conf.default.log_martians from config
    files
  replace:
    path: '{{ item.path }}'
    regexp: ^[\s]*net.ipv4.conf.default.log_martians
    replace: '#net.ipv4.conf.default.log_martians'
  loop: '{{ find_sysctl_d.files }}'
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-5(3)(a)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - reboot_required
  - sysctl_net_ipv4_conf_default_log_martians
  - unknown_severity
- name: XCCDF Value sysctl_net_ipv4_conf_default_log_martians_value # promote to variable
  set_fact:
    sysctl_net_ipv4_conf_default_log_martians_value: !!str 1
  tags:
    - always

- name: Ensure sysctl net.ipv4.conf.default.log_martians is set
  sysctl:
    name: net.ipv4.conf.default.log_martians
    value: '{{ sysctl_net_ipv4_conf_default_log_martians_value }}'
    sysctl_file: /etc/sysctl.conf
    state: present
    reload: true
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-5(3)(a)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - reboot_required
  - sysctl_net_ipv4_conf_default_log_martians
  - unknown_severity

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 net.ipv4.conf.default.log_martians from /etc/sysctl.d/*.conf files

for f in /etc/sysctl.d/*.conf /run/sysctl.d/*.conf /usr/local/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]*net.ipv4.conf.default.log_martians.*$' $f | uniq )
  if ! test -z "$matching_list"; then
    while IFS= read -r entry; do
      escaped_entry=$(sed -e 's|/|\\/|g' <<< "$entry")
      # comment out "net.ipv4.conf.default.log_martians" 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_net_ipv4_conf_default_log_martians_value='1'


#
# Set runtime for net.ipv4.conf.default.log_martians
#
if [[ "$OSCAP_BOOTC_BUILD" != "YES" ]] ; then
    /sbin/sysctl -q -n -w net.ipv4.conf.default.log_martians="$sysctl_net_ipv4_conf_default_log_martians_value"
fi

#
# If net.ipv4.conf.default.log_martians present in /etc/sysctl.conf, change value to appropriate value
#	else, add "net.ipv4.conf.default.log_martians = 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' <<< "^net.ipv4.conf.default.log_martians")

# shellcheck disable=SC2059
printf -v formatted_output "%s = %s" "$stripped_key" "$sysctl_net_ipv4_conf_default_log_martians_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 "^net.ipv4.conf.default.log_martians\\>" "${SYSCONFIG_FILE}"; then
    escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
    LC_ALL=C sed -i --follow-symlinks "s/^net.ipv4.conf.default.log_martians\\>.*/$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

Rule   Enable Kernel Parameter to Use Reverse Path Filtering on all IPv4 Interfaces by Default   [ref]

To set the runtime status of the net.ipv4.conf.default.rp_filter kernel parameter, run the following command:
$ sudo sysctl -w net.ipv4.conf.default.rp_filter=1
To make sure that the setting is persistent, add the following line to a file in the directory /etc/sysctl.d:
net.ipv4.conf.default.rp_filter = 1
Rationale:
Enabling reverse path filtering drops packets with source addresses that should not have been able to be received on the interface they were received on. It should not be used on systems which are routers for complicated networks, but is helpful for end hosts and routers serving small networks.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_sysctl_net_ipv4_conf_default_rp_filter
References:
cis-csc1, 12, 13, 14, 15, 16, 18, 2, 4, 6, 7, 8, 9
cobit5APO01.06, APO13.01, BAI04.04, DSS01.03, DSS01.05, DSS03.01, DSS03.05, DSS05.02, DSS05.04, DSS05.07, DSS06.02
cui3.1.20
disaCCI-000366
isa-62443-20094.2.3.4, 4.3.3.4, 4.4.3.3
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 6.2, SR 7.1, SR 7.2, SR 7.6
iso27001-2013A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.12.1.1, A.12.1.2, A.12.1.3, A.13.1.1, A.13.1.2, A.13.1.3, A.13.2.1, A.13.2.2, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.17.2.1, 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-7(a), CM-7(b), CM-6(a), SC-7(a)
nist-csfDE.AE-1, DE.CM-1, ID.AM-3, PR.AC-5, PR.DS-4, PR.DS-5, PR.PT-4
os-srgSRG-OS-000480-GPOS-00227
anssiR12
cis3.3.7

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-7(a)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_conf_default_rp_filter

- name: List /etc/sysctl.d/*.conf files
  find:
    paths:
    - /etc/sysctl.d/
    - /run/sysctl.d/
    - /usr/local/lib/sysctl.d/
    contains: ^[\s]*net.ipv4.conf.default.rp_filter.*$
    patterns: '*.conf'
    file_type: any
  register: find_sysctl_d
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-7(a)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_conf_default_rp_filter

- name: Comment out any occurrences of net.ipv4.conf.default.rp_filter from config
    files
  replace:
    path: '{{ item.path }}'
    regexp: ^[\s]*net.ipv4.conf.default.rp_filter
    replace: '#net.ipv4.conf.default.rp_filter'
  loop: '{{ find_sysctl_d.files }}'
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-7(a)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_conf_default_rp_filter
- name: XCCDF Value sysctl_net_ipv4_conf_default_rp_filter_value # promote to variable
  set_fact:
    sysctl_net_ipv4_conf_default_rp_filter_value: !!str 1
  tags:
    - always

- name: Ensure sysctl net.ipv4.conf.default.rp_filter is set
  sysctl:
    name: net.ipv4.conf.default.rp_filter
    value: '{{ sysctl_net_ipv4_conf_default_rp_filter_value }}'
    sysctl_file: /etc/sysctl.conf
    state: present
    reload: true
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-7(a)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_conf_default_rp_filter

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 net.ipv4.conf.default.rp_filter from /etc/sysctl.d/*.conf files

for f in /etc/sysctl.d/*.conf /run/sysctl.d/*.conf /usr/local/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]*net.ipv4.conf.default.rp_filter.*$' $f | uniq )
  if ! test -z "$matching_list"; then
    while IFS= read -r entry; do
      escaped_entry=$(sed -e 's|/|\\/|g' <<< "$entry")
      # comment out "net.ipv4.conf.default.rp_filter" 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_net_ipv4_conf_default_rp_filter_value='1'


#
# Set runtime for net.ipv4.conf.default.rp_filter
#
if [[ "$OSCAP_BOOTC_BUILD" != "YES" ]] ; then
    /sbin/sysctl -q -n -w net.ipv4.conf.default.rp_filter="$sysctl_net_ipv4_conf_default_rp_filter_value"
fi

#
# If net.ipv4.conf.default.rp_filter present in /etc/sysctl.conf, change value to appropriate value
#	else, add "net.ipv4.conf.default.rp_filter = 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' <<< "^net.ipv4.conf.default.rp_filter")

# shellcheck disable=SC2059
printf -v formatted_output "%s = %s" "$stripped_key" "$sysctl_net_ipv4_conf_default_rp_filter_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 "^net.ipv4.conf.default.rp_filter\\>" "${SYSCONFIG_FILE}"; then
    escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
    LC_ALL=C sed -i --follow-symlinks "s/^net.ipv4.conf.default.rp_filter\\>.*/$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

Rule   Configure Kernel Parameter for Accepting Secure Redirects By Default   [ref]

To set the runtime status of the net.ipv4.conf.default.secure_redirects kernel parameter, run the following command:
$ sudo sysctl -w net.ipv4.conf.default.secure_redirects=0
To make sure that the setting is persistent, add the following line to a file in the directory /etc/sysctl.d:
net.ipv4.conf.default.secure_redirects = 0
Rationale:
Accepting "secure" ICMP redirects (from those gateways listed as default gateways) has few legitimate uses. It should be disabled unless it is absolutely required.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_sysctl_net_ipv4_conf_default_secure_redirects
References:
cis-csc1, 11, 12, 13, 14, 15, 16, 18, 2, 3, 4, 6, 7, 8, 9
cobit5APO01.06, APO13.01, BAI04.04, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS01.03, DSS01.05, DSS03.01, DSS03.05, DSS05.02, DSS05.04, DSS05.05, DSS05.07, DSS06.02, DSS06.06
cui3.1.20
disaCCI-001551
isa-62443-20094.2.3.4, 4.3.3.4, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3, 4.4.3.3
isa-62443-2013SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 6.2, SR 7.1, SR 7.2, SR 7.6
iso27001-2013A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.12.1.1, A.12.1.2, A.12.1.3, A.12.5.1, A.12.6.2, A.13.1.1, A.13.1.2, A.13.1.3, A.13.2.1, A.13.2.2, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.14.2.2, A.14.2.3, A.14.2.4, A.17.2.1, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5
nerc-cipCIP-007-3 R4, CIP-007-3 R4.1, CIP-007-3 R4.2, CIP-007-3 R5.1
nistCM-7(a), CM-7(b), SC-5, SC-7(a)
nist-csfDE.AE-1, DE.CM-1, ID.AM-3, PR.AC-5, PR.DS-4, PR.DS-5, PR.IP-1, PR.PT-3, PR.PT-4
os-srgSRG-OS-000480-GPOS-00227
anssiR12
cis3.3.6

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-5
  - NIST-800-53-SC-7(a)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_conf_default_secure_redirects

- name: List /etc/sysctl.d/*.conf files
  find:
    paths:
    - /etc/sysctl.d/
    - /run/sysctl.d/
    - /usr/local/lib/sysctl.d/
    contains: ^[\s]*net.ipv4.conf.default.secure_redirects.*$
    patterns: '*.conf'
    file_type: any
  register: find_sysctl_d
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-5
  - NIST-800-53-SC-7(a)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_conf_default_secure_redirects

- name: Comment out any occurrences of net.ipv4.conf.default.secure_redirects from
    config files
  replace:
    path: '{{ item.path }}'
    regexp: ^[\s]*net.ipv4.conf.default.secure_redirects
    replace: '#net.ipv4.conf.default.secure_redirects'
  loop: '{{ find_sysctl_d.files }}'
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-5
  - NIST-800-53-SC-7(a)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_conf_default_secure_redirects
- name: XCCDF Value sysctl_net_ipv4_conf_default_secure_redirects_value # promote to variable
  set_fact:
    sysctl_net_ipv4_conf_default_secure_redirects_value: !!str 0
  tags:
    - always

- name: Ensure sysctl net.ipv4.conf.default.secure_redirects is set
  sysctl:
    name: net.ipv4.conf.default.secure_redirects
    value: '{{ sysctl_net_ipv4_conf_default_secure_redirects_value }}'
    sysctl_file: /etc/sysctl.conf
    state: present
    reload: true
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-5
  - NIST-800-53-SC-7(a)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_conf_default_secure_redirects

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 net.ipv4.conf.default.secure_redirects from /etc/sysctl.d/*.conf files

for f in /etc/sysctl.d/*.conf /run/sysctl.d/*.conf /usr/local/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]*net.ipv4.conf.default.secure_redirects.*$' $f | uniq )
  if ! test -z "$matching_list"; then
    while IFS= read -r entry; do
      escaped_entry=$(sed -e 's|/|\\/|g' <<< "$entry")
      # comment out "net.ipv4.conf.default.secure_redirects" 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_net_ipv4_conf_default_secure_redirects_value='0'


#
# Set runtime for net.ipv4.conf.default.secure_redirects
#
if [[ "$OSCAP_BOOTC_BUILD" != "YES" ]] ; then
    /sbin/sysctl -q -n -w net.ipv4.conf.default.secure_redirects="$sysctl_net_ipv4_conf_default_secure_redirects_value"
fi

#
# If net.ipv4.conf.default.secure_redirects present in /etc/sysctl.conf, change value to appropriate value
#	else, add "net.ipv4.conf.default.secure_redirects = 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' <<< "^net.ipv4.conf.default.secure_redirects")

# shellcheck disable=SC2059
printf -v formatted_output "%s = %s" "$stripped_key" "$sysctl_net_ipv4_conf_default_secure_redirects_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 "^net.ipv4.conf.default.secure_redirects\\>" "${SYSCONFIG_FILE}"; then
    escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
    LC_ALL=C sed -i --follow-symlinks "s/^net.ipv4.conf.default.secure_redirects\\>.*/$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

Rule   Enable Kernel Parameter to Ignore ICMP Broadcast Echo Requests on IPv4 Interfaces   [ref]

To set the runtime status of the net.ipv4.icmp_echo_ignore_broadcasts kernel parameter, run the following command:
$ sudo sysctl -w net.ipv4.icmp_echo_ignore_broadcasts=1
To make sure that the setting is persistent, add the following line to a file in the directory /etc/sysctl.d:
net.ipv4.icmp_echo_ignore_broadcasts = 1
Rationale:
Responding to broadcast (ICMP) echoes facilitates network mapping and provides a vector for amplification attacks.
Ignoring ICMP echo requests (pings) sent to broadcast or multicast addresses makes the system slightly more difficult to enumerate on the network.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_sysctl_net_ipv4_icmp_echo_ignore_broadcasts
References:
cis-csc1, 11, 12, 13, 14, 15, 16, 18, 2, 3, 4, 6, 7, 8, 9
cjis5.10.1.1
cobit5APO01.06, APO13.01, BAI04.04, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS01.03, DSS01.05, DSS03.01, DSS03.05, DSS05.02, DSS05.04, DSS05.05, DSS05.07, DSS06.02, DSS06.06
cui3.1.20
disaCCI-000366
isa-62443-20094.2.3.4, 4.3.3.4, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3, 4.4.3.3
isa-62443-2013SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 6.2, SR 7.1, SR 7.2, SR 7.6
iso27001-2013A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.12.1.1, A.12.1.2, A.12.1.3, A.12.5.1, A.12.6.2, A.13.1.1, A.13.1.2, A.13.1.3, A.13.2.1, A.13.2.2, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.14.2.2, A.14.2.3, A.14.2.4, A.17.2.1, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5
nerc-cipCIP-007-3 R4, CIP-007-3 R4.1, CIP-007-3 R4.2, CIP-007-3 R5.1
nistCM-7(a), CM-7(b), SC-5
nist-csfDE.AE-1, DE.CM-1, ID.AM-3, PR.AC-5, PR.DS-4, PR.DS-5, PR.IP-1, PR.PT-3, PR.PT-4
pcidssReq-1.4.3
os-srgSRG-OS-000480-GPOS-00227
cis3.3.4
pcidss41.4.2, 1.4

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - CJIS-5.10.1.1
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-5
  - PCI-DSS-Req-1.4.3
  - PCI-DSSv4-1.4
  - PCI-DSSv4-1.4.2
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_icmp_echo_ignore_broadcasts

- name: List /etc/sysctl.d/*.conf files
  find:
    paths:
    - /etc/sysctl.d/
    - /run/sysctl.d/
    - /usr/local/lib/sysctl.d/
    contains: ^[\s]*net.ipv4.icmp_echo_ignore_broadcasts.*$
    patterns: '*.conf'
    file_type: any
  register: find_sysctl_d
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - CJIS-5.10.1.1
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-5
  - PCI-DSS-Req-1.4.3
  - PCI-DSSv4-1.4
  - PCI-DSSv4-1.4.2
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_icmp_echo_ignore_broadcasts

- name: Comment out any occurrences of net.ipv4.icmp_echo_ignore_broadcasts from config
    files
  replace:
    path: '{{ item.path }}'
    regexp: ^[\s]*net.ipv4.icmp_echo_ignore_broadcasts
    replace: '#net.ipv4.icmp_echo_ignore_broadcasts'
  loop: '{{ find_sysctl_d.files }}'
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - CJIS-5.10.1.1
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-5
  - PCI-DSS-Req-1.4.3
  - PCI-DSSv4-1.4
  - PCI-DSSv4-1.4.2
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_icmp_echo_ignore_broadcasts
- name: XCCDF Value sysctl_net_ipv4_icmp_echo_ignore_broadcasts_value # promote to variable
  set_fact:
    sysctl_net_ipv4_icmp_echo_ignore_broadcasts_value: !!str 1
  tags:
    - always

- name: Ensure sysctl net.ipv4.icmp_echo_ignore_broadcasts is set
  sysctl:
    name: net.ipv4.icmp_echo_ignore_broadcasts
    value: '{{ sysctl_net_ipv4_icmp_echo_ignore_broadcasts_value }}'
    sysctl_file: /etc/sysctl.conf
    state: present
    reload: true
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - CJIS-5.10.1.1
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-5
  - PCI-DSS-Req-1.4.3
  - PCI-DSSv4-1.4
  - PCI-DSSv4-1.4.2
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_icmp_echo_ignore_broadcasts

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 net.ipv4.icmp_echo_ignore_broadcasts from /etc/sysctl.d/*.conf files

for f in /etc/sysctl.d/*.conf /run/sysctl.d/*.conf /usr/local/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]*net.ipv4.icmp_echo_ignore_broadcasts.*$' $f | uniq )
  if ! test -z "$matching_list"; then
    while IFS= read -r entry; do
      escaped_entry=$(sed -e 's|/|\\/|g' <<< "$entry")
      # comment out "net.ipv4.icmp_echo_ignore_broadcasts" 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_net_ipv4_icmp_echo_ignore_broadcasts_value='1'


#
# Set runtime for net.ipv4.icmp_echo_ignore_broadcasts
#
if [[ "$OSCAP_BOOTC_BUILD" != "YES" ]] ; then
    /sbin/sysctl -q -n -w net.ipv4.icmp_echo_ignore_broadcasts="$sysctl_net_ipv4_icmp_echo_ignore_broadcasts_value"
fi

#
# If net.ipv4.icmp_echo_ignore_broadcasts present in /etc/sysctl.conf, change value to appropriate value
#	else, add "net.ipv4.icmp_echo_ignore_broadcasts = 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' <<< "^net.ipv4.icmp_echo_ignore_broadcasts")

# shellcheck disable=SC2059
printf -v formatted_output "%s = %s" "$stripped_key" "$sysctl_net_ipv4_icmp_echo_ignore_broadcasts_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 "^net.ipv4.icmp_echo_ignore_broadcasts\\>" "${SYSCONFIG_FILE}"; then
    escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
    LC_ALL=C sed -i --follow-symlinks "s/^net.ipv4.icmp_echo_ignore_broadcasts\\>.*/$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

Rule   Enable Kernel Parameter to Ignore Bogus ICMP Error Responses on IPv4 Interfaces   [ref]

To set the runtime status of the net.ipv4.icmp_ignore_bogus_error_responses kernel parameter, run the following command:
$ sudo sysctl -w net.ipv4.icmp_ignore_bogus_error_responses=1
To make sure that the setting is persistent, add the following line to a file in the directory /etc/sysctl.d:
net.ipv4.icmp_ignore_bogus_error_responses = 1
Rationale:
Ignoring bogus ICMP error responses reduces log size, although some activity would not be logged.
Severity: 
unknown
Rule ID:xccdf_org.ssgproject.content_rule_sysctl_net_ipv4_icmp_ignore_bogus_error_responses
References:
cis-csc1, 11, 12, 13, 14, 15, 16, 2, 3, 7, 8, 9
cobit5APO13.01, BAI04.04, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS01.03, DSS03.05, DSS05.02, DSS05.05, DSS05.07, DSS06.06
cui3.1.20
disaCCI-000366
isa-62443-20094.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3
isa-62443-2013SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 6.2, SR 7.1, SR 7.2, SR 7.6
iso27001-2013A.12.1.2, A.12.1.3, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, A.17.2.1, A.9.1.2
nerc-cipCIP-007-3 R4, CIP-007-3 R4.1, CIP-007-3 R4.2, CIP-007-3 R5.1
nistCM-7(a), CM-7(b), SC-5
nist-csfDE.CM-1, PR.DS-4, PR.IP-1, PR.PT-3
pcidssReq-1.4.3
os-srgSRG-OS-000480-GPOS-00227
anssiR12
cis3.3.3
pcidss41.4.2, 1.4

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-5
  - PCI-DSS-Req-1.4.3
  - PCI-DSSv4-1.4
  - PCI-DSSv4-1.4.2
  - disable_strategy
  - low_complexity
  - medium_disruption
  - reboot_required
  - sysctl_net_ipv4_icmp_ignore_bogus_error_responses
  - unknown_severity

- name: List /etc/sysctl.d/*.conf files
  find:
    paths:
    - /etc/sysctl.d/
    - /run/sysctl.d/
    - /usr/local/lib/sysctl.d/
    contains: ^[\s]*net.ipv4.icmp_ignore_bogus_error_responses.*$
    patterns: '*.conf'
    file_type: any
  register: find_sysctl_d
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-5
  - PCI-DSS-Req-1.4.3
  - PCI-DSSv4-1.4
  - PCI-DSSv4-1.4.2
  - disable_strategy
  - low_complexity
  - medium_disruption
  - reboot_required
  - sysctl_net_ipv4_icmp_ignore_bogus_error_responses
  - unknown_severity

- name: Comment out any occurrences of net.ipv4.icmp_ignore_bogus_error_responses
    from config files
  replace:
    path: '{{ item.path }}'
    regexp: ^[\s]*net.ipv4.icmp_ignore_bogus_error_responses
    replace: '#net.ipv4.icmp_ignore_bogus_error_responses'
  loop: '{{ find_sysctl_d.files }}'
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-5
  - PCI-DSS-Req-1.4.3
  - PCI-DSSv4-1.4
  - PCI-DSSv4-1.4.2
  - disable_strategy
  - low_complexity
  - medium_disruption
  - reboot_required
  - sysctl_net_ipv4_icmp_ignore_bogus_error_responses
  - unknown_severity
- name: XCCDF Value sysctl_net_ipv4_icmp_ignore_bogus_error_responses_value # promote to variable
  set_fact:
    sysctl_net_ipv4_icmp_ignore_bogus_error_responses_value: !!str 1
  tags:
    - always

- name: Ensure sysctl net.ipv4.icmp_ignore_bogus_error_responses is set
  sysctl:
    name: net.ipv4.icmp_ignore_bogus_error_responses
    value: '{{ sysctl_net_ipv4_icmp_ignore_bogus_error_responses_value }}'
    sysctl_file: /etc/sysctl.conf
    state: present
    reload: true
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-5
  - PCI-DSS-Req-1.4.3
  - PCI-DSSv4-1.4
  - PCI-DSSv4-1.4.2
  - disable_strategy
  - low_complexity
  - medium_disruption
  - reboot_required
  - sysctl_net_ipv4_icmp_ignore_bogus_error_responses
  - unknown_severity

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 net.ipv4.icmp_ignore_bogus_error_responses from /etc/sysctl.d/*.conf files

for f in /etc/sysctl.d/*.conf /run/sysctl.d/*.conf /usr/local/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]*net.ipv4.icmp_ignore_bogus_error_responses.*$' $f | uniq )
  if ! test -z "$matching_list"; then
    while IFS= read -r entry; do
      escaped_entry=$(sed -e 's|/|\\/|g' <<< "$entry")
      # comment out "net.ipv4.icmp_ignore_bogus_error_responses" 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_net_ipv4_icmp_ignore_bogus_error_responses_value='1'


#
# Set runtime for net.ipv4.icmp_ignore_bogus_error_responses
#
if [[ "$OSCAP_BOOTC_BUILD" != "YES" ]] ; then
    /sbin/sysctl -q -n -w net.ipv4.icmp_ignore_bogus_error_responses="$sysctl_net_ipv4_icmp_ignore_bogus_error_responses_value"
fi

#
# If net.ipv4.icmp_ignore_bogus_error_responses present in /etc/sysctl.conf, change value to appropriate value
#	else, add "net.ipv4.icmp_ignore_bogus_error_responses = 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' <<< "^net.ipv4.icmp_ignore_bogus_error_responses")

# shellcheck disable=SC2059
printf -v formatted_output "%s = %s" "$stripped_key" "$sysctl_net_ipv4_icmp_ignore_bogus_error_responses_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 "^net.ipv4.icmp_ignore_bogus_error_responses\\>" "${SYSCONFIG_FILE}"; then
    escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
    LC_ALL=C sed -i --follow-symlinks "s/^net.ipv4.icmp_ignore_bogus_error_responses\\>.*/$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

Rule   Enable Kernel Parameter to Use TCP Syncookies on Network Interfaces   [ref]

To set the runtime status of the net.ipv4.tcp_syncookies kernel parameter, run the following command:
$ sudo sysctl -w net.ipv4.tcp_syncookies=1
To make sure that the setting is persistent, add the following line to a file in the directory /etc/sysctl.d:
net.ipv4.tcp_syncookies = 1
Rationale:
A TCP SYN flood attack can cause a denial of service by filling a system's TCP connection table with connections in the SYN_RCVD state. Syncookies can be used to track a connection when a subsequent ACK is received, verifying the initiator is attempting a valid connection and is not a flood source. This feature is activated when a flood condition is detected, and enables the system to continue servicing valid connection requests.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_sysctl_net_ipv4_tcp_syncookies
References:
cis-csc1, 12, 13, 14, 15, 16, 18, 2, 4, 6, 7, 8, 9
cjis5.10.1.1
cobit5APO01.06, APO13.01, BAI04.04, DSS01.03, DSS01.05, DSS03.01, DSS03.05, DSS05.02, DSS05.04, DSS05.07, DSS06.02
cui3.1.20
disaCCI-001095, CCI-000366, CCI-002385
isa-62443-20094.2.3.4, 4.3.3.4, 4.4.3.3
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 6.2, SR 7.1, SR 7.2, SR 7.6
iso27001-2013A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.12.1.1, A.12.1.2, A.12.1.3, A.13.1.1, A.13.1.2, A.13.1.3, A.13.2.1, A.13.2.2, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.17.2.1, 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-7(a), CM-7(b), SC-5(1), SC-5(2), SC-5(3)(a), CM-6(a)
nist-csfDE.AE-1, DE.CM-1, ID.AM-3, PR.AC-5, PR.DS-4, PR.DS-5, PR.PT-4
pcidssReq-1.4.1
os-srgSRG-OS-000480-GPOS-00227, SRG-OS-000420-GPOS-00186, SRG-OS-000142-GPOS-00071
anssiR12
cis3.3.10
pcidss41.4.3, 1.4

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - CJIS-5.10.1.1
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-5(1)
  - NIST-800-53-SC-5(2)
  - NIST-800-53-SC-5(3)(a)
  - PCI-DSS-Req-1.4.1
  - PCI-DSSv4-1.4
  - PCI-DSSv4-1.4.3
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_tcp_syncookies

- name: List /etc/sysctl.d/*.conf files
  find:
    paths:
    - /etc/sysctl.d/
    - /run/sysctl.d/
    - /usr/local/lib/sysctl.d/
    contains: ^[\s]*net.ipv4.tcp_syncookies.*$
    patterns: '*.conf'
    file_type: any
  register: find_sysctl_d
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - CJIS-5.10.1.1
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-5(1)
  - NIST-800-53-SC-5(2)
  - NIST-800-53-SC-5(3)(a)
  - PCI-DSS-Req-1.4.1
  - PCI-DSSv4-1.4
  - PCI-DSSv4-1.4.3
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_tcp_syncookies

- name: Comment out any occurrences of net.ipv4.tcp_syncookies from config files
  replace:
    path: '{{ item.path }}'
    regexp: ^[\s]*net.ipv4.tcp_syncookies
    replace: '#net.ipv4.tcp_syncookies'
  loop: '{{ find_sysctl_d.files }}'
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - CJIS-5.10.1.1
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-5(1)
  - NIST-800-53-SC-5(2)
  - NIST-800-53-SC-5(3)(a)
  - PCI-DSS-Req-1.4.1
  - PCI-DSSv4-1.4
  - PCI-DSSv4-1.4.3
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_tcp_syncookies
- name: XCCDF Value sysctl_net_ipv4_tcp_syncookies_value # promote to variable
  set_fact:
    sysctl_net_ipv4_tcp_syncookies_value: !!str 1
  tags:
    - always

- name: Ensure sysctl net.ipv4.tcp_syncookies is set
  sysctl:
    name: net.ipv4.tcp_syncookies
    value: '{{ sysctl_net_ipv4_tcp_syncookies_value }}'
    sysctl_file: /etc/sysctl.conf
    state: present
    reload: true
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - CJIS-5.10.1.1
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-5(1)
  - NIST-800-53-SC-5(2)
  - NIST-800-53-SC-5(3)(a)
  - PCI-DSS-Req-1.4.1
  - PCI-DSSv4-1.4
  - PCI-DSSv4-1.4.3
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_tcp_syncookies

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 net.ipv4.tcp_syncookies from /etc/sysctl.d/*.conf files

for f in /etc/sysctl.d/*.conf /run/sysctl.d/*.conf /usr/local/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]*net.ipv4.tcp_syncookies.*$' $f | uniq )
  if ! test -z "$matching_list"; then
    while IFS= read -r entry; do
      escaped_entry=$(sed -e 's|/|\\/|g' <<< "$entry")
      # comment out "net.ipv4.tcp_syncookies" 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_net_ipv4_tcp_syncookies_value='1'


#
# Set runtime for net.ipv4.tcp_syncookies
#
if [[ "$OSCAP_BOOTC_BUILD" != "YES" ]] ; then
    /sbin/sysctl -q -n -w net.ipv4.tcp_syncookies="$sysctl_net_ipv4_tcp_syncookies_value"
fi

#
# If net.ipv4.tcp_syncookies present in /etc/sysctl.conf, change value to appropriate value
#	else, add "net.ipv4.tcp_syncookies = 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' <<< "^net.ipv4.tcp_syncookies")

# shellcheck disable=SC2059
printf -v formatted_output "%s = %s" "$stripped_key" "$sysctl_net_ipv4_tcp_syncookies_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 "^net.ipv4.tcp_syncookies\\>" "${SYSCONFIG_FILE}"; then
    escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
    LC_ALL=C sed -i --follow-symlinks "s/^net.ipv4.tcp_syncookies\\>.*/$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
Group   Network Parameters for Hosts Only   Group contains 3 rules
[ref]   If the system is not going to be used as a router, then setting certain kernel parameters ensure that the host will not perform routing of network traffic.

Rule   Disable Kernel Parameter for Sending ICMP Redirects on all IPv4 Interfaces   [ref]

To set the runtime status of the net.ipv4.conf.all.send_redirects kernel parameter, run the following command:
$ sudo sysctl -w net.ipv4.conf.all.send_redirects=0
To make sure that the setting is persistent, add the following line to a file in the directory /etc/sysctl.d:
net.ipv4.conf.all.send_redirects = 0
Rationale:
ICMP redirect messages are used by routers to inform hosts that a more direct route exists for a particular destination. These messages contain information from the system's route table possibly revealing portions of the network topology.
The ability to send ICMP redirects is only appropriate for systems acting as routers.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_sysctl_net_ipv4_conf_all_send_redirects
References:
cis-csc1, 11, 12, 13, 14, 15, 16, 18, 2, 3, 4, 6, 7, 8, 9
cjis5.10.1.1
cobit5APO01.06, APO13.01, BAI04.04, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS01.03, DSS01.05, DSS03.01, DSS03.05, DSS05.02, DSS05.04, DSS05.05, DSS05.07, DSS06.02, DSS06.06
cui3.1.20
disaCCI-000366
isa-62443-20094.2.3.4, 4.3.3.4, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3, 4.4.3.3
isa-62443-2013SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 6.2, SR 7.1, SR 7.2, SR 7.6
iso27001-2013A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.12.1.1, A.12.1.2, A.12.1.3, A.12.5.1, A.12.6.2, A.13.1.1, A.13.1.2, A.13.1.3, A.13.2.1, A.13.2.2, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.14.2.2, A.14.2.3, A.14.2.4, A.17.2.1, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5
nerc-cipCIP-007-3 R4, CIP-007-3 R4.1, CIP-007-3 R4.2, CIP-007-3 R5.1
nistCM-7(a), CM-7(b), SC-5, CM-6(a), SC-7(a)
nist-csfDE.AE-1, DE.CM-1, ID.AM-3, PR.AC-5, PR.DS-4, PR.DS-5, PR.IP-1, PR.PT-3, PR.PT-4
os-srgSRG-OS-000480-GPOS-00227
anssiR12
cis3.3.2
pcidss41.4.5, 1.4

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - CJIS-5.10.1.1
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-5
  - NIST-800-53-SC-7(a)
  - PCI-DSSv4-1.4
  - PCI-DSSv4-1.4.5
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_conf_all_send_redirects

- name: List /etc/sysctl.d/*.conf files
  find:
    paths:
    - /etc/sysctl.d/
    - /run/sysctl.d/
    - /usr/local/lib/sysctl.d/
    contains: ^[\s]*net.ipv4.conf.all.send_redirects.*$
    patterns: '*.conf'
    file_type: any
  register: find_sysctl_d
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - CJIS-5.10.1.1
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-5
  - NIST-800-53-SC-7(a)
  - PCI-DSSv4-1.4
  - PCI-DSSv4-1.4.5
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_conf_all_send_redirects

- name: Comment out any occurrences of net.ipv4.conf.all.send_redirects from config
    files
  replace:
    path: '{{ item.path }}'
    regexp: ^[\s]*net.ipv4.conf.all.send_redirects
    replace: '#net.ipv4.conf.all.send_redirects'
  loop: '{{ find_sysctl_d.files }}'
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - CJIS-5.10.1.1
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-5
  - NIST-800-53-SC-7(a)
  - PCI-DSSv4-1.4
  - PCI-DSSv4-1.4.5
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_conf_all_send_redirects

- name: Ensure sysctl net.ipv4.conf.all.send_redirects is set to 0
  sysctl:
    name: net.ipv4.conf.all.send_redirects
    value: '0'
    sysctl_file: /etc/sysctl.conf
    state: present
    reload: true
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - CJIS-5.10.1.1
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-5
  - NIST-800-53-SC-7(a)
  - PCI-DSSv4-1.4
  - PCI-DSSv4-1.4.5
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_conf_all_send_redirects

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 net.ipv4.conf.all.send_redirects from /etc/sysctl.d/*.conf files

for f in /etc/sysctl.d/*.conf /run/sysctl.d/*.conf /usr/local/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]*net.ipv4.conf.all.send_redirects.*$' $f | uniq )
  if ! test -z "$matching_list"; then
    while IFS= read -r entry; do
      escaped_entry=$(sed -e 's|/|\\/|g' <<< "$entry")
      # comment out "net.ipv4.conf.all.send_redirects" 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 net.ipv4.conf.all.send_redirects
#
if [[ "$OSCAP_BOOTC_BUILD" != "YES" ]] ; then
    /sbin/sysctl -q -n -w net.ipv4.conf.all.send_redirects="0"
fi

#
# If net.ipv4.conf.all.send_redirects present in /etc/sysctl.conf, change value to "0"
#	else, add "net.ipv4.conf.all.send_redirects = 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' <<< "^net.ipv4.conf.all.send_redirects")

# 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 "^net.ipv4.conf.all.send_redirects\\>" "${SYSCONFIG_FILE}"; then
    escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
    LC_ALL=C sed -i --follow-symlinks "s/^net.ipv4.conf.all.send_redirects\\>.*/$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

Rule   Disable Kernel Parameter for Sending ICMP Redirects on all IPv4 Interfaces by Default   [ref]

To set the runtime status of the net.ipv4.conf.default.send_redirects kernel parameter, run the following command:
$ sudo sysctl -w net.ipv4.conf.default.send_redirects=0
To make sure that the setting is persistent, add the following line to a file in the directory /etc/sysctl.d:
net.ipv4.conf.default.send_redirects = 0
Rationale:
ICMP redirect messages are used by routers to inform hosts that a more direct route exists for a particular destination. These messages contain information from the system's route table possibly revealing portions of the network topology.
The ability to send ICMP redirects is only appropriate for systems acting as routers.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_sysctl_net_ipv4_conf_default_send_redirects
References:
cis-csc1, 11, 12, 13, 14, 15, 16, 18, 2, 3, 4, 6, 7, 8, 9
cjis5.10.1.1
cobit5APO01.06, APO13.01, BAI04.04, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS01.03, DSS01.05, DSS03.01, DSS03.05, DSS05.02, DSS05.04, DSS05.05, DSS05.07, DSS06.02, DSS06.06
cui3.1.20
disaCCI-000366
isa-62443-20094.2.3.4, 4.3.3.4, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3, 4.4.3.3
isa-62443-2013SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 6.2, SR 7.1, SR 7.2, SR 7.6
iso27001-2013A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.12.1.1, A.12.1.2, A.12.1.3, A.12.5.1, A.12.6.2, A.13.1.1, A.13.1.2, A.13.1.3, A.13.2.1, A.13.2.2, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.14.2.2, A.14.2.3, A.14.2.4, A.17.2.1, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5
nerc-cipCIP-007-3 R4, CIP-007-3 R4.1, CIP-007-3 R4.2, CIP-007-3 R5.1
nistCM-7(a), CM-7(b), SC-5, CM-6(a), SC-7(a)
nist-csfDE.AE-1, DE.CM-1, ID.AM-3, PR.AC-5, PR.DS-4, PR.DS-5, PR.IP-1, PR.PT-3, PR.PT-4
os-srgSRG-OS-000480-GPOS-00227
anssiR12
cis3.3.2
pcidss41.4.5, 1.4

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - CJIS-5.10.1.1
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-5
  - NIST-800-53-SC-7(a)
  - PCI-DSSv4-1.4
  - PCI-DSSv4-1.4.5
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_conf_default_send_redirects

- name: List /etc/sysctl.d/*.conf files
  find:
    paths:
    - /etc/sysctl.d/
    - /run/sysctl.d/
    - /usr/local/lib/sysctl.d/
    contains: ^[\s]*net.ipv4.conf.default.send_redirects.*$
    patterns: '*.conf'
    file_type: any
  register: find_sysctl_d
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - CJIS-5.10.1.1
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-5
  - NIST-800-53-SC-7(a)
  - PCI-DSSv4-1.4
  - PCI-DSSv4-1.4.5
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_conf_default_send_redirects

- name: Comment out any occurrences of net.ipv4.conf.default.send_redirects from config
    files
  replace:
    path: '{{ item.path }}'
    regexp: ^[\s]*net.ipv4.conf.default.send_redirects
    replace: '#net.ipv4.conf.default.send_redirects'
  loop: '{{ find_sysctl_d.files }}'
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - CJIS-5.10.1.1
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-5
  - NIST-800-53-SC-7(a)
  - PCI-DSSv4-1.4
  - PCI-DSSv4-1.4.5
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_conf_default_send_redirects

- name: Ensure sysctl net.ipv4.conf.default.send_redirects is set to 0
  sysctl:
    name: net.ipv4.conf.default.send_redirects
    value: '0'
    sysctl_file: /etc/sysctl.conf
    state: present
    reload: true
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - CJIS-5.10.1.1
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-5
  - NIST-800-53-SC-7(a)
  - PCI-DSSv4-1.4
  - PCI-DSSv4-1.4.5
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_conf_default_send_redirects

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 net.ipv4.conf.default.send_redirects from /etc/sysctl.d/*.conf files

for f in /etc/sysctl.d/*.conf /run/sysctl.d/*.conf /usr/local/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]*net.ipv4.conf.default.send_redirects.*$' $f | uniq )
  if ! test -z "$matching_list"; then
    while IFS= read -r entry; do
      escaped_entry=$(sed -e 's|/|\\/|g' <<< "$entry")
      # comment out "net.ipv4.conf.default.send_redirects" 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 net.ipv4.conf.default.send_redirects
#
if [[ "$OSCAP_BOOTC_BUILD" != "YES" ]] ; then
    /sbin/sysctl -q -n -w net.ipv4.conf.default.send_redirects="0"
fi

#
# If net.ipv4.conf.default.send_redirects present in /etc/sysctl.conf, change value to "0"
#	else, add "net.ipv4.conf.default.send_redirects = 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' <<< "^net.ipv4.conf.default.send_redirects")

# 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 "^net.ipv4.conf.default.send_redirects\\>" "${SYSCONFIG_FILE}"; then
    escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
    LC_ALL=C sed -i --follow-symlinks "s/^net.ipv4.conf.default.send_redirects\\>.*/$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

Rule   Disable Kernel Parameter for IP Forwarding on IPv4 Interfaces   [ref]

To set the runtime status of the net.ipv4.ip_forward kernel parameter, run the following command:
$ sudo sysctl -w net.ipv4.ip_forward=0
To make sure that the setting is persistent, add the following line to a file in the directory /etc/sysctl.d:
net.ipv4.ip_forward = 0
Warning:  Certain technologies such as virtual machines, containers, etc. rely on IPv4 forwarding to enable and use networking. Disabling IPv4 forwarding would cause those technologies to stop working. Therefore, this rule should not be used in profiles or benchmarks that target usage of IPv4 forwarding.
Rationale:
Routing protocol daemons are typically used on routers to exchange network topology information with other routers. If this capability is used when not required, system network information may be unnecessarily transmitted across the network.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_sysctl_net_ipv4_ip_forward
References:
cis-csc1, 11, 12, 13, 14, 15, 16, 2, 3, 7, 8, 9
cobit5APO13.01, BAI04.04, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS01.03, DSS03.05, DSS05.02, DSS05.05, DSS05.07, DSS06.06
cui3.1.20
disaCCI-000366
isa-62443-20094.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3
isa-62443-2013SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 6.2, SR 7.1, SR 7.2, SR 7.6
iso27001-2013A.12.1.2, A.12.1.3, A.12.5.1, A.12.6.2, A.13.1.1, A.13.2.1, A.14.1.3, A.14.2.2, A.14.2.3, A.14.2.4, A.17.2.1, A.9.1.2
nerc-cipCIP-007-3 R4, CIP-007-3 R4.1, CIP-007-3 R4.2, CIP-007-3 R5.1
nistCM-7(a), CM-7(b), SC-5, CM-6(a), SC-7(a)
nist-csfDE.CM-1, PR.DS-4, PR.IP-1, PR.PT-3, PR.PT-4
pcidssReq-1.3.1, Req-1.3.2
os-srgSRG-OS-000480-GPOS-00227
anssiR12
cis3.3.1
pcidss41.4.3, 1.4

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-5
  - NIST-800-53-SC-7(a)
  - PCI-DSS-Req-1.3.1
  - PCI-DSS-Req-1.3.2
  - PCI-DSSv4-1.4
  - PCI-DSSv4-1.4.3
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_ip_forward

- name: List /etc/sysctl.d/*.conf files
  find:
    paths:
    - /etc/sysctl.d/
    - /run/sysctl.d/
    - /usr/local/lib/sysctl.d/
    contains: ^[\s]*net.ipv4.ip_forward.*$
    patterns: '*.conf'
    file_type: any
  register: find_sysctl_d
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-5
  - NIST-800-53-SC-7(a)
  - PCI-DSS-Req-1.3.1
  - PCI-DSS-Req-1.3.2
  - PCI-DSSv4-1.4
  - PCI-DSSv4-1.4.3
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_ip_forward

- name: Comment out any occurrences of net.ipv4.ip_forward from config files
  replace:
    path: '{{ item.path }}'
    regexp: ^[\s]*net.ipv4.ip_forward
    replace: '#net.ipv4.ip_forward'
  loop: '{{ find_sysctl_d.files }}'
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-5
  - NIST-800-53-SC-7(a)
  - PCI-DSS-Req-1.3.1
  - PCI-DSS-Req-1.3.2
  - PCI-DSSv4-1.4
  - PCI-DSSv4-1.4.3
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_ip_forward

- name: Ensure sysctl net.ipv4.ip_forward is set to 0
  sysctl:
    name: net.ipv4.ip_forward
    value: '0'
    sysctl_file: /etc/sysctl.conf
    state: present
    reload: true
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-171-3.1.20
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-5
  - NIST-800-53-SC-7(a)
  - PCI-DSS-Req-1.3.1
  - PCI-DSS-Req-1.3.2
  - PCI-DSSv4-1.4
  - PCI-DSSv4-1.4.3
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_ip_forward

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 net.ipv4.ip_forward from /etc/sysctl.d/*.conf files

for f in /etc/sysctl.d/*.conf /run/sysctl.d/*.conf /usr/local/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]*net.ipv4.ip_forward.*$' $f | uniq )
  if ! test -z "$matching_list"; then
    while IFS= read -r entry; do
      escaped_entry=$(sed -e 's|/|\\/|g' <<< "$entry")
      # comment out "net.ipv4.ip_forward" 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 net.ipv4.ip_forward
#
if [[ "$OSCAP_BOOTC_BUILD" != "YES" ]] ; then
    /sbin/sysctl -q -n -w net.ipv4.ip_forward="0"
fi

#
# If net.ipv4.ip_forward present in /etc/sysctl.conf, change value to "0"
#	else, add "net.ipv4.ip_forward = 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' <<< "^net.ipv4.ip_forward")

# 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 "^net.ipv4.ip_forward\\>" "${SYSCONFIG_FILE}"; then
    escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
    LC_ALL=C sed -i --follow-symlinks "s/^net.ipv4.ip_forward\\>.*/$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
Group   nftables   Group contains 8 rules
[ref]   If firewalld or iptables are being used in your environment, please follow the guidance in their respective section and pass-over the guidance in this section.

nftables is a subsystem of the Linux kernel providing filtering and classification of network packets/datagrams/frames and is the successor to iptables. The biggest change with the successor nftables is its simplicity. With iptables, we have to configure every single rule and use the syntax which can be compared with normal commands. With nftables, the simpler syntax, much like BPF (Berkely Packet Filter) means shorter lines and less repetition. Support for nftables should also be compiled into the kernel, together with the related nftables modules.

It is available in Linux kernels >= 3.13. Please ensure that your kernel supports nftables before choosing this option.

Rule   Install nftables Package   [ref]

nftables provides a new in-kernel packet classification framework that is based on a network-specific Virtual Machine (VM) and a new nft userspace command line tool. nftables reuses the existing Netfilter subsystems such as the existing hook infrastructure, the connection tracking system, NAT, userspace queuing and logging subsystem. The nftables package can be installed with the following command:
$ apt-get install nftables
Rationale:
nftables is a subsystem of the Linux kernel that can protect against threats originating from within a corporate network to include malicious mobile code and poorly configured software on a host.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_package_nftables_installed
References:
cis4.3.1
pcidss41.2.1, 1.2

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

class install_nftables {
  package { 'nftables':
    ensure => 'installed',
  }
}

Complexity:low
Disruption:low
Reboot:false
Strategy:enable
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - PCI-DSSv4-1.2
  - PCI-DSSv4-1.2.1
  - enable_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - package_nftables_installed

- name: Ensure nftables is installed
  package:
    name: nftables
    state: present
  when: ( "linux-base" in ansible_facts.packages )
  tags:
  - PCI-DSSv4-1.2
  - PCI-DSSv4-1.2.1
  - enable_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - package_nftables_installed


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

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

DEBIAN_FRONTEND=noninteractive apt-get install -y "nftables"

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

Rule   Uninstall nftables package   [ref]

nftables is a subsystem of the Linux kernel providing filtering and classification of network packets/datagrams/frames and is the successor to iptables. The nftables package can be removed with the following command:
$ apt-get remove nftables
Rationale:
Running both firewalld and nftables may lead to conflict.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_package_nftables_removed
References:
cis4.4.1.2

Complexity:low
Disruption:low
Reboot:false
Strategy:disable
include remove_nftables

class remove_nftables {
  package { 'nftables':
    ensure => 'purged',
  }
}

Complexity:low
Disruption:low
Reboot:false
Strategy:disable
- name: Ensure nftables is removed
  package:
    name: nftables
    state: absent
  tags:
  - disable_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - package_nftables_removed

Complexity:low
Disruption:low
Reboot:false
Strategy:disable

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

DEBIAN_FRONTEND=noninteractive apt-get remove -y "nftables"

Rule   Verify nftables Service is Enabled   [ref]

The nftables service allows for the loading of nftables rulesets during boot, or starting on the nftables service The nftables service can be enabled with the following command:
$ sudo systemctl enable nftables.service
Rationale:
The nftables service restores the nftables rules from the rules files referenced in the /etc/sysconfig/nftables.conf file during boot or the starting of the nftables service
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_service_nftables_enabled
References:
cis4.3.9

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

class enable_nftables {
  service {'nftables':
    enable => true,
    ensure => 'running',
  }
}

Complexity:low
Disruption:low
Reboot:false
Strategy:enable
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - enable_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - service_nftables_enabled

- name: Verify nftables Service is Enabled - Enable service nftables
  block:

  - name: Gather the package facts
    package_facts:
      manager: auto

  - name: Verify nftables Service is Enabled - Enable Service nftables
    ansible.builtin.systemd:
      name: nftables
      enabled: true
      state: started
      masked: false
    when:
    - '"nftables" in ansible_facts.packages'
  when: ( "nftables" in ansible_facts.packages and "linux-base" in ansible_facts.packages
    )
  tags:
  - enable_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - service_nftables_enabled


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

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

SYSTEMCTL_EXEC='/usr/bin/systemctl'
"$SYSTEMCTL_EXEC" unmask 'nftables.service'
"$SYSTEMCTL_EXEC" start 'nftables.service'
"$SYSTEMCTL_EXEC" enable 'nftables.service'

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

Rule   Verify nftables Service is Disabled   [ref]

nftables is a subsystem of the Linux kernel providing filtering and classification of network packets/datagrams/frames and is the successor to iptables. The nftables service can be disabled with the following command:
systemctl disable nftables
Rationale:
Running both firewalld and nftables may lead to conflict. nftables is actually one of the backends for firewalld management tools.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_service_nftables_disabled
References:
cis4.4.1.2
pcidss41.2.1, 1.2

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

class disable_nftables {
  service {'nftables':
    enable => false,
    ensure => 'stopped',
  }
}

Complexity:low
Disruption:low
Reboot:false
Strategy:disable
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - PCI-DSSv4-1.2
  - PCI-DSSv4-1.2.1
  - disable_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - service_nftables_disabled

- name: Verify nftables Service is Disabled - Collect systemd Services Present in
    the System
  ansible.builtin.command: systemctl -q list-unit-files --type service
  register: service_exists
  changed_when: false
  failed_when: service_exists.rc not in [0, 1]
  check_mode: false
  when: ( "firewalld" in ansible_facts.packages and "nftables" in ansible_facts.packages
    and "linux-base" in ansible_facts.packages )
  tags:
  - PCI-DSSv4-1.2
  - PCI-DSSv4-1.2.1
  - disable_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - service_nftables_disabled

- name: Verify nftables Service is Disabled - Ensure nftables.service is Masked
  ansible.builtin.systemd:
    name: nftables.service
    state: stopped
    enabled: false
    masked: true
  when:
  - ( "firewalld" in ansible_facts.packages and "nftables" in ansible_facts.packages
    and "linux-base" in ansible_facts.packages )
  - service_exists.stdout_lines is search("nftables.service", multiline=True)
  tags:
  - PCI-DSSv4-1.2
  - PCI-DSSv4-1.2.1
  - disable_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - service_nftables_disabled

- name: Unit Socket Exists - nftables.socket
  ansible.builtin.command: systemctl -q list-unit-files nftables.socket
  register: socket_file_exists
  changed_when: false
  failed_when: socket_file_exists.rc not in [0, 1]
  check_mode: false
  when: ( "firewalld" in ansible_facts.packages and "nftables" in ansible_facts.packages
    and "linux-base" in ansible_facts.packages )
  tags:
  - PCI-DSSv4-1.2
  - PCI-DSSv4-1.2.1
  - disable_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - service_nftables_disabled

- name: Verify nftables Service is Disabled - Disable Socket nftables
  ansible.builtin.systemd:
    name: nftables.socket
    enabled: false
    state: stopped
    masked: true
  when:
  - ( "firewalld" in ansible_facts.packages and "nftables" in ansible_facts.packages
    and "linux-base" in ansible_facts.packages )
  - socket_file_exists.stdout_lines is search("nftables.socket", multiline=True)
  tags:
  - PCI-DSSv4-1.2
  - PCI-DSSv4-1.2.1
  - disable_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - service_nftables_disabled


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

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
apiVersion: machineconfiguration.openshift.io/v1
kind: MachineConfig
spec:
  config:
    ignition:
      version: 3.1.0
    systemd:
      units:
      - name: nftables.service
        enabled: false
        mask: true
      - name: nftables.socket
        enabled: false
        mask: true

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

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

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

Rule   Ensure nftables Default Deny Firewall Policy   [ref]

Base chain policy is the default verdict that will be applied to packets reaching the end of the chain. There are two policies: accept (Default) and drop. If the policy is set to accept, the firewall will accept any packet that is not configured to be denied and the packet will continue traversing the network stack. {% if 'ubuntu' in product %} Run the following commands and verify that base chains contain a policy of DROP.
$ nft list ruleset | grep 'hook input'
type filter hook input priority 0; policy drop;
$ nft list ruleset | grep 'hook forward'
type filter hook forward priority 0; policy drop;
$ nft list ruleset | grep 'hook output'
type filter hook output priority 0; policy drop;
Warning:  Changing firewall settings while connected over network can result in being locked out of the system.
Rationale:
It is easier to allow acceptable usage than to block unacceptable usage.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_nftables_ensure_default_deny_policy
References:
cis4.3.8
pcidss41.3.1, 1.3

Rule   Ensure Base Chains Exist for Nftables   [ref]

Tables in nftables hold chains. Each table only has one address family and only applies to packets of this family. Tables can have one of six families. Chains are containers for rules. They exist in two kinds, base chains and regular chains. A base chain is an entry point for packets from the networking stack, a regular chain may be used as jump target and is used for better rule organization.
Warning:  Configuring rules over ssh, by creating a base chain with policy drop will cause loss of connectivity. Ensure that a rule allowing ssh has been added to the base chain prior to setting the base cahin's policy to drop
Rationale:
If a base chain doesn't exist with a hook for input, forward, and delete, packets that would flow through those chains will not be touched by nftables.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_set_nftables_base_chain
References:
cis4.3.5

Complexity:low
Disruption:low
Reboot:false
Strategy:restrict
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy
  - set_nftables_base_chain
- name: XCCDF Value var_nftables_table # promote to variable
  set_fact:
    var_nftables_table: !!str filter
  tags:
    - always
- name: XCCDF Value var_nftables_family # promote to variable
  set_fact:
    var_nftables_family: !!str inet
  tags:
    - always
- name: XCCDF Value var_nftables_base_chain_names # promote to variable
  set_fact:
    var_nftables_base_chain_names: !!str input,forward,output
  tags:
    - always
- name: XCCDF Value var_nftables_base_chain_types # promote to variable
  set_fact:
    var_nftables_base_chain_types: !!str filter,filter,filter
  tags:
    - always
- name: XCCDF Value var_nftables_base_chain_hooks # promote to variable
  set_fact:
    var_nftables_base_chain_hooks: !!str input,forward,output
  tags:
    - always
- name: XCCDF Value var_nftables_base_chain_priorities # promote to variable
  set_fact:
    var_nftables_base_chain_priorities: !!str 0,0,0
  tags:
    - always
- name: XCCDF Value var_nftables_base_chain_policies # promote to variable
  set_fact:
    var_nftables_base_chain_policies: !!str accept,accept,accept
  tags:
    - always

- name: Ensure Base Chains Exist for Nftables - Check Existence of Nftables Table
  ansible.builtin.shell: nft list tables | grep '{{ var_nftables_family }} {{ var_nftables_table
    }}'
  register: existing_nftables
  changed_when: false
  failed_when: false
  when: '"nftables" in ansible_facts.packages'
  tags:
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy
  - set_nftables_base_chain

- name: Ensure Base Chains Exist for Nftables - Set NFTables Table
  ansible.builtin.command: nft create table {{ var_nftables_family }} {{ var_nftables_table
    }}
  when:
  - '"nftables" in ansible_facts.packages'
  - existing_nftables is not skipped and existing_nftables.rc > 0
  tags:
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy
  - set_nftables_base_chain

- name: Ensure Base Chains Exist for Nftables - Add Base Chains
  ansible.builtin.command: nft 'add chain {{ var_nftables_family }} {{ var_nftables_table
    }} {{ item.0 }} { type {{ item.1 }} hook {{ item.2 }} priority {{ item.3 }} ;
    policy {{ item.4 }} ; }'
  with_together:
  - '{{ var_nftables_base_chain_names.split(",") }}'
  - '{{ var_nftables_base_chain_types.split(",") }}'
  - '{{ var_nftables_base_chain_hooks.split(",") }}'
  - '{{ var_nftables_base_chain_priorities.split(",") }}'
  - '{{ var_nftables_base_chain_policies.split(",") }}'
  when: '"nftables" in ansible_facts.packages'
  tags:
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy
  - set_nftables_base_chain

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

#Name of the table
var_nftables_table='filter'

#Familiy of the table 
var_nftables_family='inet'

#Name(s) of base chain
var_nftables_base_chain_names='input,forward,output'

#Type(s) of base chain
var_nftables_base_chain_types='filter,filter,filter'

# Hooks for base chain
var_nftables_base_chain_hooks='input,forward,output'

#Priority
var_nftables_base_chain_priorities='0,0,0'

#Policy 
var_nftables_base_chain_policies='accept,accept,accept'


#Transfer some of strings to arrays
IFS="," read -r -a  names <<< "$var_nftables_base_chain_names"
IFS="," read -r -a  types <<< "$var_nftables_base_chain_types"
IFS="," read -r -a  hooks <<< "$var_nftables_base_chain_hooks"
IFS="," read -r -a  priorities <<< "$var_nftables_base_chain_priorities"
IFS="," read -r -a  policies <<< "$var_nftables_base_chain_policies"

my_cmd="nft list tables | grep '$var_nftables_family $var_nftables_table'"
eval IS_TABLE_EXIST=\$\($my_cmd\)
if [ -z "$IS_TABLE_EXIST" ]
then
  # We create a table and add chains to it 
  nft create table "$var_nftables_family" "$var_nftables_table"
  num_of_chains=${#names[@]}
  for ((i=0; i < num_of_chains; i++))
  do
   chain_to_add="add chain $var_nftables_family $var_nftables_table ${names[$i]} { type ${types[$i]} hook ${hooks[$i]} priority ${priorities[$i]} ; policy ${policies[$i]} ; }"
   my_cmd="nft '$chain_to_add'"
   eval $my_cmd
  done    
else
  # We add missing chains to the existing table
  num_of_chains=${#names[@]}
  for ((i=0; i < num_of_chains; i++))
  do
    IS_CHAIN_EXIST=$(nft list table "$var_nftables_family" "$var_nftables_table" | grep "hook ${hooks[$i]}")
    if [ -z "$IS_CHAIN_EXIST" ]
      then
        chain_to_add="add chain '$var_nftables_family' '$var_nftables_table' ${names[$i]} { type ${types[$i]} hook ${hooks[$i]} priority ${priorities[$i]} ; policy ${policies[$i]} ; }"
        my_cmd="nft '$chain_to_add'"
        eval $my_cmd
    fi
  done 
fi

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

Rule   Set nftables Configuration for Loopback Traffic   [ref]

Configure the loopback interface to accept traffic. Configure all other interfaces to deny traffic to the loopback network.
Warning:  Changing firewall settings while connected over network can result in being locked out of the system. Keep in mind the remediation makes changes only to the running system, in order to keep the changes need to take care to save the nft settings to the relvant configutation files.
Rationale:
Loopback traffic is generated between processes on machine and is typically critical to operation of the system. The loopback interface is the only place that loopback network traffic should be seen, all other interfaces should ignore traffic on this network as an anti-spoofing measure.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_set_nftables_loopback_traffic
References:
pcidssReq-1.4.1
cis4.3.6

Complexity:low
Disruption:low
Reboot:false
Strategy:restrict
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - PCI-DSS-Req-1.4.1
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy
  - set_nftables_loopback_traffic

- name: Implement Loopback Rules
  ansible.builtin.command: nft add rule inet filter input iif lo accept
  when: ( "nftables" in ansible_facts.packages )
  tags:
  - PCI-DSS-Req-1.4.1
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy
  - set_nftables_loopback_traffic

- name: Create Rule to Drop Input IP Address from Loopback
  ansible.builtin.command: nft add rule inet filter input ip saddr 127.0.0.0/8 counter
    drop
  when: ( "nftables" in ansible_facts.packages )
  tags:
  - PCI-DSS-Req-1.4.1
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy
  - set_nftables_loopback_traffic

- name: Check if IPv6 is Disabled in grub Configuration
  ansible.builtin.shell: |
    [ -z "$(grep "^\s*linux" /boot/grub2/grub.cfg | grep -v ipv6.disabled=1)" ]
  register: ipv6_status
  when: ( "nftables" in ansible_facts.packages )
  tags:
  - PCI-DSS-Req-1.4.1
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy
  - set_nftables_loopback_traffic

- name: Check sysctl value of net.ipv6.conf.all.disable_ipv6
  sysctl:
    name: net.ipv6.conf.all.disable_ipv6
    state: present
    value: '1'
  check_mode: true
  register: sysctl_ipv6_all
  when: ( "nftables" in ansible_facts.packages )
  tags:
  - PCI-DSS-Req-1.4.1
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy
  - set_nftables_loopback_traffic

- name: Check sysctl value of net.ipv6.conf.default.disable_ipv6
  sysctl:
    name: net.ipv6.conf.default.disable_ipv6
    state: present
    value: '1'
  check_mode: true
  register: sysctl_ipv6_default
  when: ( "nftables" in ansible_facts.packages )
  tags:
  - PCI-DSS-Req-1.4.1
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy
  - set_nftables_loopback_traffic

- name: Implement IPv6 loopback rules
  ansible.builtin.command: nft add rule inet filter input ip6 saddr ::1 counter drop
  when:
  - ( "nftables" in ansible_facts.packages )
  - ipv6_status is not skipped
  - sysctl_ipv6_default is not skipped
  - sysctl_ipv6_all is not skipped
  - ipv6_status.rc == 0 or sysctl_ipv6_all.found > 0 or sysctl_ipv6_default.found
    > 0
  tags:
  - PCI-DSS-Req-1.4.1
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy
  - set_nftables_loopback_traffic

# Remediation is applicable only in certain platforms
if ( dpkg-query --show --showformat='${db:Status-Status}\n' 'nftables' 2>/dev/null | grep -q installed ); then

var_nftables_family='inet'



grubfile="/boot/grub/grub.cfg"

# Implement the loopback rules:
nft add rule inet filter input iif lo accept
nft add rule inet filter input ip saddr 127.0.0.0/8 counter drop

# Check IPv6 is disabled, if false implement IPv6 loopback rules
disabled="false"
[ -f "$grubfile" ] && ! grep "^\s*linux" "$grubfile" | grep -vq "ipv6.disable=1" && disabled="true"

grep -Eq "^\s*net\.ipv6\.conf\.all\.disable_ipv6\s*=\s*1\b(\s+#.*)?$" \
/etc/sysctl.conf /etc/sysctl.d/*.conf && \
grep -Eq "^\s*net\.ipv6\.conf\.default\.disable_ipv6\s*=\s*1\b(\s+#.*)?$" \
/etc/sysctl.conf /etc/sysctl.d/*.conf && sysctl net.ipv6.conf.all.disable_ipv6 | \
grep -Eq "^\s*net\.ipv6\.conf\.all\.disable_ipv6\s*=\s*1\b(\s+#.*)?$" && \
sysctl net.ipv6.conf.default.disable_ipv6 | \
grep -Eq "^\s*net\.ipv6\.conf\.default\.disable_ipv6\s*=\s*1\b(\s+#.*)?$" && disabled="true"

# Is IPv6 Disabled? (true/false)
if [ "$disabled" = false ] ; then
    nft add rule inet filter input ip6 saddr ::1 counter drop
fi


nft list ruleset > "/etc/${var_nftables_family}-filter.rules"

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

Rule   Ensure a Table Exists for Nftables   [ref]

Tables in nftables hold chains. Each table only has one address family and only applies to packets of this family. Tables can have one of six families.
Warning:  Adding or editing rules in a running nftables can cause loss of connectivity to the system.
Warning:  Both the SCE check and remediation for this rule only consider runtime settings. There is no specific file to check as it depends on each site's policy. Therefore, check and remediation use the nft command directly. The fix is not persistent across system reboots.
Warning:  SCE check does not support variables, therefore the SCE check in this rule only checks the address family, regardless of the table name.
Rationale:
Nftables doesn't have any default tables. Without a table being built, nftables will not filter network traffic.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_set_nftables_table
References:
cis4.3.4

Complexity:low
Disruption:low
Reboot:false
Strategy:restrict
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy
  - set_nftables_table
- name: XCCDF Value var_nftables_family # promote to variable
  set_fact:
    var_nftables_family: !!str inet
  tags:
    - always
- name: XCCDF Value var_nftables_table # promote to variable
  set_fact:
    var_nftables_table: !!str filter
  tags:
    - always

- name: Collect Existing Nftables
  ansible.builtin.command: nft list table {{ var_nftables_family }} {{ var_nftables_table
    }}
  register: result_nftables_table_family
  changed_when: false
  failed_when: result_nftables_table_family.rc not in [0, 1]
  when: '"nftables" in ansible_facts.packages'
  tags:
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy
  - set_nftables_table

- name: Set Nftable Table
  ansible.builtin.command: nft create table {{ var_nftables_family }} {{ var_nftables_table
    }}
  when:
  - '"nftables" in ansible_facts.packages'
  - result_nftables_table_family is not skipped
  - result_nftables_table_family.rc != 0
  tags:
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - restrict_strategy
  - set_nftables_table

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

var_nftables_family='inet'

var_nftables_table='filter'


if ! nft list table $var_nftables_family $var_nftables_table; then
  nft create table "$var_nftables_family" "$var_nftables_table"
fi

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi
Group   Uncomplicated Firewall (ufw)   Group contains 7 rules
[ref]   The Linux kernel in Ubuntu provides a packet filtering system called netfilter, and the traditional interface for manipulating netfilter are the iptables suite of commands. iptables provide a complete firewall solution that is both highly configurable and highly flexible. Becoming proficient in iptables takes time, and getting started with netfilter firewalling using only iptables can be a daunting task. As a result, many frontends for iptables have been created over the years, each trying to achieve a different result and targeting a different audience. The Uncomplicated Firewall (ufw) is a frontend for iptables and is particularly well-suited for host-based firewalls. ufw provides a framework for managing netfilter, as well as a command-line interface for manipulating the firewall. ufw aims to provide an easy to use interface for people unfamiliar with firewall concepts, while at the same time simplifies complicated iptables commands to help an administrator who knows what he or she is doing. ufw is an upstream for other distributions and graphical frontends.

Rule   Install ufw Package   [ref]

The ufw package can be installed with the following command:
$ apt-get install ufw
Rationale:
ufw controls the Linux kernel network packet filtering code. ufw allows system operators to set up firewalls and IP masquerading, etc.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_package_ufw_installed
References:
disaCCI-002314
os-srgSRG-OS-000297-GPOS-00115
cis4.2.1

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

class install_ufw {
  package { 'ufw':
    ensure => 'installed',
  }
}

Complexity:low
Disruption:low
Reboot:false
Strategy:enable
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - enable_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - package_ufw_installed

- name: Ensure ufw is installed
  package:
    name: ufw
    state: present
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - enable_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - package_ufw_installed


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

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

DEBIAN_FRONTEND=noninteractive apt-get install -y "ufw"

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

Rule   Remove ufw Package   [ref]

The ufw package can be removed with the following command:
$ apt-get remove ufw
Rationale:
Running iptables.persistent with ufw enabled may lead to conflict and unexpected results.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_package_ufw_removed
References:
cis4.3.2, 4.4.1.3

Complexity:low
Disruption:low
Reboot:false
Strategy:disable
include remove_ufw

class remove_ufw {
  package { 'ufw':
    ensure => 'purged',
  }
}

Complexity:low
Disruption:low
Reboot:false
Strategy:disable
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - disable_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - package_ufw_removed

- name: Ensure ufw is removed
  package:
    name: ufw
    state: absent
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - disable_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - package_ufw_removed

Complexity:low
Disruption:low
Reboot:false
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

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

DEBIAN_FRONTEND=noninteractive apt-get remove -y "ufw"

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

Rule   Verify ufw Enabled   [ref]

The ufw service can be enabled with the following command:
$ sudo systemctl enable ufw.service
Rationale:
The ufw service must be enabled and running in order for ufw to protect the system
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_service_ufw_enabled
References:
disaCCI-002314
os-srgSRG-OS-000297-GPOS-00115
cis4.2.3

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

class enable_ufw {
  service {'ufw':
    enable => true,
    ensure => 'running',
  }
}

Complexity:low
Disruption:low
Reboot:false
Strategy:enable
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - enable_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - service_ufw_enabled

- name: Verify ufw Enabled - Enable service ufw
  block:

  - name: Gather the package facts
    package_facts:
      manager: auto

  - name: Verify ufw Enabled - Enable Service ufw
    ansible.builtin.systemd:
      name: ufw
      enabled: true
      state: started
      masked: false
    when:
    - '"ufw" in ansible_facts.packages'
  when:
  - '"linux-base" in ansible_facts.packages'
  - ( "ufw" in ansible_facts.packages and "linux-base" in ansible_facts.packages )
  tags:
  - enable_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
  - service_ufw_enabled


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

Complexity:low
Disruption:low
Reboot:false
Strategy:enable
# 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}\n' 'ufw' 2>/dev/null | grep -q installed && dpkg-query --show --showformat='${db:Status-Status}
' 'linux-base' 2>/dev/null | grep -q ^installed ); }; then

SYSTEMCTL_EXEC='/usr/bin/systemctl'
"$SYSTEMCTL_EXEC" unmask 'ufw.service'
"$SYSTEMCTL_EXEC" start 'ufw.service'
"$SYSTEMCTL_EXEC" enable 'ufw.service'

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

Rule   Verify ufw Active   [ref]

Verify the ufw is enabled on the system with the following command:
# sudo ufw status
If the above command returns the status as "inactive" or any type of error, this is a finding.
Rationale:
Remote access services, such as those providing remote access to network devices and information systems, which lack automated control capabilities, increase risk and make remote user access management difficult at best. Remote access is access to DOD nonpublic information systems by an authorized user (or an information system) communicating through an external, nonorganization-controlled network. Remote access methods include, for example, dial-up, broadband, and wireless. Ubuntu 22.04 LTS functionality (e.g., RDP) must be capable of taking enforcement action if the audit reveals unauthorized activity. Automated control of remote access sessions allows organizations to ensure ongoing compliance with remote access policies by enforcing connection rules of remote access applications on a variety of information system components.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_check_ufw_active
References:
disaCCI-002314
cis4.2.3

Rule   Ensure ufw Default Deny Firewall Policy   [ref]

A default deny policy on connections ensures that any unconfigured network usage will be rejected. Note: Any port or protocol without a explicit allow before the default deny will be blocked.
Warning:  Changing firewall settings while connected over network can result in being locked out of the system.
Rationale:
With a default accept policy the firewall will accept any packet that is not configured to be denied. It is easier to allow acceptable usage than to block unacceptable usage.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_set_ufw_default_rule
References:
cis4.2.7

Rule   Set UFW Loopback Traffic   [ref]

Configure the loopback interface to accept traffic. Configure all other interfaces to deny traffic to the loopback network.
Warning:  Changing firewall settings while connected over network can result in being locked out of the system.
Rationale:
Loopback traffic is generated between processes on machine and is typically critical to operation of the system. The loopback interface is the only place that loopback network traffic should be seen, all other interfaces should ignore traffic on this network as an anti-spoofing measure.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_set_ufw_loopback_traffic
References:
cis4.2.4

# 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}\n' 'ufw' 2>/dev/null | grep -q installed; }; then

ufw allow in on lo
ufw allow out on lo
ufw deny in from 127.0.0.0/8
ufw deny in from ::1

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

Rule   Ensure ufw Firewall Rules Exist for All Open Ports   [ref]

Any ports that have been opened on non-loopback addresses need firewall rules to govern traffic.
Warning:  Changing firewall settings while connected over network can result in being locked out of the system.
Rationale:
Without a firewall rule configured for open ports default firewall policy will drop all packets to these ports.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_ufw_rules_for_open_ports
References:
cis4.2.6
Group   File Permissions and Masks   Group contains 7 groups and 48 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 Ubuntu 24.04 installations:
$ mount -t xfs | awk '{print $3}'
For any systems that use a different local filesystem type, modify this command as appropriate.
Group   Verify Permissions on Important Files and Directories   Group contains 1 group and 24 rules
[ref]   Permissions for many files on a system must be set restrictively to ensure sensitive information is properly protected. This section discusses important permission restrictions which can be verified to ensure that no harmful discrepancies have arisen.
Group   Verify Permissions on Files with Local Account Information and Credentials   Group contains 24 rules

Rule   Verify Group Who Owns Backup group File   [ref]

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

Complexity:low
Disruption:low
Reboot:false
Strategy:configure
- name: Test for existence /etc/group-
  stat:
    path: /etc/group-
  register: file_exists
  tags:
  - NIST-800-53-AC-6 (1)
  - PCI-DSS-Req-8.7
  - PCI-DSSv4-2.2
  - PCI-DSSv4-2.2.6
  - configure_strategy
  - file_groupowner_backup_etc_group
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed

- name: Ensure group owner 0 on /etc/group-
  file:
    path: /etc/group-
    group: '0'
  when: file_exists.stat is defined and file_exists.stat.exists
  tags:
  - NIST-800-53-AC-6 (1)
  - PCI-DSS-Req-8.7
  - PCI-DSSv4-2.2
  - PCI-DSSv4-2.2.6
  - configure_strategy
  - file_groupowner_backup_etc_group
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed

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

Rule   Verify Group Who Owns Backup gshadow File   [ref]

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

Complexity:low
Disruption:low
Reboot:false
Strategy:configure
- name: Test for existence /etc/gshadow-
  stat:
    path: /etc/gshadow-
  register: file_exists
  tags:
  - NIST-800-53-AC-6 (1)
  - PCI-DSS-Req-8.7
  - configure_strategy
  - file_groupowner_backup_etc_gshadow
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed

- name: Ensure group owner 0 on /etc/gshadow-
  file:
    path: /etc/gshadow-
    group: '0'
  when: file_exists.stat is defined and file_exists.stat.exists
  tags:
  - NIST-800-53-AC-6 (1)
  - PCI-DSS-Req-8.7
  - configure_strategy
  - file_groupowner_backup_etc_gshadow
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed

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

Rule   Verify Group Who Owns Backup passwd File   [ref]

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

Complexity:low
Disruption:low
Reboot:false
Strategy:configure
- name: Test for existence /etc/passwd-
  stat:
    path: /etc/passwd-
  register: file_exists
  tags:
  - NIST-800-53-AC-6 (1)
  - PCI-DSS-Req-8.7
  - PCI-DSSv4-2.2
  - PCI-DSSv4-2.2.6
  - configure_strategy
  - file_groupowner_backup_etc_passwd
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed

- name: Ensure group owner 0 on /etc/passwd-
  file:
    path: /etc/passwd-
    group: '0'
  when: file_exists.stat is defined and file_exists.stat.exists
  tags:
  - NIST-800-53-AC-6 (1)
  - PCI-DSS-Req-8.7
  - PCI-DSSv4-2.2
  - PCI-DSSv4-2.2.6
  - configure_strategy
  - file_groupowner_backup_etc_passwd
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed

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

Rule   Verify User Who Owns Backup shadow File   [ref]

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

Complexity:low
Disruption:low
Reboot:false
Strategy:configure
- name: Test for existence /etc/shadow-
  stat:
    path: /etc/shadow-
  register: file_exists
  tags:
  - PCI-DSS-Req-8.7
  - PCI-DSSv4-2.2
  - PCI-DSSv4-2.2.6
  - configure_strategy
  - file_groupowner_backup_etc_shadow
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed

- name: Ensure group owner 42 on /etc/shadow-
  file:
    path: /etc/shadow-
    group: '42'
  when: file_exists.stat is defined and file_exists.stat.exists
  tags:
  - PCI-DSS-Req-8.7
  - PCI-DSSv4-2.2
  - PCI-DSSv4-2.2.6
  - configure_strategy
  - file_groupowner_backup_etc_shadow
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed

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

Rule   Verify Group Who Owns group File   [ref]

To properly set the group owner of /etc/group, run the command:
$ sudo chgrp root /etc/group
Rationale:
The /etc/group file contains information regarding groups that are configured on the system. Protection of this file is important for system security.
Severity: 
medium
Rule ID:xccdf_org.ssgproject.content_rule_file_groupowner_etc_group
References:
cis-csc12, 13, 14, 15, 16, 18, 3, 5
cjis5.5.2.2
cobit5APO01.06, DSS05.04, DSS05.07, DSS06.02
disaCCI-000366
isa-62443-20094.3.3.7.3
isa-62443-2013SR 2.1, SR 5.2
iso27001-2013A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5
nerc-cipCIP-003-8 R5.1.1, CIP-003-8 R5.3, CIP-004-6 R2.3, CIP-007-3 R2.1, CIP-007-3 R2.2, CIP-007-3 R2.3, CIP-007-3 R5.1, CIP-007-3 R5.1.1, CIP-007-3 R5.1.2
nistCM-6(a), AC-6(1)
nist-csfPR.AC-4, PR.DS-5
pcidssReq-8.7.c
os-srgSRG-OS-000480-GPOS-00227
anssiR50
cis7.1.3
pcidss42.2.6, 2.2

Complexity:low
Disruption:low
Reboot:false
Strategy:configure
- name: Test for existence /etc/group
  stat:
    path: /etc/group
  register: file_exists
  tags:
  - CJIS-5.5.2.2
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - PCI-DSS-Req-8.7.c
  - PCI-DSSv4-2.2
  - PCI-DSSv4-2.2.6
  - configure_strategy
  - file_groupowner_etc_group
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed

- name: Ensure group owner 0 on /etc/group
  file:
    path: /etc/group
    group: '0'
  when: file_exists.stat is defined and file_exists.stat.exists
  tags:
  - CJIS-5.5.2.2
  - NIST-800-53-AC-6(1)
  - NIST-800-53-CM-6(a)
  - PCI-DSS-Req-8.7.c
  - PCI-DSSv4-2.2
  - PCI-DSSv4-2.2.6
  - configure_strategy
  - file_groupowner_etc_group
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed

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