| contains 185 rules |
System Settings
[ref]groupContains rules that check correct system settings. |
| contains 118 rules |
Installing and Maintaining Software
[ref]groupThe following sections contain information on
security-relevant choices during the initial operating system
installation process and the setup of software
updates. |
| contains 7 rules |
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.
|
| contains 5 rules |
Install sudo Package
[ref]ruleThe sudo package can be installed with the following command:
$ sudo dnf 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. Remediation Puppet snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | enable |
|---|
include install_sudo
class install_sudo {
package { 'sudo':
ensure => 'installed',
}
}
Remediation script: (show)
[[packages]]
name = "sudo"
version = "*"
Remediation Ansible snippet: (show)
| 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
ansible.builtin.package:
name: sudo
state: present
when: '"kernel" 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
|
Ensure Only Users Logged In To Real tty Can Execute Sudo - sudo use_pty
[ref]ruleThe sudo use_pty tag, when specified, will only execute sudo
commands from users logged in to a real tty.
This should be enabled by making sure that the use_pty tag exists in
/etc/sudoers configuration file or any sudo configuration snippets
in /etc/sudoers.d/. Rationale:Requiring that sudo commands be run in a pseudo-terminal can prevent an attacker from retaining
access to the user's terminal after the main program has finished executing. Remediation Ansible snippet: (show)
| 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
- medium_severity
- no_reboot_needed
- restrict_strategy
- sudo_add_use_pty
- name: Ensure use_pty is enabled in /etc/sudoers
ansible.builtin.lineinfile:
path: /etc/sudoers
regexp: ^[\s]*Defaults.*\buse_pty\b.*$
line: Defaults use_pty
validate: /usr/sbin/visudo -cf %s
when:
- '"kernel" in ansible_facts.packages'
- '"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
- medium_severity
- no_reboot_needed
- restrict_strategy
- sudo_add_use_pty
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel && { rpm --quiet -q sudo; }; then
if /usr/sbin/visudo -qcf /etc/sudoers; then
cp /etc/sudoers /etc/sudoers.bak
if ! grep -P '^[\s]*Defaults\b[^!\n]*\buse_pty.*$' /etc/sudoers; then
# sudoers file doesn't define Option use_pty
echo "Defaults use_pty" >> /etc/sudoers
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
|
Ensure Sudo Logfile Exists - sudo logfile
[ref]ruleA 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. Remediation Ansible snippet: (show)
| 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
ansible.builtin.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:
- '"kernel" in ansible_facts.packages'
- '"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
ansible.builtin.lineinfile:
path: /etc/sudoers
line: Defaults logfile={{ var_sudo_logfile }}
validate: /usr/sbin/visudo -cf %s
when:
- '"kernel" in ansible_facts.packages'
- '"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
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel && { rpm --quiet -q sudo; }; 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\b[^!\n]*\blogfile\s*=\s*(?:"?([^",\s]+)"?).*$' /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
|
Ensure Users Re-Authenticate for Privilege Escalation - sudo
[ref]ruleThe sudo NOPASSWD and !authenticate option, when
specified, allows a user to execute commands using sudo without having to
authenticate. This should be disabled by making sure that
NOPASSWD and/or !authenticate do not exist in
/etc/sudoers configuration file or any sudo configuration snippets
in /etc/sudoers.d/." Rationale:Without re-authentication, users may access resources or perform tasks for which they
do not have authorization.
When operating systems provide the capability to escalate a functional capability, it
is critical that the user re-authenticate. References:
1, 12, 15, 16, 5, DSS05.04, DSS05.10, DSS06.03, DSS06.10, 4.3.3.5.1, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, SR 1.1, SR 1.10, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.7, SR 1.8, SR 1.9, A.18.1.4, A.9.2.1, A.9.2.2, A.9.2.3, A.9.2.4, A.9.2.6, A.9.3.1, A.9.4.2, A.9.4.3, IA-11, CM-6(a), PR.AC-1, PR.AC-7, SRG-OS-000373-GPOS-00156, 1546, 2.2.6, 2.2 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-11
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- sudo_require_authentication
- name: Find /etc/sudoers.d/ files
ansible.builtin.find:
paths:
- /etc/sudoers.d/
register: sudoers
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-CM-6(a)
- 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_authentication
- name: Remove lines containing NOPASSWD from sudoers files
ansible.builtin.replace:
regexp: (^(?!#).*[\s]+NOPASSWD[\s]*\:.*$)
replace: '# \g<1>'
path: '{{ item.path }}'
validate: /usr/sbin/visudo -cf %s
with_items:
- path: /etc/sudoers
- '{{ sudoers.files }}'
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-CM-6(a)
- 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_authentication
- name: Find /etc/sudoers.d/ files
ansible.builtin.find:
paths:
- /etc/sudoers.d/
register: sudoers
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-CM-6(a)
- 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_authentication
- 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 }}'
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-CM-6(a)
- 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_authentication
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel; then
for f in /etc/sudoers /etc/sudoers.d/* ; do
if [ ! -e "$f" ] ; then
continue
fi
matching_list=$(grep -P '^(?!#).*[\s]+NOPASSWD[\s]*\:.*$' $f | uniq )
if ! test -z "$matching_list"; then
while IFS= read -r entry; do
# comment out "NOPASSWD" matches to preserve user data
sed -i "s|^${entry}$|# &|g" $f
done <<< "$matching_list"
/usr/sbin/visudo -cf $f &> /dev/null || echo "Fail to validate $f with visudo"
fi
done
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
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
The operating system must restrict privilege elevation to authorized personnel
[ref]ruleThe sudo command allows a user to execute programs with elevated
(administrator) privileges. It prompts the user for their password
and confirms your request to execute a command by checking a file,
called sudoers.
Restrict privileged actions by removing the following entries from the sudoers file:
ALL ALL=(ALL) ALL
ALL ALL=(ALL:ALL) ALL Warning:
This rule doesn't come with a remediation, as the exact requirement allows exceptions,
and removing lines from the sudoers file can make the system non-administrable. Rationale:If the "sudoers" file is not configured correctly, any user defined
on the system can initiate privileged actions on the target system. |
Updating Software
[ref]groupThe dnf command line tool is used to install and
update software packages. The system also provides a graphical
software update tool in the System menu, in the Administration submenu,
called Software Update.
TencentOS Server 4 systems contain an installed software catalog called
the RPM database, which records metadata of installed packages. Consistently using
dnf or the graphical Software Update for all software installation
allows for insight into the current inventory of installed software on the system.
|
| contains 2 rules |
Ensure gpgcheck Enabled In Main dnf Configuration
[ref]ruleThe gpgcheck option controls whether
RPM packages' signatures are always checked prior to installation.
To configure dnf to check package signatures before installing
them, ensure the following line appears in /etc/yum.conf in
the [main] section:
gpgcheck=1 Rationale:Changes to any software components can have significant effects on the
overall security of the operating system. This requirement ensures the
software has not been tampered with and that it has been provided by a
trusted vendor.
Accordingly, patches, service packs, device drivers, or operating system
components must be signed with a certificate recognized and approved by the
organization.
Verifying the authenticity of the software prior to installation
validates the integrity of the patch or upgrade received from a vendor.
This ensures the software has not been tampered with and that it has been
provided by a trusted vendor. Self-signed certificates are disallowed by
this requirement. Certificates used to verify the software must be from an
approved Certificate Authority (CA). References:
11, 2, 3, 9, 5.10.4.1, APO01.06, BAI03.05, BAI06.01, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS06.02, 3.4.8, 164.308(a)(1)(ii)(D), 164.312(b), 164.312(c)(1), 164.312(c)(2), 164.312(e)(2)(i), 4.3.4.3.2, 4.3.4.3.3, 4.3.4.4.4, SR 3.1, SR 3.3, SR 3.4, SR 3.8, SR 7.6, A.11.2.4, A.12.1.2, A.12.2.1, A.12.5.1, A.12.6.2, A.14.1.2, A.14.1.3, A.14.2.2, A.14.2.3, A.14.2.4, CM-5(3), SI-7, SC-12, SC-12(3), CM-6(a), SA-12, SA-12(10), CM-11(a), CM-11(b), PR.DS-6, PR.DS-8, PR.IP-1, FPT_TUD_EXT.1, FPT_TUD_EXT.2, Req-6.2, SRG-OS-000366-GPOS-00153, R59, 1493, 6.3.3, 6.3 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | medium |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- CJIS-5.10.4.1
- NIST-800-171-3.4.8
- NIST-800-53-CM-11(a)
- NIST-800-53-CM-11(b)
- NIST-800-53-CM-5(3)
- NIST-800-53-CM-6(a)
- NIST-800-53-SA-12
- NIST-800-53-SA-12(10)
- NIST-800-53-SC-12
- NIST-800-53-SC-12(3)
- NIST-800-53-SI-7
- PCI-DSS-Req-6.2
- PCI-DSSv4-6.3
- PCI-DSSv4-6.3.3
- configure_strategy
- ensure_gpgcheck_globally_activated
- high_severity
- low_complexity
- medium_disruption
- no_reboot_needed
- name: Ensure GPG check is globally activated
community.general.ini_file:
dest: /etc/yum.conf
section: main
option: gpgcheck
value: 1
no_extra_spaces: true
create: false
when: '"dnf" in ansible_facts.packages'
tags:
- CJIS-5.10.4.1
- NIST-800-171-3.4.8
- NIST-800-53-CM-11(a)
- NIST-800-53-CM-11(b)
- NIST-800-53-CM-5(3)
- NIST-800-53-CM-6(a)
- NIST-800-53-SA-12
- NIST-800-53-SA-12(10)
- NIST-800-53-SC-12
- NIST-800-53-SC-12(3)
- NIST-800-53-SI-7
- PCI-DSS-Req-6.2
- PCI-DSSv4-6.3
- PCI-DSSv4-6.3.3
- configure_strategy
- ensure_gpgcheck_globally_activated
- high_severity
- low_complexity
- medium_disruption
- no_reboot_needed
|
Ensure gpgcheck Enabled for All dnf Package Repositories
[ref]ruleTo ensure signature checking is not disabled for
any repos, remove any lines from files in /etc/yum.repos.d of the form:
gpgcheck=0 Rationale:Verifying the authenticity of the software prior to installation validates
the integrity of the patch or upgrade received from a vendor. This ensures
the software has not been tampered with and that it has been provided by a
trusted vendor. Self-signed certificates are disallowed by this
requirement. Certificates used to verify the software must be from an
approved Certificate Authority (CA)." References:
11, 2, 3, 9, 5.10.4.1, APO01.06, BAI03.05, BAI06.01, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS06.02, 3.4.8, 164.308(a)(1)(ii)(D), 164.312(b), 164.312(c)(1), 164.312(c)(2), 164.312(e)(2)(i), 4.3.4.3.2, 4.3.4.3.3, 4.3.4.4.4, SR 3.1, SR 3.3, SR 3.4, SR 3.8, SR 7.6, A.11.2.4, A.12.1.2, A.12.2.1, A.12.5.1, A.12.6.2, A.14.1.2, A.14.1.3, A.14.2.2, A.14.2.3, A.14.2.4, CM-5(3), SI-7, SC-12, SC-12(3), CM-6(a), SA-12, SA-12(10), CM-11(a), CM-11(b), PR.DS-6, PR.DS-8, PR.IP-1, FPT_TUD_EXT.1, FPT_TUD_EXT.2, Req-6.2, SRG-OS-000366-GPOS-00153, R59, 1493, 6.3.3, 6.3 |
Account and Access Control
[ref]groupIn 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
TencentOS Server 4. |
| contains 48 rules |
Warning Banners for System Accesses
[ref]groupEach 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. |
| contains 12 rules |
Modify the System Login Banner
[ref]rule
To configure the system login banner edit /etc/issue. Replace the
default text with a message compliant with the local site policy or a legal
disclaimer.
The DoD required text is either:
You are accessing a U.S. Government (USG) Information System (IS) that
is provided for USG-authorized use only. By using this IS (which includes
any device attached to this IS), you consent to the following conditions:
-The USG routinely intercepts and monitors communications on this IS
for purposes including, but not limited to, penetration testing, COMSEC
monitoring, network operations and defense, personnel misconduct (PM), law
enforcement (LE), and counterintelligence (CI) investigations.
-At any time, the USG may inspect and seize data stored on this IS.
-Communications using, or data stored on, this IS are not private,
are subject to routine monitoring, interception, and search, and may be
disclosed or used for any USG-authorized purpose.
-This IS includes security measures (e.g., authentication and access
controls) to protect USG interests -- not for your personal benefit or
privacy.
-Notwithstanding the above, using this IS does not constitute consent
to PM, LE or CI investigative searching or monitoring of the content of
privileged communications, or work product, related to personal
representation or services by attorneys, psychotherapists, or clergy, and
their assistants. Such communications and work product are private and
confidential. See User Agreement for details.
OR:
I've read & consent to terms in IS user agreem't. Rationale:Display of a standardized and approved use notification before granting
access to the operating system ensures privacy and security notification
verbiage used is consistent with applicable federal laws, Executive Orders,
directives, policies, regulations, standards, and guidance.
System use notifications are required only for access via login interfaces
with human users and are not required when such human interfaces do not
exist. References:
1, 12, 15, 16, DSS05.04, DSS05.10, DSS06.10, 3.1.9, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, SR 1.1, SR 1.10, SR 1.2, SR 1.5, SR 1.7, SR 1.8, SR 1.9, A.18.1.4, A.9.2.1, A.9.2.4, A.9.3.1, A.9.4.2, A.9.4.3, AC-8(a), AC-8(c), PR.AC-7, SRG-OS-000023-GPOS-00006, SRG-OS-000228-GPOS-00088 |
Modify the System Login Banner for Remote Connections
[ref]ruleTo configure the system login banner edit /etc/issue.net. Replace the
default text with a message compliant with the local site policy or a legal
disclaimer.
The DoD required text is either:
You are accessing a U.S. Government (USG) Information System (IS) that
is provided for USG-authorized use only. By using this IS (which includes
any device attached to this IS), you consent to the following conditions:
-The USG routinely intercepts and monitors communications on this IS
for purposes including, but not limited to, penetration testing, COMSEC
monitoring, network operations and defense, personnel misconduct (PM), law
enforcement (LE), and counterintelligence (CI) investigations.
-At any time, the USG may inspect and seize data stored on this IS.
-Communications using, or data stored on, this IS are not private,
are subject to routine monitoring, interception, and search, and may be
disclosed or used for any USG-authorized purpose.
-This IS includes security measures (e.g., authentication and access
controls) to protect USG interests -- not for your personal benefit or
privacy.
-Notwithstanding the above, using this IS does not constitute consent
to PM, LE or CI investigative searching or monitoring of the content of
privileged communications, or work product, related to personal
representation or services by attorneys, psychotherapists, or clergy, and
their assistants. Such communications and work product are private and
confidential. See User Agreement for details.
OR:
I've read & consent to terms in IS user agreem't. Rationale:Display of a standardized and approved use notification before granting
access to the operating system ensures privacy and security notification
verbiage used is consistent with applicable federal laws, Executive Orders,
directives, policies, regulations, standards, and guidance.
System use notifications are required only for access via login interfaces
with human users and are not required when such human interfaces do not
exist. Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | medium |
|---|
| Reboot: | false |
|---|
| Strategy: | unknown |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- banner_etc_issue_net
- low_complexity
- medium_disruption
- medium_severity
- no_reboot_needed
- unknown_strategy
- name: XCCDF Value remote_login_banner_text # promote to variable
set_fact:
remote_login_banner_text: !!str ^(Authorized[\s\n]+uses[\s\n]+only\.[\s\n]+All[\s\n]+activity[\s\n]+may[\s\n]+be[\s\n]+monitored[\s\n]+and[\s\n]+reported\.|^(?!.*(\\|fedora|rhel|sle|ubuntu)).*)$
tags:
- always
- name: Modify the System Login Banner for Remote Connections - ensure correct banner
ansible.builtin.copy:
dest: /etc/issue.net
content: '{{ remote_login_banner_text | regex_replace("^\^(.*)\$$", "\1") | regex_replace("^\((.*\.)\|.*\)$",
"\1") | regex_replace("\[\\s\\n\]\+"," ") | regex_replace("\(\?:\[\\n\]\+\|\(\?:\\\\n\)\+\)",
"\n") | regex_replace("\\", "") | wordwrap() }}'
when: '"kernel" in ansible_facts.packages'
tags:
- banner_etc_issue_net
- low_complexity
- medium_disruption
- medium_severity
- no_reboot_needed
- unknown_strategy
Remediation Shell script: (show)
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel; then
remote_login_banner_text='^(Authorized[\s\n]+uses[\s\n]+only\.[\s\n]+All[\s\n]+activity[\s\n]+may[\s\n]+be[\s\n]+monitored[\s\n]+and[\s\n]+reported\.|^(?!.*(\\|fedora|rhel|sle|ubuntu)).*)$'
# Multiple regexes transform the banner regex into a usable banner
# 0 - Remove anchors around the banner text
remote_login_banner_text=$(echo "$remote_login_banner_text" | sed 's/^\^\(.*\)\$$/\1/g')
# 1 - Keep only the first banners if there are multiple
# (dod_banners contains the long and short banner)
remote_login_banner_text=$(echo "$remote_login_banner_text" | sed 's/^(\(.*\.\)|.*)$/\1/g')
# 2 - Add spaces ' '. (Transforms regex for "space or newline" into a " ")
remote_login_banner_text=$(echo "$remote_login_banner_text" | sed 's/\[\\s\\n\]+/ /g')
# 3 - Adds newlines. (Transforms "(?:\[\\n\]+|(?:\\n)+)" into "\n")
remote_login_banner_text=$(echo "$remote_login_banner_text" | sed 's/(?:\[\\n\]+|(?:\\\\n)+)/\n/g')
# 4 - Remove any leftover backslash. (From any parenthesis in the banner, for example).
remote_login_banner_text=$(echo "$remote_login_banner_text" | sed 's/\\//g')
formatted=$(echo "$remote_login_banner_text" | fold -sw 80)
cat <<EOF >/etc/issue.net
$formatted
EOF
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Modify the System Message of the Day Banner
[ref]ruleTo configure the system message banner edit /etc/motd. Replace the
default text with a message compliant with the local site policy or a legal
disclaimer.
The DoD required text is either:
You are accessing a U.S. Government (USG) Information System (IS) that
is provided for USG-authorized use only. By using this IS (which includes
any device attached to this IS), you consent to the following conditions:
-The USG routinely intercepts and monitors communications on this IS
for purposes including, but not limited to, penetration testing, COMSEC
monitoring, network operations and defense, personnel misconduct (PM), law
enforcement (LE), and counterintelligence (CI) investigations.
-At any time, the USG may inspect and seize data stored on this IS.
-Communications using, or data stored on, this IS are not private,
are subject to routine monitoring, interception, and search, and may be
disclosed or used for any USG-authorized purpose.
-This IS includes security measures (e.g., authentication and access
controls) to protect USG interests -- not for your personal benefit or
privacy.
-Notwithstanding the above, using this IS does not constitute consent
to PM, LE or CI investigative searching or monitoring of the content of
privileged communications, or work product, related to personal
representation or services by attorneys, psychotherapists, or clergy, and
their assistants. Such communications and work product are private and
confidential. See User Agreement for details.
OR:
I've read & consent to terms in IS user agreem't. Rationale:Display of a standardized and approved use notification before granting
access to the operating system ensures privacy and security notification
verbiage used is consistent with applicable federal laws, Executive Orders,
directives, policies, regulations, standards, and guidance.
System use notifications are required only for access via login interfaces
with human users and are not required when such human interfaces do not
exist. |
Verify Group Ownership of System Login Banner
[ref]rule
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. Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Set the file_groupowner_etc_issue_newgroup variable if represented by gid
ansible.builtin.set_fact:
file_groupowner_etc_issue_newgroup: '0'
tags:
- configure_strategy
- file_groupowner_etc_issue
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Test for existence /etc/issue
ansible.builtin.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 on /etc/issue
ansible.builtin.file:
path: /etc/issue
follow: false
group: '{{ file_groupowner_etc_issue_newgroup }}'
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
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
newgroup=""
if getent group "0" >/dev/null 2>&1; then
newgroup="0"
fi
if [[ -z "${newgroup}" ]]; then
>&2 echo "0 is not a defined group on the system"
else
if ! stat -c "%g %G" "/etc/issue" | grep -E -w -q "0"; then
chgrp --no-dereference "$newgroup" /etc/issue
fi
fi
|
Verify Group Ownership of System Login Banner for Remote Connections
[ref]rule
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. Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Set the file_groupowner_etc_issue_net_newgroup variable if represented by
gid
ansible.builtin.set_fact:
file_groupowner_etc_issue_net_newgroup: '0'
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: Test for existence /etc/issue.net
ansible.builtin.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 on /etc/issue.net
ansible.builtin.file:
path: /etc/issue.net
follow: false
group: '{{ file_groupowner_etc_issue_net_newgroup }}'
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
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
newgroup=""
if getent group "0" >/dev/null 2>&1; then
newgroup="0"
fi
if [[ -z "${newgroup}" ]]; then
>&2 echo "0 is not a defined group on the system"
else
if ! stat -c "%g %G" "/etc/issue.net" | grep -E -w -q "0"; then
chgrp --no-dereference "$newgroup" /etc/issue.net
fi
fi
|
Verify Group Ownership of Message of the Day Banner
[ref]rule
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. Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Set the file_groupowner_etc_motd_newgroup variable if represented by gid
ansible.builtin.set_fact:
file_groupowner_etc_motd_newgroup: '0'
tags:
- configure_strategy
- file_groupowner_etc_motd
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Test for existence /etc/motd
ansible.builtin.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 on /etc/motd
ansible.builtin.file:
path: /etc/motd
follow: false
group: '{{ file_groupowner_etc_motd_newgroup }}'
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
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
newgroup=""
if getent group "0" >/dev/null 2>&1; then
newgroup="0"
fi
if [[ -z "${newgroup}" ]]; then
>&2 echo "0 is not a defined group on the system"
else
if ! stat -c "%g %G" "/etc/motd" | grep -E -w -q "0"; then
chgrp --no-dereference "$newgroup" /etc/motd
fi
fi
|
Verify ownership of System Login Banner
[ref]rule
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. Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Set the file_owner_etc_issue_newown variable if represented by uid
ansible.builtin.set_fact:
file_owner_etc_issue_newown: '0'
tags:
- configure_strategy
- file_owner_etc_issue
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Test for existence /etc/issue
ansible.builtin.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 on /etc/issue
ansible.builtin.file:
path: /etc/issue
follow: false
owner: '{{ file_owner_etc_issue_newown }}'
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
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
newown=""
if id "0" >/dev/null 2>&1; then
newown="0"
fi
if [[ -z "$newown" ]]; then
>&2 echo "0 is not a defined user on the system"
else
if ! stat -c "%u %U" "/etc/issue" | grep -E -w -q "0"; then
chown --no-dereference "$newown" /etc/issue
fi
fi
|
Verify ownership of System Login Banner for Remote Connections
[ref]rule
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. Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Set the file_owner_etc_issue_net_newown variable if represented by uid
ansible.builtin.set_fact:
file_owner_etc_issue_net_newown: '0'
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: Test for existence /etc/issue.net
ansible.builtin.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 on /etc/issue.net
ansible.builtin.file:
path: /etc/issue.net
follow: false
owner: '{{ file_owner_etc_issue_net_newown }}'
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
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
newown=""
if id "0" >/dev/null 2>&1; then
newown="0"
fi
if [[ -z "$newown" ]]; then
>&2 echo "0 is not a defined user on the system"
else
if ! stat -c "%u %U" "/etc/issue.net" | grep -E -w -q "0"; then
chown --no-dereference "$newown" /etc/issue.net
fi
fi
|
Verify ownership of Message of the Day Banner
[ref]rule
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. Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Set the file_owner_etc_motd_newown variable if represented by uid
ansible.builtin.set_fact:
file_owner_etc_motd_newown: '0'
tags:
- configure_strategy
- file_owner_etc_motd
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Test for existence /etc/motd
ansible.builtin.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 on /etc/motd
ansible.builtin.file:
path: /etc/motd
follow: false
owner: '{{ file_owner_etc_motd_newown }}'
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
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
newown=""
if id "0" >/dev/null 2>&1; then
newown="0"
fi
if [[ -z "$newown" ]]; then
>&2 echo "0 is not a defined user on the system"
else
if ! stat -c "%u %U" "/etc/motd" | grep -E -w -q "0"; then
chown --no-dereference "$newown" /etc/motd
fi
fi
|
Verify permissions on System Login Banner
[ref]rule
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. Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Test for existence /etc/issue
ansible.builtin.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
ansible.builtin.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
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
chmod u-xs,g-xws,o-xwt /etc/issue
|
Verify permissions on System Login Banner for Remote Connections
[ref]rule
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. Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Test for existence /etc/issue.net
ansible.builtin.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
ansible.builtin.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
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
chmod u-xs,g-xws,o-xwt /etc/issue.net
|
Verify permissions on Message of the Day Banner
[ref]rule
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. Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Test for existence /etc/motd
ansible.builtin.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
ansible.builtin.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
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
chmod u-xs,g-xws,o-xwt /etc/motd
|
Protect Accounts by Configuring PAM
[ref]groupPAM, or Pluggable Authentication Modules, is a system
which implements modular authentication for Linux programs. PAM provides
a flexible and configurable architecture for authentication, and it should be configured
to minimize exposure to unnecessary risk. This section contains
guidance on how to accomplish that.
PAM is implemented as a set of shared objects which are
loaded and invoked whenever an application wishes to authenticate a
user. Typically, the application must be running as root in order
to take advantage of PAM, because PAM's modules often need to be able
to access sensitive stores of account information, such as /etc/shadow.
Traditional privileged network listeners
(e.g. sshd) or SUID programs (e.g. sudo) already meet this
requirement. An SUID root application, userhelper, is provided so
that programs which are not SUID or privileged themselves can still
take advantage of PAM.
PAM looks in the directory /etc/pam.d for
application-specific configuration information. For instance, if
the program login attempts to authenticate a user, then PAM's
libraries follow the instructions in the file /etc/pam.d/login
to determine what actions should be taken.
One very important file in /etc/pam.d is
/etc/pam.d/system-auth. This file, which is included by
many other PAM configuration files, defines 'default' system authentication
measures. Modifying this file is a good way to make far-reaching
authentication changes, for instance when implementing a
centralized authentication service. Warning:
Be careful when making changes to PAM's configuration files.
The syntax for these files is complex, and modifications can
have unexpected consequences. The default configurations shipped
with applications should be sufficient for most users. |
| contains 13 rules |
Set Lockouts for Failed Password Attempts
[ref]groupThe pam_faillock PAM module provides the capability to
lock out user accounts after a number of failed login attempts. Its
documentation is available in
/usr/share/doc/pam-VERSION/txts/README.pam_faillock.
Warning:
Locking out user accounts presents the
risk of a denial-of-service attack. The lockout policy
must weigh whether the risk of such a
denial-of-service attack outweighs the benefits of thwarting
password guessing attacks. |
| contains 2 rules |
Lock Accounts After Failed Password Attempts
[ref]ruleThis rule configures the system to lock out accounts after a number of incorrect login attempts
using pam_faillock.so.
pam_faillock.so module requires multiple entries in pam files. These entries must be carefully
defined to work as expected.
Ensure that the file /etc/security/faillock.conf contains the following entry:
deny = <count>
Where count should be less than or equal to
5 and greater than 0.
In order to avoid errors when manually editing these files, it is
recommended to use the appropriate tools, such as authselect or authconfig,
depending on the OS version. Warning:
If the system relies on authselect tool to manage PAM settings, the remediation
will also use authselect tool. However, if any manual modification was made in
PAM files, the authselect integrity check will fail and the remediation will be
aborted in order to preserve intentional changes. In this case, an informative message will
be shown in the remediation report.
If the system supports the /etc/security/faillock.conf file, the pam_faillock
parameters should be defined in faillock.conf file. Rationale:By limiting the number of failed logon attempts, the risk of unauthorized system access via
user password guessing, also known as brute-forcing, is reduced. Limits are imposed by locking
the account. References:
1, 12, 15, 16, 5.5.3, DSS05.04, DSS05.10, DSS06.10, 3.1.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, SR 1.1, SR 1.10, SR 1.2, SR 1.5, SR 1.7, SR 1.8, SR 1.9, A.18.1.4, A.9.2.1, A.9.2.4, A.9.3.1, A.9.4.2, A.9.4.3, CM-6(a), AC-7(a), PR.AC-7, FIA_AFL.1, Req-8.1.6, SRG-OS-000329-GPOS-00128, SRG-OS-000021-GPOS-00005, R31, 0421, 0422, 0974, 1173, 1401, 1504, 1505, 1546, 1557, 1558, 1559, 1560, 1561, 8.3.4, 8.3 Remediation Shell script: (show)
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel && { rpm --quiet -q pam; }; then
var_accounts_passwords_pam_faillock_deny='5'
if [ -f /usr/bin/authselect ]; then
if ! authselect check; then
echo "
authselect integrity check failed. Remediation aborted!
This remediation could not be applied because an authselect profile was not selected or the selected profile is not intact.
It is not recommended to manually edit the PAM files when authselect tool is available.
In cases where the default authselect profile does not cover a specific demand, a custom authselect profile is recommended."
exit 1
fi
authselect enable-feature with-faillock
authselect apply-changes -b
else
AUTH_FILES=("/etc/pam.d/system-auth" "/etc/pam.d/password-auth")
for pam_file in "${AUTH_FILES[@]}"
do
if ! grep -qE '^\s*auth\s+required\s+pam_faillock\.so\s+(preauth silent|authfail).*$' "$pam_file" ; then
sed -i --follow-symlinks '/^auth.*sufficient.*pam_unix\.so.*/i auth required pam_faillock.so preauth silent' "$pam_file"
sed -i --follow-symlinks '/^auth.*required.*pam_deny\.so.*/i auth required pam_faillock.so authfail' "$pam_file"
sed -i --follow-symlinks '/^account.*required.*pam_unix\.so.*/i account required pam_faillock.so' "$pam_file"
fi
sed -Ei 's/(auth.*)(\[default=die\])(.*pam_faillock\.so)/\1required \3/g' "$pam_file"
done
fi
AUTH_FILES=("/etc/pam.d/system-auth" "/etc/pam.d/password-auth")
SKIP_FAILLOCK_CHECK=false
FAILLOCK_CONF="/etc/security/faillock.conf"
if [ -f $FAILLOCK_CONF ] || [ "$SKIP_FAILLOCK_CHECK" = "true" ]; then
regex="^\s*deny\s*="
line="deny = $var_accounts_passwords_pam_faillock_deny"
if ! grep -q $regex $FAILLOCK_CONF; then
echo $line >> $FAILLOCK_CONF
else
sed -i --follow-symlinks 's|^\s*\(deny\s*=\s*\)\(\S\+\)|\1'"$var_accounts_passwords_pam_faillock_deny"'|g' $FAILLOCK_CONF
fi
for pam_file in "${AUTH_FILES[@]}"
do
if [ -e "$pam_file" ] ; then
PAM_FILE_PATH="$pam_file"
if [ -f /usr/bin/authselect ]; then
if ! authselect check; then
echo "
authselect integrity check failed. Remediation aborted!
This remediation could not be applied because an authselect profile was not selected or the selected profile is not intact.
It is not recommended to manually edit the PAM files when authselect tool is available.
In cases where the default authselect profile does not cover a specific demand, a custom authselect profile is recommended."
exit 1
fi
CURRENT_PROFILE=$(authselect current -r | awk '{ print $1 }')
# If not already in use, a custom profile is created preserving the enabled features.
if [[ ! $CURRENT_PROFILE == custom/* ]]; then
ENABLED_FEATURES=$(authselect current | tail -n+3 | awk '{ print $2 }')
# The "local" profile does not contain essential security features required by multiple Benchmarks.
# If currently used, it is replaced by "sssd", which is the best option in this case.
if [[ $CURRENT_PROFILE == local ]]; then
CURRENT_PROFILE="sssd"
fi
authselect create-profile hardening -b $CURRENT_PROFILE
CURRENT_PROFILE="custom/hardening"
authselect apply-changes -b --backup=before-hardening-custom-profile
authselect select $CURRENT_PROFILE
for feature in $ENABLED_FEATURES; do
authselect enable-feature $feature;
done
authselect apply-changes -b --backup=after-hardening-custom-profile
fi
PAM_FILE_NAME=$(basename "$pam_file")
PAM_FILE_PATH="/etc/authselect/$CURRENT_PROFILE/$PAM_FILE_NAME"
authselect apply-changes -b
fi
if grep -qP "^\s*auth\s.*\bpam_faillock.so\s.*\bdeny\b" "$PAM_FILE_PATH"; then
sed -i -E --follow-symlinks "s/(.*auth.*pam_faillock.so.*)\bdeny\b=?[[:alnum:]]*(.*)/\1\2/g" "$PAM_FILE_PATH"
fi
if [ -f /usr/bin/authselect ]; then
authselect apply-changes -b
fi
else
echo "$pam_file was not found" >&2
fi
done
else
for pam_file in "${AUTH_FILES[@]}"
do
if ! grep -qE '^\s*auth.*pam_faillock\.so\s+(preauth|authfail).*deny' "$pam_file"; then
sed -i --follow-symlinks '/^auth.*required.*pam_faillock\.so.*preauth.*/ s/$/ deny='"$var_accounts_passwords_pam_faillock_deny"'/' "$pam_file"
sed -i --follow-symlinks '/^auth.*required.*pam_faillock\.so.*authfail.*/ s/$/ deny='"$var_accounts_passwords_pam_faillock_deny"'/' "$pam_file"
else
sed -i --follow-symlinks 's/\(^auth.*required.*pam_faillock\.so.*preauth.*\)\('"deny"'=\)\S\+\b\(.*\)/\1\2'"$var_accounts_passwords_pam_faillock_deny"'\3/' "$pam_file"
sed -i --follow-symlinks 's/\(^auth.*required.*pam_faillock\.so.*authfail.*\)\('"deny"'=\)\S\+\b\(.*\)/\1\2'"$var_accounts_passwords_pam_faillock_deny"'\3/' "$pam_file"
fi
done
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Set Lockout Time for Failed Password Attempts
[ref]ruleThis rule configures the system to lock out accounts during a specified time period after a
number of incorrect login attempts using pam_faillock.so.
Ensure that the file /etc/security/faillock.conf contains the following entry:
unlock_time=<interval-in-seconds> where
interval-in-seconds is 300 or greater.
pam_faillock.so module requires multiple entries in pam files. These entries must be carefully
defined to work as expected. In order to avoid any errors when manually editing these files,
it is recommended to use the appropriate tools, such as authselect or authconfig,
depending on the OS version.
If unlock_time is set to 0, manual intervention by an administrator is required
to unlock a user. This should be done using the faillock tool. Warning:
If the system supports the new /etc/security/faillock.conf file but the
pam_faillock.so parameters are defined directly in /etc/pam.d/system-auth and
/etc/pam.d/password-auth, the remediation will migrate the unlock_time parameter
to /etc/security/faillock.conf to ensure compatibility with authselect tool.
The parameters deny and fail_interval, if used, also have to be migrated
by their respective remediation. Warning:
If the system relies on authselect tool to manage PAM settings, the remediation
will also use authselect tool. However, if any manual modification was made in
PAM files, the authselect integrity check will fail and the remediation will be
aborted in order to preserve intentional changes. In this case, an informative message will
be shown in the remediation report.
If the system supports the /etc/security/faillock.conf file, the pam_faillock
parameters should be defined in faillock.conf file. Rationale:By limiting the number of failed logon attempts the risk of unauthorized system
access via user password guessing, otherwise known as brute-forcing, is reduced.
Limits are imposed by locking the account. References:
1, 12, 15, 16, 5.5.3, DSS05.04, DSS05.10, DSS06.10, 3.1.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, SR 1.1, SR 1.10, SR 1.2, SR 1.5, SR 1.7, SR 1.8, SR 1.9, A.18.1.4, A.9.2.1, A.9.2.4, A.9.3.1, A.9.4.2, A.9.4.3, CM-6(a), AC-7(b), PR.AC-7, FIA_AFL.1, Req-8.1.7, SRG-OS-000329-GPOS-00128, SRG-OS-000021-GPOS-00005, R31, 0421, 0422, 0974, 1173, 1401, 1504, 1505, 1546, 1557, 1558, 1559, 1560, 1561, 8.3.4, 8.3 Remediation Shell script: (show)
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel && { rpm --quiet -q pam; }; then
var_accounts_passwords_pam_faillock_unlock_time='300'
if [ -f /usr/bin/authselect ]; then
if ! authselect check; then
echo "
authselect integrity check failed. Remediation aborted!
This remediation could not be applied because an authselect profile was not selected or the selected profile is not intact.
It is not recommended to manually edit the PAM files when authselect tool is available.
In cases where the default authselect profile does not cover a specific demand, a custom authselect profile is recommended."
exit 1
fi
authselect enable-feature with-faillock
authselect apply-changes -b
else
AUTH_FILES=("/etc/pam.d/system-auth" "/etc/pam.d/password-auth")
for pam_file in "${AUTH_FILES[@]}"
do
if ! grep -qE '^\s*auth\s+required\s+pam_faillock\.so\s+(preauth silent|authfail).*$' "$pam_file" ; then
sed -i --follow-symlinks '/^auth.*sufficient.*pam_unix\.so.*/i auth required pam_faillock.so preauth silent' "$pam_file"
sed -i --follow-symlinks '/^auth.*required.*pam_deny\.so.*/i auth required pam_faillock.so authfail' "$pam_file"
sed -i --follow-symlinks '/^account.*required.*pam_unix\.so.*/i account required pam_faillock.so' "$pam_file"
fi
sed -Ei 's/(auth.*)(\[default=die\])(.*pam_faillock\.so)/\1required \3/g' "$pam_file"
done
fi
AUTH_FILES=("/etc/pam.d/system-auth" "/etc/pam.d/password-auth")
SKIP_FAILLOCK_CHECK=false
FAILLOCK_CONF="/etc/security/faillock.conf"
if [ -f $FAILLOCK_CONF ] || [ "$SKIP_FAILLOCK_CHECK" = "true" ]; then
regex="^\s*unlock_time\s*="
line="unlock_time = $var_accounts_passwords_pam_faillock_unlock_time"
if ! grep -q $regex $FAILLOCK_CONF; then
echo $line >> $FAILLOCK_CONF
else
sed -i --follow-symlinks 's|^\s*\(unlock_time\s*=\s*\)\(\S\+\)|\1'"$var_accounts_passwords_pam_faillock_unlock_time"'|g' $FAILLOCK_CONF
fi
for pam_file in "${AUTH_FILES[@]}"
do
if [ -e "$pam_file" ] ; then
PAM_FILE_PATH="$pam_file"
if [ -f /usr/bin/authselect ]; then
if ! authselect check; then
echo "
authselect integrity check failed. Remediation aborted!
This remediation could not be applied because an authselect profile was not selected or the selected profile is not intact.
It is not recommended to manually edit the PAM files when authselect tool is available.
In cases where the default authselect profile does not cover a specific demand, a custom authselect profile is recommended."
exit 1
fi
CURRENT_PROFILE=$(authselect current -r | awk '{ print $1 }')
# If not already in use, a custom profile is created preserving the enabled features.
if [[ ! $CURRENT_PROFILE == custom/* ]]; then
ENABLED_FEATURES=$(authselect current | tail -n+3 | awk '{ print $2 }')
# The "local" profile does not contain essential security features required by multiple Benchmarks.
# If currently used, it is replaced by "sssd", which is the best option in this case.
if [[ $CURRENT_PROFILE == local ]]; then
CURRENT_PROFILE="sssd"
fi
authselect create-profile hardening -b $CURRENT_PROFILE
CURRENT_PROFILE="custom/hardening"
authselect apply-changes -b --backup=before-hardening-custom-profile
authselect select $CURRENT_PROFILE
for feature in $ENABLED_FEATURES; do
authselect enable-feature $feature;
done
authselect apply-changes -b --backup=after-hardening-custom-profile
fi
PAM_FILE_NAME=$(basename "$pam_file")
PAM_FILE_PATH="/etc/authselect/$CURRENT_PROFILE/$PAM_FILE_NAME"
authselect apply-changes -b
fi
if grep -qP "^\s*auth\s.*\bpam_faillock.so\s.*\bunlock_time\b" "$PAM_FILE_PATH"; then
sed -i -E --follow-symlinks "s/(.*auth.*pam_faillock.so.*)\bunlock_time\b=?[[:alnum:]]*(.*)/\1\2/g" "$PAM_FILE_PATH"
fi
if [ -f /usr/bin/authselect ]; then
authselect apply-changes -b
fi
else
echo "$pam_file was not found" >&2
fi
done
else
for pam_file in "${AUTH_FILES[@]}"
do
if ! grep -qE '^\s*auth.*pam_faillock\.so\s+(preauth|authfail).*unlock_time' "$pam_file"; then
sed -i --follow-symlinks '/^auth.*required.*pam_faillock\.so.*preauth.*/ s/$/ unlock_time='"$var_accounts_passwords_pam_faillock_unlock_time"'/' "$pam_file"
sed -i --follow-symlinks '/^auth.*required.*pam_faillock\.so.*authfail.*/ s/$/ unlock_time='"$var_accounts_passwords_pam_faillock_unlock_time"'/' "$pam_file"
else
sed -i --follow-symlinks 's/\(^auth.*required.*pam_faillock\.so.*preauth.*\)\('"unlock_time"'=\)\S\+\b\(.*\)/\1\2'"$var_accounts_passwords_pam_faillock_unlock_time"'\3/' "$pam_file"
sed -i --follow-symlinks 's/\(^auth.*required.*pam_faillock\.so.*authfail.*\)\('"unlock_time"'=\)\S\+\b\(.*\)/\1\2'"$var_accounts_passwords_pam_faillock_unlock_time"'\3/' "$pam_file"
fi
done
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Set Password Quality Requirements
[ref]groupThe default pam_pwquality PAM module provides strength
checking for passwords. It performs a number of checks, such as
making sure passwords are not similar to dictionary words, are of
at least a certain length, are not the previous password reversed,
and are not simply a change of case from the previous password. It
can also require passwords to be in certain character classes. The
pam_pwquality module is the preferred way of configuring
password requirements.
The man pages pam_pwquality(8)
provide information on the capabilities and configuration of
each. |
| contains 8 rules |
Set Password Quality Requirements with pam_pwquality
[ref]groupThe pam_pwquality PAM module can be configured to meet
requirements for a variety of policies.
For example, to configure pam_pwquality to require at least one uppercase
character, lowercase character, digit, and other (special)
character, make sure that pam_pwquality exists in /etc/pam.d/system-auth:
password requisite pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type=
If no such line exists, add one as the first line of the password section in /etc/pam.d/system-auth.
Next, modify the settings in /etc/security/pwquality.conf to match the following:
difok = 4
minlen = 14
dcredit = -1
ucredit = -1
lcredit = -1
ocredit = -1
maxrepeat = 3
The arguments can be modified to ensure compliance with
your organization's security policy. Discussion of each parameter follows. |
| contains 8 rules |
Ensure PAM Enforces Password Requirements - Minimum Digit Characters
[ref]ruleThe pam_pwquality module's dcredit parameter controls requirements for
usage of digits in a password. When set to a negative number, any password will be required to
contain that many digits. When set to a positive number, pam_pwquality will grant +1 additional
length credit for each digit. Modify the dcredit setting in
/etc/security/pwquality.conf to require the use of a digit in passwords. Rationale:Use of a complex password helps to increase the time and resources required
to compromise the password. Password complexity, or strength, is a measure of
the effectiveness of a password in resisting attempts at guessing and brute-force
attacks.
Password complexity is one factor of several that determines how long it takes
to crack a password. The more complex the password, the greater the number of
possible combinations that need to be tested before the password is compromised.
Requiring digits makes password guessing attacks more difficult by ensuring a larger
search space. References:
1, 12, 15, 16, 5, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.10, 4.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.2, 4.3.3.7.4, SR 1.1, SR 1.10, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.7, SR 1.8, SR 1.9, SR 2.1, A.18.1.4, A.7.1.1, A.9.2.1, A.9.2.2, A.9.2.3, A.9.2.4, A.9.2.6, A.9.3.1, A.9.4.2, A.9.4.3, IA-5(c), IA-5(1)(a), CM-6(a), IA-5(4), PR.AC-1, PR.AC-6, PR.AC-7, FMT_SMF_EXT.1, Req-8.2.3, SRG-OS-000071-GPOS-00039, R31, 0421, 0422, 0974, 1173, 1401, 1504, 1505, 1546, 1557, 1558, 1559, 1560, 1561, 8.3.6, 8.3 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-5(1)(a)
- NIST-800-53-IA-5(4)
- NIST-800-53-IA-5(c)
- PCI-DSS-Req-8.2.3
- PCI-DSSv4-8.3
- PCI-DSSv4-8.3.6
- accounts_password_pam_dcredit
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: XCCDF Value var_password_pam_dcredit # promote to variable
set_fact:
var_password_pam_dcredit: !!str 0
tags:
- always
- name: Ensure PAM Enforces Password Requirements - Minimum Digit Characters - Ensure
PAM variable dcredit is set accordingly
ansible.builtin.lineinfile:
create: true
dest: /etc/security/pwquality.conf
regexp: ^#?\s*dcredit
line: dcredit = {{ var_password_pam_dcredit }}
when:
- '"kernel" in ansible_facts.packages'
- '"libpwquality" in ansible_facts.packages'
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-5(1)(a)
- NIST-800-53-IA-5(4)
- NIST-800-53-IA-5(c)
- PCI-DSS-Req-8.2.3
- PCI-DSSv4-8.3
- PCI-DSSv4-8.3.6
- accounts_password_pam_dcredit
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel && { rpm --quiet -q libpwquality; }; then
var_password_pam_dcredit='0'
# Strip any search characters in the key arg so that the key can be replaced without
# adding any search characters to the config file.
stripped_key=$(sed 's/[\^=\$,;+]*//g' <<< "^dcredit")
# shellcheck disable=SC2059
printf -v formatted_output "%s = %s" "$stripped_key" "$var_password_pam_dcredit"
# If the key exists, change it. Otherwise, add it to the config_file.
# We search for the key string followed by a word boundary (matched by \>),
# so if we search for 'setting', 'setting2' won't match.
if LC_ALL=C grep -q -m 1 -i -e "^dcredit\\>" "/etc/security/pwquality.conf"; then
escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
LC_ALL=C sed -i --follow-symlinks "s/^dcredit\\>.*/$escaped_formatted_output/gi" "/etc/security/pwquality.conf"
else
if [[ -s "/etc/security/pwquality.conf" ]] && [[ -n "$(tail -c 1 -- "/etc/security/pwquality.conf" || true)" ]]; then
LC_ALL=C sed -i --follow-symlinks '$a'\\ "/etc/security/pwquality.conf"
fi
printf '%s\n' "$formatted_output" >> "/etc/security/pwquality.conf"
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Ensure PAM Enforces Password Requirements - Enforce for root User
[ref]ruleThe pam_pwquality module's enforce_for_root parameter controls requirements for
enforcing password complexity for the root user. Enable the enforce_for_root
setting in /etc/security/pwquality.conf to require the root user
to use complex passwords. Rationale:Use of a complex password helps to increase the time and resources required to compromise
the password. Password complexity, or strength, is a measure of the effectiveness of a
password in resisting attempts at guessing and brute-force attacks.
Password complexity is one factor of several that determines how long it takes to crack a
password. The more complex the password, the greater the number of possible combinations
that need to be tested before the password is compromised. References:
IA-5(c), IA-5(1)(a), CM-6(a), IA-5(4), SRG-OS-000072-GPOS-00040, SRG-OS-000071-GPOS-00039, SRG-OS-000070-GPOS-00038, SRG-OS-000266-GPOS-00101, SRG-OS-000078-GPOS-00046, SRG-OS-000480-GPOS-00225, SRG-OS-000069-GPOS-00037 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-5(1)(a)
- NIST-800-53-IA-5(4)
- NIST-800-53-IA-5(c)
- accounts_password_pam_enforce_root
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Ensure PAM Enforces Password Requirements - Enforce for root User
ansible.builtin.lineinfile:
path: /etc/security/pwquality.conf
create: true
regexp: ''
line: enforce_for_root
state: present
when:
- '"kernel" in ansible_facts.packages'
- '"libpwquality" in ansible_facts.packages'
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-5(1)(a)
- NIST-800-53-IA-5(4)
- NIST-800-53-IA-5(c)
- accounts_password_pam_enforce_root
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel && { rpm --quiet -q libpwquality; }; then
if [ -e "/etc/security/pwquality.conf" ] ; then
LC_ALL=C sed -i "/^\s*enforce_for_root/Id" "/etc/security/pwquality.conf"
else
touch "/etc/security/pwquality.conf"
fi
# make sure file has newline at the end
sed -i -e '$a\' "/etc/security/pwquality.conf"
cp "/etc/security/pwquality.conf" "/etc/security/pwquality.conf.bak"
# Insert at the end of the file
printf '%s\n' "enforce_for_root" >> "/etc/security/pwquality.conf"
# Clean up after ourselves.
rm "/etc/security/pwquality.conf.bak"
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Ensure PAM Enforces Password Requirements - Minimum Lowercase Characters
[ref]ruleThe pam_pwquality module's lcredit parameter controls requirements for
usage of lowercase letters in a password. When set to a negative number, any password will be required to
contain that many lowercase characters. When set to a positive number, pam_pwquality will grant +1 additional
length credit for each lowercase character. Modify the lcredit setting in
/etc/security/pwquality.conf to require the use of a lowercase character in passwords. Rationale:Use of a complex password helps to increase the time and resources required
to compromise the password. Password complexity, or strength, is a measure of
the effectiveness of a password in resisting attempts at guessing and brute-force
attacks.
Password complexity is one factor of several that determines how long it takes
to crack a password. The more complex the password, the greater the number of
possible combinations that need to be tested before the password is compromised.
Requiring a minimum number of lowercase characters makes password guessing attacks
more difficult by ensuring a larger search space. References:
1, 12, 15, 16, 5, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.10, 4.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.2, 4.3.3.7.4, SR 1.1, SR 1.10, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.7, SR 1.8, SR 1.9, SR 2.1, A.18.1.4, A.7.1.1, A.9.2.1, A.9.2.2, A.9.2.3, A.9.2.4, A.9.2.6, A.9.3.1, A.9.4.2, A.9.4.3, IA-5(c), IA-5(1)(a), CM-6(a), IA-5(4), PR.AC-1, PR.AC-6, PR.AC-7, FMT_SMF_EXT.1, Req-8.2.3, SRG-OS-000070-GPOS-00038, R31, 0421, 0422, 0974, 1173, 1401, 1504, 1505, 1546, 1557, 1558, 1559, 1560, 1561, 8.3.6, 8.3 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-5(1)(a)
- NIST-800-53-IA-5(4)
- NIST-800-53-IA-5(c)
- PCI-DSS-Req-8.2.3
- PCI-DSSv4-8.3
- PCI-DSSv4-8.3.6
- accounts_password_pam_lcredit
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: XCCDF Value var_password_pam_lcredit # promote to variable
set_fact:
var_password_pam_lcredit: !!str 0
tags:
- always
- name: Ensure PAM Enforces Password Requirements - Minimum Lowercase Characters -
Ensure PAM variable lcredit is set accordingly
ansible.builtin.lineinfile:
create: true
dest: /etc/security/pwquality.conf
regexp: ^#?\s*lcredit
line: lcredit = {{ var_password_pam_lcredit }}
when:
- '"kernel" in ansible_facts.packages'
- '"libpwquality" in ansible_facts.packages'
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-5(1)(a)
- NIST-800-53-IA-5(4)
- NIST-800-53-IA-5(c)
- PCI-DSS-Req-8.2.3
- PCI-DSSv4-8.3
- PCI-DSSv4-8.3.6
- accounts_password_pam_lcredit
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel && { rpm --quiet -q libpwquality; }; then
var_password_pam_lcredit='0'
# Strip any search characters in the key arg so that the key can be replaced without
# adding any search characters to the config file.
stripped_key=$(sed 's/[\^=\$,;+]*//g' <<< "^lcredit")
# shellcheck disable=SC2059
printf -v formatted_output "%s = %s" "$stripped_key" "$var_password_pam_lcredit"
# If the key exists, change it. Otherwise, add it to the config_file.
# We search for the key string followed by a word boundary (matched by \>),
# so if we search for 'setting', 'setting2' won't match.
if LC_ALL=C grep -q -m 1 -i -e "^lcredit\\>" "/etc/security/pwquality.conf"; then
escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
LC_ALL=C sed -i --follow-symlinks "s/^lcredit\\>.*/$escaped_formatted_output/gi" "/etc/security/pwquality.conf"
else
if [[ -s "/etc/security/pwquality.conf" ]] && [[ -n "$(tail -c 1 -- "/etc/security/pwquality.conf" || true)" ]]; then
LC_ALL=C sed -i --follow-symlinks '$a'\\ "/etc/security/pwquality.conf"
fi
printf '%s\n' "$formatted_output" >> "/etc/security/pwquality.conf"
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Ensure PAM Enforces Password Requirements - Minimum Different Categories
[ref]ruleThe pam_pwquality module's minclass parameter controls
requirements for usage of different character classes, or types, of character
that must exist in a password before it is considered valid. For example,
setting this value to three (3) requires that any password must have characters
from at least three different categories in order to be approved. The default
value is zero (0), meaning there are no required classes. There are four
categories available:
* Upper-case characters
* Lower-case characters
* Digits
* Special characters (for example, punctuation)
Modify the minclass setting in /etc/security/pwquality.conf entry
to require 3
differing categories of characters when changing passwords.Rationale:Use of a complex password helps to increase the time and resources required to compromise the password.
Password complexity, or strength, is a measure of the effectiveness of a password in resisting attempts
at guessing and brute-force attacks.
Password complexity is one factor of several that determines how long it takes to crack a password. The
more complex the password, the greater the number of possible combinations that need to be tested before
the password is compromised.
Requiring a minimum number of character categories makes password guessing attacks more difficult
by ensuring a larger search space. References:
1, 12, 15, 16, 5, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.10, 4.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.2, 4.3.3.7.4, SR 1.1, SR 1.10, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.7, SR 1.8, SR 1.9, SR 2.1, A.18.1.4, A.7.1.1, A.9.2.1, A.9.2.2, A.9.2.3, A.9.2.4, A.9.2.6, A.9.3.1, A.9.4.2, A.9.4.3, IA-5(c), IA-5(1)(a), CM-6(a), IA-5(4), PR.AC-1, PR.AC-6, PR.AC-7, SRG-OS-000072-GPOS-00040, R68, 0421, 0422, 0974, 1173, 1401, 1504, 1505, 1546, 1557, 1558, 1559, 1560, 1561 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-5(1)(a)
- NIST-800-53-IA-5(4)
- NIST-800-53-IA-5(c)
- accounts_password_pam_minclass
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: XCCDF Value var_password_pam_minclass # promote to variable
set_fact:
var_password_pam_minclass: !!str 3
tags:
- always
- name: Ensure PAM Enforces Password Requirements - Minimum Different Categories -
Ensure PAM variable minclass is set accordingly
ansible.builtin.lineinfile:
create: true
dest: /etc/security/pwquality.conf
regexp: ^#?\s*minclass
line: minclass = {{ var_password_pam_minclass }}
when:
- '"kernel" in ansible_facts.packages'
- '"libpwquality" in ansible_facts.packages'
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-5(1)(a)
- NIST-800-53-IA-5(4)
- NIST-800-53-IA-5(c)
- accounts_password_pam_minclass
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel && { rpm --quiet -q libpwquality; }; then
var_password_pam_minclass='3'
# Strip any search characters in the key arg so that the key can be replaced without
# adding any search characters to the config file.
stripped_key=$(sed 's/[\^=\$,;+]*//g' <<< "^minclass")
# shellcheck disable=SC2059
printf -v formatted_output "%s = %s" "$stripped_key" "$var_password_pam_minclass"
# If the key exists, change it. Otherwise, add it to the config_file.
# We search for the key string followed by a word boundary (matched by \>),
# so if we search for 'setting', 'setting2' won't match.
if LC_ALL=C grep -q -m 1 -i -e "^minclass\\>" "/etc/security/pwquality.conf"; then
escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
LC_ALL=C sed -i --follow-symlinks "s/^minclass\\>.*/$escaped_formatted_output/gi" "/etc/security/pwquality.conf"
else
if [[ -s "/etc/security/pwquality.conf" ]] && [[ -n "$(tail -c 1 -- "/etc/security/pwquality.conf" || true)" ]]; then
LC_ALL=C sed -i --follow-symlinks '$a'\\ "/etc/security/pwquality.conf"
fi
printf '%s\n' "$formatted_output" >> "/etc/security/pwquality.conf"
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Ensure PAM Enforces Password Requirements - Minimum Length
[ref]ruleThe pam_pwquality module's minlen parameter controls requirements for
minimum characters required in a password. Add minlen=8
after pam_pwquality to set minimum password length requirements. Rationale:The shorter the password, the lower the number of possible combinations
that need to be tested before the password is compromised.
Password complexity, or strength, is a measure of the effectiveness of a
password in resisting attempts at guessing and brute-force attacks.
Password length is one factor of several that helps to determine strength
and how long it takes to crack a password. Use of more characters in a password
helps to exponentially increase the time and/or resources required to
compromise the password. References:
1, 12, 15, 16, 5, 5.6.2.1.1, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.10, 4.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.2, 4.3.3.7.4, SR 1.1, SR 1.10, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.7, SR 1.8, SR 1.9, SR 2.1, A.18.1.4, A.7.1.1, A.9.2.1, A.9.2.2, A.9.2.3, A.9.2.4, A.9.2.6, A.9.3.1, A.9.4.2, A.9.4.3, IA-5(c), IA-5(1)(a), CM-6(a), IA-5(4), PR.AC-1, PR.AC-6, PR.AC-7, FMT_SMF_EXT.1, Req-8.2.3, SRG-OS-000078-GPOS-00046, R31, R68, 0421, 0422, 0974, 1173, 1401, 1504, 1505, 1546, 1557, 1558, 1559, 1560, 1561, 8.3.6, 8.3 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- CJIS-5.6.2.1.1
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-5(1)(a)
- NIST-800-53-IA-5(4)
- NIST-800-53-IA-5(c)
- PCI-DSS-Req-8.2.3
- PCI-DSSv4-8.3
- PCI-DSSv4-8.3.6
- accounts_password_pam_minlen
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: XCCDF Value var_password_pam_minlen # promote to variable
set_fact:
var_password_pam_minlen: !!str 8
tags:
- always
- name: Ensure PAM Enforces Password Requirements - Minimum Length - Ensure PAM variable
minlen is set accordingly
ansible.builtin.lineinfile:
create: true
dest: /etc/security/pwquality.conf
regexp: ^#?\s*minlen
line: minlen = {{ var_password_pam_minlen }}
when:
- '"kernel" in ansible_facts.packages'
- '"libpwquality" in ansible_facts.packages'
tags:
- CJIS-5.6.2.1.1
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-5(1)(a)
- NIST-800-53-IA-5(4)
- NIST-800-53-IA-5(c)
- PCI-DSS-Req-8.2.3
- PCI-DSSv4-8.3
- PCI-DSSv4-8.3.6
- accounts_password_pam_minlen
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel && { rpm --quiet -q libpwquality; }; then
var_password_pam_minlen='8'
# Strip any search characters in the key arg so that the key can be replaced without
# adding any search characters to the config file.
stripped_key=$(sed 's/[\^=\$,;+]*//g' <<< "^minlen")
# shellcheck disable=SC2059
printf -v formatted_output "%s = %s" "$stripped_key" "$var_password_pam_minlen"
# If the key exists, change it. Otherwise, add it to the config_file.
# We search for the key string followed by a word boundary (matched by \>),
# so if we search for 'setting', 'setting2' won't match.
if LC_ALL=C grep -q -m 1 -i -e "^minlen\\>" "/etc/security/pwquality.conf"; then
escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
LC_ALL=C sed -i --follow-symlinks "s/^minlen\\>.*/$escaped_formatted_output/gi" "/etc/security/pwquality.conf"
else
if [[ -s "/etc/security/pwquality.conf" ]] && [[ -n "$(tail -c 1 -- "/etc/security/pwquality.conf" || true)" ]]; then
LC_ALL=C sed -i --follow-symlinks '$a'\\ "/etc/security/pwquality.conf"
fi
printf '%s\n' "$formatted_output" >> "/etc/security/pwquality.conf"
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Ensure PAM Enforces Password Requirements - Minimum Special Characters
[ref]ruleThe pam_pwquality module's ocredit= parameter controls requirements for
usage of special (or "other") characters in a password. When set to a negative number,
any password will be required to contain that many special characters.
When set to a positive number, pam_pwquality will grant +1
additional length credit for each special character. Modify the ocredit setting
in /etc/security/pwquality.conf to equal 0
to require use of a special character in passwords. Rationale:Use of a complex password helps to increase the time and resources required
to compromise the password. Password complexity, or strength, is a measure of
the effectiveness of a password in resisting attempts at guessing and brute-force
attacks.
Password complexity is one factor of several that determines how long it takes
to crack a password. The more complex the password, the greater the number of
possible combinations that need to be tested before the password is compromised.
Requiring a minimum number of special characters makes password guessing attacks
more difficult by ensuring a larger search space. References:
1, 12, 15, 16, 5, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.10, 4.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.2, 4.3.3.7.4, SR 1.1, SR 1.10, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.7, SR 1.8, SR 1.9, SR 2.1, A.18.1.4, A.7.1.1, A.9.2.1, A.9.2.2, A.9.2.3, A.9.2.4, A.9.2.6, A.9.3.1, A.9.4.2, A.9.4.3, IA-5(c), IA-5(1)(a), CM-6(a), IA-5(4), PR.AC-1, PR.AC-6, PR.AC-7, FMT_SMF_EXT.1, SRG-OS-000266-GPOS-00101, R31, 0421, 0422, 0974, 1173, 1401, 1504, 1505, 1546, 1557, 1558, 1559, 1560, 1561 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-5(1)(a)
- NIST-800-53-IA-5(4)
- NIST-800-53-IA-5(c)
- accounts_password_pam_ocredit
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: XCCDF Value var_password_pam_ocredit # promote to variable
set_fact:
var_password_pam_ocredit: !!str 0
tags:
- always
- name: Ensure PAM Enforces Password Requirements - Minimum Special Characters - Ensure
PAM variable ocredit is set accordingly
ansible.builtin.lineinfile:
create: true
dest: /etc/security/pwquality.conf
regexp: ^#?\s*ocredit
line: ocredit = {{ var_password_pam_ocredit }}
when:
- '"kernel" in ansible_facts.packages'
- '"libpwquality" in ansible_facts.packages'
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-5(1)(a)
- NIST-800-53-IA-5(4)
- NIST-800-53-IA-5(c)
- accounts_password_pam_ocredit
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel && { rpm --quiet -q libpwquality; }; then
var_password_pam_ocredit='0'
# Strip any search characters in the key arg so that the key can be replaced without
# adding any search characters to the config file.
stripped_key=$(sed 's/[\^=\$,;+]*//g' <<< "^ocredit")
# shellcheck disable=SC2059
printf -v formatted_output "%s = %s" "$stripped_key" "$var_password_pam_ocredit"
# If the key exists, change it. Otherwise, add it to the config_file.
# We search for the key string followed by a word boundary (matched by \>),
# so if we search for 'setting', 'setting2' won't match.
if LC_ALL=C grep -q -m 1 -i -e "^ocredit\\>" "/etc/security/pwquality.conf"; then
escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
LC_ALL=C sed -i --follow-symlinks "s/^ocredit\\>.*/$escaped_formatted_output/gi" "/etc/security/pwquality.conf"
else
if [[ -s "/etc/security/pwquality.conf" ]] && [[ -n "$(tail -c 1 -- "/etc/security/pwquality.conf" || true)" ]]; then
LC_ALL=C sed -i --follow-symlinks '$a'\\ "/etc/security/pwquality.conf"
fi
printf '%s\n' "$formatted_output" >> "/etc/security/pwquality.conf"
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Ensure PAM Enforces Password Requirements - Authentication Retry Prompts Permitted Per-Session
[ref]ruleTo configure the number of retry prompts that are permitted per-session:
Edit the pam_pwquality.so statement in
/etc/pam.d/system-auth to show
retry=3, or a lower value if site
policy is more restrictive. The profile requirement is a maximum of retry=3 prompts
per session. Rationale:Setting the password retry prompts that are permitted on a per-session basis to a low value
requires some software, such as SSH, to re-connect. This can slow down and
draw additional attention to some types of password-guessing attacks. Note that this
is different from account lockout, which is provided by the pam_faillock module. References:
1, 11, 12, 15, 16, 3, 5, 9, 5.5.3, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.10, 4.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.2, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3, SR 1.1, SR 1.10, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 7.6, A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, A.18.1.4, A.7.1.1, A.9.2.1, A.9.2.2, A.9.2.3, A.9.2.4, A.9.2.6, A.9.3.1, A.9.4.2, A.9.4.3, CM-6(a), AC-7(a), IA-5(4), PR.AC-1, PR.AC-6, PR.AC-7, PR.IP-1, SRG-OS-000069-GPOS-00037, SRG-OS-000480-GPOS-00227, R68 Remediation Shell script: (show)
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel && { rpm --quiet -q libpwquality; }; then
var_password_pam_retry='3'
if [ -e "/etc/pam.d/system-auth" ] ; then
PAM_FILE_PATH="/etc/pam.d/system-auth"
if [ -f /usr/bin/authselect ]; then
if ! authselect check; then
echo "
authselect integrity check failed. Remediation aborted!
This remediation could not be applied because an authselect profile was not selected or the selected profile is not intact.
It is not recommended to manually edit the PAM files when authselect tool is available.
In cases where the default authselect profile does not cover a specific demand, a custom authselect profile is recommended."
exit 1
fi
CURRENT_PROFILE=$(authselect current -r | awk '{ print $1 }')
# If not already in use, a custom profile is created preserving the enabled features.
if [[ ! $CURRENT_PROFILE == custom/* ]]; then
ENABLED_FEATURES=$(authselect current | tail -n+3 | awk '{ print $2 }')
# The "local" profile does not contain essential security features required by multiple Benchmarks.
# If currently used, it is replaced by "sssd", which is the best option in this case.
if [[ $CURRENT_PROFILE == local ]]; then
CURRENT_PROFILE="sssd"
fi
authselect create-profile hardening -b $CURRENT_PROFILE
CURRENT_PROFILE="custom/hardening"
authselect apply-changes -b --backup=before-hardening-custom-profile
authselect select $CURRENT_PROFILE
for feature in $ENABLED_FEATURES; do
authselect enable-feature $feature;
done
authselect apply-changes -b --backup=after-hardening-custom-profile
fi
PAM_FILE_NAME=$(basename "/etc/pam.d/system-auth")
PAM_FILE_PATH="/etc/authselect/$CURRENT_PROFILE/$PAM_FILE_NAME"
authselect apply-changes -b
fi
if ! grep -qP "^\s*password\s+requisite\s+pam_pwquality.so\s*.*" "$PAM_FILE_PATH"; then
# Line matching group + control + module was not found. Check group + module.
if [ "$(grep -cP '^\s*password\s+.*\s+pam_pwquality.so\s*' "$PAM_FILE_PATH")" -eq 1 ]; then
# The control is updated only if one single line matches.
sed -i -E --follow-symlinks "s/^(\s*password\s+).*(\bpam_pwquality.so.*)/\1requisite \2/" "$PAM_FILE_PATH"
else
LAST_MATCH_LINE=$(grep -nP "^\s*account" "$PAM_FILE_PATH" | tail -n 1 | cut -d: -f 1)
if [ ! -z $LAST_MATCH_LINE ]; then
sed -i --follow-symlinks $LAST_MATCH_LINE" a password requisite pam_pwquality.so" "$PAM_FILE_PATH"
else
echo "password requisite pam_pwquality.so" >> "$PAM_FILE_PATH"
fi
fi
fi
# Check the option
if ! grep -qP "^\s*password\s+requisite\s+pam_pwquality.so\s*.*\sretry\b" "$PAM_FILE_PATH"; then
sed -i -E --follow-symlinks "/\s*password\s+requisite\s+pam_pwquality.so.*/ s/$/ retry=$var_password_pam_retry/" "$PAM_FILE_PATH"
else
sed -i -E --follow-symlinks "s/(\s*password\s+requisite\s+pam_pwquality.so\s+.*)(retry=)[[:alnum:]]*\s*(.*)/\1\2$var_password_pam_retry \3/" "$PAM_FILE_PATH"
fi
if [ -f /usr/bin/authselect ]; then
authselect apply-changes -b
fi
else
echo "/etc/pam.d/system-auth was not found" >&2
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Ensure PAM Enforces Password Requirements - Minimum Uppercase Characters
[ref]ruleThe pam_pwquality module's ucredit= parameter controls requirements for
usage of uppercase letters in a password. When set to a negative number, any password will be required to
contain that many uppercase characters. When set to a positive number, pam_pwquality will grant +1 additional
length credit for each uppercase character. Modify the ucredit setting in
/etc/security/pwquality.conf to require the use of an uppercase character in passwords. Rationale:Use of a complex password helps to increase the time and resources required to compromise the password.
Password complexity, or strength, is a measure of the effectiveness of a password in resisting attempts
at guessing and brute-force attacks.
Password complexity is one factor of several that determines how long it takes to crack a password. The more
complex the password, the greater the number of possible combinations that need to be tested before
the password is compromised. References:
1, 12, 15, 16, 5, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.10, 4.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.2, 4.3.3.7.4, SR 1.1, SR 1.10, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.7, SR 1.8, SR 1.9, SR 2.1, A.18.1.4, A.7.1.1, A.9.2.1, A.9.2.2, A.9.2.3, A.9.2.4, A.9.2.6, A.9.3.1, A.9.4.2, A.9.4.3, IA-5(c), IA-5(1)(a), CM-6(a), IA-5(4), PR.AC-1, PR.AC-6, PR.AC-7, FMT_SMF_EXT.1, Req-8.2.3, SRG-OS-000069-GPOS-00037, SRG-OS-000070-GPOS-00038, R31, 0421, 0422, 0974, 1173, 1401, 1504, 1505, 1546, 1557, 1558, 1559, 1560, 1561 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-5(1)(a)
- NIST-800-53-IA-5(4)
- NIST-800-53-IA-5(c)
- PCI-DSS-Req-8.2.3
- accounts_password_pam_ucredit
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: XCCDF Value var_password_pam_ucredit # promote to variable
set_fact:
var_password_pam_ucredit: !!str 0
tags:
- always
- name: Ensure PAM Enforces Password Requirements - Minimum Uppercase Characters -
Ensure PAM variable ucredit is set accordingly
ansible.builtin.lineinfile:
create: true
dest: /etc/security/pwquality.conf
regexp: ^#?\s*ucredit
line: ucredit = {{ var_password_pam_ucredit }}
when:
- '"kernel" in ansible_facts.packages'
- '"libpwquality" in ansible_facts.packages'
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-5(1)(a)
- NIST-800-53-IA-5(4)
- NIST-800-53-IA-5(c)
- PCI-DSS-Req-8.2.3
- accounts_password_pam_ucredit
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel && { rpm --quiet -q libpwquality; }; then
var_password_pam_ucredit='0'
# Strip any search characters in the key arg so that the key can be replaced without
# adding any search characters to the config file.
stripped_key=$(sed 's/[\^=\$,;+]*//g' <<< "^ucredit")
# shellcheck disable=SC2059
printf -v formatted_output "%s = %s" "$stripped_key" "$var_password_pam_ucredit"
# If the key exists, change it. Otherwise, add it to the config_file.
# We search for the key string followed by a word boundary (matched by \>),
# so if we search for 'setting', 'setting2' won't match.
if LC_ALL=C grep -q -m 1 -i -e "^ucredit\\>" "/etc/security/pwquality.conf"; then
escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
LC_ALL=C sed -i --follow-symlinks "s/^ucredit\\>.*/$escaped_formatted_output/gi" "/etc/security/pwquality.conf"
else
if [[ -s "/etc/security/pwquality.conf" ]] && [[ -n "$(tail -c 1 -- "/etc/security/pwquality.conf" || true)" ]]; then
LC_ALL=C sed -i --follow-symlinks '$a'\\ "/etc/security/pwquality.conf"
fi
printf '%s\n' "$formatted_output" >> "/etc/security/pwquality.conf"
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Set Password Hashing Algorithm
[ref]groupThe system's default algorithm for storing password hashes in
/etc/shadow is SHA-512. This can be configured in several
locations. |
| contains 2 rules |
Set PAM Password Hashing Algorithm - password-auth
[ref]ruleThe PAM system service can be configured to only store encrypted representations of passwords.
In /etc/pam.d/password-auth, the password section of the file controls which
PAM modules to execute during a password change.
Set the pam_unix.so module in the password section to include the option
sha512 and no other hashing
algorithms as shown below:
password sufficient pam_unix.so sha512 other arguments...
This will help ensure that new passwords for local users will be stored using the
sha512 algorithm.Warning:
The hashing algorithms to be used with pam_unix.so are defined with independent module
options. There are at least 7 possible algorithms and likely more algorithms will be
introduced along the time. Due the the number of options and its possible combinations,
the use of multiple hashing algorithm options may bring unexpected behaviors to the
system. For this reason the check will pass only when one hashing algorithm option is
defined and is aligned to the "var_password_hashing_algorithm_pam" variable. The
remediation will ensure the correct option and remove any other extra hashing algorithm
option. Rationale:Passwords need to be protected at all times, and encryption is the standard method for
protecting passwords. If passwords are not encrypted, they can be plainly read
(i.e., clear text) and easily compromised. Passwords that are encrypted with a weak algorithm
are no more protected than if they are kept in plain text.
This setting ensures user and group account administration utilities are configured to store
only encrypted representations of passwords. Additionally, the crypt_style
configuration option in /etc/libuser.conf ensures the use of a strong hashing
algorithm that makes password cracking attacks more difficult. References:
1, 12, 15, 16, 5, 5.6.2.2, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.10, 3.13.11, 4.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.2, 4.3.3.7.4, SR 1.1, SR 1.10, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.7, SR 1.8, SR 1.9, SR 2.1, A.18.1.4, A.7.1.1, A.9.2.1, A.9.2.2, A.9.2.3, A.9.2.4, A.9.2.6, A.9.3.1, A.9.4.2, A.9.4.3, IA-5(c), IA-5(1)(c), CM-6(a), PR.AC-1, PR.AC-6, PR.AC-7, Req-8.2.1, SRG-OS-000073-GPOS-00041, SRG-OS-000120-GPOS-00061, 0418, 1055, 1402 |
Set PAM Password Hashing Algorithm - system-auth
[ref]ruleThe PAM system service can be configured to only store encrypted representations of passwords.
In "/etc/pam.d/system-auth", the password section of the file controls which
PAM modules to execute during a password change.
Set the pam_unix.so module in the password section to include the option
sha512 and no other hashing
algorithms as shown below:
password sufficient pam_unix.so sha512 other arguments...
This will help ensure that new passwords for local users will be stored using the
sha512 algorithm.Warning:
The hashing algorithms to be used with pam_unix.so are defined with independent module
options. There are at least 7 possible algorithms and likely more algorithms will be
introduced along the time. Due the the number of options and its possible combinations,
the use of multiple hashing algorithm options may bring unexpected behaviors to the
system. For this reason the check will pass only when one hashing algorithm option is
defined and is aligned to the "var_password_hashing_algorithm_pam" variable. The
remediation will ensure the correct option and remove any other extra hashing algorithm
option. Rationale:Passwords need to be protected at all times, and encryption is the standard method for
protecting passwords. If passwords are not encrypted, they can be plainly read
(i.e., clear text) and easily compromised. Passwords that are encrypted with a weak algorithm
are no more protected than if they are kept in plain text.
This setting ensures user and group account administration utilities are configured to store
only encrypted representations of passwords. Additionally, the crypt_style
configuration option in /etc/libuser.conf ensures the use of a strong hashing
algorithm that makes password cracking attacks more difficult. References:
1, 12, 15, 16, 5, 5.6.2.2, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.10, 3.13.11, 4.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.2, 4.3.3.7.4, SR 1.1, SR 1.10, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.7, SR 1.8, SR 1.9, SR 2.1, A.18.1.4, A.7.1.1, A.9.2.1, A.9.2.2, A.9.2.3, A.9.2.4, A.9.2.6, A.9.3.1, A.9.4.2, A.9.4.3, IA-5(c), IA-5(1)(c), CM-6(a), PR.AC-1, PR.AC-6, PR.AC-7, Req-8.2.1, SRG-OS-000073-GPOS-00041, SRG-OS-000120-GPOS-00061, R68, 0418, 1055, 1402, 8.3.2, 8.3 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | medium |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- CJIS-5.6.2.2
- NIST-800-171-3.13.11
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-5(1)(c)
- NIST-800-53-IA-5(c)
- PCI-DSS-Req-8.2.1
- PCI-DSSv4-8.3
- PCI-DSSv4-8.3.2
- configure_strategy
- low_complexity
- medium_disruption
- medium_severity
- no_reboot_needed
- set_password_hashing_algorithm_systemauth
- name: XCCDF Value var_password_hashing_algorithm_pam # promote to variable
set_fact:
var_password_hashing_algorithm_pam: !!str sha512
tags:
- always
- name: Set PAM Password Hashing Algorithm - system-auth - Check if /etc/pam.d/system-auth
file is present
ansible.builtin.stat:
path: /etc/pam.d/system-auth
register: result_pam_auth_file_present
when:
- '"kernel" in ansible_facts.packages'
- '"pam" in ansible_facts.packages'
tags:
- CJIS-5.6.2.2
- NIST-800-171-3.13.11
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-5(1)(c)
- NIST-800-53-IA-5(c)
- PCI-DSS-Req-8.2.1
- PCI-DSSv4-8.3
- PCI-DSSv4-8.3.2
- configure_strategy
- low_complexity
- medium_disruption
- medium_severity
- no_reboot_needed
- set_password_hashing_algorithm_systemauth
- name: Set PAM Password Hashing Algorithm - system-auth - Check the proper remediation
for the system
block:
- name: Set PAM Password Hashing Algorithm - system-auth - Define the PAM file to
be edited as a local fact
ansible.builtin.set_fact:
pam_file_path: /etc/pam.d/system-auth
- name: Set PAM Password Hashing Algorithm - system-auth - Check if system relies
on authselect tool
ansible.builtin.stat:
path: /usr/bin/authselect
register: result_authselect_present
- name: Set PAM Password Hashing Algorithm - system-auth - Ensure authselect custom
profile is used if authselect is present
block:
- name: Set PAM Password Hashing Algorithm - system-auth - Check integrity of
authselect current profile
ansible.builtin.command:
cmd: authselect check
register: result_authselect_check_cmd
changed_when: false
check_mode: false
failed_when: false
- name: Set PAM Password Hashing Algorithm - system-auth - Informative message
based on the authselect integrity check result
ansible.builtin.assert:
that:
- ansible_check_mode or result_authselect_check_cmd.rc == 0
fail_msg:
- authselect integrity check failed. Remediation aborted!
- This remediation could not be applied because an authselect profile was
not selected or the selected profile is not intact.
- It is not recommended to manually edit the PAM files when authselect tool
is available.
- In cases where the default authselect profile does not cover a specific
demand, a custom authselect profile is recommended.
success_msg:
- authselect integrity check passed
- name: Set PAM Password Hashing Algorithm - system-auth - Get authselect current
profile
ansible.builtin.shell:
cmd: authselect current -r | awk '{ print $1 }'
register: result_authselect_profile
changed_when: false
when:
- result_authselect_check_cmd is success
- name: Set PAM Password Hashing Algorithm - system-auth - Define the current
authselect profile as a local fact
ansible.builtin.set_fact:
authselect_current_profile: '{{ result_authselect_profile.stdout }}'
authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
when:
- result_authselect_profile is not skipped
- result_authselect_profile.stdout is match("custom/")
- name: Set PAM Password Hashing Algorithm - system-auth - Define the new authselect
custom profile as a local fact
ansible.builtin.set_fact:
authselect_current_profile: '{{ result_authselect_profile.stdout }}'
authselect_custom_profile: custom/hardening
when:
- result_authselect_profile is not skipped
- result_authselect_profile.stdout is not match("custom/")
- name: Set PAM Password Hashing Algorithm - system-auth - Get authselect current
features to also enable them in the custom profile
ansible.builtin.shell:
cmd: authselect current | tail -n+3 | awk '{ print $2 }'
register: result_authselect_features
changed_when: false
check_mode: false
when:
- result_authselect_profile is not skipped
- authselect_current_profile is not match("custom/")
- name: Set PAM Password Hashing Algorithm - system-auth - Check if any custom
profile with the same name was already created
ansible.builtin.stat:
path: /etc/authselect/{{ authselect_custom_profile }}
register: result_authselect_custom_profile_present
changed_when: false
when:
- result_authselect_profile is not skipped
- authselect_current_profile is not match("custom/")
- name: Set PAM Password Hashing Algorithm - system-auth - Create an authselect
custom profile based on the current profile
ansible.builtin.command:
cmd: authselect create-profile hardening -b {{ authselect_current_profile
}}
when:
- result_authselect_profile is not skipped
- result_authselect_check_cmd is success
- authselect_current_profile is not match("^(custom/|local)")
- not result_authselect_custom_profile_present.stat.exists
- name: Set PAM Password Hashing Algorithm - system-auth - Create an authselect
custom profile based on sssd profile
ansible.builtin.command:
cmd: authselect create-profile hardening -b sssd
when:
- result_authselect_profile is not skipped
- result_authselect_check_cmd is success
- authselect_current_profile is match("local")
- not result_authselect_custom_profile_present.stat.exists
- name: Set PAM Password Hashing Algorithm - system-auth - Ensure authselect changes
are applied
ansible.builtin.command:
cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
when:
- result_authselect_check_cmd is success
- result_authselect_profile is not skipped
- authselect_current_profile is not match("custom/")
- authselect_custom_profile is not match(authselect_current_profile)
- name: Set PAM Password Hashing Algorithm - system-auth - Ensure the authselect
custom profile is selected
ansible.builtin.command:
cmd: authselect select {{ authselect_custom_profile }}
register: result_pam_authselect_select_profile
when:
- result_authselect_check_cmd is success
- result_authselect_profile is not skipped
- authselect_current_profile is not match("custom/")
- authselect_custom_profile is not match(authselect_current_profile)
- name: Set PAM Password Hashing Algorithm - system-auth - Restore the authselect
features in the custom profile
ansible.builtin.command:
cmd: authselect enable-feature {{ item }}
loop: '{{ result_authselect_features.stdout_lines }}'
register: result_pam_authselect_restore_features
when:
- result_authselect_profile is not skipped
- result_authselect_features is not skipped
- result_pam_authselect_select_profile is not skipped
- name: Set PAM Password Hashing Algorithm - system-auth - Ensure authselect changes
are applied
ansible.builtin.command:
cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
when:
- result_authselect_check_cmd is success
- result_authselect_profile is not skipped
- result_pam_authselect_restore_features is not skipped
- name: Set PAM Password Hashing Algorithm - system-auth - Change the PAM file
to be edited according to the custom authselect profile
ansible.builtin.set_fact:
pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
| basename }}
when:
- authselect_custom_profile is defined
when:
- result_authselect_present.stat.exists
- name: Set PAM Password Hashing Algorithm - system-auth - Define a fact for control
already filtered in case filters are used
ansible.builtin.set_fact:
pam_module_control: sufficient
- name: Set PAM Password Hashing Algorithm - system-auth - Check if expected PAM
module line is present in {{ pam_file_path }}
ansible.builtin.lineinfile:
path: '{{ pam_file_path }}'
regexp: ^\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_unix.so\s*.*
state: absent
check_mode: true
changed_when: false
register: result_pam_line_present
- name: Set PAM Password Hashing Algorithm - system-auth - Include or update the
PAM module line in {{ pam_file_path }}
block:
- name: Set PAM Password Hashing Algorithm - system-auth - Check if required PAM
module line is present in {{ pam_file_path }} with different control
ansible.builtin.lineinfile:
path: '{{ pam_file_path }}'
regexp: ^\s*password\s+.*\s+pam_unix.so\s*
state: absent
check_mode: true
changed_when: false
register: result_pam_line_other_control_present
- name: Set PAM Password Hashing Algorithm - system-auth - Ensure the correct
control for the required PAM module line in {{ pam_file_path }}
ansible.builtin.replace:
dest: '{{ pam_file_path }}'
regexp: ^(\s*password\s+).*(\bpam_unix.so.*)
replace: \1{{ pam_module_control }} \2
register: result_pam_module_edit
when:
- result_pam_line_other_control_present.found == 1
- name: Set PAM Password Hashing Algorithm - system-auth - Ensure the required
PAM module line is included in {{ pam_file_path }}
ansible.builtin.lineinfile:
dest: '{{ pam_file_path }}'
line: password {{ pam_module_control }} pam_unix.so
register: result_pam_module_add
when:
- result_pam_line_other_control_present.found == 0 or result_pam_line_other_control_present.found
> 1
- name: Set PAM Password Hashing Algorithm - system-auth - Ensure authselect changes
are applied
ansible.builtin.command:
cmd: authselect apply-changes -b
when:
- result_authselect_present is defined
- result_authselect_present.stat.exists
- |-
(result_pam_module_add is defined and result_pam_module_add.changed)
or (result_pam_module_edit is defined and result_pam_module_edit.changed)
when:
- result_pam_line_present.found is defined
- result_pam_line_present.found == 0
- name: Set PAM Password Hashing Algorithm - system-auth - Define a fact for control
already filtered in case filters are used
ansible.builtin.set_fact:
pam_module_control: sufficient
- name: Set PAM Password Hashing Algorithm - system-auth - Check if the required
PAM module option is present in {{ pam_file_path }}
ansible.builtin.lineinfile:
path: '{{ pam_file_path }}'
regexp: ^\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_unix.so\s*.*\s{{
var_password_hashing_algorithm_pam.split("|")[0] }}\b
state: absent
check_mode: true
changed_when: false
register: result_pam_module_set_password_hashing_algorithm_systemauth_option_present
- name: Set PAM Password Hashing Algorithm - system-auth - Ensure the "{{ var_password_hashing_algorithm_pam.split("|")[0]
}}" PAM option for "pam_unix.so" is included in {{ pam_file_path }}
ansible.builtin.lineinfile:
path: '{{ pam_file_path }}'
backrefs: true
regexp: ^(\s*password\s+{{ pam_module_control | regex_escape() }}\s+pam_unix.so.*)
line: \1 {{ var_password_hashing_algorithm_pam.split("|")[0] }}
state: present
register: result_pam_set_password_hashing_algorithm_systemauth_add
when:
- result_pam_module_set_password_hashing_algorithm_systemauth_option_present.found
is defined
- result_pam_module_set_password_hashing_algorithm_systemauth_option_present.found
== 0
- name: Set PAM Password Hashing Algorithm - system-auth - Ensure authselect changes
are applied
ansible.builtin.command:
cmd: authselect apply-changes -b
when:
- result_authselect_present.stat.exists
- |-
(result_pam_set_password_hashing_algorithm_systemauth_add is defined and result_pam_set_password_hashing_algorithm_systemauth_add.changed)
or (result_pam_set_password_hashing_algorithm_systemauth_edit is defined and result_pam_set_password_hashing_algorithm_systemauth_edit.changed)
when:
- '"kernel" in ansible_facts.packages'
- '"pam" in ansible_facts.packages'
- result_pam_auth_file_present.stat.exists
tags:
- CJIS-5.6.2.2
- NIST-800-171-3.13.11
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-5(1)(c)
- NIST-800-53-IA-5(c)
- PCI-DSS-Req-8.2.1
- PCI-DSSv4-8.3
- PCI-DSSv4-8.3.2
- configure_strategy
- low_complexity
- medium_disruption
- medium_severity
- no_reboot_needed
- set_password_hashing_algorithm_systemauth
- name: Set PAM Password Hashing Algorithm - system-auth - Check if /etc/pam.d/system-auth
File is Present
ansible.builtin.stat:
path: /etc/pam.d/system-auth
register: result_pam_auth_file_present
when:
- '"kernel" in ansible_facts.packages'
- '"pam" in ansible_facts.packages'
tags:
- CJIS-5.6.2.2
- NIST-800-171-3.13.11
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-5(1)(c)
- NIST-800-53-IA-5(c)
- PCI-DSS-Req-8.2.1
- PCI-DSSv4-8.3
- PCI-DSSv4-8.3.2
- configure_strategy
- low_complexity
- medium_disruption
- medium_severity
- no_reboot_needed
- set_password_hashing_algorithm_systemauth
- name: Set PAM Password Hashing Algorithm - system-auth - Check The Proper Remediation
For The System
block:
- name: Set PAM Password Hashing Algorithm - system-auth - Define the PAM file to
be edited as a local fact
ansible.builtin.set_fact:
pam_file_path: /etc/pam.d/system-auth
- name: Set PAM Password Hashing Algorithm - system-auth - Check if system relies
on authselect tool
ansible.builtin.stat:
path: /usr/bin/authselect
register: result_authselect_present
- name: Set PAM Password Hashing Algorithm - system-auth - Ensure authselect custom
profile is used if authselect is present
block:
- name: Set PAM Password Hashing Algorithm - system-auth - Check integrity of
authselect current profile
ansible.builtin.command:
cmd: authselect check
register: result_authselect_check_cmd
changed_when: false
check_mode: false
failed_when: false
- name: Set PAM Password Hashing Algorithm - system-auth - Informative message
based on the authselect integrity check result
ansible.builtin.assert:
that:
- ansible_check_mode or result_authselect_check_cmd.rc == 0
fail_msg:
- authselect integrity check failed. Remediation aborted!
- This remediation could not be applied because an authselect profile was
not selected or the selected profile is not intact.
- It is not recommended to manually edit the PAM files when authselect tool
is available.
- In cases where the default authselect profile does not cover a specific
demand, a custom authselect profile is recommended.
success_msg:
- authselect integrity check passed
- name: Set PAM Password Hashing Algorithm - system-auth - Get authselect current
profile
ansible.builtin.shell:
cmd: authselect current -r | awk '{ print $1 }'
register: result_authselect_profile
changed_when: false
when:
- result_authselect_check_cmd is success
- name: Set PAM Password Hashing Algorithm - system-auth - Define the current
authselect profile as a local fact
ansible.builtin.set_fact:
authselect_current_profile: '{{ result_authselect_profile.stdout }}'
authselect_custom_profile: '{{ result_authselect_profile.stdout }}'
when:
- result_authselect_profile is not skipped
- result_authselect_profile.stdout is match("custom/")
- name: Set PAM Password Hashing Algorithm - system-auth - Define the new authselect
custom profile as a local fact
ansible.builtin.set_fact:
authselect_current_profile: '{{ result_authselect_profile.stdout }}'
authselect_custom_profile: custom/hardening
when:
- result_authselect_profile is not skipped
- result_authselect_profile.stdout is not match("custom/")
- name: Set PAM Password Hashing Algorithm - system-auth - Get authselect current
features to also enable them in the custom profile
ansible.builtin.shell:
cmd: authselect current | tail -n+3 | awk '{ print $2 }'
register: result_authselect_features
changed_when: false
check_mode: false
when:
- result_authselect_profile is not skipped
- authselect_current_profile is not match("custom/")
- name: Set PAM Password Hashing Algorithm - system-auth - Check if any custom
profile with the same name was already created
ansible.builtin.stat:
path: /etc/authselect/{{ authselect_custom_profile }}
register: result_authselect_custom_profile_present
changed_when: false
when:
- result_authselect_profile is not skipped
- authselect_current_profile is not match("custom/")
- name: Set PAM Password Hashing Algorithm - system-auth - Create an authselect
custom profile based on the current profile
ansible.builtin.command:
cmd: authselect create-profile hardening -b {{ authselect_current_profile
}}
when:
- result_authselect_profile is not skipped
- result_authselect_check_cmd is success
- authselect_current_profile is not match("^(custom/|local)")
- not result_authselect_custom_profile_present.stat.exists
- name: Set PAM Password Hashing Algorithm - system-auth - Create an authselect
custom profile based on sssd profile
ansible.builtin.command:
cmd: authselect create-profile hardening -b sssd
when:
- result_authselect_profile is not skipped
- result_authselect_check_cmd is success
- authselect_current_profile is match("local")
- not result_authselect_custom_profile_present.stat.exists
- name: Set PAM Password Hashing Algorithm - system-auth - Ensure authselect changes
are applied
ansible.builtin.command:
cmd: authselect apply-changes -b --backup=before-hardening-custom-profile
when:
- result_authselect_check_cmd is success
- result_authselect_profile is not skipped
- authselect_current_profile is not match("custom/")
- authselect_custom_profile is not match(authselect_current_profile)
- name: Set PAM Password Hashing Algorithm - system-auth - Ensure the authselect
custom profile is selected
ansible.builtin.command:
cmd: authselect select {{ authselect_custom_profile }}
register: result_pam_authselect_select_profile
when:
- result_authselect_check_cmd is success
- result_authselect_profile is not skipped
- authselect_current_profile is not match("custom/")
- authselect_custom_profile is not match(authselect_current_profile)
- name: Set PAM Password Hashing Algorithm - system-auth - Restore the authselect
features in the custom profile
ansible.builtin.command:
cmd: authselect enable-feature {{ item }}
loop: '{{ result_authselect_features.stdout_lines }}'
register: result_pam_authselect_restore_features
when:
- result_authselect_profile is not skipped
- result_authselect_features is not skipped
- result_pam_authselect_select_profile is not skipped
- name: Set PAM Password Hashing Algorithm - system-auth - Ensure authselect changes
are applied
ansible.builtin.command:
cmd: authselect apply-changes -b --backup=after-hardening-custom-profile
when:
- result_authselect_check_cmd is success
- result_authselect_profile is not skipped
- result_pam_authselect_restore_features is not skipped
- name: Set PAM Password Hashing Algorithm - system-auth - Change the PAM file
to be edited according to the custom authselect profile
ansible.builtin.set_fact:
pam_file_path: /etc/authselect/{{ authselect_custom_profile }}/{{ pam_file_path
| basename }}
when:
- authselect_custom_profile is defined
when:
- result_authselect_present.stat.exists
- name: Set PAM Password Hashing Algorithm - system-auth - Check if "{{ pam_file_path
}}" File is Present
ansible.builtin.stat:
path: '{{ pam_file_path }}'
register: pam_file_path_present
- name: Set PAM Password Hashing Algorithm - system-auth - Ensure That Only the
Correct Hashing Algorithm Option For pam_unix.so Is Used in {{ pam_file_path
}}
ansible.builtin.replace:
dest: '{{ pam_file_path }}'
regexp: (^\s*password.*pam_unix\.so.*)\b{{ item }}\b\s*(.*)
replace: \1\2
when:
- item != var_password_hashing_algorithm_pam.split('|')[0]
- pam_file_path_present.stat.exists
loop:
- sha512
- yescrypt
- gost_yescrypt
- blowfish
- sha256
- md5
- bigcrypt
register: result_pam_hashing_options_removal
- name: Set PAM Password Hashing Algorithm - system-auth - Ensure authselect changes
are applied
ansible.builtin.command:
cmd: authselect apply-changes -b
when:
- result_authselect_present.stat.exists
- result_pam_hashing_options_removal is changed
when:
- '"kernel" in ansible_facts.packages'
- '"pam" in ansible_facts.packages'
- result_pam_auth_file_present.stat.exists
tags:
- CJIS-5.6.2.2
- NIST-800-171-3.13.11
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-5(1)(c)
- NIST-800-53-IA-5(c)
- PCI-DSS-Req-8.2.1
- PCI-DSSv4-8.3
- PCI-DSSv4-8.3.2
- configure_strategy
- low_complexity
- medium_disruption
- medium_severity
- no_reboot_needed
- set_password_hashing_algorithm_systemauth
Remediation Shell script: (show)
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel && { rpm --quiet -q pam; }; then
var_password_hashing_algorithm_pam='sha512'
# Allow multiple algorithms, but choose the first one for remediation
var_password_hashing_algorithm_pam="$(echo $var_password_hashing_algorithm_pam | cut -d \| -f 1)"
PAM_FILE_PATH="/etc/pam.d/system-auth"
# Ensure all the hashing algorithm option is removed.
declare -a HASHING_ALGORITHMS_OPTIONS=("sha512" "yescrypt" "gost_yescrypt" "blowfish" "sha256" "md5" "bigcrypt")
for hash_option in "${HASHING_ALGORITHMS_OPTIONS[@]}"; do
if grep -qP "^\s*password\s+.*\s+pam_unix.so\s+.*\b$hash_option\b" "$PAM_FILE_PATH"; then
if [ -e "$PAM_FILE_PATH" ] ; then
PAM_FILE_PATH="$PAM_FILE_PATH"
if [ -f /usr/bin/authselect ]; then
if ! authselect check; then
echo "
authselect integrity check failed. Remediation aborted!
This remediation could not be applied because an authselect profile was not selected or the selected profile is not intact.
It is not recommended to manually edit the PAM files when authselect tool is available.
In cases where the default authselect profile does not cover a specific demand, a custom authselect profile is recommended."
exit 1
fi
CURRENT_PROFILE=$(authselect current -r | awk '{ print $1 }')
# If not already in use, a custom profile is created preserving the enabled features.
if [[ ! $CURRENT_PROFILE == custom/* ]]; then
ENABLED_FEATURES=$(authselect current | tail -n+3 | awk '{ print $2 }')
# The "local" profile does not contain essential security features required by multiple Benchmarks.
# If currently used, it is replaced by "sssd", which is the best option in this case.
if [[ $CURRENT_PROFILE == local ]]; then
CURRENT_PROFILE="sssd"
fi
authselect create-profile hardening -b $CURRENT_PROFILE
CURRENT_PROFILE="custom/hardening"
authselect apply-changes -b --backup=before-hardening-custom-profile
authselect select $CURRENT_PROFILE
for feature in $ENABLED_FEATURES; do
authselect enable-feature $feature;
done
authselect apply-changes -b --backup=after-hardening-custom-profile
fi
PAM_FILE_NAME=$(basename "$PAM_FILE_PATH")
PAM_FILE_PATH="/etc/authselect/$CURRENT_PROFILE/$PAM_FILE_NAME"
authselect apply-changes -b
fi
if grep -qP "^\s*password\s+.*\s+pam_unix.so\s.*\b$hash_option\b" "$PAM_FILE_PATH"; then
sed -i -E --follow-symlinks "s/(.*password.*.*.*pam_unix.so.*)\b$hash_option\b=?[[:alnum:]]*(.*)/\1\2/g" "$PAM_FILE_PATH"
fi
if [ -f /usr/bin/authselect ]; then
authselect apply-changes -b
fi
else
echo "$PAM_FILE_PATH was not found" >&2
fi
fi
done
if [ -e "$PAM_FILE_PATH" ] ; then
PAM_FILE_PATH="$PAM_FILE_PATH"
if [ -f /usr/bin/authselect ]; then
if ! authselect check; then
echo "
authselect integrity check failed. Remediation aborted!
This remediation could not be applied because an authselect profile was not selected or the selected profile is not intact.
It is not recommended to manually edit the PAM files when authselect tool is available.
In cases where the default authselect profile does not cover a specific demand, a custom authselect profile is recommended."
exit 1
fi
CURRENT_PROFILE=$(authselect current -r | awk '{ print $1 }')
# If not already in use, a custom profile is created preserving the enabled features.
if [[ ! $CURRENT_PROFILE == custom/* ]]; then
ENABLED_FEATURES=$(authselect current | tail -n+3 | awk '{ print $2 }')
# The "local" profile does not contain essential security features required by multiple Benchmarks.
# If currently used, it is replaced by "sssd", which is the best option in this case.
if [[ $CURRENT_PROFILE == local ]]; then
CURRENT_PROFILE="sssd"
fi
authselect create-profile hardening -b $CURRENT_PROFILE
CURRENT_PROFILE="custom/hardening"
authselect apply-changes -b --backup=before-hardening-custom-profile
authselect select $CURRENT_PROFILE
for feature in $ENABLED_FEATURES; do
authselect enable-feature $feature;
done
authselect apply-changes -b --backup=after-hardening-custom-profile
fi
PAM_FILE_NAME=$(basename "$PAM_FILE_PATH")
PAM_FILE_PATH="/etc/authselect/$CURRENT_PROFILE/$PAM_FILE_NAME"
authselect apply-changes -b
fi
if ! grep -qP "^\s*password\s+sufficient\s+pam_unix.so\s*.*" "$PAM_FILE_PATH"; then
# Line matching group + control + module was not found. Check group + module.
if [ "$(grep -cP '^\s*password\s+.*\s+pam_unix.so\s*' "$PAM_FILE_PATH")" -eq 1 ]; then
# The control is updated only if one single line matches.
sed -i -E --follow-symlinks "s/^(\s*password\s+).*(\bpam_unix.so.*)/\1sufficient \2/" "$PAM_FILE_PATH"
else
echo "password sufficient pam_unix.so" >> "$PAM_FILE_PATH"
fi
fi
# Check the option
if ! grep -qP "^\s*password\s+sufficient\s+pam_unix.so\s*.*\s$var_password_hashing_algorithm_pam\b" "$PAM_FILE_PATH"; then
sed -i -E --follow-symlinks "/\s*password\s+sufficient\s+pam_unix.so.*/ s/$/ $var_password_hashing_algorithm_pam/" "$PAM_FILE_PATH"
fi
if [ -f /usr/bin/authselect ]; then
authselect apply-changes -b
fi
else
echo "$PAM_FILE_PATH was not found" >&2
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Ensure PAM Displays Last Logon/Access Notification
[ref]ruleTo configure the system to notify users of last logon/access using pam_lastlog,
add or correct the pam_lastlog settings in /etc/pam.d/postlogin
to include showfailed option, such as:
session [default=1] pam_lastlog.so showfailed
And make sure that the silent option is not set for this specific line.Warning:
If the system relies on authselect tool to manage PAM settings, the remediation
will also use authselect tool. However, if any manual modification was made in
PAM files, the authselect integrity check will fail and the remediation will be
aborted in order to preserve intentional changes. In this case, an informative message will
be shown in the remediation report. Warning:
authselect contains an authselect feature to easily and properly enable Last Logon
notifications with pam_lastlog.so module. If a custom profile was created and used
in the system before this authselect feature was available, the new feature can't be used
with this custom profile and the remediation will fail. In this case, the custom profile
should be recreated or manually updated. Rationale:Users need to be aware of activity that occurs regarding their account. Providing users with
information regarding the number of unsuccessful attempts that were made to login to their
account allows the user to determine if any unauthorized activity has occurred and gives them
an opportunity to notify administrators. References:
1, 12, 15, 16, 5.5.2, DSS05.04, DSS05.10, DSS06.10, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, SR 1.1, SR 1.10, SR 1.2, SR 1.5, SR 1.7, SR 1.8, SR 1.9, A.18.1.4, A.9.2.1, A.9.2.4, A.9.3.1, A.9.4.2, A.9.4.3, AC-9, AC-9(1), PR.AC-7, Req-10.2.4, SRG-OS-000480-GPOS-00227, 10.2.1.4, 10.2.1, 10.2 |
Protect Physical Console Access
[ref]groupIt is impossible to fully protect a system from an
attacker with physical access, so securing the space in which the
system is located should be considered a necessary step. However,
there are some steps which, if taken, make it more difficult for an
attacker to quickly or undetectably modify a system from its
console. |
| contains 1 rule |
Require Authentication for Emergency Systemd Target
[ref]ruleEmergency mode is intended as a system recovery
method, providing a single user root access to the system
during a failed boot sequence.
By default, Emergency mode is protected by requiring a password and is set
in /usr/lib/systemd/system/emergency.service. Rationale:This prevents attackers with physical access from trivially bypassing security
on the machine and gaining root access. Such accesses are further prevented
by configuring the bootloader password. References:
1, 11, 12, 14, 15, 16, 18, 3, 5, DSS05.02, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.06, DSS06.10, 3.1.1, 3.4.5, 164.308(a)(1)(ii)(B), 164.308(a)(7)(i), 164.308(a)(7)(ii)(A), 164.310(a)(1), 164.310(a)(2)(i), 164.310(a)(2)(ii), 164.310(a)(2)(iii), 164.310(b), 164.310(c), 164.310(d)(1), 164.310(d)(2)(iii), 4.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, A.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, IA-2, AC-3, CM-6(a), PR.AC-1, PR.AC-4, PR.AC-6, PR.AC-7, PR.PT-3, SRG-OS-000080-GPOS-00048, 0421, 0422, 0974, 1173, 1401, 1504, 1505, 1546, 1557, 1558, 1559, 1560, 1561 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- NIST-800-171-3.1.1
- NIST-800-171-3.4.5
- NIST-800-53-AC-3
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-2
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- require_emergency_target_auth
- restrict_strategy
- name: Require emergency mode password
ansible.builtin.lineinfile:
create: true
dest: /usr/lib/systemd/system/emergency.service
regexp: ^#?ExecStart=
line: ExecStart=-/bin/sh -c "/sbin/sulogin; /usr/bin/systemctl --fail --no-block
default"
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-171-3.1.1
- NIST-800-171-3.4.5
- NIST-800-53-AC-3
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-2
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- require_emergency_target_auth
- restrict_strategy
Remediation Shell script: (show)
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel; then
service_file="/usr/lib/systemd/system/emergency.service"
sulogin='/bin/sh -c "/sbin/sulogin; /usr/bin/systemctl --fail --no-block default"'
if grep "^ExecStart=.*" "$service_file" ; then
sed -i "s%^ExecStart=.*%ExecStart=-$sulogin%" "$service_file"
else
echo "ExecStart=-$sulogin" >> "$service_file"
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Protect Accounts by Restricting Password-Based Login
[ref]groupConventionally, Unix shell accounts are accessed by
providing a username and password to a login program, which tests
these values for correctness using the /etc/passwd and
/etc/shadow files. Password-based login is vulnerable to
guessing of weak passwords, and to sniffing and man-in-the-middle
attacks against passwords entered over a network or at an insecure
console. Therefore, mechanisms for accessing accounts by entering
usernames and passwords should be restricted to those which are
operationally necessary. |
| contains 17 rules |
Set Account Expiration Parameters
[ref]groupAccounts can be configured to be automatically disabled
after a certain time period,
meaning that they will require administrator interaction to become usable again.
Expiration of accounts after inactivity can be set for all accounts by default
and also on a per-account basis, such as for accounts that are known to be temporary.
To configure automatic expiration of an account following
the expiration of its password (that is, after the password has expired and not been changed),
run the following command, substituting NUM_DAYS and USER appropriately:
$ sudo chage -I NUM_DAYS USER
Accounts, such as temporary accounts, can also be configured to expire on an explicitly-set date with the
-E option.
The file /etc/default/useradd controls
default settings for all newly-created accounts created with the system's
normal command line utilities.Warning:
This will only apply to newly created accounts |
| contains 2 rules |
Set Account Expiration Following Inactivity
[ref]ruleTo specify the number of days after a password expires (which
signifies inactivity) until an account is permanently disabled, add or correct
the following line in /etc/default/useradd:
INACTIVE=30
If a password is currently on the verge of expiration, then
30
day(s) remain(s) until the account is automatically
disabled. However, if the password will not expire for another 60 days, then 60
days plus 30 day(s) could
elapse until the account would be automatically disabled. See the
useradd man page for more information.Rationale:Inactive identifiers pose a risk to systems and applications because attackers may exploit an inactive identifier and potentially obtain undetected access to the system.
Disabling inactive accounts ensures that accounts which may not have been responsibly removed are not available to attackers who may have compromised their credentials.
Owners of inactive accounts will not notice if unauthorized access to their user account has been obtained. References:
1, 12, 13, 14, 15, 16, 18, 3, 5, 7, 8, 5.6.2.1.1, DSS01.03, DSS03.05, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.10, 3.5.6, 4.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, SR 1.1, SR 1.10, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 6.2, A.12.4.1, A.12.4.3, A.18.1.4, A.6.1.2, A.7.1.1, A.9.1.2, A.9.2.1, A.9.2.2, A.9.2.3, A.9.2.4, A.9.2.6, A.9.3.1, A.9.4.1, A.9.4.2, A.9.4.3, A.9.4.4, A.9.4.5, CIP-004-6 R2.2.2, CIP-004-6 R2.2.3, CIP-007-3 R.1.3, CIP-007-3 R5, CIP-007-3 R5.1.1, CIP-007-3 R5.1.3, CIP-007-3 R5.2.1, CIP-007-3 R5.2.3, IA-4(e), AC-2(3), CM-6(a), DE.CM-1, DE.CM-3, PR.AC-1, PR.AC-4, PR.AC-6, PR.AC-7, Req-8.1.4, SRG-OS-000118-GPOS-00060, 8.2.6, 8.2 |
Ensure All Accounts on the System Have Unique Names
[ref]ruleEnsure accounts on the system have unique names.
To ensure all accounts have unique names, run the following command:
$ sudo getent passwd | awk -F: '{ print $1}' | uniq -d
If a username is returned, change or delete the username.Rationale:Unique usernames allow for accountability on the system. |
Set Password Expiration Parameters
[ref]groupThe file /etc/login.defs controls several
password-related settings. Programs such as passwd,
su, and
login consult /etc/login.defs to determine
behavior with regard to password aging, expiration warnings,
and length. See the man page login.defs(5) for more information.
Users should be forced to change their passwords, in order to
decrease the utility of compromised passwords. However, the need to
change passwords often should be balanced against the risk that
users will reuse or write down passwords if forced to change them
too often. Forcing password changes every 90-360 days, depending on
the environment, is recommended. Set the appropriate value as
PASS_MAX_DAYS and apply it to existing accounts with the
-M flag.
The PASS_MIN_DAYS (-m) setting prevents password
changes for 7 days after the first change, to discourage password
cycling. If you use this setting, train users to contact an administrator
for an emergency password change in case a new password becomes
compromised. The PASS_WARN_AGE (-W) setting gives
users 7 days of warnings at login time that their passwords are about to expire.
For example, for each existing human user USER, expiration parameters
could be adjusted to a 180 day maximum password age, 7 day minimum password
age, and 7 day warning period with the following command:
$ sudo chage -M 180 -m 7 -W 7 USER |
| contains 7 rules |
Set Password Maximum Age
[ref]ruleTo specify password maximum age for new accounts,
edit the file /etc/login.defs
and add or correct the following line:
PASS_MAX_DAYS 180
The profile requirement is 180.Rationale:Any password, no matter how complex, can eventually be cracked. Therefore, passwords
need to be changed periodically. If the operating system does not limit the lifetime
of passwords and force users to change their passwords, there is the risk that the
operating system passwords could be compromised.
Setting the password maximum age ensures users are required to
periodically change their passwords. Requiring shorter password lifetimes
increases the risk of users writing down the password in a convenient
location subject to physical compromise. References:
1, 12, 15, 16, 5, 5.6.2.1, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.10, 3.5.6, 4.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.2, 4.3.3.7.4, SR 1.1, SR 1.10, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.7, SR 1.8, SR 1.9, SR 2.1, A.18.1.4, A.7.1.1, A.9.2.1, A.9.2.2, A.9.2.3, A.9.2.4, A.9.2.6, A.9.3.1, A.9.4.2, A.9.4.3, IA-5(f), IA-5(1)(d), CM-6(a), PR.AC-1, PR.AC-6, PR.AC-7, Req-8.2.4, SRG-OS-000076-GPOS-00044, 0418, 1055, 1402, 8.3.9, 8.3 Remediation Shell script: (show)
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel && { rpm --quiet -q shadow-utils; }; then
var_accounts_maximum_age_login_defs='180'
# 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' <<< "^PASS_MAX_DAYS")
# shellcheck disable=SC2059
printf -v formatted_output "%s %s" "$stripped_key" "$var_accounts_maximum_age_login_defs"
# 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 "^PASS_MAX_DAYS\\>" "/etc/login.defs"; then
escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
LC_ALL=C sed -i --follow-symlinks "s/^PASS_MAX_DAYS\\>.*/$escaped_formatted_output/gi" "/etc/login.defs"
else
if [[ -s "/etc/login.defs" ]] && [[ -n "$(tail -c 1 -- "/etc/login.defs" || true)" ]]; then
LC_ALL=C sed -i --follow-symlinks '$a'\\ "/etc/login.defs"
fi
printf '%s\n' "$formatted_output" >> "/etc/login.defs"
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Set Password Minimum Age
[ref]ruleTo specify password minimum age for new accounts,
edit the file /etc/login.defs
and add or correct the following line:
PASS_MIN_DAYS 1
A value of 1 day is considered sufficient for many
environments.
The profile requirement is 1.Rationale:Enforcing a minimum password lifetime helps to prevent repeated password
changes to defeat the password reuse or history enforcement requirement. If
users are allowed to immediately and continually change their password,
then the password could be repeatedly changed in a short period of time to
defeat the organization's policy regarding password reuse.
Setting the minimum password age protects against users cycling back to a
favorite password after satisfying the password reuse requirement. References:
1, 12, 15, 16, 5, 5.6.2.1.1, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.10, 3.5.8, 4.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.2, 4.3.3.7.4, SR 1.1, SR 1.10, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.7, SR 1.8, SR 1.9, SR 2.1, A.18.1.4, A.7.1.1, A.9.2.1, A.9.2.2, A.9.2.3, A.9.2.4, A.9.2.6, A.9.3.1, A.9.4.2, A.9.4.3, IA-5(f), IA-5(1)(d), CM-6(a), PR.AC-1, PR.AC-6, PR.AC-7, SRG-OS-000075-GPOS-00043, 0418, 1055, 1402 Remediation Shell script: (show)
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel && { rpm --quiet -q shadow-utils; }; then
var_accounts_minimum_age_login_defs='1'
# 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' <<< "^PASS_MIN_DAYS")
# shellcheck disable=SC2059
printf -v formatted_output "%s %s" "$stripped_key" "$var_accounts_minimum_age_login_defs"
# 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 "^PASS_MIN_DAYS\\>" "/etc/login.defs"; then
escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
LC_ALL=C sed -i --follow-symlinks "s/^PASS_MIN_DAYS\\>.*/$escaped_formatted_output/gi" "/etc/login.defs"
else
if [[ -s "/etc/login.defs" ]] && [[ -n "$(tail -c 1 -- "/etc/login.defs" || true)" ]]; then
LC_ALL=C sed -i --follow-symlinks '$a'\\ "/etc/login.defs"
fi
printf '%s\n' "$formatted_output" >> "/etc/login.defs"
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Set Existing Passwords Maximum Age
[ref]ruleConfigure non-compliant accounts to enforce a 180-day maximum password lifetime
restriction by running the following command:
$ sudo chage -M 180 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. |
Set Existing Passwords Minimum Age
[ref]ruleConfigure non-compliant accounts to enforce a 24 hours/1 day minimum password
lifetime by running the following command:
$ sudo chage -m 1 USER Rationale:Enforcing a minimum password lifetime helps to prevent repeated password
changes to defeat the password reuse or history enforcement requirement. If
users are allowed to immediately and continually change their password, the
password could be repeatedly changed in a short period of time to defeat the
organization's policy regarding password reuse. Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-5(1)(d)
- NIST-800-53-IA-5(f)
- accounts_password_set_min_life_existing
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: XCCDF Value var_accounts_minimum_age_login_defs # promote to variable
set_fact:
var_accounts_minimum_age_login_defs: !!str 1
tags:
- always
- name: Collect users with not correct minimum time period between password changes
ansible.builtin.command: |
awk -F':' '(/^[^:]+:[^!*]/ && ($4 < {{ var_accounts_minimum_age_login_defs }} || $4 == "")) {print $1}' /etc/shadow
register: user_names
changed_when: false
check_mode: false
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-5(1)(d)
- NIST-800-53-IA-5(f)
- accounts_password_set_min_life_existing
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Change the minimum time period between password changes
ansible.builtin.command: |
chage -m {{ var_accounts_minimum_age_login_defs }} {{ item }}
with_items: '{{ user_names.stdout_lines }}'
when:
- '"kernel" in ansible_facts.packages'
- user_names.stdout_lines | length > 0
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-5(1)(d)
- NIST-800-53-IA-5(f)
- accounts_password_set_min_life_existing
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel; then
var_accounts_minimum_age_login_defs='1'
while IFS= read -r i; do
chage -m $var_accounts_minimum_age_login_defs $i
done < <(awk -v var="$var_accounts_minimum_age_login_defs" -F: '(/^[^:]+:[^!*]/ && ($4 < var || $4 == "")) {print $1}' /etc/shadow)
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Set Existing Passwords Warning Age
[ref]ruleTo configure how many days prior to password expiration that a warning will be issued to
users, run the command:
$ sudo chage --warndays 7 USER
This profile requirement is 7.Rationale:Providing an advance warning that a password will be expiring gives users
time to think of a secure password. Users caught unaware may choose a simple
password or write it down where it may be discovered. Remediation Ansible snippet: (show)
| 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-IA-5(1)(d)
- NIST-800-53-IA-5(f)
- PCI-DSSv4-8.3
- PCI-DSSv4-8.3.9
- accounts_password_set_warn_age_existing
- configure_strategy
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: XCCDF Value var_accounts_password_warn_age_login_defs # promote to variable
set_fact:
var_accounts_password_warn_age_login_defs: !!str 7
tags:
- always
- name: Set Existing Passwords Warning Age - Collect Users With Incorrect Number of
Days of Warning Before Password Expires
ansible.builtin.command:
cmd: awk -F':' '(($6 < {{ var_accounts_password_warn_age_login_defs }} || $6 ==
"") && $2 ~ /^\$/) {print $1}' /etc/shadow
register: result_pass_warn_age_user_names
changed_when: false
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-5(1)(d)
- NIST-800-53-IA-5(f)
- PCI-DSSv4-8.3
- PCI-DSSv4-8.3.9
- accounts_password_set_warn_age_existing
- configure_strategy
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Set Existing Passwords Warning Age - Ensure the Number of Days of Warning
Before Password Expires
ansible.builtin.command:
cmd: chage --warndays {{ var_accounts_password_warn_age_login_defs }} {{ item
}}
with_items: '{{ result_pass_warn_age_user_names.stdout_lines }}'
when:
- '"kernel" in ansible_facts.packages'
- result_pass_warn_age_user_names is not skipped and result_pass_warn_age_user_names.stdout_lines
| length > 0
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-5(1)(d)
- NIST-800-53-IA-5(f)
- PCI-DSSv4-8.3
- PCI-DSSv4-8.3.9
- accounts_password_set_warn_age_existing
- configure_strategy
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel; then
var_accounts_password_warn_age_login_defs='7'
while IFS= read -r i; do
chage --warndays $var_accounts_password_warn_age_login_defs $i
done < <(awk -v var="$var_accounts_password_warn_age_login_defs" -F: '(($6 < var || $6 == "") && $2 ~ /^\$/) {print $1}' /etc/shadow)
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Set Password Warning Age
[ref]ruleTo specify how many days prior to password
expiration that a warning will be issued to users,
edit the file /etc/login.defs and add or correct
the following line:
PASS_WARN_AGE 7
The profile requirement is 7.Rationale:Setting the password warning age enables users to
make the change at a practical time. References:
1, 12, 13, 14, 15, 16, 18, 3, 5, 7, 8, DSS01.03, DSS03.05, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.10, 3.5.8, 4.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, SR 1.1, SR 1.10, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 6.2, A.12.4.1, A.12.4.3, A.18.1.4, A.6.1.2, A.7.1.1, A.9.1.2, A.9.2.1, A.9.2.2, A.9.2.3, A.9.2.4, A.9.2.6, A.9.3.1, A.9.4.1, A.9.4.2, A.9.4.3, A.9.4.4, A.9.4.5, IA-5(f), IA-5(1)(d), CM-6(a), DE.CM-1, DE.CM-3, PR.AC-1, PR.AC-4, PR.AC-6, PR.AC-7, Req-8.2.4, 0418, 1055, 1402, 8.3.9, 8.3 Remediation Shell script: (show)
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel && { rpm --quiet -q shadow-utils; }; then
var_accounts_password_warn_age_login_defs='7'
# 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' <<< "^PASS_WARN_AGE")
# shellcheck disable=SC2059
printf -v formatted_output "%s %s" "$stripped_key" "$var_accounts_password_warn_age_login_defs"
# 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 "^PASS_WARN_AGE\\>" "/etc/login.defs"; then
escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
LC_ALL=C sed -i --follow-symlinks "s/^PASS_WARN_AGE\\>.*/$escaped_formatted_output/gi" "/etc/login.defs"
else
if [[ -s "/etc/login.defs" ]] && [[ -n "$(tail -c 1 -- "/etc/login.defs" || true)" ]]; then
LC_ALL=C sed -i --follow-symlinks '$a'\\ "/etc/login.defs"
fi
printf '%s\n' "$formatted_output" >> "/etc/login.defs"
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Set existing passwords a period of inactivity before they been locked
[ref]ruleConfigure user accounts that have been inactive for over a given period of time
to be automatically disabled by running the following command:
$ sudo chage --inactive 30 USER Rationale:Inactive accounts pose a threat to system security since the users are not logging in to
notice failed login attempts or other anomalies. References:
DSS01.03, DSS03.05, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.10, 3.5.6, 4.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, SR 1.1, SR 1.10, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 6.2, A.12.4.1, A.12.4.3, A.18.1.4, A.6.1.2, A.7.1.1, A.9.1.2, A.9.2.1, A.9.2.2, A.9.2.3, A.9.2.4, A.9.2.6, A.9.3.1, A.9.4.1, A.9.4.2, A.9.4.3, A.9.4.4, A.9.4.5, CIP-004-6 R2.2.2, CIP-004-6 R2.2.3, CIP-007-3 R.1.3, CIP-007-3 R5, CIP-007-3 R5.1.1, CIP-007-3 R5.1.3, CIP-007-3 R5.2.1, CIP-007-3 R5.2.3, IA-4(e), AC-2(3), CM-6(a), DE.CM-1, DE.CM-3, PR.AC-1, PR.AC-4, PR.AC-6, PR.AC-7, Req-8.1.4, SRG-OS-000118-GPOS-00060, 8.2.6, 8.2 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- NIST-800-171-3.5.6
- NIST-800-53-AC-2(3)
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-4(e)
- PCI-DSS-Req-8.1.4
- PCI-DSSv4-8.2
- PCI-DSSv4-8.2.6
- accounts_set_post_pw_existing
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: XCCDF Value var_account_disable_post_pw_expiration # promote to variable
set_fact:
var_account_disable_post_pw_expiration: !!str 30
tags:
- always
- name: Collect users with not correct INACTIVE parameter set
ansible.builtin.command:
cmd: awk -F':' '(($7 > {{ var_account_disable_post_pw_expiration }} || $7 == "")
&& $2 ~ /^\$/) {print $1}' /etc/shadow
register: user_names
changed_when: false
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-171-3.5.6
- NIST-800-53-AC-2(3)
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-4(e)
- PCI-DSS-Req-8.1.4
- PCI-DSSv4-8.2
- PCI-DSSv4-8.2.6
- accounts_set_post_pw_existing
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Change the period of inactivity
ansible.builtin.command:
cmd: chage --inactive {{ var_account_disable_post_pw_expiration }} {{ item }}
with_items: '{{ user_names.stdout_lines }}'
when:
- '"kernel" in ansible_facts.packages'
- user_names is not skipped and user_names.stdout_lines | length > 0
tags:
- NIST-800-171-3.5.6
- NIST-800-53-AC-2(3)
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-4(e)
- PCI-DSS-Req-8.1.4
- PCI-DSSv4-8.2
- PCI-DSSv4-8.2.6
- accounts_set_post_pw_existing
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel; then
var_account_disable_post_pw_expiration='30'
while IFS= read -r i; do
chage --inactive $var_account_disable_post_pw_expiration $i
done < <(awk -v var="$var_account_disable_post_pw_expiration" -F: '(($7 > var || $7 == "") && $2 ~ /^\$/) {print $1}' /etc/shadow)
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Verify Proper Storage and Existence of Password
Hashes
[ref]groupBy default, password hashes for local accounts are stored
in the second field (colon-separated) in
/etc/shadow. This file should be readable only by
processes running with root credentials, preventing users from
casually accessing others' password hashes and attempting
to crack them.
However, it remains possible to misconfigure the system
and store password hashes
in world-readable files such as /etc/passwd, or
to even store passwords themselves in plaintext on the system.
Using system-provided tools for password change/creation
should allow administrators to avoid such misconfiguration. |
| contains 3 rules |
Ensure all users last password change date is in the past
[ref]ruleAll 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. |
Verify No .forward Files Exist
[ref]ruleThe .forward file specifies an email address to forward the user's mail to. Rationale:Use of the .forward file poses a security risk in that sensitive data may
be inadvertently transferred outside the organization. The .forward file
also poses a risk as it can be used to execute commands that may perform
unintended actions. |
Verify No netrc Files Exist
[ref]ruleThe .netrc files contain login information
used to auto-login into FTP servers and reside in the user's home
directory. These files may contain unencrypted passwords to
remote FTP servers making them susceptible to access by unauthorized
users and should not be used. Any .netrc files should be removed. Rationale:Unencrypted passwords for remote FTP servers may be stored in .netrc
files. References:
1, 11, 12, 14, 15, 16, 18, 3, 5, DSS05.02, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.06, DSS06.10, 4.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, A.18.1.4, A.6.1.2, A.7.1.1, A.9.1.2, A.9.2.1, A.9.2.2, A.9.2.3, A.9.2.4, A.9.2.6, A.9.3.1, A.9.4.1, A.9.4.2, A.9.4.3, A.9.4.4, A.9.4.5, CIP-003-8 R1.3, CIP-003-8 R3, CIP-003-8 R3.1, CIP-003-8 R3.2, CIP-003-8 R3.3, CIP-003-8 R5.1.1, CIP-003-8 R5.3, CIP-004-6 R2.2.3, CIP-004-6 R2.3, CIP-007-3 R5.1, CIP-007-3 R5.1.2, CIP-007-3 R5.2, CIP-007-3 R5.3.1, CIP-007-3 R5.3.2, CIP-007-3 R5.3.3, IA-5(h), IA-5(1)(c), CM-6(a), IA-5(7), PR.AC-1, PR.AC-4, PR.AC-6, PR.AC-7, PR.PT-3 |
Restrict Root Logins
[ref]groupDirect 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. |
| contains 2 rules |
Verify Root Has A Primary GID 0
[ref]ruleThe root user should have a primary group of 0. Rationale:To help ensure that root-owned files are not inadvertently exposed to other users. |
Ensure that System Accounts Do Not Run a Shell Upon Login
[ref]ruleSome 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. References:
1, 12, 13, 14, 15, 16, 18, 3, 5, 7, 8, DSS01.03, DSS03.05, DSS05.04, DSS05.05, DSS05.07, DSS06.03, 4.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, SR 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, A.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, AC-6, CM-6(a), CM-6(b), CM-6.1(iv), DE.CM-1, DE.CM-3, PR.AC-1, PR.AC-4, PR.AC-6, SRG-OS-000480-GPOS-00227, 1491, 8.2.2, 8.2 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | medium |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
- name: Gather the package facts
package_facts:
manager: auto
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 - Get All Local
Users From /etc/passwd
ansible.builtin.getent:
database: passwd
split: ':'
when: '"kernel" in ansible_facts.packages'
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 }}'
when: '"kernel" in ansible_facts.packages'
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:
- '"kernel" in ansible_facts.packages'
- 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
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | medium |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel; then
readarray -t systemaccounts < <(awk -F: '($3 < 1000 && $1 != "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
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Ensure All Accounts on the System Have Unique User IDs
[ref]ruleChange user IDs (UIDs), or delete accounts, so each has a unique name. Warning:
Automatic remediation of this control is not available due to unique requirements of each
system. Rationale:To assure accountability and prevent unauthenticated access, interactive users must be identified and authenticated to prevent potential misuse and compromise of the system. |
Ensure All Groups on the System Have Unique Group ID
[ref]ruleChange 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. |
Ensure All Groups on the System Have Unique Group Names
[ref]ruleChange 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. |
Secure Session Configuration Files for Login Accounts
[ref]groupWhen 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. |
| contains 5 rules |
Ensure that Users Have Sensible Umask Values
[ref]groupThe 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.
|
| contains 1 rule |
Ensure the Default Bash Umask is Set Correctly
[ref]ruleTo ensure the default umask for users of the Bash shell is set properly,
add or correct the umask setting in /etc/bashrc to read
as follows:
umask 027 Rationale:The umask value influences the permissions assigned to files when they are created.
A misconfigured umask value could result in files with excessive permissions that can be read or
written to by unauthorized users. References:
18, APO13.01, BAI03.01, BAI03.02, BAI03.03, 4.3.4.3.3, A.14.1.1, A.14.2.1, A.14.2.5, A.6.1.5, CIP-003-8 R5.1.1, CIP-003-8 R5.3, CIP-004-6 R2.3, CIP-007-3 R2.1, CIP-007-3 R2.2, CIP-007-3 R2.3, CIP-007-3 R5.1, CIP-007-3 R5.1.1, CIP-007-3 R5.1.2, AC-6(1), CM-6(a), PR.IP-2, SRG-OS-000480-GPOS-00228, SRG-OS-000480-GPOS-00227, R36 Remediation Ansible snippet: (show)
| 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/bashrc is already set
ansible.builtin.lineinfile:
path: /etc/bashrc
regexp: ^[^#]*\bumask\s+\d+$
state: absent
check_mode: true
changed_when: false
register: umask_replace
when:
- '"kernel" in ansible_facts.packages'
- '"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/bashrc
ansible.builtin.replace:
path: /etc/bashrc
regexp: ^([^#]*\b)umask\s+\d+$
replace: \g<1>umask {{ var_accounts_user_umask }}
when:
- '"kernel" in ansible_facts.packages'
- '"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/bashrc
line: umask {{ var_accounts_user_umask }}
when:
- '"kernel" in ansible_facts.packages'
- '"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 Shell script: (show)
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel && { rpm --quiet -q bash; }; then
var_accounts_user_umask='027'
grep -q "^[^#]*\bumask" /etc/bashrc && \
sed -i -E -e "s/^([^#]*\bumask)[[:space:]]+[[:digit:]]+/\1 $var_accounts_user_umask/g" /etc/bashrc
if ! [ $? -eq 0 ]; then
echo "umask $var_accounts_user_umask" >> /etc/bashrc
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Set Interactive Session Timeout
[ref]ruleSetting the TMOUT option in /etc/profile ensures that
all user sessions will terminate based on inactivity. A value of 0 (zero)
disables the automatic logout feature and is therefore not a compliant setting.
The value of TMOUT should be a positive integer, exported, and read only.
The TMOUT
setting in a file loaded by /etc/profile, e.g.
/etc/profile.d/tmout.sh should read as follows:
typeset -xr TMOUT=900
or
declare -xr TMOUT=900
Using the typeset keyword is preferred for wider compatibility with ksh and other shells.Rationale:Terminating an idle session within a short time period reduces
the window of opportunity for unauthorized personnel to take control of a
management session enabled on the console or console port that has been
left unattended. References:
1, 12, 15, 16, DSS05.04, DSS05.10, DSS06.10, 3.1.11, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, SR 1.1, SR 1.10, SR 1.2, SR 1.5, SR 1.7, SR 1.8, SR 1.9, A.18.1.4, A.9.2.1, A.9.2.4, A.9.3.1, A.9.4.2, A.9.4.3, CIP-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, AC-12, SC-10, AC-2(5), CM-6(a), PR.AC-7, SRG-OS-000163-GPOS-00072, SRG-OS-000029-GPOS-00010, R32, 8.6.1, 8.6 Remediation Ansible snippet: (show)
| 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
ansible.builtin.replace:
path: /etc/profile
regexp: ^[^#].*TMOUT=.*
replace: typeset -xr TMOUT={{ var_accounts_tmout }}
register: profile_replaced
when: '"kernel" 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
ansible.builtin.lineinfile:
path: /etc/profile.d/tmout.sh
create: true
regexp: TMOUT=
line: typeset -xr TMOUT={{ var_accounts_tmout }}
state: present
when: '"kernel" 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 Shell script: (show)
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel; then
var_accounts_tmout='900'
# if 0, no occurrence of tmout found, if 1, occurrence found
tmout_found=0
for f in /etc/profile /etc/profile.d/*.sh; do
if grep --silent '^[^#].*TMOUT' $f; then
sed -i -E "s/^(.*)TMOUT\s*=\s*(\w|\$)*(.*)$/typeset -xr TMOUT=$var_accounts_tmout\3/g" $f
tmout_found=1
fi
done
if [ $tmout_found -eq 0 ]; then
echo -e "\n# Set TMOUT to $var_accounts_tmout per security requirements" >> /etc/profile.d/tmout.sh
echo "typeset -xr TMOUT=$var_accounts_tmout" >> /etc/profile.d/tmout.sh
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
All Interactive Users Home Directories Must Exist
[ref]ruleCreate 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. Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- accounts_user_interactive_home_directory_exists
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Get all local users from /etc/passwd
ansible.builtin.getent:
database: passwd
split: ':'
when: '"kernel" in ansible_facts.packages'
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 }}'
when: '"kernel" in ansible_facts.packages'
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:
- '"kernel" in ansible_facts.packages'
- item.value[1]|int >= 1000
- item.value[1]|int != 65534
tags:
- accounts_user_interactive_home_directory_exists
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel; then
for user in $(awk -F':' '{ if ($3 >= 1000 && $3 != 65534) print $1}' /etc/passwd); do
mkhomedir_helper $user 0077;
done
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
All User Files and Directories In The Home Directory Must Have Mode 0750 Or Less Permissive
[ref]ruleSet the mode on files and directories in the local interactive user home
directory with the following command:
$ sudo chmod 0750 /home/USER/FILE_DIR
Files that begin with a "." are excluded from this requirement.Rationale:If a local interactive user files have excessive permissions, unintended users
may be able to access or modify them. Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- accounts_users_home_files_permissions
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Get all local users from /etc/passwd
ansible.builtin.getent:
database: passwd
split: ':'
when: '"kernel" in ansible_facts.packages'
tags:
- accounts_users_home_files_permissions
- 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 }}'
when: '"kernel" in ansible_facts.packages'
tags:
- accounts_users_home_files_permissions
- 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:
- '"kernel" in ansible_facts.packages'
- item.value[1]|int >= 1000
- item.value[1]|int != 65534
- item.value[4] != "/"
tags:
- accounts_users_home_files_permissions
- 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: true
loop: '{{ local_users|zip(path_exists.results)|list }}'
when:
- '"kernel" in ansible_facts.packages'
- item.1.stat is defined and item.1.stat.exists
tags:
- accounts_users_home_files_permissions
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel; then
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" -perm /7027 \! -type l -exec chmod u-s,g-w-s,o=- {} \;
done
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
All Interactive User Home Directories Must Have mode 0750 Or Less Permissive
[ref]ruleChange 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. Remediation Ansible snippet: (show)
| 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
Remediation Shell script: (show)
| 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
|
Configure Syslog
[ref]groupThe 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 TencentOS Server 4, rsyslog has replaced ksyslogd as the
syslog daemon of choice, and it includes some additional security features
such as reliable, connection-oriented (i.e. TCP) transmission of logs, the
option to log to database formats, and the encryption of log data en route to
a central logging server.
This section discusses how to configure rsyslog for
best effect, and how to use tools provided with the system to maintain and
monitor logs. |
| contains 1 rule |
Ensure rsyslog is Installed
[ref]ruleRsyslog is installed by default. The rsyslog package can be installed with the following command: $ sudo dnf install rsyslog Rationale:The rsyslog package provides the rsyslog daemon, which provides
system logging services. References:
1, 14, 15, 16, 3, 5, 6, APO11.04, BAI03.05, DSS05.04, DSS05.07, MEA02.01, 164.312(a)(2)(ii), 4.3.3.3.9, 4.3.3.5.8, 4.3.4.4.7, 4.4.2.1, 4.4.2.2, 4.4.2.4, SR 2.10, SR 2.11, SR 2.12, SR 2.8, SR 2.9, A.12.4.1, A.12.4.2, A.12.4.3, A.12.4.4, A.12.7.1, CM-6(a), PR.PT-1, SRG-OS-000479-GPOS-00224, SRG-OS-000051-GPOS-00024, SRG-OS-000480-GPOS-00227, 1409 Remediation Puppet snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | enable |
|---|
include install_rsyslog
class install_rsyslog {
package { 'rsyslog':
ensure => 'installed',
}
}
Remediation script: (show)
[[packages]]
name = "rsyslog"
version = "*"
Remediation Ansible snippet: (show)
| 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
ansible.builtin.package:
name: rsyslog
state: present
when: '"kernel" 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
|
Network Configuration and Firewalls
[ref]groupMost 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. |
| contains 24 rules |
firewalld
[ref]groupThe dynamic firewall daemon firewalld provides a
dynamically managed firewall with support for network “zones” to assign
a level of trust to a network and its associated connections and interfaces.
It has support for IPv4 and IPv6 firewall settings. It supports Ethernet
bridges and has a separation of runtime and permanent configuration options.
It also has an interface for services or applications to add firewall rules
directly.
A graphical configuration tool, firewall-config, is used to configure
firewalld, which in turn uses iptables tool to communicate
with Netfilter in the kernel which implements packet filtering.
The firewall service provided by firewalld is dynamic rather than
static because changes to the configuration can be made at anytime and are
immediately implemented. There is no need to save or apply the changes. No
unintended disruption of existing network connections occurs as no part of
the firewall has to be reloaded. |
| contains 1 rule |
Inspect and Activate Default firewalld Rules
[ref]groupFirewalls can be used to separate networks into different zones
based on the level of trust the user has decided to place on the devices and
traffic within that network. NetworkManager informs firewalld to which
zone an interface belongs. An interface's assigned zone can be changed by
NetworkManager or via the firewall-config tool.
The zone settings in /etc/firewalld/ are a range of preset settings
which can be quickly applied to a network interface. These are the zones
provided by firewalld sorted according to the default trust level of the
zones from untrusted to trusted:
drop
Any incoming network packets are dropped, there is no
reply. Only outgoing network connections are possible. block
Any incoming network connections are rejected with an
icmp-host-prohibited message for IPv4 and icmp6-adm-prohibited
for IPv6. Only network connections initiated from within the system are
possible. public
For use in public areas. You do not trust the other
computers on the network to not harm your computer. Only selected incoming
connections are accepted. external
For use on external networks with masquerading enabled
especially for routers. You do not trust the other computers on the network to
not harm your computer. Only selected incoming connections are accepted. dmz
For computers in your demilitarized zone that are
publicly-accessible with limited access to your internal network. Only selected
incoming connections are accepted. work
For use in work areas. You mostly trust the other computers
on networks to not harm your computer. Only selected incoming connections are
accepted. home
For use in home areas. You mostly trust the other computers
on networks to not harm your computer. Only selected incoming connections are
accepted. internal
For use on internal networks. You mostly trust the
other computers on the networks to not harm your computer. Only selected
incoming connections are accepted. trusted
All network connections are accepted.
It is possible to designate one of these zones to be the default zone. When
interface connections are added to NetworkManager, they are assigned
to the default zone. On installation, the default zone in firewalld is set to
be the public zone.
To find out all the settings of a zone, for example the public zone,
enter the following command as root:
# firewall-cmd --zone=public --list-all
Example output of this command might look like the following:
# firewall-cmd --zone=public --list-all
public
interfaces:
services: mdns dhcpv6-client ssh
ports:
forward-ports:
icmp-blocks: source-quench
To view the network zones currently active, enter the following command as root:
# firewall-cmd --get-service
The following listing displays the result of this command
on common TencentOS Server 4 system:
# firewall-cmd --get-service
amanda-client bacula bacula-client dhcp dhcpv6 dhcpv6-client dns ftp
high-availability http https imaps ipp ipp-client ipsec kerberos kpasswd
ldap ldaps libvirt libvirt-tls mdns mountd ms-wbt mysql nfs ntp openvpn
pmcd pmproxy pmwebapi pmwebapis pop3s postgresql proxy-dhcp radius rpc-bind
samba samba-client smtp ssh telnet tftp tftp-client transmission-client
vnc-server wbem-https
Finally to view the network zones that will be active after the next firewalld
service reload, enter the following command as root:
# firewall-cmd --get-service --permanent |
| contains 1 rule |
Install firewalld Package
[ref]ruleThe firewalld package can be installed with the following command:
$ sudo dnf install firewalld Rationale:"Firewalld" provides an easy and effective way to block/limit remote access to the system via ports, services, and protocols.
Remote access services, such as those providing remote access to network devices and information systems, which lack automated control capabilities, increase risk and make remote user access management difficult at best.
Remote access is access to nonpublic information systems by an authorized user (or an information system) communicating through an external, non-organization-controlled network. Remote access methods include, for example, dial-up, broadband, and wireless.
TencentOS Server 4 functionality (e.g., SSH) must be capable of taking enforcement action if the audit reveals unauthorized activity.
Automated control of remote access sessions allows organizations to ensure ongoing compliance with remote access policies by enforcing connection rules of remote access applications on a variety of information system components (e.g., servers, workstations, notebook computers, smartphones, and tablets)." Remediation Puppet snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | enable |
|---|
include install_firewalld
class install_firewalld {
package { 'firewalld':
ensure => 'installed',
}
}
Remediation script: (show)
[[packages]]
name = "firewalld"
version = "*"
Remediation Ansible snippet: (show)
| 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-1.2
- PCI-DSSv4-1.2.1
- enable_strategy
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- package_firewalld_installed
- name: Ensure firewalld is installed
ansible.builtin.package:
name: firewalld
state: present
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-CM-6(a)
- PCI-DSSv4-1.2
- PCI-DSSv4-1.2.1
- enable_strategy
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- package_firewalld_installed
|
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. |
| contains 7 rules |
Configure IPv6 Settings if Necessary
[ref]groupA 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. |
| contains 7 rules |
Configure Accepting Router Advertisements on All IPv6 Interfaces
[ref]ruleTo 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. References:
11, 14, 3, 9, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.05, DSS06.06, 3.1.20, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 7.6, A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, A.9.1.2, CM-7(a), CM-7(b), CM-6(a), PR.IP-1, PR.PT-3, SRG-OS-000480-GPOS-00227 Remediation Ansible snippet: (show)
| 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: 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: Configure Accepting Router Advertisements on All IPv6 Interfaces - Set fact
for sysctl paths
ansible.builtin.set_fact:
sysctl_paths:
- /etc/sysctl.d/
- /run/sysctl.d/
- /usr/local/lib/sysctl.d/
- /usr/lib/sysctl.d/
when: '"kernel" 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: Configure Accepting Router Advertisements on All IPv6 Interfaces - Find all
files that contain net.ipv6.conf.all.accept_ra
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*net.ipv6.conf.all.accept_ra\s*=\s*.*$'
register: find_all_values
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" 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: Configure Accepting Router Advertisements on All IPv6 Interfaces - Find all
files that set net.ipv6.conf.all.accept_ra to correct value
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*net.ipv6.conf.all.accept_ra\s*=\s*{{ sysctl_net_ipv6_conf_all_accept_ra_value
}}$'
register: find_correct_value
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" 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: Configure Accepting Router Advertisements on All IPv6 Interfaces - Comment
out any occurrences of net.ipv6.conf.all.accept_ra from config files
ansible.builtin.replace:
path: '{{ item | split(":") | first }}'
regexp: ^[\s]*net.ipv6.conf.all.accept_ra
replace: '#net.ipv6.conf.all.accept_ra'
loop: '{{ find_all_values.stdout_lines }}'
when:
- '"kernel" in ansible_facts.packages'
- find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
| length > find_correct_value.stdout_lines | length
tags:
- NIST-800-171-3.1.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: Configure Accepting Router Advertisements on All IPv6 Interfaces - Ensure
sysctl net.ipv6.conf.all.accept_ra is set
ansible.posix.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: '"kernel" 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
|
Disable Accepting ICMP Redirects for All IPv6 Interfaces
[ref]ruleTo 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. References:
11, 14, 3, 9, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.05, DSS06.06, 3.1.20, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 7.6, A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, A.9.1.2, CM-7(a), CM-7(b), CM-6(a), CM-6(b), CM-6.1(iv), PR.IP-1, PR.PT-3, SRG-OS-000480-GPOS-00227, R13 Remediation Ansible snippet: (show)
| 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: 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: Disable Accepting ICMP Redirects for All IPv6 Interfaces - Set fact for sysctl
paths
ansible.builtin.set_fact:
sysctl_paths:
- /etc/sysctl.d/
- /run/sysctl.d/
- /usr/local/lib/sysctl.d/
- /usr/lib/sysctl.d/
when: '"kernel" 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: Disable Accepting ICMP Redirects for All IPv6 Interfaces - Find all files
that contain net.ipv6.conf.all.accept_redirects
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*net.ipv6.conf.all.accept_redirects\s*=\s*.*$'
register: find_all_values
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" 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: Disable Accepting ICMP Redirects for All IPv6 Interfaces - Find all files
that set net.ipv6.conf.all.accept_redirects to correct value
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*net.ipv6.conf.all.accept_redirects\s*=\s*{{ sysctl_net_ipv6_conf_all_accept_redirects_value
}}$'
register: find_correct_value
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" 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: Disable Accepting ICMP Redirects for All IPv6 Interfaces - Comment out any
occurrences of net.ipv6.conf.all.accept_redirects from config files
ansible.builtin.replace:
path: '{{ item | split(":") | first }}'
regexp: ^[\s]*net.ipv6.conf.all.accept_redirects
replace: '#net.ipv6.conf.all.accept_redirects'
loop: '{{ find_all_values.stdout_lines }}'
when:
- '"kernel" in ansible_facts.packages'
- find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
| length > find_correct_value.stdout_lines | length
tags:
- NIST-800-171-3.1.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: Disable Accepting ICMP Redirects for All IPv6 Interfaces - Ensure sysctl net.ipv6.conf.all.accept_redirects
is set
ansible.posix.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: '"kernel" 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
|
Disable Kernel Parameter for Accepting Source-Routed Packets on all IPv6 Interfaces
[ref]ruleTo 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. References:
1, 12, 13, 14, 15, 16, 18, 4, 6, 8, 9, APO01.06, APO13.01, DSS01.05, DSS03.01, DSS05.02, DSS05.04, DSS05.07, DSS06.02, 3.1.20, 4.2.3.4, 4.3.3.4, 4.4.3.3, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 7.1, SR 7.6, A.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, CM-7(a), CM-7(b), CM-6(a), DE.AE-1, ID.AM-3, PR.AC-5, PR.DS-5, PR.PT-4, SRG-OS-000480-GPOS-00227, R13 Remediation Ansible snippet: (show)
| 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: 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: Disable Kernel Parameter for Accepting Source-Routed Packets on all IPv6 Interfaces
- Set fact for sysctl paths
ansible.builtin.set_fact:
sysctl_paths:
- /etc/sysctl.d/
- /run/sysctl.d/
- /usr/local/lib/sysctl.d/
- /usr/lib/sysctl.d/
when: '"kernel" 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: Disable Kernel Parameter for Accepting Source-Routed Packets on all IPv6 Interfaces
- Find all files that contain net.ipv6.conf.all.accept_source_route
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*net.ipv6.conf.all.accept_source_route\s*=\s*.*$'
register: find_all_values
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" 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: Disable Kernel Parameter for Accepting Source-Routed Packets on all IPv6 Interfaces
- Find all files that set net.ipv6.conf.all.accept_source_route to correct value
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*net.ipv6.conf.all.accept_source_route\s*=\s*{{ sysctl_net_ipv6_conf_all_accept_source_route_value
}}$'
register: find_correct_value
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" 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: Disable Kernel Parameter for Accepting Source-Routed Packets on all IPv6 Interfaces
- Comment out any occurrences of net.ipv6.conf.all.accept_source_route from config
files
ansible.builtin.replace:
path: '{{ item | split(":") | first }}'
regexp: ^[\s]*net.ipv6.conf.all.accept_source_route
replace: '#net.ipv6.conf.all.accept_source_route'
loop: '{{ find_all_values.stdout_lines }}'
when:
- '"kernel" in ansible_facts.packages'
- find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
| length > find_correct_value.stdout_lines | length
tags:
- NIST-800-171-3.1.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: Disable Kernel Parameter for Accepting Source-Routed Packets on all IPv6 Interfaces
- Ensure sysctl net.ipv6.conf.all.accept_source_route is set
ansible.posix.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: '"kernel" 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
|
Disable Kernel Parameter for IPv6 Forwarding
[ref]ruleTo 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. References:
1, 11, 12, 13, 14, 15, 16, 2, 3, 7, 8, 9, APO13.01, BAI04.04, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS01.03, DSS03.05, DSS05.02, DSS05.05, DSS05.07, DSS06.06, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 6.2, SR 7.1, SR 7.2, SR 7.6, A.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, CM-7(a), CM-7(b), CM-6(a), CM-6(b), CM-6.1(iv), DE.CM-1, PR.DS-4, PR.IP-1, PR.PT-3, SRG-OS-000480-GPOS-00227 Remediation Ansible snippet: (show)
| 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: 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: Disable Kernel Parameter for IPv6 Forwarding - Set fact for sysctl paths
ansible.builtin.set_fact:
sysctl_paths:
- /etc/sysctl.d/
- /run/sysctl.d/
- /usr/local/lib/sysctl.d/
- /usr/lib/sysctl.d/
when: '"kernel" 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: Disable Kernel Parameter for IPv6 Forwarding - Find all files that contain
net.ipv6.conf.all.forwarding
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*net.ipv6.conf.all.forwarding\s*=\s*.*$'
register: find_all_values
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" 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: Disable Kernel Parameter for IPv6 Forwarding - Find all files that set net.ipv6.conf.all.forwarding
to correct value
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*net.ipv6.conf.all.forwarding\s*=\s*{{ sysctl_net_ipv6_conf_all_forwarding_value
}}$'
register: find_correct_value
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" 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: Disable Kernel Parameter for IPv6 Forwarding - Comment out any occurrences
of net.ipv6.conf.all.forwarding from config files
ansible.builtin.replace:
path: '{{ item | split(":") | first }}'
regexp: ^[\s]*net.ipv6.conf.all.forwarding
replace: '#net.ipv6.conf.all.forwarding'
loop: '{{ find_all_values.stdout_lines }}'
when:
- '"kernel" in ansible_facts.packages'
- find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
| length > find_correct_value.stdout_lines | length
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-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: Disable Kernel Parameter for IPv6 Forwarding - Ensure sysctl net.ipv6.conf.all.forwarding
is set
ansible.posix.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: '"kernel" 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
|
Disable Accepting Router Advertisements on all IPv6 Interfaces by Default
[ref]ruleTo 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. References:
11, 14, 3, 9, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.05, DSS06.06, 3.1.20, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 7.6, A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, A.9.1.2, CM-7(a), CM-7(b), CM-6(a), PR.IP-1, PR.PT-3, SRG-OS-000480-GPOS-00227 Remediation Ansible snippet: (show)
| 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: 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: Disable Accepting Router Advertisements on all IPv6 Interfaces by Default
- Set fact for sysctl paths
ansible.builtin.set_fact:
sysctl_paths:
- /etc/sysctl.d/
- /run/sysctl.d/
- /usr/local/lib/sysctl.d/
- /usr/lib/sysctl.d/
when: '"kernel" 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: Disable Accepting Router Advertisements on all IPv6 Interfaces by Default
- Find all files that contain net.ipv6.conf.default.accept_ra
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*net.ipv6.conf.default.accept_ra\s*=\s*.*$'
register: find_all_values
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" 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: Disable Accepting Router Advertisements on all IPv6 Interfaces by Default
- Find all files that set net.ipv6.conf.default.accept_ra to correct value
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*net.ipv6.conf.default.accept_ra\s*=\s*{{ sysctl_net_ipv6_conf_default_accept_ra_value
}}$'
register: find_correct_value
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" 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: Disable Accepting Router Advertisements on all IPv6 Interfaces by Default
- Comment out any occurrences of net.ipv6.conf.default.accept_ra from config files
ansible.builtin.replace:
path: '{{ item | split(":") | first }}'
regexp: ^[\s]*net.ipv6.conf.default.accept_ra
replace: '#net.ipv6.conf.default.accept_ra'
loop: '{{ find_all_values.stdout_lines }}'
when:
- '"kernel" in ansible_facts.packages'
- find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
| length > find_correct_value.stdout_lines | length
tags:
- NIST-800-171-3.1.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: Disable Accepting Router Advertisements on all IPv6 Interfaces by Default
- Ensure sysctl net.ipv6.conf.default.accept_ra is set
ansible.posix.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: '"kernel" 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
|
Disable Kernel Parameter for Accepting ICMP Redirects by Default on IPv6 Interfaces
[ref]ruleTo 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. References:
11, 14, 3, 9, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.05, DSS06.06, 3.1.20, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 7.6, A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, A.9.1.2, CM-7(a), CM-7(b), CM-6(a), PR.IP-1, PR.PT-3, SRG-OS-000480-GPOS-00227, R13 Remediation Ansible snippet: (show)
| 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: 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: Disable Kernel Parameter for Accepting ICMP Redirects by Default on IPv6 Interfaces
- Set fact for sysctl paths
ansible.builtin.set_fact:
sysctl_paths:
- /etc/sysctl.d/
- /run/sysctl.d/
- /usr/local/lib/sysctl.d/
- /usr/lib/sysctl.d/
when: '"kernel" 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: Disable Kernel Parameter for Accepting ICMP Redirects by Default on IPv6 Interfaces
- Find all files that contain net.ipv6.conf.default.accept_redirects
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*net.ipv6.conf.default.accept_redirects\s*=\s*.*$'
register: find_all_values
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" 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: Disable Kernel Parameter for Accepting ICMP Redirects by Default on IPv6 Interfaces
- Find all files that set net.ipv6.conf.default.accept_redirects to correct value
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*net.ipv6.conf.default.accept_redirects\s*=\s*{{ sysctl_net_ipv6_conf_default_accept_redirects_value
}}$'
register: find_correct_value
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" 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: Disable Kernel Parameter for Accepting ICMP Redirects by Default on IPv6 Interfaces
- Comment out any occurrences of net.ipv6.conf.default.accept_redirects from config
files
ansible.builtin.replace:
path: '{{ item | split(":") | first }}'
regexp: ^[\s]*net.ipv6.conf.default.accept_redirects
replace: '#net.ipv6.conf.default.accept_redirects'
loop: '{{ find_all_values.stdout_lines }}'
when:
- '"kernel" in ansible_facts.packages'
- find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
| length > find_correct_value.stdout_lines | length
tags:
- NIST-800-171-3.1.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: Disable Kernel Parameter for Accepting ICMP Redirects by Default on IPv6 Interfaces
- Ensure sysctl net.ipv6.conf.default.accept_redirects is set
ansible.posix.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: '"kernel" 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
|
Disable Kernel Parameter for Accepting Source-Routed Packets on IPv6 Interfaces by Default
[ref]ruleTo 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. References:
1, 12, 13, 14, 15, 16, 18, 4, 6, 8, 9, APO01.06, APO13.01, DSS01.05, DSS03.01, DSS05.02, DSS05.04, DSS05.07, DSS06.02, 3.1.20, 4.2.3.4, 4.3.3.4, 4.4.3.3, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 7.1, SR 7.6, A.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, CM-7(a), CM-7(b), CM-6(a), CM-6(b), CM-6.1(iv), DE.AE-1, ID.AM-3, PR.AC-5, PR.DS-5, PR.PT-4, Req-1.4.3, SRG-OS-000480-GPOS-00227, R13, 1.4.2, 1.4 Remediation Ansible snippet: (show)
| 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: 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: Disable Kernel Parameter for Accepting Source-Routed Packets on IPv6 Interfaces
by Default - Set fact for sysctl paths
ansible.builtin.set_fact:
sysctl_paths:
- /etc/sysctl.d/
- /run/sysctl.d/
- /usr/local/lib/sysctl.d/
- /usr/lib/sysctl.d/
when: '"kernel" 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: Disable Kernel Parameter for Accepting Source-Routed Packets on IPv6 Interfaces
by Default - Find all files that contain net.ipv6.conf.default.accept_source_route
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*net.ipv6.conf.default.accept_source_route\s*=\s*.*$'
register: find_all_values
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" 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: Disable Kernel Parameter for Accepting Source-Routed Packets on IPv6 Interfaces
by Default - Find all files that set net.ipv6.conf.default.accept_source_route
to correct value
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*net.ipv6.conf.default.accept_source_route\s*=\s*{{ sysctl_net_ipv6_conf_default_accept_source_route_value
}}$'
register: find_correct_value
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" 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: Disable Kernel Parameter for Accepting Source-Routed Packets on IPv6 Interfaces
by Default - Comment out any occurrences of net.ipv6.conf.default.accept_source_route
from config files
ansible.builtin.replace:
path: '{{ item | split(":") | first }}'
regexp: ^[\s]*net.ipv6.conf.default.accept_source_route
replace: '#net.ipv6.conf.default.accept_source_route'
loop: '{{ find_all_values.stdout_lines }}'
when:
- '"kernel" in ansible_facts.packages'
- find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
| length > find_correct_value.stdout_lines | length
tags:
- NIST-800-171-3.1.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: Disable Kernel Parameter for Accepting Source-Routed Packets on IPv6 Interfaces
by Default - Ensure sysctl net.ipv6.conf.default.accept_source_route is set
ansible.posix.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: '"kernel" 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
|
Kernel Parameters Which Affect Networking
[ref]groupThe 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. |
| contains 16 rules |
Network Related Kernel Runtime Parameters for Hosts and Routers
[ref]groupCertain 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. |
| contains 13 rules |
Disable Accepting ICMP Redirects for All IPv4 Interfaces
[ref]ruleTo 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." References:
1, 11, 12, 13, 14, 15, 16, 2, 3, 7, 8, 9, 5.10.1.1, APO13.01, BAI04.04, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS01.03, DSS03.05, DSS05.02, DSS05.05, DSS05.07, DSS06.06, 3.1.20, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 6.2, SR 7.1, SR 7.2, SR 7.6, A.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, CM-7(a), CM-7(b), CM-6(a), SC-7(a), DE.CM-1, PR.DS-4, PR.IP-1, PR.PT-3, SRG-OS-000480-GPOS-00227, R12 Remediation Ansible snippet: (show)
| 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: 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: Disable Accepting ICMP Redirects for All IPv4 Interfaces - Set fact for sysctl
paths
ansible.builtin.set_fact:
sysctl_paths:
- /etc/sysctl.d/
- /run/sysctl.d/
- /usr/local/lib/sysctl.d/
- /usr/lib/sysctl.d/
when: '"kernel" 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: Disable Accepting ICMP Redirects for All IPv4 Interfaces - Find all files
that contain net.ipv4.conf.all.accept_redirects
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*net.ipv4.conf.all.accept_redirects\s*=\s*.*$'
register: find_all_values
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" 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: Disable Accepting ICMP Redirects for All IPv4 Interfaces - Find all files
that set net.ipv4.conf.all.accept_redirects to correct value
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*net.ipv4.conf.all.accept_redirects\s*=\s*{{ sysctl_net_ipv4_conf_all_accept_redirects_value
}}$'
register: find_correct_value
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" 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: Disable Accepting ICMP Redirects for All IPv4 Interfaces - Comment out any
occurrences of net.ipv4.conf.all.accept_redirects from config files
ansible.builtin.replace:
path: '{{ item | split(":") | first }}'
regexp: ^[\s]*net.ipv4.conf.all.accept_redirects
replace: '#net.ipv4.conf.all.accept_redirects'
loop: '{{ find_all_values.stdout_lines }}'
when:
- '"kernel" in ansible_facts.packages'
- find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
| length > find_correct_value.stdout_lines | length
tags:
- 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: Disable Accepting ICMP Redirects for All IPv4 Interfaces - Ensure sysctl net.ipv4.conf.all.accept_redirects
is set
ansible.posix.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: '"kernel" 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
|
Disable Kernel Parameter for Accepting Source-Routed Packets on all IPv4 Interfaces
[ref]ruleTo 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. References:
1, 11, 12, 13, 14, 15, 16, 18, 2, 3, 4, 6, 7, 8, 9, APO01.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, 3.1.20, 4.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, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 6.2, SR 7.1, SR 7.2, SR 7.6, A.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, CIP-007-3 R4, CIP-007-3 R4.1, CIP-007-3 R4.2, CIP-007-3 R5.1, CM-7(a), CM-7(b), SC-5, CM-6(a), SC-7(a), DE.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, SRG-OS-000480-GPOS-00227, R12 Remediation Ansible snippet: (show)
| 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: 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: Disable Kernel Parameter for Accepting Source-Routed Packets on all IPv4 Interfaces
- Set fact for sysctl paths
ansible.builtin.set_fact:
sysctl_paths:
- /etc/sysctl.d/
- /run/sysctl.d/
- /usr/local/lib/sysctl.d/
- /usr/lib/sysctl.d/
when: '"kernel" 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: Disable Kernel Parameter for Accepting Source-Routed Packets on all IPv4 Interfaces
- Find all files that contain net.ipv4.conf.all.accept_source_route
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*net.ipv4.conf.all.accept_source_route\s*=\s*.*$'
register: find_all_values
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" 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: Disable Kernel Parameter for Accepting Source-Routed Packets on all IPv4 Interfaces
- Find all files that set net.ipv4.conf.all.accept_source_route to correct value
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*net.ipv4.conf.all.accept_source_route\s*=\s*{{ sysctl_net_ipv4_conf_all_accept_source_route_value
}}$'
register: find_correct_value
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" 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: Disable Kernel Parameter for Accepting Source-Routed Packets on all IPv4 Interfaces
- Comment out any occurrences of net.ipv4.conf.all.accept_source_route from config
files
ansible.builtin.replace:
path: '{{ item | split(":") | first }}'
regexp: ^[\s]*net.ipv4.conf.all.accept_source_route
replace: '#net.ipv4.conf.all.accept_source_route'
loop: '{{ find_all_values.stdout_lines }}'
when:
- '"kernel" in ansible_facts.packages'
- find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
| length > find_correct_value.stdout_lines | length
tags:
- NIST-800-171-3.1.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: Disable Kernel Parameter for Accepting Source-Routed Packets on all IPv4 Interfaces
- Ensure sysctl net.ipv4.conf.all.accept_source_route is set
ansible.posix.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: '"kernel" 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
|
Enable Kernel Parameter to Log Martian Packets on all IPv4 Interfaces
[ref]ruleTo 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. References:
1, 11, 12, 13, 14, 15, 16, 2, 3, 7, 8, 9, APO13.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, 3.1.20, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 6.2, SR 7.1, SR 7.2, SR 7.6, A.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, CM-7(a), CM-7(b), SC-5(3)(a), DE.CM-1, PR.AC-3, PR.DS-4, PR.IP-1, PR.PT-3, PR.PT-4, SRG-OS-000480-GPOS-00227 Remediation Ansible snippet: (show)
| 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: 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: Enable Kernel Parameter to Log Martian Packets on all IPv4 Interfaces - Set
fact for sysctl paths
ansible.builtin.set_fact:
sysctl_paths:
- /etc/sysctl.d/
- /run/sysctl.d/
- /usr/local/lib/sysctl.d/
- /usr/lib/sysctl.d/
when: '"kernel" 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: Enable Kernel Parameter to Log Martian Packets on all IPv4 Interfaces - Find
all files that contain net.ipv4.conf.all.log_martians
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*net.ipv4.conf.all.log_martians\s*=\s*.*$'
register: find_all_values
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" 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: Enable Kernel Parameter to Log Martian Packets on all IPv4 Interfaces - Find
all files that set net.ipv4.conf.all.log_martians to correct value
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*net.ipv4.conf.all.log_martians\s*=\s*{{ sysctl_net_ipv4_conf_all_log_martians_value
}}$'
register: find_correct_value
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" 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: Enable Kernel Parameter to Log Martian Packets on all IPv4 Interfaces - Comment
out any occurrences of net.ipv4.conf.all.log_martians from config files
ansible.builtin.replace:
path: '{{ item | split(":") | first }}'
regexp: ^[\s]*net.ipv4.conf.all.log_martians
replace: '#net.ipv4.conf.all.log_martians'
loop: '{{ find_all_values.stdout_lines }}'
when:
- '"kernel" in ansible_facts.packages'
- find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
| length > find_correct_value.stdout_lines | length
tags:
- NIST-800-171-3.1.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: Enable Kernel Parameter to Log Martian Packets on all IPv4 Interfaces - Ensure
sysctl net.ipv4.conf.all.log_martians is set
ansible.posix.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: '"kernel" 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
|
Enable Kernel Parameter to Use Reverse Path Filtering on all IPv4 Interfaces
[ref]ruleTo 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. References:
1, 12, 13, 14, 15, 16, 18, 2, 4, 6, 7, 8, 9, APO01.06, APO13.01, BAI04.04, DSS01.03, DSS01.05, DSS03.01, DSS03.05, DSS05.02, DSS05.04, DSS05.07, DSS06.02, 3.1.20, 4.2.3.4, 4.3.3.4, 4.4.3.3, 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, A.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, CM-7(a), CM-7(b), CM-6(a), SC-7(a), DE.AE-1, DE.CM-1, ID.AM-3, PR.AC-5, PR.DS-4, PR.DS-5, PR.PT-4, Req-1.4.3, SRG-OS-000480-GPOS-00227, R12, 1.4.3, 1.4 Remediation Ansible snippet: (show)
| 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: 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: Enable Kernel Parameter to Use Reverse Path Filtering on all IPv4 Interfaces
- Set fact for sysctl paths
ansible.builtin.set_fact:
sysctl_paths:
- /etc/sysctl.d/
- /run/sysctl.d/
- /usr/local/lib/sysctl.d/
- /usr/lib/sysctl.d/
when: '"kernel" 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: Enable Kernel Parameter to Use Reverse Path Filtering on all IPv4 Interfaces
- Find all files that contain net.ipv4.conf.all.rp_filter
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*net.ipv4.conf.all.rp_filter\s*=\s*.*$'
register: find_all_values
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" 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: Enable Kernel Parameter to Use Reverse Path Filtering on all IPv4 Interfaces
- Find all files that set net.ipv4.conf.all.rp_filter to correct value
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*net.ipv4.conf.all.rp_filter\s*=\s*{{ sysctl_net_ipv4_conf_all_rp_filter_value
}}$'
register: find_correct_value
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" 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: Enable Kernel Parameter to Use Reverse Path Filtering on all IPv4 Interfaces
- Comment out any occurrences of net.ipv4.conf.all.rp_filter from config files
ansible.builtin.replace:
path: '{{ item | split(":") | first }}'
regexp: ^[\s]*net.ipv4.conf.all.rp_filter
replace: '#net.ipv4.conf.all.rp_filter'
loop: '{{ find_all_values.stdout_lines }}'
when:
- '"kernel" in ansible_facts.packages'
- find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
| length > find_correct_value.stdout_lines | length
tags:
- NIST-800-171-3.1.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: Enable Kernel Parameter to Use Reverse Path Filtering on all IPv4 Interfaces
- Ensure sysctl net.ipv4.conf.all.rp_filter is set
ansible.posix.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: '"kernel" 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
|
Disable Kernel Parameter for Accepting Secure ICMP Redirects on all IPv4 Interfaces
[ref]ruleTo 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. References:
1, 11, 12, 13, 14, 15, 16, 18, 2, 3, 4, 6, 7, 8, 9, APO01.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, 3.1.20, 4.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, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 6.2, SR 7.1, SR 7.2, SR 7.6, A.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, CM-7(a), CM-7(b), CM-6(a), SC-7(a), DE.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, Req-1.4.3, SRG-OS-000480-GPOS-00227, R12, 1.4.3, 1.4 Remediation Ansible snippet: (show)
| 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: 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: Disable Kernel Parameter for Accepting Secure ICMP Redirects on all IPv4 Interfaces
- Set fact for sysctl paths
ansible.builtin.set_fact:
sysctl_paths:
- /etc/sysctl.d/
- /run/sysctl.d/
- /usr/local/lib/sysctl.d/
- /usr/lib/sysctl.d/
when: '"kernel" 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: Disable Kernel Parameter for Accepting Secure ICMP Redirects on all IPv4 Interfaces
- Find all files that contain net.ipv4.conf.all.secure_redirects
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*net.ipv4.conf.all.secure_redirects\s*=\s*.*$'
register: find_all_values
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" 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: Disable Kernel Parameter for Accepting Secure ICMP Redirects on all IPv4 Interfaces
- Find all files that set net.ipv4.conf.all.secure_redirects to correct value
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*net.ipv4.conf.all.secure_redirects\s*=\s*{{ sysctl_net_ipv4_conf_all_secure_redirects_value
}}$'
register: find_correct_value
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" 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: Disable Kernel Parameter for Accepting Secure ICMP Redirects on all IPv4 Interfaces
- Comment out any occurrences of net.ipv4.conf.all.secure_redirects from config
files
ansible.builtin.replace:
path: '{{ item | split(":") | first }}'
regexp: ^[\s]*net.ipv4.conf.all.secure_redirects
replace: '#net.ipv4.conf.all.secure_redirects'
loop: '{{ find_all_values.stdout_lines }}'
when:
- '"kernel" in ansible_facts.packages'
- find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
| length > find_correct_value.stdout_lines | length
tags:
- NIST-800-171-3.1.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: Disable Kernel Parameter for Accepting Secure ICMP Redirects on all IPv4 Interfaces
- Ensure sysctl net.ipv4.conf.all.secure_redirects is set
ansible.posix.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: '"kernel" 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
|
Disable Kernel Parameter for Accepting ICMP Redirects by Default on IPv4 Interfaces
[ref]ruleTo 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. References:
1, 11, 12, 13, 14, 15, 16, 18, 2, 3, 4, 6, 7, 8, 9, 5.10.1.1, APO01.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, 3.1.20, 4.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, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 6.2, SR 7.1, SR 7.2, SR 7.6, A.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, CM-7(a), CM-7(b), CM-6(a), SC-7(a), DE.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, Req-1.4.3, SRG-OS-000480-GPOS-00227, R12, 1.4.3, 1.4 Remediation Ansible snippet: (show)
| 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: 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: Disable Kernel Parameter for Accepting ICMP Redirects by Default on IPv4 Interfaces
- Set fact for sysctl paths
ansible.builtin.set_fact:
sysctl_paths:
- /etc/sysctl.d/
- /run/sysctl.d/
- /usr/local/lib/sysctl.d/
- /usr/lib/sysctl.d/
when: '"kernel" 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: Disable Kernel Parameter for Accepting ICMP Redirects by Default on IPv4 Interfaces
- Find all files that contain net.ipv4.conf.default.accept_redirects
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*net.ipv4.conf.default.accept_redirects\s*=\s*.*$'
register: find_all_values
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" 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: Disable Kernel Parameter for Accepting ICMP Redirects by Default on IPv4 Interfaces
- Find all files that set net.ipv4.conf.default.accept_redirects to correct value
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*net.ipv4.conf.default.accept_redirects\s*=\s*{{ sysctl_net_ipv4_conf_default_accept_redirects_value
}}$'
register: find_correct_value
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" 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: Disable Kernel Parameter for Accepting ICMP Redirects by Default on IPv4 Interfaces
- Comment out any occurrences of net.ipv4.conf.default.accept_redirects from config
files
ansible.builtin.replace:
path: '{{ item | split(":") | first }}'
regexp: ^[\s]*net.ipv4.conf.default.accept_redirects
replace: '#net.ipv4.conf.default.accept_redirects'
loop: '{{ find_all_values.stdout_lines }}'
when:
- '"kernel" in ansible_facts.packages'
- find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
| length > find_correct_value.stdout_lines | length
tags:
- 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: Disable Kernel Parameter for Accepting ICMP Redirects by Default on IPv4 Interfaces
- Ensure sysctl net.ipv4.conf.default.accept_redirects is set
ansible.posix.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: '"kernel" 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
|
Disable Kernel Parameter for Accepting Source-Routed Packets on IPv4 Interfaces by Default
[ref]ruleTo 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. References:
1, 11, 12, 13, 14, 15, 16, 18, 2, 3, 4, 6, 7, 8, 9, 5.10.1.1, APO01.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, 3.1.20, 4.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, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 6.2, SR 7.1, SR 7.2, SR 7.6, A.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, CIP-007-3 R4, CIP-007-3 R4.1, CIP-007-3 R4.2, CIP-007-3 R5.1, CM-7(a), CM-7(b), SC-5, SC-7(a), DE.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, SRG-OS-000480-GPOS-00227, R12 Remediation Ansible snippet: (show)
| 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: 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: Disable Kernel Parameter for Accepting Source-Routed Packets on IPv4 Interfaces
by Default - Set fact for sysctl paths
ansible.builtin.set_fact:
sysctl_paths:
- /etc/sysctl.d/
- /run/sysctl.d/
- /usr/local/lib/sysctl.d/
- /usr/lib/sysctl.d/
when: '"kernel" 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: Disable Kernel Parameter for Accepting Source-Routed Packets on IPv4 Interfaces
by Default - Find all files that contain net.ipv4.conf.default.accept_source_route
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*net.ipv4.conf.default.accept_source_route\s*=\s*.*$'
register: find_all_values
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" 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: Disable Kernel Parameter for Accepting Source-Routed Packets on IPv4 Interfaces
by Default - Find all files that set net.ipv4.conf.default.accept_source_route
to correct value
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*net.ipv4.conf.default.accept_source_route\s*=\s*{{ sysctl_net_ipv4_conf_default_accept_source_route_value
}}$'
register: find_correct_value
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" 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: Disable Kernel Parameter for Accepting Source-Routed Packets on IPv4 Interfaces
by Default - Comment out any occurrences of net.ipv4.conf.default.accept_source_route
from config files
ansible.builtin.replace:
path: '{{ item | split(":") | first }}'
regexp: ^[\s]*net.ipv4.conf.default.accept_source_route
replace: '#net.ipv4.conf.default.accept_source_route'
loop: '{{ find_all_values.stdout_lines }}'
when:
- '"kernel" in ansible_facts.packages'
- find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
| length > find_correct_value.stdout_lines | length
tags:
- 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: Disable Kernel Parameter for Accepting Source-Routed Packets on IPv4 Interfaces
by Default - Ensure sysctl net.ipv4.conf.default.accept_source_route is set
ansible.posix.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: '"kernel" 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
|
Enable Kernel Parameter to Log Martian Packets on all IPv4 Interfaces by Default
[ref]ruleTo 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. References:
1, 11, 12, 13, 14, 15, 16, 2, 3, 7, 8, 9, APO13.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, 3.1.20, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 6.2, SR 7.1, SR 7.2, SR 7.6, A.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, CM-7(a), CM-7(b), SC-5(3)(a), DE.CM-1, PR.AC-3, PR.DS-4, PR.IP-1, PR.PT-3, PR.PT-4, SRG-OS-000480-GPOS-00227 Remediation Ansible snippet: (show)
| 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: 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: Enable Kernel Parameter to Log Martian Packets on all IPv4 Interfaces by Default
- Set fact for sysctl paths
ansible.builtin.set_fact:
sysctl_paths:
- /etc/sysctl.d/
- /run/sysctl.d/
- /usr/local/lib/sysctl.d/
- /usr/lib/sysctl.d/
when: '"kernel" 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: Enable Kernel Parameter to Log Martian Packets on all IPv4 Interfaces by Default
- Find all files that contain net.ipv4.conf.default.log_martians
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*net.ipv4.conf.default.log_martians\s*=\s*.*$'
register: find_all_values
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" 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: Enable Kernel Parameter to Log Martian Packets on all IPv4 Interfaces by Default
- Find all files that set net.ipv4.conf.default.log_martians to correct value
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*net.ipv4.conf.default.log_martians\s*=\s*{{ sysctl_net_ipv4_conf_default_log_martians_value
}}$'
register: find_correct_value
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" 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: Enable Kernel Parameter to Log Martian Packets on all IPv4 Interfaces by Default
- Comment out any occurrences of net.ipv4.conf.default.log_martians from config
files
ansible.builtin.replace:
path: '{{ item | split(":") | first }}'
regexp: ^[\s]*net.ipv4.conf.default.log_martians
replace: '#net.ipv4.conf.default.log_martians'
loop: '{{ find_all_values.stdout_lines }}'
when:
- '"kernel" in ansible_facts.packages'
- find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
| length > find_correct_value.stdout_lines | length
tags:
- NIST-800-171-3.1.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: Enable Kernel Parameter to Log Martian Packets on all IPv4 Interfaces by Default
- Ensure sysctl net.ipv4.conf.default.log_martians is set
ansible.posix.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: '"kernel" 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
|
Enable Kernel Parameter to Use Reverse Path Filtering on all IPv4 Interfaces by Default
[ref]ruleTo 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. References:
1, 12, 13, 14, 15, 16, 18, 2, 4, 6, 7, 8, 9, APO01.06, APO13.01, BAI04.04, DSS01.03, DSS01.05, DSS03.01, DSS03.05, DSS05.02, DSS05.04, DSS05.07, DSS06.02, 3.1.20, 4.2.3.4, 4.3.3.4, 4.4.3.3, 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, A.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, CM-7(a), CM-7(b), CM-6(a), SC-7(a), DE.AE-1, DE.CM-1, ID.AM-3, PR.AC-5, PR.DS-4, PR.DS-5, PR.PT-4, SRG-OS-000480-GPOS-00227, R12 Remediation Ansible snippet: (show)
| 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: 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: Enable Kernel Parameter to Use Reverse Path Filtering on all IPv4 Interfaces
by Default - Set fact for sysctl paths
ansible.builtin.set_fact:
sysctl_paths:
- /etc/sysctl.d/
- /run/sysctl.d/
- /usr/local/lib/sysctl.d/
- /usr/lib/sysctl.d/
when: '"kernel" 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: Enable Kernel Parameter to Use Reverse Path Filtering on all IPv4 Interfaces
by Default - Find all files that contain net.ipv4.conf.default.rp_filter
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*net.ipv4.conf.default.rp_filter\s*=\s*.*$'
register: find_all_values
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" 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: Enable Kernel Parameter to Use Reverse Path Filtering on all IPv4 Interfaces
by Default - Find all files that set net.ipv4.conf.default.rp_filter to correct
value
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*net.ipv4.conf.default.rp_filter\s*=\s*{{ sysctl_net_ipv4_conf_default_rp_filter_value
}}$'
register: find_correct_value
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" 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: Enable Kernel Parameter to Use Reverse Path Filtering on all IPv4 Interfaces
by Default - Comment out any occurrences of net.ipv4.conf.default.rp_filter from
config files
ansible.builtin.replace:
path: '{{ item | split(":") | first }}'
regexp: ^[\s]*net.ipv4.conf.default.rp_filter
replace: '#net.ipv4.conf.default.rp_filter'
loop: '{{ find_all_values.stdout_lines }}'
when:
- '"kernel" in ansible_facts.packages'
- find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
| length > find_correct_value.stdout_lines | length
tags:
- NIST-800-171-3.1.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: Enable Kernel Parameter to Use Reverse Path Filtering on all IPv4 Interfaces
by Default - Ensure sysctl net.ipv4.conf.default.rp_filter is set
ansible.posix.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: '"kernel" 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
|
Configure Kernel Parameter for Accepting Secure Redirects By Default
[ref]ruleTo 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. References:
1, 11, 12, 13, 14, 15, 16, 18, 2, 3, 4, 6, 7, 8, 9, APO01.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, 3.1.20, 4.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, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 6.2, SR 7.1, SR 7.2, SR 7.6, A.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, CIP-007-3 R4, CIP-007-3 R4.1, CIP-007-3 R4.2, CIP-007-3 R5.1, CM-7(a), CM-7(b), SC-5, SC-7(a), DE.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, SRG-OS-000480-GPOS-00227, R12 Remediation Ansible snippet: (show)
| 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: 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: Configure Kernel Parameter for Accepting Secure Redirects By Default - Set
fact for sysctl paths
ansible.builtin.set_fact:
sysctl_paths:
- /etc/sysctl.d/
- /run/sysctl.d/
- /usr/local/lib/sysctl.d/
- /usr/lib/sysctl.d/
when: '"kernel" 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: Configure Kernel Parameter for Accepting Secure Redirects By Default - Find
all files that contain net.ipv4.conf.default.secure_redirects
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*net.ipv4.conf.default.secure_redirects\s*=\s*.*$'
register: find_all_values
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" 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: Configure Kernel Parameter for Accepting Secure Redirects By Default - Find
all files that set net.ipv4.conf.default.secure_redirects to correct value
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*net.ipv4.conf.default.secure_redirects\s*=\s*{{ sysctl_net_ipv4_conf_default_secure_redirects_value
}}$'
register: find_correct_value
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" 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: Configure Kernel Parameter for Accepting Secure Redirects By Default - Comment
out any occurrences of net.ipv4.conf.default.secure_redirects from config files
ansible.builtin.replace:
path: '{{ item | split(":") | first }}'
regexp: ^[\s]*net.ipv4.conf.default.secure_redirects
replace: '#net.ipv4.conf.default.secure_redirects'
loop: '{{ find_all_values.stdout_lines }}'
when:
- '"kernel" in ansible_facts.packages'
- find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
| length > find_correct_value.stdout_lines | length
tags:
- NIST-800-171-3.1.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: Configure Kernel Parameter for Accepting Secure Redirects By Default - Ensure
sysctl net.ipv4.conf.default.secure_redirects is set
ansible.posix.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: '"kernel" 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
|
Enable Kernel Parameter to Ignore ICMP Broadcast Echo Requests on IPv4 Interfaces
[ref]ruleTo 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. References:
1, 11, 12, 13, 14, 15, 16, 18, 2, 3, 4, 6, 7, 8, 9, 5.10.1.1, APO01.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, 3.1.20, 4.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, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 6.2, SR 7.1, SR 7.2, SR 7.6, A.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, CIP-007-3 R4, CIP-007-3 R4.1, CIP-007-3 R4.2, CIP-007-3 R5.1, CM-7(a), CM-7(b), SC-5, DE.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, Req-1.4.3, SRG-OS-000480-GPOS-00227, 1.4.2, 1.4 Remediation Ansible snippet: (show)
| 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: 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: Enable Kernel Parameter to Ignore ICMP Broadcast Echo Requests on IPv4 Interfaces
- Set fact for sysctl paths
ansible.builtin.set_fact:
sysctl_paths:
- /etc/sysctl.d/
- /run/sysctl.d/
- /usr/local/lib/sysctl.d/
- /usr/lib/sysctl.d/
when: '"kernel" 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: Enable Kernel Parameter to Ignore ICMP Broadcast Echo Requests on IPv4 Interfaces
- Find all files that contain net.ipv4.icmp_echo_ignore_broadcasts
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*net.ipv4.icmp_echo_ignore_broadcasts\s*=\s*.*$'
register: find_all_values
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" 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: Enable Kernel Parameter to Ignore ICMP Broadcast Echo Requests on IPv4 Interfaces
- Find all files that set net.ipv4.icmp_echo_ignore_broadcasts to correct value
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*net.ipv4.icmp_echo_ignore_broadcasts\s*=\s*{{ sysctl_net_ipv4_icmp_echo_ignore_broadcasts_value
}}$'
register: find_correct_value
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" 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: Enable Kernel Parameter to Ignore ICMP Broadcast Echo Requests on IPv4 Interfaces
- Comment out any occurrences of net.ipv4.icmp_echo_ignore_broadcasts from config
files
ansible.builtin.replace:
path: '{{ item | split(":") | first }}'
regexp: ^[\s]*net.ipv4.icmp_echo_ignore_broadcasts
replace: '#net.ipv4.icmp_echo_ignore_broadcasts'
loop: '{{ find_all_values.stdout_lines }}'
when:
- '"kernel" in ansible_facts.packages'
- find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
| length > find_correct_value.stdout_lines | length
tags:
- 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: Enable Kernel Parameter to Ignore ICMP Broadcast Echo Requests on IPv4 Interfaces
- Ensure sysctl net.ipv4.icmp_echo_ignore_broadcasts is set
ansible.posix.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: '"kernel" 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
|
Enable Kernel Parameter to Ignore Bogus ICMP Error Responses on IPv4 Interfaces
[ref]ruleTo 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. References:
1, 11, 12, 13, 14, 15, 16, 2, 3, 7, 8, 9, APO13.01, BAI04.04, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS01.03, DSS03.05, DSS05.02, DSS05.05, DSS05.07, DSS06.06, 3.1.20, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 6.2, SR 7.1, SR 7.2, SR 7.6, A.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, CIP-007-3 R4, CIP-007-3 R4.1, CIP-007-3 R4.2, CIP-007-3 R5.1, CM-7(a), CM-7(b), SC-5, DE.CM-1, PR.DS-4, PR.IP-1, PR.PT-3, Req-1.4.3, SRG-OS-000480-GPOS-00227, R12, 1.4.2, 1.4 Remediation Ansible snippet: (show)
| 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: 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: Enable Kernel Parameter to Ignore Bogus ICMP Error Responses on IPv4 Interfaces
- Set fact for sysctl paths
ansible.builtin.set_fact:
sysctl_paths:
- /etc/sysctl.d/
- /run/sysctl.d/
- /usr/local/lib/sysctl.d/
- /usr/lib/sysctl.d/
when: '"kernel" 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: Enable Kernel Parameter to Ignore Bogus ICMP Error Responses on IPv4 Interfaces
- Find all files that contain net.ipv4.icmp_ignore_bogus_error_responses
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*net.ipv4.icmp_ignore_bogus_error_responses\s*=\s*.*$'
register: find_all_values
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" 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: Enable Kernel Parameter to Ignore Bogus ICMP Error Responses on IPv4 Interfaces
- Find all files that set net.ipv4.icmp_ignore_bogus_error_responses to correct
value
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*net.ipv4.icmp_ignore_bogus_error_responses\s*=\s*{{ sysctl_net_ipv4_icmp_ignore_bogus_error_responses_value
}}$'
register: find_correct_value
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" 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: Enable Kernel Parameter to Ignore Bogus ICMP Error Responses on IPv4 Interfaces
- Comment out any occurrences of net.ipv4.icmp_ignore_bogus_error_responses from
config files
ansible.builtin.replace:
path: '{{ item | split(":") | first }}'
regexp: ^[\s]*net.ipv4.icmp_ignore_bogus_error_responses
replace: '#net.ipv4.icmp_ignore_bogus_error_responses'
loop: '{{ find_all_values.stdout_lines }}'
when:
- '"kernel" in ansible_facts.packages'
- find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
| length > find_correct_value.stdout_lines | length
tags:
- NIST-800-171-3.1.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: Enable Kernel Parameter to Ignore Bogus ICMP Error Responses on IPv4 Interfaces
- Ensure sysctl net.ipv4.icmp_ignore_bogus_error_responses is set
ansible.posix.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: '"kernel" 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
|
Enable Kernel Parameter to Use TCP Syncookies on Network Interfaces
[ref]ruleTo 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. References:
1, 12, 13, 14, 15, 16, 18, 2, 4, 6, 7, 8, 9, 5.10.1.1, APO01.06, APO13.01, BAI04.04, DSS01.03, DSS01.05, DSS03.01, DSS03.05, DSS05.02, DSS05.04, DSS05.07, DSS06.02, 3.1.20, 4.2.3.4, 4.3.3.4, 4.4.3.3, 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, A.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, CM-7(a), CM-7(b), SC-5(1), SC-5(2), SC-5(3)(a), CM-6(a), DE.AE-1, DE.CM-1, ID.AM-3, PR.AC-5, PR.DS-4, PR.DS-5, PR.PT-4, Req-1.4.1, SRG-OS-000480-GPOS-00227, SRG-OS-000420-GPOS-00186, SRG-OS-000142-GPOS-00071, R12, 1.4.3, 1.4 Remediation Ansible snippet: (show)
| 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: XCCDF Value sysctl_net_ipv4_tcp_syncookies_value # promote to variable
set_fact:
sysctl_net_ipv4_tcp_syncookies_value: !!str 1
tags:
- always
- name: Enable Kernel Parameter to Use TCP Syncookies on Network Interfaces - Set
fact for sysctl paths
ansible.builtin.set_fact:
sysctl_paths:
- /etc/sysctl.d/
- /run/sysctl.d/
- /usr/local/lib/sysctl.d/
- /usr/lib/sysctl.d/
when: '"kernel" 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: Enable Kernel Parameter to Use TCP Syncookies on Network Interfaces - Find
all files that contain net.ipv4.tcp_syncookies
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*net.ipv4.tcp_syncookies\s*=\s*.*$'
register: find_all_values
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" 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: Enable Kernel Parameter to Use TCP Syncookies on Network Interfaces - Find
all files that set net.ipv4.tcp_syncookies to correct value
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*net.ipv4.tcp_syncookies\s*=\s*{{ sysctl_net_ipv4_tcp_syncookies_value
}}$'
register: find_correct_value
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" 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: Enable Kernel Parameter to Use TCP Syncookies on Network Interfaces - Comment
out any occurrences of net.ipv4.tcp_syncookies from config files
ansible.builtin.replace:
path: '{{ item | split(":") | first }}'
regexp: ^[\s]*net.ipv4.tcp_syncookies
replace: '#net.ipv4.tcp_syncookies'
loop: '{{ find_all_values.stdout_lines }}'
when:
- '"kernel" in ansible_facts.packages'
- find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
| length > find_correct_value.stdout_lines | length
tags:
- 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: Enable Kernel Parameter to Use TCP Syncookies on Network Interfaces - Ensure
sysctl net.ipv4.tcp_syncookies is set
ansible.posix.sysctl:
name: net.ipv4.tcp_syncookies
value: '{{ sysctl_net_ipv4_tcp_syncookies_value }}'
sysctl_file: /etc/sysctl.conf
state: present
reload: true
when: '"kernel" 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
|
Network Parameters for Hosts Only
[ref]groupIf 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. |
| contains 3 rules |
Disable Kernel Parameter for Sending ICMP Redirects on all IPv4 Interfaces
[ref]ruleTo 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. References:
1, 11, 12, 13, 14, 15, 16, 18, 2, 3, 4, 6, 7, 8, 9, 5.10.1.1, APO01.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, 3.1.20, 4.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, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 6.2, SR 7.1, SR 7.2, SR 7.6, A.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, CIP-007-3 R4, CIP-007-3 R4.1, CIP-007-3 R4.2, CIP-007-3 R5.1, CM-7(a), CM-7(b), SC-5, CM-6(a), SC-7(a), DE.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, SRG-OS-000480-GPOS-00227, R12, 1.4.5, 1.4 Remediation Ansible snippet: (show)
| 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: Disable Kernel Parameter for Sending ICMP Redirects on all IPv4 Interfaces
- Set fact for sysctl paths
ansible.builtin.set_fact:
sysctl_paths:
- /etc/sysctl.d/
- /run/sysctl.d/
- /usr/local/lib/sysctl.d/
- /usr/lib/sysctl.d/
when: '"kernel" 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: Disable Kernel Parameter for Sending ICMP Redirects on all IPv4 Interfaces
- Find all files that contain net.ipv4.conf.all.send_redirects
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*net.ipv4.conf.all.send_redirects\s*=\s*.*$'
register: find_all_values
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" 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: Disable Kernel Parameter for Sending ICMP Redirects on all IPv4 Interfaces
- Find all files that set net.ipv4.conf.all.send_redirects to correct value
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*net.ipv4.conf.all.send_redirects\s*=\s*0$'
register: find_correct_value
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" 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: Disable Kernel Parameter for Sending ICMP Redirects on all IPv4 Interfaces
- Comment out any occurrences of net.ipv4.conf.all.send_redirects from config
files
ansible.builtin.replace:
path: '{{ item | split(":") | first }}'
regexp: ^[\s]*net.ipv4.conf.all.send_redirects
replace: '#net.ipv4.conf.all.send_redirects'
loop: '{{ find_all_values.stdout_lines }}'
when:
- '"kernel" in ansible_facts.packages'
- find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
| length > find_correct_value.stdout_lines | length
tags:
- 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: Disable Kernel Parameter for Sending ICMP Redirects on all IPv4 Interfaces
- Ensure sysctl net.ipv4.conf.all.send_redirects is set to 0
ansible.posix.sysctl:
name: net.ipv4.conf.all.send_redirects
value: '0'
sysctl_file: /etc/sysctl.conf
state: present
reload: true
when: '"kernel" 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
|
Disable Kernel Parameter for Sending ICMP Redirects on all IPv4 Interfaces by Default
[ref]ruleTo 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. References:
1, 11, 12, 13, 14, 15, 16, 18, 2, 3, 4, 6, 7, 8, 9, 5.10.1.1, APO01.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, 3.1.20, 4.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, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 6.2, SR 7.1, SR 7.2, SR 7.6, A.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, CIP-007-3 R4, CIP-007-3 R4.1, CIP-007-3 R4.2, CIP-007-3 R5.1, CM-7(a), CM-7(b), SC-5, CM-6(a), SC-7(a), DE.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, SRG-OS-000480-GPOS-00227, R12, 1.4.5, 1.4 Remediation Ansible snippet: (show)
| 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: Disable Kernel Parameter for Sending ICMP Redirects on all IPv4 Interfaces
by Default - Set fact for sysctl paths
ansible.builtin.set_fact:
sysctl_paths:
- /etc/sysctl.d/
- /run/sysctl.d/
- /usr/local/lib/sysctl.d/
- /usr/lib/sysctl.d/
when: '"kernel" 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: Disable Kernel Parameter for Sending ICMP Redirects on all IPv4 Interfaces
by Default - Find all files that contain net.ipv4.conf.default.send_redirects
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*net.ipv4.conf.default.send_redirects\s*=\s*.*$'
register: find_all_values
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" 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: Disable Kernel Parameter for Sending ICMP Redirects on all IPv4 Interfaces
by Default - Find all files that set net.ipv4.conf.default.send_redirects to correct
value
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*net.ipv4.conf.default.send_redirects\s*=\s*0$'
register: find_correct_value
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" 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: Disable Kernel Parameter for Sending ICMP Redirects on all IPv4 Interfaces
by Default - Comment out any occurrences of net.ipv4.conf.default.send_redirects
from config files
ansible.builtin.replace:
path: '{{ item | split(":") | first }}'
regexp: ^[\s]*net.ipv4.conf.default.send_redirects
replace: '#net.ipv4.conf.default.send_redirects'
loop: '{{ find_all_values.stdout_lines }}'
when:
- '"kernel" in ansible_facts.packages'
- find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
| length > find_correct_value.stdout_lines | length
tags:
- 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: Disable Kernel Parameter for Sending ICMP Redirects on all IPv4 Interfaces
by Default - Ensure sysctl net.ipv4.conf.default.send_redirects is set to 0
ansible.posix.sysctl:
name: net.ipv4.conf.default.send_redirects
value: '0'
sysctl_file: /etc/sysctl.conf
state: present
reload: true
when: '"kernel" 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
|
Disable Kernel Parameter for IP Forwarding on IPv4 Interfaces
[ref]ruleTo 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. References:
1, 11, 12, 13, 14, 15, 16, 2, 3, 7, 8, 9, APO13.01, BAI04.04, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS01.03, DSS03.05, DSS05.02, DSS05.05, DSS05.07, DSS06.06, 3.1.20, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 6.2, SR 7.1, SR 7.2, SR 7.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.9.1.2, CIP-007-3 R4, CIP-007-3 R4.1, CIP-007-3 R4.2, CIP-007-3 R5.1, CM-7(a), CM-7(b), SC-5, CM-6(a), SC-7(a), DE.CM-1, PR.DS-4, PR.IP-1, PR.PT-3, PR.PT-4, Req-1.3.1, Req-1.3.2, SRG-OS-000480-GPOS-00227, R12, 1.4.3, 1.4 Remediation Ansible snippet: (show)
| 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: Disable Kernel Parameter for IP Forwarding on IPv4 Interfaces - Set fact for
sysctl paths
ansible.builtin.set_fact:
sysctl_paths:
- /etc/sysctl.d/
- /run/sysctl.d/
- /usr/local/lib/sysctl.d/
- /usr/lib/sysctl.d/
when: '"kernel" 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: Disable Kernel Parameter for IP Forwarding on IPv4 Interfaces - Find all files
that contain net.ipv4.ip_forward
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*net.ipv4.ip_forward\s*=\s*.*$'
register: find_all_values
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" 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: Disable Kernel Parameter for IP Forwarding on IPv4 Interfaces - Find all files
that set net.ipv4.ip_forward to correct value
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*net.ipv4.ip_forward\s*=\s*0$'
register: find_correct_value
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" 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: Disable Kernel Parameter for IP Forwarding on IPv4 Interfaces - Comment out
any occurrences of net.ipv4.ip_forward from config files
ansible.builtin.replace:
path: '{{ item | split(":") | first }}'
regexp: ^[\s]*net.ipv4.ip_forward
replace: '#net.ipv4.ip_forward'
loop: '{{ find_all_values.stdout_lines }}'
when:
- '"kernel" in ansible_facts.packages'
- find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
| length > find_correct_value.stdout_lines | length
tags:
- NIST-800-171-3.1.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: Disable Kernel Parameter for IP Forwarding on IPv4 Interfaces - Ensure sysctl
net.ipv4.ip_forward is set to 0
ansible.posix.sysctl:
name: net.ipv4.ip_forward
value: '0'
sysctl_file: /etc/sysctl.conf
state: present
reload: true
when: '"kernel" 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
|
File Permissions and Masks
[ref]groupTraditional 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 TencentOS Server 4
installations:
$ mount -t xfs | awk '{print $3}'
For any systems that use a different
local filesystem type, modify this command as appropriate. |
| contains 38 rules |
Verify Permissions on Important Files and
Directories
[ref]groupPermissions for many files on a system must be set
restrictively to ensure sensitive information is properly protected.
This section discusses important
permission restrictions which can be verified
to ensure that no harmful discrepancies have
arisen. |
| contains 29 rules |
Verify Permissions on Files with Local Account Information and Credentials
[ref]groupThe default restrictive permissions for files which act as
important security databases such as passwd, shadow,
group, and gshadow files must be maintained. Many utilities
need read access to the passwd file in order to function properly, but
read access to the shadow file allows malicious attacks against system
passwords, and should never be enabled. |
| contains 24 rules |
Verify Group Who Owns Backup group File
[ref]rule 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. Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Set the file_groupowner_backup_etc_group_newgroup variable if represented
by gid
ansible.builtin.set_fact:
file_groupowner_backup_etc_group_newgroup: '0'
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: Test for existence /etc/group-
ansible.builtin.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 on /etc/group-
ansible.builtin.file:
path: /etc/group-
follow: false
group: '{{ file_groupowner_backup_etc_group_newgroup }}'
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
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
newgroup=""
if getent group "0" >/dev/null 2>&1; then
newgroup="0"
fi
if [[ -z "${newgroup}" ]]; then
>&2 echo "0 is not a defined group on the system"
else
if ! stat -c "%g %G" "/etc/group-" | grep -E -w -q "0"; then
chgrp --no-dereference "$newgroup" /etc/group-
fi
fi
|
Verify Group Who Owns Backup gshadow File
[ref]rule To properly set the group owner of /etc/gshadow-, run the command:
$ sudo chgrp root /etc/gshadow-
Rationale:The /etc/gshadow- file is a backup of /etc/gshadow, and as such,
it contains group password hashes. Protection of this file is critical for system security. Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Set the file_groupowner_backup_etc_gshadow_newgroup variable if represented
by gid
ansible.builtin.set_fact:
file_groupowner_backup_etc_gshadow_newgroup: '0'
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: Test for existence /etc/gshadow-
ansible.builtin.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 on /etc/gshadow-
ansible.builtin.file:
path: /etc/gshadow-
follow: false
group: '{{ file_groupowner_backup_etc_gshadow_newgroup }}'
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
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
newgroup=""
if getent group "0" >/dev/null 2>&1; then
newgroup="0"
fi
if [[ -z "${newgroup}" ]]; then
>&2 echo "0 is not a defined group on the system"
else
if ! stat -c "%g %G" "/etc/gshadow-" | grep -E -w -q "0"; then
chgrp --no-dereference "$newgroup" /etc/gshadow-
fi
fi
|
Verify Group Who Owns Backup passwd File
[ref]rule 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. Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Set the file_groupowner_backup_etc_passwd_newgroup variable if represented
by gid
ansible.builtin.set_fact:
file_groupowner_backup_etc_passwd_newgroup: '0'
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: Test for existence /etc/passwd-
ansible.builtin.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 on /etc/passwd-
ansible.builtin.file:
path: /etc/passwd-
follow: false
group: '{{ file_groupowner_backup_etc_passwd_newgroup }}'
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
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
newgroup=""
if getent group "0" >/dev/null 2>&1; then
newgroup="0"
fi
if [[ -z "${newgroup}" ]]; then
>&2 echo "0 is not a defined group on the system"
else
if ! stat -c "%g %G" "/etc/passwd-" | grep -E -w -q "0"; then
chgrp --no-dereference "$newgroup" /etc/passwd-
fi
fi
|
Verify User Who Owns Backup shadow File
[ref]rule To properly set the group owner of /etc/shadow-, run the command:
$ sudo chgrp root /etc/shadow-
Rationale:The /etc/shadow- file is a backup file of /etc/shadow, and as such,
it contains the list of local system accounts and password hashes.
Protection of this file is critical for system security. Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Set the file_groupowner_backup_etc_shadow_newgroup variable if represented
by gid
ansible.builtin.set_fact:
file_groupowner_backup_etc_shadow_newgroup: '0'
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: Test for existence /etc/shadow-
ansible.builtin.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 on /etc/shadow-
ansible.builtin.file:
path: /etc/shadow-
follow: false
group: '{{ file_groupowner_backup_etc_shadow_newgroup }}'
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
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
newgroup=""
if getent group "0" >/dev/null 2>&1; then
newgroup="0"
fi
if [[ -z "${newgroup}" ]]; then
>&2 echo "0 is not a defined group on the system"
else
if ! stat -c "%g %G" "/etc/shadow-" | grep -E -w -q "0"; then
chgrp --no-dereference "$newgroup" /etc/shadow-
fi
fi
|
Verify Group Who Owns group File
[ref]rule 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. References:
12, 13, 14, 15, 16, 18, 3, 5, 5.5.2.2, APO01.06, DSS05.04, DSS05.07, DSS06.02, 4.3.3.7.3, SR 2.1, SR 5.2, A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5, CIP-003-8 R5.1.1, CIP-003-8 R5.3, CIP-004-6 R2.3, CIP-007-3 R2.1, CIP-007-3 R2.2, CIP-007-3 R2.3, CIP-007-3 R5.1, CIP-007-3 R5.1.1, CIP-007-3 R5.1.2, CM-6(a), AC-6(1), PR.AC-4, PR.DS-5, Req-8.7.c, SRG-OS-000480-GPOS-00227, R50, 2.2.6, 2.2 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Set the file_groupowner_etc_group_newgroup variable if represented by gid
ansible.builtin.set_fact:
file_groupowner_etc_group_newgroup: '0'
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: Test for existence /etc/group
ansible.builtin.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 on /etc/group
ansible.builtin.file:
path: /etc/group
follow: false
group: '{{ file_groupowner_etc_group_newgroup }}'
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
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
newgroup=""
if getent group "0" >/dev/null 2>&1; then
newgroup="0"
fi
if [[ -z "${newgroup}" ]]; then
>&2 echo "0 is not a defined group on the system"
else
if ! stat -c "%g %G" "/etc/group" | grep -E -w -q "0"; then
chgrp --no-dereference "$newgroup" /etc/group
fi
fi
|
Verify Group Who Owns gshadow File
[ref]rule To properly set the group owner of /etc/gshadow, run the command:
$ sudo chgrp root /etc/gshadow
Rationale:The /etc/gshadow file contains group password hashes. Protection of this file
is critical for system security. References:
12, 13, 14, 15, 16, 18, 3, 5, APO01.06, DSS05.04, DSS05.07, DSS06.02, 4.3.3.7.3, SR 2.1, SR 5.2, A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5, CIP-003-8 R5.1.1, CIP-003-8 R5.3, CIP-004-6 R2.3, CIP-007-3 R2.1, CIP-007-3 R2.2, CIP-007-3 R2.3, CIP-007-3 R5.1, CIP-007-3 R5.1.1, CIP-007-3 R5.1.2, CM-6(a), AC-6(1), PR.AC-4, PR.DS-5, SRG-OS-000480-GPOS-00227, R50 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Set the file_groupowner_etc_gshadow_newgroup variable if represented by gid
ansible.builtin.set_fact:
file_groupowner_etc_gshadow_newgroup: '0'
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- configure_strategy
- file_groupowner_etc_gshadow
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Test for existence /etc/gshadow
ansible.builtin.stat:
path: /etc/gshadow
register: file_exists
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- configure_strategy
- file_groupowner_etc_gshadow
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Ensure group owner on /etc/gshadow
ansible.builtin.file:
path: /etc/gshadow
follow: false
group: '{{ file_groupowner_etc_gshadow_newgroup }}'
when: file_exists.stat is defined and file_exists.stat.exists
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- configure_strategy
- file_groupowner_etc_gshadow
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
newgroup=""
if getent group "0" >/dev/null 2>&1; then
newgroup="0"
fi
if [[ -z "${newgroup}" ]]; then
>&2 echo "0 is not a defined group on the system"
else
if ! stat -c "%g %G" "/etc/gshadow" | grep -E -w -q "0"; then
chgrp --no-dereference "$newgroup" /etc/gshadow
fi
fi
|
Verify Group Who Owns passwd File
[ref]rule To properly set the group owner of /etc/passwd, run the command:
$ sudo chgrp root /etc/passwd
Rationale:The /etc/passwd file contains information about the users that are configured on
the system. Protection of this file is critical for system security. References:
12, 13, 14, 15, 16, 18, 3, 5, 5.5.2.2, APO01.06, DSS05.04, DSS05.07, DSS06.02, 4.3.3.7.3, SR 2.1, SR 5.2, A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5, CIP-003-8 R5.1.1, CIP-003-8 R5.3, CIP-004-6 R2.3, CIP-007-3 R2.1, CIP-007-3 R2.2, CIP-007-3 R2.3, CIP-007-3 R5.1, CIP-007-3 R5.1.1, CIP-007-3 R5.1.2, CM-6(a), AC-6(1), PR.AC-4, PR.DS-5, Req-8.7.c, SRG-OS-000480-GPOS-00227, R50, 2.2.6, 2.2 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Set the file_groupowner_etc_passwd_newgroup variable if represented by gid
ansible.builtin.set_fact:
file_groupowner_etc_passwd_newgroup: '0'
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_passwd
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Test for existence /etc/passwd
ansible.builtin.stat:
path: /etc/passwd
register: file_exists
tags:
- CJIS-5.5.2.2
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSS-Req-8.7.c
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_groupowner_etc_passwd
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Ensure group owner on /etc/passwd
ansible.builtin.file:
path: /etc/passwd
follow: false
group: '{{ file_groupowner_etc_passwd_newgroup }}'
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_passwd
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
newgroup=""
if getent group "0" >/dev/null 2>&1; then
newgroup="0"
fi
if [[ -z "${newgroup}" ]]; then
>&2 echo "0 is not a defined group on the system"
else
if ! stat -c "%g %G" "/etc/passwd" | grep -E -w -q "0"; then
chgrp --no-dereference "$newgroup" /etc/passwd
fi
fi
|
Verify Group Who Owns shadow File
[ref]rule To properly set the group owner of /etc/shadow, run the command:
$ sudo chgrp root /etc/shadow
Rationale:The /etc/shadow file stores password hashes. Protection of this file is
critical for system security. References:
12, 13, 14, 15, 16, 18, 3, 5, 5.5.2.2, APO01.06, DSS05.04, DSS05.07, DSS06.02, 4.3.3.7.3, SR 2.1, SR 5.2, A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5, CIP-003-8 R5.1.1, CIP-003-8 R5.3, CIP-004-6 R2.3, CIP-007-3 R2.1, CIP-007-3 R2.2, CIP-007-3 R2.3, CIP-007-3 R5.1, CIP-007-3 R5.1.1, CIP-007-3 R5.1.2, CM-6(a), AC-6(1), PR.AC-4, PR.DS-5, Req-8.7.c, SRG-OS-000480-GPOS-00227, R50, 2.2.6, 2.2 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Set the file_groupowner_etc_shadow_newgroup variable if represented by gid
ansible.builtin.set_fact:
file_groupowner_etc_shadow_newgroup: '0'
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_shadow
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Test for existence /etc/shadow
ansible.builtin.stat:
path: /etc/shadow
register: file_exists
tags:
- CJIS-5.5.2.2
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSS-Req-8.7.c
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_groupowner_etc_shadow
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Ensure group owner on /etc/shadow
ansible.builtin.file:
path: /etc/shadow
follow: false
group: '{{ file_groupowner_etc_shadow_newgroup }}'
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_shadow
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
newgroup=""
if getent group "0" >/dev/null 2>&1; then
newgroup="0"
fi
if [[ -z "${newgroup}" ]]; then
>&2 echo "0 is not a defined group on the system"
else
if ! stat -c "%g %G" "/etc/shadow" | grep -E -w -q "0"; then
chgrp --no-dereference "$newgroup" /etc/shadow
fi
fi
|
Verify User Who Owns Backup group File
[ref]rule To properly set the owner of /etc/group-, run the command:
$ sudo chown root /etc/group-
Rationale:The /etc/group- file is a backup file of /etc/group, and as such,
it contains information regarding groups that are configured on the system.
Protection of this file is important for system security. Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Set the file_owner_backup_etc_group_newown variable if represented by uid
ansible.builtin.set_fact:
file_owner_backup_etc_group_newown: '0'
tags:
- NIST-800-53-AC-6 (1)
- PCI-DSS-Req-8.7.c
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_owner_backup_etc_group
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Test for existence /etc/group-
ansible.builtin.stat:
path: /etc/group-
register: file_exists
tags:
- NIST-800-53-AC-6 (1)
- PCI-DSS-Req-8.7.c
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_owner_backup_etc_group
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Ensure owner on /etc/group-
ansible.builtin.file:
path: /etc/group-
follow: false
owner: '{{ file_owner_backup_etc_group_newown }}'
when: file_exists.stat is defined and file_exists.stat.exists
tags:
- NIST-800-53-AC-6 (1)
- PCI-DSS-Req-8.7.c
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_owner_backup_etc_group
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
newown=""
if id "0" >/dev/null 2>&1; then
newown="0"
fi
if [[ -z "$newown" ]]; then
>&2 echo "0 is not a defined user on the system"
else
if ! stat -c "%u %U" "/etc/group-" | grep -E -w -q "0"; then
chown --no-dereference "$newown" /etc/group-
fi
fi
|
Verify User Who Owns Backup gshadow File
[ref]rule To properly set the owner of /etc/gshadow-, run the command:
$ sudo chown root /etc/gshadow-
Rationale:The /etc/gshadow- file is a backup of /etc/gshadow, and as such,
it contains group password hashes. Protection of this file is critical for system security. Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Set the file_owner_backup_etc_gshadow_newown variable if represented by uid
ansible.builtin.set_fact:
file_owner_backup_etc_gshadow_newown: '0'
tags:
- NIST-800-53-AC-6 (1)
- PCI-DSS-Req-8.7
- configure_strategy
- file_owner_backup_etc_gshadow
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Test for existence /etc/gshadow-
ansible.builtin.stat:
path: /etc/gshadow-
register: file_exists
tags:
- NIST-800-53-AC-6 (1)
- PCI-DSS-Req-8.7
- configure_strategy
- file_owner_backup_etc_gshadow
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Ensure owner on /etc/gshadow-
ansible.builtin.file:
path: /etc/gshadow-
follow: false
owner: '{{ file_owner_backup_etc_gshadow_newown }}'
when: file_exists.stat is defined and file_exists.stat.exists
tags:
- NIST-800-53-AC-6 (1)
- PCI-DSS-Req-8.7
- configure_strategy
- file_owner_backup_etc_gshadow
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
newown=""
if id "0" >/dev/null 2>&1; then
newown="0"
fi
if [[ -z "$newown" ]]; then
>&2 echo "0 is not a defined user on the system"
else
if ! stat -c "%u %U" "/etc/gshadow-" | grep -E -w -q "0"; then
chown --no-dereference "$newown" /etc/gshadow-
fi
fi
|
Verify User Who Owns Backup passwd File
[ref]rule To properly set the owner of /etc/passwd-, run the command:
$ sudo chown root /etc/passwd-
Rationale:The /etc/passwd- file is a backup file of /etc/passwd, and as such,
it contains information about the users that are configured on the system.
Protection of this file is critical for system security. Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Set the file_owner_backup_etc_passwd_newown variable if represented by uid
ansible.builtin.set_fact:
file_owner_backup_etc_passwd_newown: '0'
tags:
- NIST-800-53-AC-6 (1)
- PCI-DSS-Req-8.7.c
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_owner_backup_etc_passwd
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Test for existence /etc/passwd-
ansible.builtin.stat:
path: /etc/passwd-
register: file_exists
tags:
- NIST-800-53-AC-6 (1)
- PCI-DSS-Req-8.7.c
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_owner_backup_etc_passwd
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Ensure owner on /etc/passwd-
ansible.builtin.file:
path: /etc/passwd-
follow: false
owner: '{{ file_owner_backup_etc_passwd_newown }}'
when: file_exists.stat is defined and file_exists.stat.exists
tags:
- NIST-800-53-AC-6 (1)
- PCI-DSS-Req-8.7.c
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_owner_backup_etc_passwd
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
newown=""
if id "0" >/dev/null 2>&1; then
newown="0"
fi
if [[ -z "$newown" ]]; then
>&2 echo "0 is not a defined user on the system"
else
if ! stat -c "%u %U" "/etc/passwd-" | grep -E -w -q "0"; then
chown --no-dereference "$newown" /etc/passwd-
fi
fi
|
Verify Group Who Owns Backup shadow File
[ref]rule To properly set the owner of /etc/shadow-, run the command:
$ sudo chown root /etc/shadow-
Rationale:The /etc/shadow- file is a backup file of /etc/shadow, and as such,
it contains the list of local system accounts and password hashes.
Protection of this file is critical for system security. Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Set the file_owner_backup_etc_shadow_newown variable if represented by uid
ansible.builtin.set_fact:
file_owner_backup_etc_shadow_newown: '0'
tags:
- NIST-800-53-AC-6 (1)
- PCI-DSS-Req-8.7.c
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_owner_backup_etc_shadow
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Test for existence /etc/shadow-
ansible.builtin.stat:
path: /etc/shadow-
register: file_exists
tags:
- NIST-800-53-AC-6 (1)
- PCI-DSS-Req-8.7.c
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_owner_backup_etc_shadow
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Ensure owner on /etc/shadow-
ansible.builtin.file:
path: /etc/shadow-
follow: false
owner: '{{ file_owner_backup_etc_shadow_newown }}'
when: file_exists.stat is defined and file_exists.stat.exists
tags:
- NIST-800-53-AC-6 (1)
- PCI-DSS-Req-8.7.c
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_owner_backup_etc_shadow
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
newown=""
if id "0" >/dev/null 2>&1; then
newown="0"
fi
if [[ -z "$newown" ]]; then
>&2 echo "0 is not a defined user on the system"
else
if ! stat -c "%u %U" "/etc/shadow-" | grep -E -w -q "0"; then
chown --no-dereference "$newown" /etc/shadow-
fi
fi
|
Verify User Who Owns group File
[ref]rule To properly set the owner of /etc/group, run the command:
$ sudo chown root /etc/group
Rationale:The /etc/group file contains information regarding groups that are configured
on the system. Protection of this file is important for system security. References:
12, 13, 14, 15, 16, 18, 3, 5, 5.5.2.2, APO01.06, DSS05.04, DSS05.07, DSS06.02, 4.3.3.7.3, SR 2.1, SR 5.2, A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5, CIP-003-8 R5.1.1, CIP-003-8 R5.3, CIP-004-6 R2.3, CIP-007-3 R2.1, CIP-007-3 R2.2, CIP-007-3 R2.3, CIP-007-3 R5.1, CIP-007-3 R5.1.1, CIP-007-3 R5.1.2, CM-6(a), AC-6(1), PR.AC-4, PR.DS-5, Req-8.7.c, SRG-OS-000480-GPOS-00227, R50, 2.2.6, 2.2 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Set the file_owner_etc_group_newown variable if represented by uid
ansible.builtin.set_fact:
file_owner_etc_group_newown: '0'
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_owner_etc_group
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Test for existence /etc/group
ansible.builtin.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_owner_etc_group
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Ensure owner on /etc/group
ansible.builtin.file:
path: /etc/group
follow: false
owner: '{{ file_owner_etc_group_newown }}'
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_owner_etc_group
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
newown=""
if id "0" >/dev/null 2>&1; then
newown="0"
fi
if [[ -z "$newown" ]]; then
>&2 echo "0 is not a defined user on the system"
else
if ! stat -c "%u %U" "/etc/group" | grep -E -w -q "0"; then
chown --no-dereference "$newown" /etc/group
fi
fi
|
Verify User Who Owns gshadow File
[ref]rule To properly set the owner of /etc/gshadow, run the command:
$ sudo chown root /etc/gshadow
Rationale:The /etc/gshadow file contains group password hashes. Protection of this file
is critical for system security. References:
12, 13, 14, 15, 16, 18, 3, 5, APO01.06, DSS05.04, DSS05.07, DSS06.02, 4.3.3.7.3, SR 2.1, SR 5.2, A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5, CIP-003-8 R5.1.1, CIP-003-8 R5.3, CIP-004-6 R2.3, CIP-007-3 R2.1, CIP-007-3 R2.2, CIP-007-3 R2.3, CIP-007-3 R5.1, CIP-007-3 R5.1.1, CIP-007-3 R5.1.2, CM-6(a), AC-6(1), PR.AC-4, PR.DS-5, SRG-OS-000480-GPOS-00227, R50 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Set the file_owner_etc_gshadow_newown variable if represented by uid
ansible.builtin.set_fact:
file_owner_etc_gshadow_newown: '0'
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- configure_strategy
- file_owner_etc_gshadow
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Test for existence /etc/gshadow
ansible.builtin.stat:
path: /etc/gshadow
register: file_exists
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- configure_strategy
- file_owner_etc_gshadow
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Ensure owner on /etc/gshadow
ansible.builtin.file:
path: /etc/gshadow
follow: false
owner: '{{ file_owner_etc_gshadow_newown }}'
when: file_exists.stat is defined and file_exists.stat.exists
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- configure_strategy
- file_owner_etc_gshadow
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
newown=""
if id "0" >/dev/null 2>&1; then
newown="0"
fi
if [[ -z "$newown" ]]; then
>&2 echo "0 is not a defined user on the system"
else
if ! stat -c "%u %U" "/etc/gshadow" | grep -E -w -q "0"; then
chown --no-dereference "$newown" /etc/gshadow
fi
fi
|
Verify User Who Owns passwd File
[ref]rule To properly set the owner of /etc/passwd, run the command:
$ sudo chown root /etc/passwd
Rationale:The /etc/passwd file contains information about the users that are configured on
the system. Protection of this file is critical for system security. References:
12, 13, 14, 15, 16, 18, 3, 5, 5.5.2.2, APO01.06, DSS05.04, DSS05.07, DSS06.02, 4.3.3.7.3, SR 2.1, SR 5.2, A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5, CIP-003-8 R5.1.1, CIP-003-8 R5.3, CIP-004-6 R2.3, CIP-007-3 R2.1, CIP-007-3 R2.2, CIP-007-3 R2.3, CIP-007-3 R5.1, CIP-007-3 R5.1.1, CIP-007-3 R5.1.2, CM-6(a), AC-6(1), PR.AC-4, PR.DS-5, Req-8.7.c, SRG-OS-000480-GPOS-00227, R50, 2.2.6, 2.2 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Set the file_owner_etc_passwd_newown variable if represented by uid
ansible.builtin.set_fact:
file_owner_etc_passwd_newown: '0'
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_owner_etc_passwd
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Test for existence /etc/passwd
ansible.builtin.stat:
path: /etc/passwd
register: file_exists
tags:
- CJIS-5.5.2.2
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSS-Req-8.7.c
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_owner_etc_passwd
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Ensure owner on /etc/passwd
ansible.builtin.file:
path: /etc/passwd
follow: false
owner: '{{ file_owner_etc_passwd_newown }}'
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_owner_etc_passwd
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
newown=""
if id "0" >/dev/null 2>&1; then
newown="0"
fi
if [[ -z "$newown" ]]; then
>&2 echo "0 is not a defined user on the system"
else
if ! stat -c "%u %U" "/etc/passwd" | grep -E -w -q "0"; then
chown --no-dereference "$newown" /etc/passwd
fi
fi
|
Verify User Who Owns shadow File
[ref]rule To properly set the owner of /etc/shadow, run the command:
$ sudo chown root /etc/shadow
Rationale:The /etc/shadow file contains the list of local
system accounts and stores password hashes. Protection of this file is
critical for system security. Failure to give ownership of this file
to root provides the designated owner with access to sensitive information
which could weaken the system security posture. References:
12, 13, 14, 15, 16, 18, 3, 5, 5.5.2.2, APO01.06, DSS05.04, DSS05.07, DSS06.02, 4.3.3.7.3, SR 2.1, SR 5.2, A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5, CIP-003-8 R5.1.1, CIP-003-8 R5.3, CIP-004-6 R2.3, CIP-007-3 R2.1, CIP-007-3 R2.2, CIP-007-3 R2.3, CIP-007-3 R5.1, CIP-007-3 R5.1.1, CIP-007-3 R5.1.2, CM-6(a), AC-6(1), PR.AC-4, PR.DS-5, Req-8.7.c, SRG-OS-000480-GPOS-00227, R50, 2.2.6, 2.2 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Set the file_owner_etc_shadow_newown variable if represented by uid
ansible.builtin.set_fact:
file_owner_etc_shadow_newown: '0'
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_owner_etc_shadow
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Test for existence /etc/shadow
ansible.builtin.stat:
path: /etc/shadow
register: file_exists
tags:
- CJIS-5.5.2.2
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSS-Req-8.7.c
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_owner_etc_shadow
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Ensure owner on /etc/shadow
ansible.builtin.file:
path: /etc/shadow
follow: false
owner: '{{ file_owner_etc_shadow_newown }}'
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_owner_etc_shadow
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
newown=""
if id "0" >/dev/null 2>&1; then
newown="0"
fi
if [[ -z "$newown" ]]; then
>&2 echo "0 is not a defined user on the system"
else
if ! stat -c "%u %U" "/etc/shadow" | grep -E -w -q "0"; then
chown --no-dereference "$newown" /etc/shadow
fi
fi
|
Verify Permissions on Backup group File
[ref]rule
To properly set the permissions of /etc/group-, run the command:
$ sudo chmod 0644 /etc/group- Rationale:The /etc/group- file is a backup file of /etc/group, and as such,
it contains information regarding groups that are configured on the system.
Protection of this file is important for system security. Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Test for existence /etc/group-
ansible.builtin.stat:
path: /etc/group-
register: file_exists
tags:
- NIST-800-53-AC-6 (1)
- PCI-DSS-Req-8.7.c
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_permissions_backup_etc_group
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Ensure permission u-xs,g-xws,o-xwt on /etc/group-
ansible.builtin.file:
path: /etc/group-
mode: u-xs,g-xws,o-xwt
when: file_exists.stat is defined and file_exists.stat.exists
tags:
- NIST-800-53-AC-6 (1)
- PCI-DSS-Req-8.7.c
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_permissions_backup_etc_group
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
chmod u-xs,g-xws,o-xwt /etc/group-
|
Verify Permissions on Backup gshadow File
[ref]rule
To properly set the permissions of /etc/gshadow-, run the command:
$ sudo chmod 0000 /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. Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Test for existence /etc/gshadow-
ansible.builtin.stat:
path: /etc/gshadow-
register: file_exists
tags:
- NIST-800-53-AC-6 (1)
- configure_strategy
- file_permissions_backup_etc_gshadow
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Ensure permission u-xwrs,g-xwrs,o-xwrt on /etc/gshadow-
ansible.builtin.file:
path: /etc/gshadow-
mode: u-xwrs,g-xwrs,o-xwrt
when: file_exists.stat is defined and file_exists.stat.exists
tags:
- NIST-800-53-AC-6 (1)
- configure_strategy
- file_permissions_backup_etc_gshadow
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
chmod u-xwrs,g-xwrs,o-xwrt /etc/gshadow-
|
Verify Permissions on Backup passwd File
[ref]rule
To properly set the permissions of /etc/passwd-, run the command:
$ sudo chmod 0644 /etc/passwd- Rationale:The /etc/passwd- file is a backup file of /etc/passwd, and as such,
it contains information about the users that are configured on the system.
Protection of this file is critical for system security. Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Test for existence /etc/passwd-
ansible.builtin.stat:
path: /etc/passwd-
register: file_exists
tags:
- NIST-800-53-AC-6 (1)
- PCI-DSS-Req-8.7.c
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_permissions_backup_etc_passwd
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Ensure permission u-xs,g-xws,o-xwt on /etc/passwd-
ansible.builtin.file:
path: /etc/passwd-
mode: u-xs,g-xws,o-xwt
when: file_exists.stat is defined and file_exists.stat.exists
tags:
- NIST-800-53-AC-6 (1)
- PCI-DSS-Req-8.7.c
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_permissions_backup_etc_passwd
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
chmod u-xs,g-xws,o-xwt /etc/passwd-
|
Verify Permissions on Backup shadow File
[ref]rule
To properly set the permissions of /etc/shadow-, run the command:
$ sudo chmod 0000 /etc/shadow- Rationale:The /etc/shadow- file is a backup file of /etc/shadow, and as such,
it contains the list of local system accounts and password hashes.
Protection of this file is critical for system security. Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Test for existence /etc/shadow-
ansible.builtin.stat:
path: /etc/shadow-
register: file_exists
tags:
- NIST-800-53-AC-6 (1)
- PCI-DSS-Req-8.7.c
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_permissions_backup_etc_shadow
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Ensure permission u-xwrs,g-xwrs,o-xwrt on /etc/shadow-
ansible.builtin.file:
path: /etc/shadow-
mode: u-xwrs,g-xwrs,o-xwrt
when: file_exists.stat is defined and file_exists.stat.exists
tags:
- NIST-800-53-AC-6 (1)
- PCI-DSS-Req-8.7.c
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_permissions_backup_etc_shadow
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
chmod u-xwrs,g-xwrs,o-xwrt /etc/shadow-
|
Verify Permissions on group File
[ref]rule
To properly set the permissions of /etc/group, run the command:
$ sudo chmod 0644 /etc/group Rationale:The /etc/group file contains information regarding groups that are configured
on the system. Protection of this file is important for system security. References:
12, 13, 14, 15, 16, 18, 3, 5, 5.5.2.2, APO01.06, DSS05.04, DSS05.07, DSS06.02, 4.3.3.7.3, SR 2.1, SR 5.2, A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5, CIP-003-8 R5.1.1, CIP-003-8 R5.3, CIP-004-6 R2.3, CIP-007-3 R2.1, CIP-007-3 R2.2, CIP-007-3 R2.3, CIP-007-3 R5.1, CIP-007-3 R5.1.1, CIP-007-3 R5.1.2, CM-6(a), AC-6(1), PR.AC-4, PR.DS-5, Req-8.7.c, SRG-OS-000480-GPOS-00227, R50, 2.2.6, 2.2 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Test for existence /etc/group
ansible.builtin.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_permissions_etc_group
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Ensure permission u-xs,g-xws,o-xwt on /etc/group
ansible.builtin.file:
path: /etc/group
mode: u-xs,g-xws,o-xwt
when: file_exists.stat is defined and file_exists.stat.exists
tags:
- CJIS-5.5.2.2
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSS-Req-8.7.c
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_permissions_etc_group
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
chmod u-xs,g-xws,o-xwt /etc/group
|
Verify Permissions on gshadow File
[ref]rule
To properly set the permissions of /etc/gshadow, run the command:
$ sudo chmod 0000 /etc/gshadow Rationale:The /etc/gshadow file contains group password hashes. Protection of this file
is critical for system security. References:
12, 13, 14, 15, 16, 18, 3, 5, APO01.06, DSS05.04, DSS05.07, DSS06.02, 4.3.3.7.3, SR 2.1, SR 5.2, A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5, CIP-003-8 R5.1.1, CIP-003-8 R5.3, CIP-004-6 R2.3, CIP-007-3 R2.1, CIP-007-3 R2.2, CIP-007-3 R2.3, CIP-007-3 R5.1, CIP-007-3 R5.1.1, CIP-007-3 R5.1.2, CM-6(a), AC-6(1), PR.AC-4, PR.DS-5, SRG-OS-000480-GPOS-00227, R50 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Test for existence /etc/gshadow
ansible.builtin.stat:
path: /etc/gshadow
register: file_exists
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- configure_strategy
- file_permissions_etc_gshadow
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Ensure permission u-xwrs,g-xwrs,o-xwrt on /etc/gshadow
ansible.builtin.file:
path: /etc/gshadow
mode: u-xwrs,g-xwrs,o-xwrt
when: file_exists.stat is defined and file_exists.stat.exists
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- configure_strategy
- file_permissions_etc_gshadow
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
chmod u-xwrs,g-xwrs,o-xwrt /etc/gshadow
|
Verify Permissions on passwd File
[ref]rule
To properly set the permissions of /etc/passwd, run the command:
$ sudo chmod 0644 /etc/passwd Rationale:If the /etc/passwd file is writable by a group-owner or the
world the risk of its compromise is increased. The file contains the list of
accounts on the system and associated information, and protection of this file
is critical for system security. References:
12, 13, 14, 15, 16, 18, 3, 5, 5.5.2.2, APO01.06, DSS05.04, DSS05.07, DSS06.02, 4.3.3.7.3, SR 2.1, SR 5.2, A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5, CIP-003-8 R5.1.1, CIP-003-8 R5.3, CIP-004-6 R2.3, CIP-007-3 R2.1, CIP-007-3 R2.2, CIP-007-3 R2.3, CIP-007-3 R5.1, CIP-007-3 R5.1.1, CIP-007-3 R5.1.2, CM-6(a), AC-6(1), PR.AC-4, PR.DS-5, Req-8.7.c, SRG-OS-000480-GPOS-00227, R50, 2.2.6, 2.2 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Test for existence /etc/passwd
ansible.builtin.stat:
path: /etc/passwd
register: file_exists
tags:
- CJIS-5.5.2.2
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSS-Req-8.7.c
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_permissions_etc_passwd
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Ensure permission u-xs,g-xws,o-xwt on /etc/passwd
ansible.builtin.file:
path: /etc/passwd
mode: u-xs,g-xws,o-xwt
when: file_exists.stat is defined and file_exists.stat.exists
tags:
- CJIS-5.5.2.2
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSS-Req-8.7.c
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_permissions_etc_passwd
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
chmod u-xs,g-xws,o-xwt /etc/passwd
|
Verify Permissions on shadow File
[ref]rule
To properly set the permissions of /etc/shadow, run the command:
$ sudo chmod 0000 /etc/shadow Rationale:The /etc/shadow file contains the list of local
system accounts and stores password hashes. Protection of this file is
critical for system security. Failure to give ownership of this file
to root provides the designated owner with access to sensitive information
which could weaken the system security posture. References:
12, 13, 14, 15, 16, 18, 3, 5, 5.5.2.2, APO01.06, DSS05.04, DSS05.07, DSS06.02, 4.3.3.7.3, SR 2.1, SR 5.2, A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5, CIP-003-8 R5.1.1, CIP-003-8 R5.3, CIP-004-6 R2.3, CIP-007-3 R2.1, CIP-007-3 R2.2, CIP-007-3 R2.3, CIP-007-3 R5.1, CIP-007-3 R5.1.1, CIP-007-3 R5.1.2, CM-6(a), AC-6(1), PR.AC-4, PR.DS-5, Req-8.7.c, SRG-OS-000480-GPOS-00227, R50, 2.2.6, 2.2 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Test for existence /etc/shadow
ansible.builtin.stat:
path: /etc/shadow
register: file_exists
tags:
- CJIS-5.5.2.2
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSS-Req-8.7.c
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_permissions_etc_shadow
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Ensure permission u-xwrs,g-xwrs,o-xwrt on /etc/shadow
ansible.builtin.file:
path: /etc/shadow
mode: u-xwrs,g-xwrs,o-xwrt
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_permissions_etc_shadow
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
chmod u-xwrs,g-xwrs,o-xwrt /etc/shadow
|
Ensure All SGID Executables Are Authorized
[ref]ruleThe SGID (set group id) bit should be set only on files that were installed via authorized
means. A straightforward means of identifying unauthorized SGID files is determine if any were
not installed as part of an RPM package, which is cryptographically verified. Investigate the
origin of any unpackaged SGID files. This configuration check considers authorized SGID files
those which were installed via RPM. It is assumed that when an individual has sudo access to
install an RPM and all packages are signed with an organizationally-recognized GPG key, the
software should be considered an approved package on the system. Any SGID file not deployed
through an RPM will be flagged for further review. Warning:
This rule can take a long time to perform the check and might consume a considerable
amount of resources depending on the number of files present on the system. It is not a
problem in most cases, but especially systems with a large number of files can be affected.
See https://access.redhat.com/articles/6999111. Rationale:Executable files with the SGID permission run with the privileges of the owner of the file.
SGID files of uncertain provenance could allow for unprivileged users to elevate privileges.
The presence of these files should be strictly controlled on the system. References:
12, 13, 14, 15, 16, 18, 3, 5, APO01.06, DSS05.04, DSS05.07, DSS06.02, 4.3.3.7.3, SR 2.1, SR 5.2, A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5, CM-6(a), AC-6(1), PR.AC-4, PR.DS-5, R56, 1409 |
Ensure All SUID Executables Are Authorized
[ref]ruleThe SUID (set user id) bit should be set only on files that were installed via authorized
means. A straightforward means of identifying unauthorized SUID files is determine if any were
not installed as part of an RPM package, which is cryptographically verified. Investigate the
origin of any unpackaged SUID files. This configuration check considers authorized SUID files
those which were installed via RPM. It is assumed that when an individual has sudo access to
install an RPM and all packages are signed with an organizationally-recognized GPG key, the
software should be considered an approved package on the system. Any SUID file not deployed
through an RPM will be flagged for further review. Warning:
This rule can take a long time to perform the check and might consume a considerable
amount of resources depending on the number of files present on the system. It is not a
problem in most cases, but especially systems with a large number of files can be affected.
See https://access.redhat.com/articles/6999111. Rationale:Executable files with the SUID permission run with the privileges of the owner of the file.
SUID files of uncertain provenance could allow for unprivileged users to elevate privileges.
The presence of these files should be strictly controlled on the system. References:
12, 13, 14, 15, 16, 18, 3, 5, APO01.06, DSS05.04, DSS05.07, DSS06.02, 4.3.3.7.3, SR 2.1, SR 5.2, A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5, CM-6(a), AC-6(1), PR.AC-4, PR.DS-5, R56, 1409 |
Ensure No World-Writable Files Exist
[ref]ruleIt is generally a good idea to remove global (other) write access to a file when it is
discovered. However, check with documentation for specific applications before making changes.
Also, monitor for recurring world-writable files, as these may be symptoms of a misconfigured
application or user account. Finally, this applies to real files and not virtual files that
are a part of pseudo file systems such as sysfs or procfs. Warning:
This rule can take a long time to perform the check and might consume a considerable
amount of resources depending on the number of files present on the system. It is not a
problem in most cases, but especially systems with a large number of files can be affected.
See https://access.redhat.com/articles/6999111. Rationale:Data in world-writable files can be modified by any user on the system. In almost all
circumstances, files can be configured using a combination of user and group permissions to
support whatever legitimate access is needed without the risk caused by world-writable files. References:
12, 13, 14, 15, 16, 18, 3, 5, APO01.06, DSS05.04, DSS05.07, DSS06.02, 4.3.3.7.3, SR 2.1, SR 5.2, A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5, CIP-003-8 R5.1.1, CIP-003-8 R5.3, CIP-004-6 R2.3, CIP-007-3 R2.1, CIP-007-3 R2.2, CIP-007-3 R2.3, CIP-007-3 R5.1, CIP-007-3 R5.1.1, CIP-007-3 R5.1.2, CM-6(a), AC-6(1), PR.AC-4, PR.DS-5, R54, 1409, 2.2.6, 2.2 Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
FILTER_NODEV=$(awk '/nodev/ { print $2 }' /proc/filesystems | paste -sd,)
# Do not consider /sysroot partition because it contains only the physical
# read-only root on bootable containers.
PARTITIONS=$(findmnt -n -l -k -it $FILTER_NODEV | awk '{ print $1 }' | grep -v "/sysroot")
for PARTITION in $PARTITIONS; do
find "${PARTITION}" -xdev -type f -perm -002 -exec chmod o-w {} \; 2>/dev/null
done
# Ensure /tmp is also fixed when tmpfs is used.
if grep "^tmpfs /tmp" /proc/mounts; then
find /tmp -xdev -type f -perm -002 -exec chmod o-w {} \; 2>/dev/null
fi
|
Ensure All Files Are Owned by a Group
[ref]ruleIf any file is not group-owned by a valid defined group, the cause of the lack of
group-ownership must be investigated. Following this, those files should be deleted or
assigned to an appropriate group. The groups need to be defined in /etc/group
or in /usr/lib/group if nss-altfiles are configured to be used
in /etc/nsswitch.conf.
Locate the mount points related to local devices by the following command:
$ findmnt -n -l -k -it $(awk '/nodev/ { print $2 }' /proc/filesystems | paste -sd,)
For all mount points listed by the previous command, it is necessary to search for files which
do not belong to a valid group using the following command:
$ sudo find MOUNTPOINT -xdev -nogroup 2>/dev/null Warning:
This rule only considers local groups as valid groups.
If you have your groups defined outside /etc/group or /usr/lib/group, the rule won't consider those. Warning:
This rule can take a long time to perform the check and might consume a considerable
amount of resources depending on the number of files present on the system. It is not a
problem in most cases, but especially systems with a large number of files can be affected.
See https://access.redhat.com/articles/6999111. Rationale:Unowned files do not directly imply a security problem, but they are generally a sign that
something is amiss. They may be caused by an intruder, by incorrect software installation or
draft software removal, or by failure to remove all files belonging to a deleted account, or
other similar cases. The files should be repaired so they will not cause problems when
accounts are created in the future, and the cause should be discovered and addressed. References:
1, 11, 12, 13, 14, 15, 16, 18, 3, 5, APO01.06, DSS05.02, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.02, DSS06.03, DSS06.06, DSS06.10, 4.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 5.2, A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.18.1.4, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.1, A.9.2.2, A.9.2.3, A.9.2.4, A.9.2.6, A.9.3.1, A.9.4.1, A.9.4.2, A.9.4.3, A.9.4.4, A.9.4.5, CM-6(a), AC-6(1), PR.AC-1, PR.AC-4, PR.AC-6, PR.AC-7, PR.DS-5, PR.PT-3, SRG-OS-000480-GPOS-00227, R53, 2.2.6, 2.2 |
Ensure All Files Are Owned by a User
[ref]ruleIf any files are not owned by a user, then the cause of their lack of ownership should be
investigated. Following this, the files should be deleted or assigned to an appropriate user.
Locate the mount points related to local devices by the following command:
$ findmnt -n -l -k -it $(awk '/nodev/ { print $2 }' /proc/filesystems | paste -sd,)
For all mount points listed by the previous command, it is necessary to search for files which
do not belong to a valid user using the following command:
$ sudo find MOUNTPOINT -xdev -nouser 2>/dev/null Warning:
For this rule to evaluate centralized user accounts, getent must be working properly
so that running the command getent passwd returns a list of all users in your organization.
If using the System Security Services Daemon (SSSD), enumerate = true must be configured
in your organization's domain to return a complete list of users Warning:
This rule can take a long time to perform the check and might consume a considerable
amount of resources depending on the number of files present on the system. It is not a
problem in most cases, but especially systems with a large number of files can be affected.
See https://access.redhat.com/articles/6999111. Rationale:Unowned files do not directly imply a security problem, but they are generally a sign that
something is amiss. They may be caused by an intruder, by incorrect software installation or
draft software removal, or by failure to remove all files belonging to a deleted account, or
other similar cases. The files should be repaired so they will not cause problems when
accounts are created in the future, and the cause should be discovered and addressed. References:
11, 12, 13, 14, 15, 16, 18, 3, 5, 9, APO01.06, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.04, DSS05.05, DSS05.07, DSS06.02, DSS06.03, DSS06.06, 4.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 5.2, SR 7.6, A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.12.1.2, A.12.5.1, A.12.6.2, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.14.2.2, A.14.2.3, A.14.2.4, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.1, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5, CM-6(a), AC-6(1), PR.AC-4, PR.AC-6, PR.DS-5, PR.IP-1, PR.PT-3, SRG-OS-000480-GPOS-00227, R53, 2.2.6, 2.2 |
Restrict Dynamic Mounting and Unmounting of
Filesystems
[ref]groupLinux includes a number of facilities for the automated addition
and removal of filesystems on a running system. These facilities may be
necessary in many environments, but this capability also carries some risk -- whether direct
risk from allowing users to introduce arbitrary filesystems,
or risk that software flaws in the automated mount facility itself could
allow an attacker to compromise the system.
This command can be used to list the types of filesystems that are
available to the currently executing kernel:
$ find /lib/modules/`uname -r`/kernel/fs -type f -name '*.ko'
If these filesystems are not required then they can be explicitly disabled
in a configuratio file in /etc/modprobe.d. |
| contains 2 rules |
Disable Mounting of cramfs
[ref]rule
To configure the system to prevent the cramfs
kernel module from being loaded, add the following line to the file /etc/modprobe.d/cramfs.conf:
install cramfs /bin/false
This entry will cause a non-zero return value during a cramfs module installation
and additionally convey the meaning of the entry to the user in form of an error message.
If you would like to omit a non-zero return value and an error message, you may want to add a different line instead
(both /bin/true and /bin/false are allowed by OVAL and will be accepted by the scan):
install cramfs /bin/true
This effectively prevents usage of this uncommon filesystem.
The cramfs filesystem type is a compressed read-only
Linux filesystem embedded in small footprint systems. A
cramfs image can be used without having to first
decompress the image.Rationale:Removing support for unneeded filesystem types reduces the local attack surface
of the server. References:
11, 14, 3, 9, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.05, DSS06.06, 3.4.6, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 7.6, A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, A.9.1.2, CM-7(a), CM-7(b), CM-6(a), PR.IP-1, PR.PT-3, SRG-OS-000095-GPOS-00049 |
Disable Mounting of squashfs
[ref]rule
To configure the system to prevent the squashfs
kernel module from being loaded, add the following line to the file /etc/modprobe.d/squashfs.conf:
install squashfs /bin/false
This entry will cause a non-zero return value during a squashfs module installation
and additionally convey the meaning of the entry to the user in form of an error message.
If you would like to omit a non-zero return value and an error message, you may want to add a different line instead
(both /bin/true and /bin/false are allowed by OVAL and will be accepted by the scan):
install squashfs /bin/true
This effectively prevents usage of this uncommon filesystem.
The squashfs filesystem type is a compressed read-only Linux
filesystem embedded in small footprint systems (similar to
cramfs). A squashfs image can be used without having
to first decompress the image.Rationale:Removing support for unneeded filesystem types reduces the local attack
surface of the system. References:
11, 14, 3, 9, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.05, DSS06.06, 3.4.6, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 7.6, A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, A.9.1.2, CM-7(a), CM-7(b), CM-6(a), PR.IP-1, PR.PT-3 |
Restrict Programs from Dangerous Execution Patterns
[ref]groupThe recommendations in this section are designed to
ensure that the system's features to protect against potentially
dangerous program execution are activated.
These protections are applied at the system initialization or
kernel level, and defend against certain types of badly-configured
or compromised programs. |
| contains 7 rules |
Disable Core Dumps
[ref]groupA core dump file is the memory image of an executable
program when it was terminated by the operating system due to
errant behavior. In most cases, only software developers
legitimately need to access these files. The core dump files may
also contain sensitive information, or unnecessarily occupy large
amounts of disk space.
Once a hard limit is set in /etc/security/limits.conf, or
to a file within the /etc/security/limits.d/ directory, a
user cannot increase that limit within his or her own session. If access
to core dumps is required, consider restricting them to only
certain users or groups. See the limits.conf man page for more
information.
The core dumps of setuid programs are further protected. The
sysctl variable fs.suid_dumpable controls whether
the kernel allows core dumps from these programs at all. The default
value of 0 is recommended. |
| contains 4 rules |
Disable core dump backtraces
[ref]ruleThe ProcessSizeMax option in [Coredump] section
of /etc/systemd/coredump.conf or in a drop-in file under
/etc/systemd/coredump.conf.d/ specifies the maximum size in bytes
of a core which will be processed. Core dumps exceeding this size may be
stored, but the backtrace will not be generated. Warning:
If the /etc/systemd/coredump.conf file or a drop-in file under /etc/systemd/coredump.conf.d/
does not already contain the [Coredump] section,
the value will not be configured correctly. Rationale:A core dump includes a memory image taken at the time the operating system
terminates an application. The memory image could contain sensitive data
and is generally useful only for developers or system operators trying to
debug problems.
Enabling core dumps on production systems is not recommended,
however there may be overriding operational requirements to enable advanced
debugging. Permitting temporary enablement of core dumps during such situations
should be reviewed through local needs and policy. Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- NIST-800-53-CM-6
- PCI-DSS-Req-3.2
- PCI-DSSv4-3.3
- PCI-DSSv4-3.3.1
- PCI-DSSv4-3.3.1.1
- coredump_disable_backtraces
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Disable core dump backtraces - Search for a section in files
ansible.builtin.find:
paths: '{{item.path}}'
patterns: '{{item.pattern}}'
contains: ^\s*\[Coredump\]
read_whole_file: true
use_regex: true
register: systemd_dropin_files_with_section
loop:
- path: '{{ ''/etc/systemd/coredump.conf'' | dirname }}'
pattern: '{{ ''/etc/systemd/coredump.conf'' | basename | regex_escape }}'
- path: /etc/systemd/coredump.conf.d
pattern: .*\.conf
when:
- '"kernel" in ansible_facts.packages'
- '"systemd" in ansible_facts.packages'
tags:
- NIST-800-53-CM-6
- PCI-DSS-Req-3.2
- PCI-DSSv4-3.3
- PCI-DSSv4-3.3.1
- PCI-DSSv4-3.3.1.1
- coredump_disable_backtraces
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Disable core dump backtraces - Count number of files which contain the correct
section
ansible.builtin.set_fact:
count_of_systemd_dropin_files_with_section: '{{systemd_dropin_files_with_section.results
| map(attribute=''matched'') | list | map(''int'') | sum}}'
when:
- '"kernel" in ansible_facts.packages'
- '"systemd" in ansible_facts.packages'
tags:
- NIST-800-53-CM-6
- PCI-DSS-Req-3.2
- PCI-DSSv4-3.3
- PCI-DSSv4-3.3.1
- PCI-DSSv4-3.3.1.1
- coredump_disable_backtraces
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Disable core dump backtraces - Add missing configuration to correct section
community.general.ini_file:
path: '{{item}}'
section: Coredump
option: ProcessSizeMax
value: '0'
state: present
no_extra_spaces: true
when:
- '"kernel" in ansible_facts.packages'
- '"systemd" in ansible_facts.packages'
- count_of_systemd_dropin_files_with_section | int > 0
loop: '{{systemd_dropin_files_with_section.results | sum(attribute=''files'', start=[])
| map(attribute=''path'') | list }}'
tags:
- NIST-800-53-CM-6
- PCI-DSS-Req-3.2
- PCI-DSSv4-3.3
- PCI-DSSv4-3.3.1
- PCI-DSSv4-3.3.1.1
- coredump_disable_backtraces
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Disable core dump backtraces - Add configuration to new remediation file
community.general.ini_file:
path: /etc/systemd/coredump.conf.d/complianceascode_hardening.conf
section: Coredump
option: ProcessSizeMax
value: '0'
state: present
no_extra_spaces: true
create: true
when:
- '"kernel" in ansible_facts.packages'
- '"systemd" in ansible_facts.packages'
- count_of_systemd_dropin_files_with_section | int == 0
tags:
- NIST-800-53-CM-6
- PCI-DSS-Req-3.2
- PCI-DSSv4-3.3
- PCI-DSSv4-3.3.1
- PCI-DSSv4-3.3.1.1
- coredump_disable_backtraces
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel && { rpm --quiet -q systemd; }; then
found=false
# set value in all files if they contain section or key
for f in $(echo -n "/etc/systemd/coredump.conf.d/complianceascode_hardening.conf /etc/systemd/coredump.conf.d/*.conf /etc/systemd/coredump.conf"); do
if [ ! -e "$f" ]; then
continue
fi
# find key in section and change value
if grep -qzosP "(?m)^[[:space:]]*\[Coredump\]([^\n\[]*\n+)+?[[:space:]]*ProcessSizeMax" "$f"; then
if ! grep -qzosP "(?m)^[[:space:]]*ProcessSizeMax[[:space:]]*=[[:space:]]*0" "$f"; then
sed -i "/^[[:space:]]*ProcessSizeMax/s/\([[:blank:]]*=[[:blank:]]*\).*/\10/" "$f"
fi
found=true
# find section and add key = value to it
elif grep -qs "^[[:space:]]*\[Coredump\]" "$f"; then
sed -i "/^[[:space:]]*\[Coredump\]/a ProcessSizeMax=0" "$f"
found=true
fi
done
# if section not in any file, append section with key = value to FIRST file in files parameter
if ! $found ; then
file=$(echo "/etc/systemd/coredump.conf.d/complianceascode_hardening.conf /etc/systemd/coredump.conf.d/*.conf /etc/systemd/coredump.conf" | cut -f1 -d ' ')
mkdir -p "$(dirname "$file")"
echo -e "[Coredump]\nProcessSizeMax=0" >> "$file"
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Disable storing core dump
[ref]ruleThe Storage option in [Coredump] section
of /etc/systemd/coredump.conf or a drop-in file in
/etc/systemd/coredump.conf.d/*.conf
can be set to none to disable storing core dumps permanently. Warning:
If the /etc/systemd/coredump.conf file or a drop-in file under /etc/systemd/coredump.conf.d/
does not already contain the [Coredump] section,
the value will not be configured correctly. Rationale:A core dump includes a memory image taken at the time the operating system
terminates an application. The memory image could contain sensitive data
and is generally useful only for developers or system operators trying to
debug problems. Enabling core dumps on production systems is not recommended,
however there may be overriding operational requirements to enable advanced
debugging. Permitting temporary enablement of core dumps during such situations
should be reviewed through local needs and policy. Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- NIST-800-53-CM-6
- PCI-DSS-Req-3.2
- PCI-DSSv4-3.3
- PCI-DSSv4-3.3.1
- PCI-DSSv4-3.3.1.1
- coredump_disable_storage
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Disable storing core dump - Search for a section in files
ansible.builtin.find:
paths: '{{item.path}}'
patterns: '{{item.pattern}}'
contains: ^\s*\[Coredump\]
read_whole_file: true
use_regex: true
register: systemd_dropin_files_with_section
loop:
- path: '{{ ''/etc/systemd/coredump.conf'' | dirname }}'
pattern: '{{ ''/etc/systemd/coredump.conf'' | basename | regex_escape }}'
- path: /etc/systemd/coredump.conf.d
pattern: .*\.conf
when:
- '"kernel" in ansible_facts.packages'
- '"systemd" in ansible_facts.packages'
tags:
- NIST-800-53-CM-6
- PCI-DSS-Req-3.2
- PCI-DSSv4-3.3
- PCI-DSSv4-3.3.1
- PCI-DSSv4-3.3.1.1
- coredump_disable_storage
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Disable storing core dump - Count number of files which contain the correct
section
ansible.builtin.set_fact:
count_of_systemd_dropin_files_with_section: '{{systemd_dropin_files_with_section.results
| map(attribute=''matched'') | list | map(''int'') | sum}}'
when:
- '"kernel" in ansible_facts.packages'
- '"systemd" in ansible_facts.packages'
tags:
- NIST-800-53-CM-6
- PCI-DSS-Req-3.2
- PCI-DSSv4-3.3
- PCI-DSSv4-3.3.1
- PCI-DSSv4-3.3.1.1
- coredump_disable_storage
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Disable storing core dump - Add missing configuration to correct section
community.general.ini_file:
path: '{{item}}'
section: Coredump
option: Storage
value: none
state: present
no_extra_spaces: true
when:
- '"kernel" in ansible_facts.packages'
- '"systemd" in ansible_facts.packages'
- count_of_systemd_dropin_files_with_section | int > 0
loop: '{{systemd_dropin_files_with_section.results | sum(attribute=''files'', start=[])
| map(attribute=''path'') | list }}'
tags:
- NIST-800-53-CM-6
- PCI-DSS-Req-3.2
- PCI-DSSv4-3.3
- PCI-DSSv4-3.3.1
- PCI-DSSv4-3.3.1.1
- coredump_disable_storage
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Disable storing core dump - Add configuration to new remediation file
community.general.ini_file:
path: /etc/systemd/coredump.conf.d/complianceascode_hardening.conf
section: Coredump
option: Storage
value: none
state: present
no_extra_spaces: true
create: true
when:
- '"kernel" in ansible_facts.packages'
- '"systemd" in ansible_facts.packages'
- count_of_systemd_dropin_files_with_section | int == 0
tags:
- NIST-800-53-CM-6
- PCI-DSS-Req-3.2
- PCI-DSSv4-3.3
- PCI-DSSv4-3.3.1
- PCI-DSSv4-3.3.1.1
- coredump_disable_storage
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel && { rpm --quiet -q systemd; }; then
found=false
# set value in all files if they contain section or key
for f in $(echo -n "/etc/systemd/coredump.conf.d/complianceascode_hardening.conf /etc/systemd/coredump.conf.d/*.conf /etc/systemd/coredump.conf"); do
if [ ! -e "$f" ]; then
continue
fi
# find key in section and change value
if grep -qzosP "(?m)^[[:space:]]*\[Coredump\]([^\n\[]*\n+)+?[[:space:]]*Storage" "$f"; then
if ! grep -qzosP "(?m)^[[:space:]]*Storage[[:space:]]*=[[:space:]]*none" "$f"; then
sed -i "/^[[:space:]]*Storage/s/\([[:blank:]]*=[[:blank:]]*\).*/\1none/" "$f"
fi
found=true
# find section and add key = value to it
elif grep -qs "^[[:space:]]*\[Coredump\]" "$f"; then
sed -i "/^[[:space:]]*\[Coredump\]/a Storage=none" "$f"
found=true
fi
done
# if section not in any file, append section with key = value to FIRST file in files parameter
if ! $found ; then
file=$(echo "/etc/systemd/coredump.conf.d/complianceascode_hardening.conf /etc/systemd/coredump.conf.d/*.conf /etc/systemd/coredump.conf" | cut -f1 -d ' ')
mkdir -p "$(dirname "$file")"
echo -e "[Coredump]\nStorage=none" >> "$file"
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Disable Core Dumps for All Users
[ref]ruleTo disable core dumps for all users, add the following line to
/etc/security/limits.conf, or to a file within the
/etc/security/limits.d/ directory:
* hard core 0 Rationale:A core dump includes a memory image taken at the time the operating system
terminates an application. The memory image could contain sensitive data and is generally useful
only for developers trying to debug problems. References:
1, 12, 13, 15, 16, 2, 7, 8, APO13.01, BAI04.04, DSS01.03, DSS03.05, DSS05.07, SR 6.2, SR 7.1, SR 7.2, A.12.1.3, A.17.2.1, CM-6, SC-7(10), DE.CM-1, PR.DS-4, SRG-OS-000480-GPOS-00227, 3.3.1.1, 3.3.1, 3.3 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- NIST-800-53-CM-6
- NIST-800-53-SC-7(10)
- PCI-DSSv4-3.3
- PCI-DSSv4-3.3.1
- PCI-DSSv4-3.3.1.1
- disable_users_coredumps
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Disable Core Dumps for All Users - Set dirs, files and regex variables
ansible.builtin.set_fact:
limits_dropin_dir: /etc/security/limits.d
limits_dropin_file: /etc/security/limits.d/10-ssg-hardening.conf
limits_main_file: /etc/security/limits.conf
limits_correct_regex: ^\s*\*\s+hard\s+core\s+0\s*$
when:
- '"kernel" in ansible_facts.packages'
- '"pam" in ansible_facts.packages'
tags:
- NIST-800-53-CM-6
- NIST-800-53-SC-7(10)
- PCI-DSSv4-3.3
- PCI-DSSv4-3.3.1
- PCI-DSSv4-3.3.1.1
- disable_users_coredumps
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Disable Core Dumps for All Users - Find valid drop-ins for core limit
ansible.builtin.find:
paths: '{{ limits_dropin_dir }}'
patterns: '*.conf'
contains: '{{ limits_correct_regex }}'
file_type: file
register: valid_dropins
failed_when: false
when:
- '"kernel" in ansible_facts.packages'
- '"pam" in ansible_facts.packages'
tags:
- NIST-800-53-CM-6
- NIST-800-53-SC-7(10)
- PCI-DSSv4-3.3
- PCI-DSSv4-3.3.1
- PCI-DSSv4-3.3.1.1
- disable_users_coredumps
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Disable Core Dumps for All Users - Find all drop-ins with any core limit
ansible.builtin.find:
paths: '{{ limits_dropin_dir }}'
patterns: '*.conf'
contains: ^\s*\*\s+hard\s+core\s+
file_type: file
register: all_dropins
failed_when: false
when:
- '"kernel" in ansible_facts.packages'
- '"pam" in ansible_facts.packages'
tags:
- NIST-800-53-CM-6
- NIST-800-53-SC-7(10)
- PCI-DSSv4-3.3
- PCI-DSSv4-3.3.1
- PCI-DSSv4-3.3.1.1
- disable_users_coredumps
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Disable Core Dumps for All Users - Get invalid drop-ins
ansible.builtin.set_fact:
invalid_dropins: '{{ all_dropins.files | rejectattr(''path'', ''in'', valid_dropins.files
| map(attribute=''path'') | list) | map(attribute=''path'') | list }}'
when:
- '"kernel" in ansible_facts.packages'
- '"pam" in ansible_facts.packages'
tags:
- NIST-800-53-CM-6
- NIST-800-53-SC-7(10)
- PCI-DSSv4-3.3
- PCI-DSSv4-3.3.1
- PCI-DSSv4-3.3.1.1
- disable_users_coredumps
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Disable Core Dumps for All Users - Comment invalid * hard core lines in drop-ins
ansible.builtin.replace:
path: '{{ item }}'
regexp: (^\s*\*\s+hard\s+core\s+.*$)
replace: '#\1'
loop: '{{ invalid_dropins }}'
when:
- '"kernel" in ansible_facts.packages'
- '"pam" in ansible_facts.packages'
- invalid_dropins | length > 0
tags:
- NIST-800-53-CM-6
- NIST-800-53-SC-7(10)
- PCI-DSSv4-3.3
- PCI-DSSv4-3.3.1
- PCI-DSSv4-3.3.1.1
- disable_users_coredumps
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Disable Core Dumps for All Users - Check if main limits.conf contains correct
core limit
ansible.builtin.find:
paths: /etc/security
patterns: limits.conf
contains: '{{ limits_correct_regex }}'
file_type: file
register: main_valid
failed_when: false
when:
- '"kernel" in ansible_facts.packages'
- '"pam" in ansible_facts.packages'
- not (valid_dropins.matched | default(0) > 0)
tags:
- NIST-800-53-CM-6
- NIST-800-53-SC-7(10)
- PCI-DSSv4-3.3
- PCI-DSSv4-3.3.1
- PCI-DSSv4-3.3.1.1
- disable_users_coredumps
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Disable Core Dumps for All Users - Set fact if configuration is valid
ansible.builtin.set_fact:
core_limit_valid: '{{ (valid_dropins.matched | default(0)) > 0 or (main_valid.matched
| default(0)) > 0 }}'
when:
- '"kernel" in ansible_facts.packages'
- '"pam" in ansible_facts.packages'
tags:
- NIST-800-53-CM-6
- NIST-800-53-SC-7(10)
- PCI-DSSv4-3.3
- PCI-DSSv4-3.3.1
- PCI-DSSv4-3.3.1.1
- disable_users_coredumps
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Disable Core Dumps for All Users - Ensure drop-in directory exists
ansible.builtin.file:
path: '{{ limits_dropin_dir }}'
state: directory
when:
- '"kernel" in ansible_facts.packages'
- '"pam" in ansible_facts.packages'
- not core_limit_valid
tags:
- NIST-800-53-CM-6
- NIST-800-53-SC-7(10)
- PCI-DSSv4-3.3
- PCI-DSSv4-3.3.1
- PCI-DSSv4-3.3.1.1
- disable_users_coredumps
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Disable Core Dumps for All Users - Deploy 10-ssg-hardening.conf drop-in with
correct core limit
ansible.builtin.copy:
dest: '{{ limits_dropin_file }}'
content: |
* hard core 0
when:
- '"kernel" in ansible_facts.packages'
- '"pam" in ansible_facts.packages'
- not core_limit_valid
tags:
- NIST-800-53-CM-6
- NIST-800-53-SC-7(10)
- PCI-DSSv4-3.3
- PCI-DSSv4-3.3.1
- PCI-DSSv4-3.3.1.1
- disable_users_coredumps
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
|
Disable Core Dumps for SUID programs
[ref]ruleTo set the runtime status of the fs.suid_dumpable kernel parameter, run the following command: $ sudo sysctl -w fs.suid_dumpable=0
To make sure that the setting is persistent, add the following line to a file in the directory /etc/sysctl.d: fs.suid_dumpable = 0 Rationale:The core dump of a setuid program is more likely to contain
sensitive data, as the program itself runs with greater privileges than the
user who initiated execution of the program. Disabling the ability for any
setuid program to write a core file decreases the risk of unauthorized access
of such data. References:
164.308(a)(1)(ii)(D), 164.308(a)(3), 164.308(a)(4), 164.310(b), 164.310(c), 164.312(a), 164.312(e), SI-11(a), SI-11(b), R14, 3.3.1.1, 3.3.1, 3.3 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | medium |
|---|
| Reboot: | true |
|---|
| Strategy: | disable |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- NIST-800-53-SI-11(a)
- NIST-800-53-SI-11(b)
- PCI-DSSv4-3.3
- PCI-DSSv4-3.3.1
- PCI-DSSv4-3.3.1.1
- disable_strategy
- low_complexity
- medium_disruption
- medium_severity
- reboot_required
- sysctl_fs_suid_dumpable
- name: Disable Core Dumps for SUID programs - Set fact for sysctl paths
ansible.builtin.set_fact:
sysctl_paths:
- /etc/sysctl.d/
- /run/sysctl.d/
- /usr/local/lib/sysctl.d/
- /usr/lib/sysctl.d/
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-SI-11(a)
- NIST-800-53-SI-11(b)
- PCI-DSSv4-3.3
- PCI-DSSv4-3.3.1
- PCI-DSSv4-3.3.1.1
- disable_strategy
- low_complexity
- medium_disruption
- medium_severity
- reboot_required
- sysctl_fs_suid_dumpable
- name: Disable Core Dumps for SUID programs - Find all files that contain fs.suid_dumpable
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*fs.suid_dumpable\s*=\s*.*$'
register: find_all_values
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-SI-11(a)
- NIST-800-53-SI-11(b)
- PCI-DSSv4-3.3
- PCI-DSSv4-3.3.1
- PCI-DSSv4-3.3.1.1
- disable_strategy
- low_complexity
- medium_disruption
- medium_severity
- reboot_required
- sysctl_fs_suid_dumpable
- name: Disable Core Dumps for SUID programs - Find all files that set fs.suid_dumpable
to correct value
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*fs.suid_dumpable\s*=\s*0$'
register: find_correct_value
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-SI-11(a)
- NIST-800-53-SI-11(b)
- PCI-DSSv4-3.3
- PCI-DSSv4-3.3.1
- PCI-DSSv4-3.3.1.1
- disable_strategy
- low_complexity
- medium_disruption
- medium_severity
- reboot_required
- sysctl_fs_suid_dumpable
- name: Disable Core Dumps for SUID programs - Comment out any occurrences of fs.suid_dumpable
from config files
ansible.builtin.replace:
path: '{{ item | split(":") | first }}'
regexp: ^[\s]*fs.suid_dumpable
replace: '#fs.suid_dumpable'
loop: '{{ find_all_values.stdout_lines }}'
when:
- '"kernel" in ansible_facts.packages'
- find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
| length > find_correct_value.stdout_lines | length
tags:
- NIST-800-53-SI-11(a)
- NIST-800-53-SI-11(b)
- PCI-DSSv4-3.3
- PCI-DSSv4-3.3.1
- PCI-DSSv4-3.3.1.1
- disable_strategy
- low_complexity
- medium_disruption
- medium_severity
- reboot_required
- sysctl_fs_suid_dumpable
- name: Disable Core Dumps for SUID programs - Ensure sysctl fs.suid_dumpable is set
to 0
ansible.posix.sysctl:
name: fs.suid_dumpable
value: '0'
sysctl_file: /etc/sysctl.conf
state: present
reload: true
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-SI-11(a)
- NIST-800-53-SI-11(b)
- PCI-DSSv4-3.3
- PCI-DSSv4-3.3.1
- PCI-DSSv4-3.3.1.1
- disable_strategy
- low_complexity
- medium_disruption
- medium_severity
- reboot_required
- sysctl_fs_suid_dumpable
|
Enable ExecShield
[ref]groupExecShield describes kernel features that provide
protection against exploitation of memory corruption errors such as buffer
overflows. These features include random placement of the stack and other
memory regions, prevention of execution in memory that should only hold data,
and special handling of text buffers. These protections are enabled by default
on 32-bit systems and controlled through sysctl variables
kernel.exec-shield and kernel.randomize_va_space. On the latest
64-bit systems, kernel.exec-shield cannot be enabled or disabled with
sysctl. |
| contains 2 rules |
Restrict Exposed Kernel Pointer Addresses Access
[ref]ruleTo set the runtime status of the kernel.kptr_restrict kernel parameter, run the following command: $ sudo sysctl -w kernel.kptr_restrict=1
To make sure that the setting is persistent, add the following line to a file in the directory /etc/sysctl.d: kernel.kptr_restrict = 1 Rationale:Exposing kernel pointers (through procfs or seq_printf()) exposes kernel
writeable structures which may contain functions pointers. If a write vulnerability
occurs in the kernel, allowing write access to any of this structure, the kernel can
be compromised. This option disallow any program without the CAP_SYSLOG capability
to get the addresses of kernel pointers by replacing them with 0. References:
CIP-002-5 R1.1, CIP-002-5 R1.2, CIP-003-8 R5.1.1, CIP-003-8 R5.3, CIP-004-6 4.1, CIP-004-6 4.2, CIP-004-6 R2.2.3, CIP-004-6 R2.2.4, CIP-004-6 R2.3, CIP-004-6 R4, CIP-005-6 R1, CIP-005-6 R1.1, CIP-005-6 R1.2, CIP-007-3 R3, CIP-007-3 R3.1, CIP-007-3 R5.1, CIP-007-3 R5.1.2, CIP-007-3 R5.1.3, CIP-007-3 R5.2.1, CIP-007-3 R5.2.3, CIP-007-3 R8.4, CIP-009-6 R.1.1, CIP-009-6 R4, SC-30, SC-30(2), SC-30(5), CM-6(a), FMT_SMF_EXT.1, SRG-OS-000132-GPOS-00067, SRG-OS-000433-GPOS-00192, SRG-OS-000480-GPOS-00227, R9, 1409 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | medium |
|---|
| Reboot: | true |
|---|
| Strategy: | disable |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-SC-30
- NIST-800-53-SC-30(2)
- NIST-800-53-SC-30(5)
- disable_strategy
- low_complexity
- medium_disruption
- medium_severity
- reboot_required
- sysctl_kernel_kptr_restrict
- name: XCCDF Value sysctl_kernel_kptr_restrict_value # promote to variable
set_fact:
sysctl_kernel_kptr_restrict_value: !!str 1
tags:
- always
- name: Restrict Exposed Kernel Pointer Addresses Access - Set fact for sysctl paths
ansible.builtin.set_fact:
sysctl_paths:
- /etc/sysctl.d/
- /run/sysctl.d/
- /usr/local/lib/sysctl.d/
- /usr/lib/sysctl.d/
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-SC-30
- NIST-800-53-SC-30(2)
- NIST-800-53-SC-30(5)
- disable_strategy
- low_complexity
- medium_disruption
- medium_severity
- reboot_required
- sysctl_kernel_kptr_restrict
- name: Restrict Exposed Kernel Pointer Addresses Access - Find all files that contain
kernel.kptr_restrict
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*kernel.kptr_restrict\s*=\s*.*$'
register: find_all_values
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-SC-30
- NIST-800-53-SC-30(2)
- NIST-800-53-SC-30(5)
- disable_strategy
- low_complexity
- medium_disruption
- medium_severity
- reboot_required
- sysctl_kernel_kptr_restrict
- name: Restrict Exposed Kernel Pointer Addresses Access - Find all files that set
kernel.kptr_restrict to correct value
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*kernel.kptr_restrict\s*=\s*{{ sysctl_kernel_kptr_restrict_value }}$'
register: find_correct_value
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-SC-30
- NIST-800-53-SC-30(2)
- NIST-800-53-SC-30(5)
- disable_strategy
- low_complexity
- medium_disruption
- medium_severity
- reboot_required
- sysctl_kernel_kptr_restrict
- name: Restrict Exposed Kernel Pointer Addresses Access - Comment out any occurrences
of kernel.kptr_restrict from config files
ansible.builtin.replace:
path: '{{ item | split(":") | first }}'
regexp: ^[\s]*kernel.kptr_restrict
replace: '#kernel.kptr_restrict'
loop: '{{ find_all_values.stdout_lines }}'
when:
- '"kernel" in ansible_facts.packages'
- find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
| length > find_correct_value.stdout_lines | length
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-SC-30
- NIST-800-53-SC-30(2)
- NIST-800-53-SC-30(5)
- disable_strategy
- low_complexity
- medium_disruption
- medium_severity
- reboot_required
- sysctl_kernel_kptr_restrict
- name: Restrict Exposed Kernel Pointer Addresses Access - Ensure sysctl kernel.kptr_restrict
is set
ansible.posix.sysctl:
name: kernel.kptr_restrict
value: '{{ sysctl_kernel_kptr_restrict_value }}'
sysctl_file: /etc/sysctl.conf
state: present
reload: true
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-SC-30
- NIST-800-53-SC-30(2)
- NIST-800-53-SC-30(5)
- disable_strategy
- low_complexity
- medium_disruption
- medium_severity
- reboot_required
- sysctl_kernel_kptr_restrict
|
Enable Randomized Layout of Virtual Address Space
[ref]ruleTo set the runtime status of the kernel.randomize_va_space kernel parameter, run the following command: $ sudo sysctl -w kernel.randomize_va_space=2
To make sure that the setting is persistent, add the following line to a file in the directory /etc/sysctl.d: kernel.randomize_va_space = 2 Rationale:Address space layout randomization (ASLR) makes it more difficult for an
attacker to predict the location of attack code they have introduced into a
process's address space during an attempt at exploitation. Additionally,
ASLR makes it more difficult for an attacker to know the location of
existing code in order to re-purpose it using return oriented programming
(ROP) techniques. References:
3.1.7, 164.308(a)(1)(ii)(D), 164.308(a)(3), 164.308(a)(4), 164.310(b), 164.310(c), 164.312(a), 164.312(e), CIP-002-5 R1.1, CIP-002-5 R1.2, CIP-003-8 R5.1.1, CIP-003-8 R5.3, CIP-004-6 4.1, CIP-004-6 4.2, CIP-004-6 R2.2.3, CIP-004-6 R2.2.4, CIP-004-6 R2.3, CIP-004-6 R4, CIP-005-6 R1, CIP-005-6 R1.1, CIP-005-6 R1.2, CIP-007-3 R3, CIP-007-3 R3.1, CIP-007-3 R5.1, CIP-007-3 R5.1.2, CIP-007-3 R5.1.3, CIP-007-3 R5.2.1, CIP-007-3 R5.2.3, CIP-007-3 R8.4, CIP-009-6 R.1.1, CIP-009-6 R4, SC-30, SC-30(2), CM-6(a), Req-2.2.1, SRG-OS-000433-GPOS-00193, SRG-OS-000480-GPOS-00227, SRG-APP-000450-CTR-001105, R9, 1409, 3.3.1.1, 3.3.1, 3.3 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | medium |
|---|
| Reboot: | true |
|---|
| Strategy: | disable |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- NIST-800-171-3.1.7
- NIST-800-53-CM-6(a)
- NIST-800-53-SC-30
- NIST-800-53-SC-30(2)
- PCI-DSS-Req-2.2.1
- PCI-DSSv4-3.3
- PCI-DSSv4-3.3.1
- PCI-DSSv4-3.3.1.1
- disable_strategy
- low_complexity
- medium_disruption
- medium_severity
- reboot_required
- sysctl_kernel_randomize_va_space
- name: Enable Randomized Layout of Virtual Address Space - Set fact for sysctl paths
ansible.builtin.set_fact:
sysctl_paths:
- /etc/sysctl.d/
- /run/sysctl.d/
- /usr/local/lib/sysctl.d/
- /usr/lib/sysctl.d/
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-171-3.1.7
- NIST-800-53-CM-6(a)
- NIST-800-53-SC-30
- NIST-800-53-SC-30(2)
- PCI-DSS-Req-2.2.1
- PCI-DSSv4-3.3
- PCI-DSSv4-3.3.1
- PCI-DSSv4-3.3.1.1
- disable_strategy
- low_complexity
- medium_disruption
- medium_severity
- reboot_required
- sysctl_kernel_randomize_va_space
- name: Enable Randomized Layout of Virtual Address Space - Find all files that contain
kernel.randomize_va_space
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*kernel.randomize_va_space\s*=\s*.*$'
register: find_all_values
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-171-3.1.7
- NIST-800-53-CM-6(a)
- NIST-800-53-SC-30
- NIST-800-53-SC-30(2)
- PCI-DSS-Req-2.2.1
- PCI-DSSv4-3.3
- PCI-DSSv4-3.3.1
- PCI-DSSv4-3.3.1.1
- disable_strategy
- low_complexity
- medium_disruption
- medium_severity
- reboot_required
- sysctl_kernel_randomize_va_space
- name: Enable Randomized Layout of Virtual Address Space - Find all files that set
kernel.randomize_va_space to correct value
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*kernel.randomize_va_space\s*=\s*2$'
register: find_correct_value
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-171-3.1.7
- NIST-800-53-CM-6(a)
- NIST-800-53-SC-30
- NIST-800-53-SC-30(2)
- PCI-DSS-Req-2.2.1
- PCI-DSSv4-3.3
- PCI-DSSv4-3.3.1
- PCI-DSSv4-3.3.1.1
- disable_strategy
- low_complexity
- medium_disruption
- medium_severity
- reboot_required
- sysctl_kernel_randomize_va_space
- name: Enable Randomized Layout of Virtual Address Space - Comment out any occurrences
of kernel.randomize_va_space from config files
ansible.builtin.replace:
path: '{{ item | split(":") | first }}'
regexp: ^[\s]*kernel.randomize_va_space
replace: '#kernel.randomize_va_space'
loop: '{{ find_all_values.stdout_lines }}'
when:
- '"kernel" in ansible_facts.packages'
- find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
| length > find_correct_value.stdout_lines | length
tags:
- NIST-800-171-3.1.7
- NIST-800-53-CM-6(a)
- NIST-800-53-SC-30
- NIST-800-53-SC-30(2)
- PCI-DSS-Req-2.2.1
- PCI-DSSv4-3.3
- PCI-DSSv4-3.3.1
- PCI-DSSv4-3.3.1.1
- disable_strategy
- low_complexity
- medium_disruption
- medium_severity
- reboot_required
- sysctl_kernel_randomize_va_space
- name: Enable Randomized Layout of Virtual Address Space - Ensure sysctl kernel.randomize_va_space
is set to 2
ansible.posix.sysctl:
name: kernel.randomize_va_space
value: '2'
sysctl_file: /etc/sysctl.conf
state: present
reload: true
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-171-3.1.7
- NIST-800-53-CM-6(a)
- NIST-800-53-SC-30
- NIST-800-53-SC-30(2)
- PCI-DSS-Req-2.2.1
- PCI-DSSv4-3.3
- PCI-DSSv4-3.3.1
- PCI-DSSv4-3.3.1.1
- disable_strategy
- low_complexity
- medium_disruption
- medium_severity
- reboot_required
- sysctl_kernel_randomize_va_space
|
Restrict Access to Kernel Message Buffer
[ref]ruleTo set the runtime status of the kernel.dmesg_restrict kernel parameter, run the following command: $ sudo sysctl -w kernel.dmesg_restrict=1
To make sure that the setting is persistent, add the following line to a file in the directory /etc/sysctl.d: kernel.dmesg_restrict = 1 Rationale:Unprivileged access to the kernel syslog can expose sensitive kernel
address information. References:
3.1.5, 164.308(a)(1)(ii)(D), 164.308(a)(3), 164.308(a)(4), 164.310(b), 164.310(c), 164.312(a), 164.312(e), SI-11(a), SI-11(b), FMT_SMF_EXT.1, SRG-OS-000132-GPOS-00067, SRG-OS-000138-GPOS-00069, SRG-APP-000243-CTR-000600, R9, 1546 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | medium |
|---|
| Reboot: | true |
|---|
| Strategy: | disable |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- NIST-800-171-3.1.5
- NIST-800-53-SI-11(a)
- NIST-800-53-SI-11(b)
- disable_strategy
- low_complexity
- low_severity
- medium_disruption
- reboot_required
- sysctl_kernel_dmesg_restrict
- name: Restrict Access to Kernel Message Buffer - Set fact for sysctl paths
ansible.builtin.set_fact:
sysctl_paths:
- /etc/sysctl.d/
- /run/sysctl.d/
- /usr/local/lib/sysctl.d/
- /usr/lib/sysctl.d/
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-171-3.1.5
- NIST-800-53-SI-11(a)
- NIST-800-53-SI-11(b)
- disable_strategy
- low_complexity
- low_severity
- medium_disruption
- reboot_required
- sysctl_kernel_dmesg_restrict
- name: Restrict Access to Kernel Message Buffer - Find all files that contain kernel.dmesg_restrict
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*kernel.dmesg_restrict\s*=\s*.*$'
register: find_all_values
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-171-3.1.5
- NIST-800-53-SI-11(a)
- NIST-800-53-SI-11(b)
- disable_strategy
- low_complexity
- low_severity
- medium_disruption
- reboot_required
- sysctl_kernel_dmesg_restrict
- name: Restrict Access to Kernel Message Buffer - Find all files that set kernel.dmesg_restrict
to correct value
ansible.builtin.shell:
cmd: find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep
-HP '^\s*kernel.dmesg_restrict\s*=\s*1$'
register: find_correct_value
check_mode: false
changed_when: false
failed_when: false
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-171-3.1.5
- NIST-800-53-SI-11(a)
- NIST-800-53-SI-11(b)
- disable_strategy
- low_complexity
- low_severity
- medium_disruption
- reboot_required
- sysctl_kernel_dmesg_restrict
- name: Restrict Access to Kernel Message Buffer - Comment out any occurrences of
kernel.dmesg_restrict from config files
ansible.builtin.replace:
path: '{{ item | split(":") | first }}'
regexp: ^[\s]*kernel.dmesg_restrict
replace: '#kernel.dmesg_restrict'
loop: '{{ find_all_values.stdout_lines }}'
when:
- '"kernel" in ansible_facts.packages'
- find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
| length > find_correct_value.stdout_lines | length
tags:
- NIST-800-171-3.1.5
- NIST-800-53-SI-11(a)
- NIST-800-53-SI-11(b)
- disable_strategy
- low_complexity
- low_severity
- medium_disruption
- reboot_required
- sysctl_kernel_dmesg_restrict
- name: Restrict Access to Kernel Message Buffer - Ensure sysctl kernel.dmesg_restrict
is set to 1
ansible.posix.sysctl:
name: kernel.dmesg_restrict
value: '1'
sysctl_file: /etc/sysctl.conf
state: present
reload: true
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-171-3.1.5
- NIST-800-53-SI-11(a)
- NIST-800-53-SI-11(b)
- disable_strategy
- low_complexity
- low_severity
- medium_disruption
- reboot_required
- sysctl_kernel_dmesg_restrict
|
Services
[ref]groupThe best protection against vulnerable software is running less software. This section describes how to review
the software which TencentOS Server 4 installs on a system and disable software which is not needed. It
then enumerates the software packages installed on a default TencentOS Server 4 system and provides guidance about which
ones can be safely disabled.
TencentOS Server 4 provides a convenient minimal install option that essentially installs the bare necessities for a functional
system. When building TencentOS Server 4 systems, it is highly recommended to select the minimal packages and then build up
the system from there. |
| contains 65 rules |
Avahi Server
[ref]groupThe Avahi daemon implements the DNS Service Discovery
and Multicast DNS protocols, which provide service and host
discovery on a network. It allows a system to automatically
identify resources on the network, such as printers or web servers.
This capability is also known as mDNSresponder and is a major part
of Zeroconf networking. |
| contains 1 rule |
Disable Avahi Server if Possible
[ref]groupBecause the Avahi daemon service keeps an open network
port, it is subject to network attacks.
Disabling it can reduce the system's vulnerability to such attacks. |
| contains 1 rule |
Uninstall avahi Server Package
[ref]ruleIf the system does not need to have an Avahi server which implements
the DNS Service Discovery and Multicast DNS protocols,
the avahi-autoipd and avahi packages can be uninstalled. Rationale:Automatic discovery of network services is not normally required for
system functionality. It is recommended to remove this package to reduce
the potential attack surface. References:
11, 14, 3, 9, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.05, DSS06.06, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 7.6, A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, A.9.1.2, CM-7(a), CM-7(b), CM-6(a), PR.IP-1, PR.PT-3 Remediation Puppet snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | disable |
|---|
include remove_avahi
class remove_avahi {
package { 'avahi':
ensure => 'purged',
}
}
Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | disable |
|---|
- name: 'Uninstall avahi Server Package: Ensure avahi is removed'
ansible.builtin.package:
name: avahi
state: absent
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-CM-7(a)
- NIST-800-53-CM-7(b)
- disable_strategy
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- package_avahi_removed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | disable |
|---|
# CAUTION: This remediation script will remove avahi
# from the system, and may remove any packages
# that depend on avahi. Execute this
# remediation AFTER testing on a non-production
# system!
if rpm -q --quiet "avahi" ; then
dnf remove -y --noautoremove "avahi"
fi
|
Cron and At Daemons
[ref]groupThe cron and at services are used to allow commands to
be executed at a later time. The cron service is required by almost
all systems to perform necessary maintenance tasks, while at may or
may not be required on a given system. Both daemons should be
configured defensively. |
| contains 27 rules |
Restrict at and cron to Authorized Users if Necessary
[ref]groupThe /etc/cron.allow and /etc/at.allow files contain lists of
users who are allowed to use cron and at to delay execution of
processes. If these files exist and if the corresponding files
/etc/cron.deny and /etc/at.deny do not exist, then only users
listed in the relevant allow files can run the crontab and at commands
to submit jobs to be run at scheduled intervals. On many systems, only the
system administrator needs the ability to schedule jobs. Note that even if a
given user is not listed in cron.allow, cron jobs can still be run as
that user. The cron.allow file controls only administrative access
to the crontab command for scheduling and modifying cron jobs.
To restrict at and cron to only authorized users:
- Remove the
cron.deny file:$ sudo rm /etc/cron.deny - Edit
/etc/cron.allow, adding one line for each user allowed to use
the crontab command to create cron jobs. - Remove the
at.deny file:$ sudo rm /etc/at.deny - Edit
/etc/at.allow, adding one line for each user allowed to use
the at command to create at jobs.
|
| contains 8 rules |
Ensure that /etc/at.deny does not exist
[ref]ruleThe file /etc/at.deny should not exist.
Use /etc/at.allow instead. Rationale:Access to at should be restricted.
It is easier to manage an allow list than a deny list. Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | disable |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- disable_strategy
- file_at_deny_not_exist
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Ensure that /etc/at.deny does not exist - Remove /etc/at.deny
ansible.builtin.file:
path: /etc/at.deny
state: absent
when: '"kernel" in ansible_facts.packages'
tags:
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- disable_strategy
- file_at_deny_not_exist
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | disable |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel; then
if [[ -f /etc/at.deny ]]; then
rm /etc/at.deny
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Ensure that /etc/cron.deny does not exist
[ref]ruleThe file /etc/cron.deny should not exist.
Use /etc/cron.allow instead. Rationale:Access to cron should be restricted.
It is easier to manage an allow list than a deny list. Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | disable |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- disable_strategy
- file_cron_deny_not_exist
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Ensure that /etc/cron.deny does not exist - Remove /etc/cron.deny
ansible.builtin.file:
path: /etc/cron.deny
state: absent
when: '"kernel" in ansible_facts.packages'
tags:
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- disable_strategy
- file_cron_deny_not_exist
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | disable |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel; then
if [[ -f /etc/cron.deny ]]; then
rm /etc/cron.deny
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Verify Group Who Owns /etc/at.allow file
[ref]ruleIf /etc/at.allow exists, it must be group-owned by root.
To properly set the group owner of /etc/at.allow, run the command:
$ sudo chgrp root /etc/at.allow
Rationale:If the owner of the at.allow file is not set to root, the possibility exists for an
unauthorized user to view or edit sensitive information. Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_groupowner_at_allow
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Set the file_groupowner_at_allow_newgroup variable if represented by gid
ansible.builtin.set_fact:
file_groupowner_at_allow_newgroup: '0'
when: '"kernel" in ansible_facts.packages'
tags:
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_groupowner_at_allow
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Test for existence /etc/at.allow
ansible.builtin.stat:
path: /etc/at.allow
register: file_exists
when: '"kernel" in ansible_facts.packages'
tags:
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_groupowner_at_allow
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Ensure group owner on /etc/at.allow
ansible.builtin.file:
path: /etc/at.allow
follow: false
group: '{{ file_groupowner_at_allow_newgroup }}'
when:
- '"kernel" in ansible_facts.packages'
- file_exists.stat is defined and file_exists.stat.exists
tags:
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_groupowner_at_allow
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel; then
newgroup=""
if getent group "0" >/dev/null 2>&1; then
newgroup="0"
fi
if [[ -z "${newgroup}" ]]; then
>&2 echo "0 is not a defined group on the system"
else
if ! stat -c "%g %G" "/etc/at.allow" | grep -E -w -q "0"; then
chgrp --no-dereference "$newgroup" /etc/at.allow
fi
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Verify Group Who Owns /etc/cron.allow file
[ref]ruleIf /etc/cron.allow exists, it must be group-owned by root.
To properly set the group owner of /etc/cron.allow, run the command:
$ sudo chgrp root /etc/cron.allow
Rationale:If the owner of the cron.allow file is not set to root, the possibility exists for an
unauthorized user to view or edit sensitive information. References:
12, 13, 14, 15, 16, 18, 3, 5, APO01.06, DSS05.04, DSS05.07, DSS06.02, 4.3.3.7.3, SR 2.1, SR 5.2, A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5, CM-6(a), AC-6(1), PR.AC-4, PR.DS-5, SRG-OS-000480-GPOS-00227, 2.2.6, 2.2 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_groupowner_cron_allow
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Set the file_groupowner_cron_allow_newgroup variable if represented by gid
ansible.builtin.set_fact:
file_groupowner_cron_allow_newgroup: '0'
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_groupowner_cron_allow
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Test for existence /etc/cron.allow
ansible.builtin.stat:
path: /etc/cron.allow
register: file_exists
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_groupowner_cron_allow
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Ensure group owner on /etc/cron.allow
ansible.builtin.file:
path: /etc/cron.allow
follow: false
group: '{{ file_groupowner_cron_allow_newgroup }}'
when:
- '"kernel" in ansible_facts.packages'
- file_exists.stat is defined and file_exists.stat.exists
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_groupowner_cron_allow
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel; then
newgroup=""
if getent group "0" >/dev/null 2>&1; then
newgroup="0"
fi
if [[ -z "${newgroup}" ]]; then
>&2 echo "0 is not a defined group on the system"
else
if ! stat -c "%g %G" "/etc/cron.allow" | grep -E -w -q "0"; then
chgrp --no-dereference "$newgroup" /etc/cron.allow
fi
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Verify User Who Owns /etc/at.allow file
[ref]ruleIf /etc/at.allow exists, it must be owned by root.
To properly set the owner of /etc/at.allow, run the command:
$ sudo chown root /etc/at.allow
Rationale:If the owner of the at.allow file is not set to root, the possibility exists for an
unauthorized user to view or edit sensitive information. Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_owner_at_allow
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Set the file_owner_at_allow_newown variable if represented by uid
ansible.builtin.set_fact:
file_owner_at_allow_newown: '0'
when: '"kernel" in ansible_facts.packages'
tags:
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_owner_at_allow
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Test for existence /etc/at.allow
ansible.builtin.stat:
path: /etc/at.allow
register: file_exists
when: '"kernel" in ansible_facts.packages'
tags:
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_owner_at_allow
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Ensure owner on /etc/at.allow
ansible.builtin.file:
path: /etc/at.allow
follow: false
owner: '{{ file_owner_at_allow_newown }}'
when:
- '"kernel" in ansible_facts.packages'
- file_exists.stat is defined and file_exists.stat.exists
tags:
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_owner_at_allow
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel; then
newown=""
if id "0" >/dev/null 2>&1; then
newown="0"
fi
if [[ -z "$newown" ]]; then
>&2 echo "0 is not a defined user on the system"
else
if ! stat -c "%u %U" "/etc/at.allow" | grep -E -w -q "0"; then
chown --no-dereference "$newown" /etc/at.allow
fi
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Verify User Who Owns /etc/cron.allow file
[ref]ruleIf /etc/cron.allow exists, it must be owned by root.
To properly set the owner of /etc/cron.allow, run the command:
$ sudo chown root /etc/cron.allow
Rationale:If the owner of the cron.allow file is not set to root, the possibility exists for an
unauthorized user to view or edit sensitive information. References:
12, 13, 14, 15, 16, 18, 3, 5, APO01.06, DSS05.04, DSS05.07, DSS06.02, 4.3.3.7.3, SR 2.1, SR 5.2, A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5, CM-6(a), AC-6(1), PR.AC-4, PR.DS-5, SRG-OS-000480-GPOS-00227, 2.2.6, 2.2 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_owner_cron_allow
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Set the file_owner_cron_allow_newown variable if represented by uid
ansible.builtin.set_fact:
file_owner_cron_allow_newown: '0'
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_owner_cron_allow
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Test for existence /etc/cron.allow
ansible.builtin.stat:
path: /etc/cron.allow
register: file_exists
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_owner_cron_allow
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Ensure owner on /etc/cron.allow
ansible.builtin.file:
path: /etc/cron.allow
follow: false
owner: '{{ file_owner_cron_allow_newown }}'
when:
- '"kernel" in ansible_facts.packages'
- file_exists.stat is defined and file_exists.stat.exists
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_owner_cron_allow
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel; then
newown=""
if id "0" >/dev/null 2>&1; then
newown="0"
fi
if [[ -z "$newown" ]]; then
>&2 echo "0 is not a defined user on the system"
else
if ! stat -c "%u %U" "/etc/cron.allow" | grep -E -w -q "0"; then
chown --no-dereference "$newown" /etc/cron.allow
fi
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Verify Permissions on /etc/at.allow file
[ref]ruleIf /etc/at.allow exists, it must have permissions 0640
or more restrictive.
To properly set the permissions of /etc/at.allow, run the command:
$ sudo chmod 0640 /etc/at.allow Rationale:If the permissions of the at.allow file are not set to 0640 or more restrictive,
the possibility exists for an unauthorized user to view or edit sensitive information. Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_permissions_at_allow
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Test for existence /etc/at.allow
ansible.builtin.stat:
path: /etc/at.allow
register: file_exists
when: '"kernel" in ansible_facts.packages'
tags:
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_permissions_at_allow
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Ensure permission u-xs,g-xws,o-xwrt on /etc/at.allow
ansible.builtin.file:
path: /etc/at.allow
mode: u-xs,g-xws,o-xwrt
when:
- '"kernel" in ansible_facts.packages'
- file_exists.stat is defined and file_exists.stat.exists
tags:
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_permissions_at_allow
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel; then
chmod u-xs,g-xws,o-xwrt /etc/at.allow
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Verify Permissions on /etc/cron.allow file
[ref]ruleIf /etc/cron.allow exists, it must have permissions 0640
or more restrictive.
To properly set the permissions of /etc/cron.allow, run the command:
$ sudo chmod 0640 /etc/cron.allow Rationale:If the permissions of the cron.allow file are not set to 0640 or more restrictive,
the possibility exists for an unauthorized user to view or edit sensitive information. Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_permissions_cron_allow
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Test for existence /etc/cron.allow
ansible.builtin.stat:
path: /etc/cron.allow
register: file_exists
when: '"kernel" in ansible_facts.packages'
tags:
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_permissions_cron_allow
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Ensure permission u-xs,g-xws,o-xwrt on /etc/cron.allow
ansible.builtin.file:
path: /etc/cron.allow
mode: u-xs,g-xws,o-xwrt
when:
- '"kernel" in ansible_facts.packages'
- file_exists.stat is defined and file_exists.stat.exists
tags:
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_permissions_cron_allow
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel; then
chmod u-xs,g-xws,o-xwrt /etc/cron.allow
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Enable cron Service
[ref]ruleThe crond service is used to execute commands at
preconfigured times. It is required by almost all systems to perform necessary
maintenance tasks, such as notifying root of system activity.
The crond service can be enabled with the following command:
$ sudo systemctl enable crond.service Rationale:Due to its usage for maintenance and security-supporting tasks,
enabling the cron daemon is essential. References:
11, 14, 3, 9, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.05, DSS06.06, 164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii), 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 7.6, A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, A.9.1.2, CM-6(a), PR.IP-1, PR.PT-3 Remediation Puppet snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | enable |
|---|
include enable_crond
class enable_crond {
service {'crond':
enable => true,
ensure => 'running',
}
}
Remediation script: (show)
[customizations.services]
enabled = ["crond"]
Remediation Ansible snippet: (show)
| 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
- service_crond_enabled
- name: Enable cron Service - Enable service crond
block:
- name: Gather the package facts
ansible.builtin.package_facts:
manager: auto
- name: Enable cron Service - Enable Service crond
ansible.builtin.systemd:
name: crond
enabled: true
state: started
masked: false
when:
- '"cronie" in ansible_facts.packages'
tags:
- NIST-800-53-CM-6(a)
- enable_strategy
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- service_crond_enabled
- special_service_block
when: '"kernel" in ansible_facts.packages'
|
Verify Group Who Owns cron.d
[ref]rule
To properly set the group owner of /etc/cron.d, run the command:
$ sudo chgrp root /etc/cron.d
Rationale:Service configuration files enable or disable features of their respective services that if configured incorrectly
can lead to insecure and vulnerable configurations. Therefore, service configuration files should be owned by the
correct group to prevent unauthorized changes. References:
12, 13, 14, 15, 16, 18, 3, 5, APO01.06, DSS05.04, DSS05.07, DSS06.02, 4.3.3.7.3, SR 2.1, SR 5.2, A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5, CM-6(a), AC-6(1), PR.AC-4, PR.DS-5, SRG-OS-000480-GPOS-00227, 2.2.6, 2.2 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_groupowner_cron_d
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Set the file_groupowner_cron_d_newgroup variable if represented by gid
ansible.builtin.set_fact:
file_groupowner_cron_d_newgroup: '0'
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_groupowner_cron_d
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Ensure group owner on /etc/cron.d/
ansible.builtin.file:
path: /etc/cron.d/
follow: false
state: directory
group: '{{ file_groupowner_cron_d_newgroup }}'
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_groupowner_cron_d
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel; then
newgroup=""
if getent group "0" >/dev/null 2>&1; then
newgroup="0"
fi
if [[ -z "${newgroup}" ]]; then
>&2 echo "0 is not a defined group on the system"
else
find -P /etc/cron.d/ -maxdepth 0 -type d ! -group 0 -exec chgrp --no-dereference "$newgroup" {} \;
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Verify Group Who Owns cron.daily
[ref]rule
To properly set the group owner of /etc/cron.daily, run the command:
$ sudo chgrp root /etc/cron.daily
Rationale:Service configuration files enable or disable features of their respective services that if configured incorrectly
can lead to insecure and vulnerable configurations. Therefore, service configuration files should be owned by the
correct group to prevent unauthorized changes. References:
12, 13, 14, 15, 16, 18, 3, 5, APO01.06, DSS05.04, DSS05.07, DSS06.02, 4.3.3.7.3, SR 2.1, SR 5.2, A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5, CM-6(a), AC-6(1), PR.AC-4, PR.DS-5, SRG-OS-000480-GPOS-00227, 2.2.6, 2.2 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_groupowner_cron_daily
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Set the file_groupowner_cron_daily_newgroup variable if represented by gid
ansible.builtin.set_fact:
file_groupowner_cron_daily_newgroup: '0'
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_groupowner_cron_daily
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Ensure group owner on /etc/cron.daily/
ansible.builtin.file:
path: /etc/cron.daily/
follow: false
state: directory
group: '{{ file_groupowner_cron_daily_newgroup }}'
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_groupowner_cron_daily
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel; then
newgroup=""
if getent group "0" >/dev/null 2>&1; then
newgroup="0"
fi
if [[ -z "${newgroup}" ]]; then
>&2 echo "0 is not a defined group on the system"
else
find -P /etc/cron.daily/ -maxdepth 0 -type d ! -group 0 -exec chgrp --no-dereference "$newgroup" {} \;
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Verify Group Who Owns cron.hourly
[ref]rule
To properly set the group owner of /etc/cron.hourly, run the command:
$ sudo chgrp root /etc/cron.hourly
Rationale:Service configuration files enable or disable features of their respective services that if configured incorrectly
can lead to insecure and vulnerable configurations. Therefore, service configuration files should be owned by the
correct group to prevent unauthorized changes. References:
12, 13, 14, 15, 16, 18, 3, 5, APO01.06, DSS05.04, DSS05.07, DSS06.02, 4.3.3.7.3, SR 2.1, SR 5.2, A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5, CM-6(a), AC-6(1), PR.AC-4, PR.DS-5, SRG-OS-000480-GPOS-00227, 2.2.6, 2.2 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_groupowner_cron_hourly
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Set the file_groupowner_cron_hourly_newgroup variable if represented by gid
ansible.builtin.set_fact:
file_groupowner_cron_hourly_newgroup: '0'
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_groupowner_cron_hourly
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Ensure group owner on /etc/cron.hourly/
ansible.builtin.file:
path: /etc/cron.hourly/
follow: false
state: directory
group: '{{ file_groupowner_cron_hourly_newgroup }}'
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_groupowner_cron_hourly
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel; then
newgroup=""
if getent group "0" >/dev/null 2>&1; then
newgroup="0"
fi
if [[ -z "${newgroup}" ]]; then
>&2 echo "0 is not a defined group on the system"
else
find -P /etc/cron.hourly/ -maxdepth 0 -type d ! -group 0 -exec chgrp --no-dereference "$newgroup" {} \;
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Verify Group Who Owns cron.monthly
[ref]rule
To properly set the group owner of /etc/cron.monthly, run the command:
$ sudo chgrp root /etc/cron.monthly
Rationale:Service configuration files enable or disable features of their respective services that if configured incorrectly
can lead to insecure and vulnerable configurations. Therefore, service configuration files should be owned by the
correct group to prevent unauthorized changes. References:
12, 13, 14, 15, 16, 18, 3, 5, APO01.06, DSS05.04, DSS05.07, DSS06.02, 4.3.3.7.3, SR 2.1, SR 5.2, A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5, CM-6(a), AC-6(1), PR.AC-4, PR.DS-5, SRG-OS-000480-GPOS-00227, 2.2.6, 2.2 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_groupowner_cron_monthly
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Set the file_groupowner_cron_monthly_newgroup variable if represented by gid
ansible.builtin.set_fact:
file_groupowner_cron_monthly_newgroup: '0'
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_groupowner_cron_monthly
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Ensure group owner on /etc/cron.monthly/
ansible.builtin.file:
path: /etc/cron.monthly/
follow: false
state: directory
group: '{{ file_groupowner_cron_monthly_newgroup }}'
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_groupowner_cron_monthly
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel; then
newgroup=""
if getent group "0" >/dev/null 2>&1; then
newgroup="0"
fi
if [[ -z "${newgroup}" ]]; then
>&2 echo "0 is not a defined group on the system"
else
find -P /etc/cron.monthly/ -maxdepth 0 -type d ! -group 0 -exec chgrp --no-dereference "$newgroup" {} \;
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Verify Group Who Owns cron.weekly
[ref]rule
To properly set the group owner of /etc/cron.weekly, run the command:
$ sudo chgrp root /etc/cron.weekly
Rationale:Service configuration files enable or disable features of their respective services that if configured incorrectly
can lead to insecure and vulnerable configurations. Therefore, service configuration files should be owned by the
correct group to prevent unauthorized changes. References:
12, 13, 14, 15, 16, 18, 3, 5, APO01.06, DSS05.04, DSS05.07, DSS06.02, 4.3.3.7.3, SR 2.1, SR 5.2, A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5, CM-6(a), AC-6(1), PR.AC-4, PR.DS-5, SRG-OS-000480-GPOS-00227, 2.2.6, 2.2 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_groupowner_cron_weekly
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Set the file_groupowner_cron_weekly_newgroup variable if represented by gid
ansible.builtin.set_fact:
file_groupowner_cron_weekly_newgroup: '0'
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_groupowner_cron_weekly
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Ensure group owner on /etc/cron.weekly/
ansible.builtin.file:
path: /etc/cron.weekly/
follow: false
state: directory
group: '{{ file_groupowner_cron_weekly_newgroup }}'
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_groupowner_cron_weekly
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel; then
newgroup=""
if getent group "0" >/dev/null 2>&1; then
newgroup="0"
fi
if [[ -z "${newgroup}" ]]; then
>&2 echo "0 is not a defined group on the system"
else
find -P /etc/cron.weekly/ -maxdepth 0 -type d ! -group 0 -exec chgrp --no-dereference "$newgroup" {} \;
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Verify Group Who Owns Crontab
[ref]rule
To properly set the group owner of /etc/crontab, run the command:
$ sudo chgrp root /etc/crontab
Rationale:Service configuration files enable or disable features of their respective services that if configured incorrectly
can lead to insecure and vulnerable configurations. Therefore, service configuration files should be owned by the
correct group to prevent unauthorized changes. References:
12, 13, 14, 15, 16, 18, 3, 5, APO01.06, DSS05.04, DSS05.07, DSS06.02, 4.3.3.7.3, SR 2.1, SR 5.2, A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5, CM-6(a), AC-6(1), PR.AC-4, PR.DS-5, SRG-OS-000480-GPOS-00227, 2.2.6, 2.2 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_groupowner_crontab
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Set the file_groupowner_crontab_newgroup variable if represented by gid
ansible.builtin.set_fact:
file_groupowner_crontab_newgroup: '0'
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_groupowner_crontab
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Test for existence /etc/crontab
ansible.builtin.stat:
path: /etc/crontab
register: file_exists
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_groupowner_crontab
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Ensure group owner on /etc/crontab
ansible.builtin.file:
path: /etc/crontab
follow: false
group: '{{ file_groupowner_crontab_newgroup }}'
when:
- '"kernel" in ansible_facts.packages'
- file_exists.stat is defined and file_exists.stat.exists
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_groupowner_crontab
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel; then
newgroup=""
if getent group "0" >/dev/null 2>&1; then
newgroup="0"
fi
if [[ -z "${newgroup}" ]]; then
>&2 echo "0 is not a defined group on the system"
else
if ! stat -c "%g %G" "/etc/crontab" | grep -E -w -q "0"; then
chgrp --no-dereference "$newgroup" /etc/crontab
fi
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Verify Owner on cron.d
[ref]rule
To properly set the owner of /etc/cron.d, run the command:
$ sudo chown root /etc/cron.d
Rationale:Service configuration files enable or disable features of their respective services that if configured incorrectly
can lead to insecure and vulnerable configurations. Therefore, service configuration files should be owned by the
correct user to prevent unauthorized changes. References:
12, 13, 14, 15, 16, 18, 3, 5, APO01.06, DSS05.04, DSS05.07, DSS06.02, 4.3.3.7.3, SR 2.1, SR 5.2, A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5, CM-6(a), AC-6(1), PR.AC-4, PR.DS-5, SRG-OS-000480-GPOS-00227, 2.2.6, 2.2 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_owner_cron_d
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Set the file_owner_cron_d_newown variable if represented by uid
ansible.builtin.set_fact:
file_owner_cron_d_newown: '0'
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_owner_cron_d
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Ensure owner on directory /etc/cron.d/
ansible.builtin.file:
path: /etc/cron.d/
follow: false
state: directory
owner: '{{ file_owner_cron_d_newown }}'
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_owner_cron_d
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel; then
newown=""
if id "0" >/dev/null 2>&1; then
newown="0"
fi
if [[ -z "$newown" ]]; then
>&2 echo "0 is not a defined user on the system"
else
find -P /etc/cron.d/ -maxdepth 0 -type d ! -user 0 -exec chown --no-dereference "$newown" {} \;
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Verify Owner on cron.daily
[ref]rule
To properly set the owner of /etc/cron.daily, run the command:
$ sudo chown root /etc/cron.daily
Rationale:Service configuration files enable or disable features of their respective services that if configured incorrectly
can lead to insecure and vulnerable configurations. Therefore, service configuration files should be owned by the
correct user to prevent unauthorized changes. References:
12, 13, 14, 15, 16, 18, 3, 5, APO01.06, DSS05.04, DSS05.07, DSS06.02, 4.3.3.7.3, SR 2.1, SR 5.2, A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5, CM-6(a), AC-6(1), PR.AC-4, PR.DS-5, SRG-OS-000480-GPOS-00227, 2.2.6, 2.2 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_owner_cron_daily
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Set the file_owner_cron_daily_newown variable if represented by uid
ansible.builtin.set_fact:
file_owner_cron_daily_newown: '0'
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_owner_cron_daily
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Ensure owner on directory /etc/cron.daily/
ansible.builtin.file:
path: /etc/cron.daily/
follow: false
state: directory
owner: '{{ file_owner_cron_daily_newown }}'
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_owner_cron_daily
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel; then
newown=""
if id "0" >/dev/null 2>&1; then
newown="0"
fi
if [[ -z "$newown" ]]; then
>&2 echo "0 is not a defined user on the system"
else
find -P /etc/cron.daily/ -maxdepth 0 -type d ! -user 0 -exec chown --no-dereference "$newown" {} \;
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Verify Owner on cron.hourly
[ref]rule
To properly set the owner of /etc/cron.hourly, run the command:
$ sudo chown root /etc/cron.hourly
Rationale:Service configuration files enable or disable features of their respective services that if configured incorrectly
can lead to insecure and vulnerable configurations. Therefore, service configuration files should be owned by the
correct user to prevent unauthorized changes. References:
12, 13, 14, 15, 16, 18, 3, 5, APO01.06, DSS05.04, DSS05.07, DSS06.02, 4.3.3.7.3, SR 2.1, SR 5.2, A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5, CM-6(a), AC-6(1), PR.AC-4, PR.DS-5, SRG-OS-000480-GPOS-00227, 2.2.6, 2.2 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_owner_cron_hourly
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Set the file_owner_cron_hourly_newown variable if represented by uid
ansible.builtin.set_fact:
file_owner_cron_hourly_newown: '0'
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_owner_cron_hourly
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Ensure owner on directory /etc/cron.hourly/
ansible.builtin.file:
path: /etc/cron.hourly/
follow: false
state: directory
owner: '{{ file_owner_cron_hourly_newown }}'
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_owner_cron_hourly
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel; then
newown=""
if id "0" >/dev/null 2>&1; then
newown="0"
fi
if [[ -z "$newown" ]]; then
>&2 echo "0 is not a defined user on the system"
else
find -P /etc/cron.hourly/ -maxdepth 0 -type d ! -user 0 -exec chown --no-dereference "$newown" {} \;
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Verify Owner on cron.monthly
[ref]rule
To properly set the owner of /etc/cron.monthly, run the command:
$ sudo chown root /etc/cron.monthly
Rationale:Service configuration files enable or disable features of their respective services that if configured incorrectly
can lead to insecure and vulnerable configurations. Therefore, service configuration files should be owned by the
correct user to prevent unauthorized changes. References:
12, 13, 14, 15, 16, 18, 3, 5, APO01.06, DSS05.04, DSS05.07, DSS06.02, 4.3.3.7.3, SR 2.1, SR 5.2, A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5, CM-6(a), AC-6(1), PR.AC-4, PR.DS-5, SRG-OS-000480-GPOS-00227, 2.2.6, 2.2 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_owner_cron_monthly
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Set the file_owner_cron_monthly_newown variable if represented by uid
ansible.builtin.set_fact:
file_owner_cron_monthly_newown: '0'
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_owner_cron_monthly
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Ensure owner on directory /etc/cron.monthly/
ansible.builtin.file:
path: /etc/cron.monthly/
follow: false
state: directory
owner: '{{ file_owner_cron_monthly_newown }}'
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_owner_cron_monthly
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel; then
newown=""
if id "0" >/dev/null 2>&1; then
newown="0"
fi
if [[ -z "$newown" ]]; then
>&2 echo "0 is not a defined user on the system"
else
find -P /etc/cron.monthly/ -maxdepth 0 -type d ! -user 0 -exec chown --no-dereference "$newown" {} \;
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Verify Owner on cron.weekly
[ref]rule
To properly set the owner of /etc/cron.weekly, run the command:
$ sudo chown root /etc/cron.weekly
Rationale:Service configuration files enable or disable features of their respective services that if configured incorrectly
can lead to insecure and vulnerable configurations. Therefore, service configuration files should be owned by the
correct user to prevent unauthorized changes. References:
12, 13, 14, 15, 16, 18, 3, 5, APO01.06, DSS05.04, DSS05.07, DSS06.02, 4.3.3.7.3, SR 2.1, SR 5.2, A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5, CM-6(a), AC-6(1), PR.AC-4, PR.DS-5, SRG-OS-000480-GPOS-00227, 2.2.6, 2.2 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_owner_cron_weekly
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Set the file_owner_cron_weekly_newown variable if represented by uid
ansible.builtin.set_fact:
file_owner_cron_weekly_newown: '0'
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_owner_cron_weekly
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Ensure owner on directory /etc/cron.weekly/
ansible.builtin.file:
path: /etc/cron.weekly/
follow: false
state: directory
owner: '{{ file_owner_cron_weekly_newown }}'
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_owner_cron_weekly
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel; then
newown=""
if id "0" >/dev/null 2>&1; then
newown="0"
fi
if [[ -z "$newown" ]]; then
>&2 echo "0 is not a defined user on the system"
else
find -P /etc/cron.weekly/ -maxdepth 0 -type d ! -user 0 -exec chown --no-dereference "$newown" {} \;
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Verify Owner on crontab
[ref]rule
To properly set the owner of /etc/crontab, run the command:
$ sudo chown root /etc/crontab
Rationale:Service configuration files enable or disable features of their respective services that if configured incorrectly
can lead to insecure and vulnerable configurations. Therefore, service configuration files should be owned by the
correct user to prevent unauthorized changes. References:
12, 13, 14, 15, 16, 18, 3, 5, APO01.06, DSS05.04, DSS05.07, DSS06.02, 4.3.3.7.3, SR 2.1, SR 5.2, A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5, CM-6(a), AC-6(1), PR.AC-4, PR.DS-5, SRG-OS-000480-GPOS-00227, 2.2.6, 2.2 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_owner_crontab
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Set the file_owner_crontab_newown variable if represented by uid
ansible.builtin.set_fact:
file_owner_crontab_newown: '0'
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_owner_crontab
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Test for existence /etc/crontab
ansible.builtin.stat:
path: /etc/crontab
register: file_exists
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_owner_crontab
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Ensure owner on /etc/crontab
ansible.builtin.file:
path: /etc/crontab
follow: false
owner: '{{ file_owner_crontab_newown }}'
when:
- '"kernel" in ansible_facts.packages'
- file_exists.stat is defined and file_exists.stat.exists
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_owner_crontab
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel; then
newown=""
if id "0" >/dev/null 2>&1; then
newown="0"
fi
if [[ -z "$newown" ]]; then
>&2 echo "0 is not a defined user on the system"
else
if ! stat -c "%u %U" "/etc/crontab" | grep -E -w -q "0"; then
chown --no-dereference "$newown" /etc/crontab
fi
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Verify Permissions on cron.d
[ref]rule
To properly set the permissions of /etc/cron.d, run the command:
$ sudo chmod 0700 /etc/cron.d Rationale:Service configuration files enable or disable features of their respective services that if configured incorrectly
can lead to insecure and vulnerable configurations. Therefore, service configuration files should have the
correct access rights to prevent unauthorized changes. References:
12, 13, 14, 15, 16, 18, 3, 5, APO01.06, DSS05.04, DSS05.07, DSS06.02, 4.3.3.7.3, SR 2.1, SR 5.2, A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5, CM-6(a), AC-6(1), PR.AC-4, PR.DS-5, SRG-OS-000480-GPOS-00227, 2.2.6, 2.2 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- 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_cron_d
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Find /etc/cron.d/ file(s)
ansible.builtin.command: 'find -P /etc/cron.d/ -maxdepth 0 -perm /u+s,g+xwrs,o+xwrt -type
d '
register: files_found
changed_when: false
failed_when: false
check_mode: false
when: '"kernel" in ansible_facts.packages'
tags:
- 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_cron_d
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Set permissions for /etc/cron.d/ file(s)
ansible.builtin.file:
path: '{{ item }}'
mode: u-s,g-xwrs,o-xwrt
state: directory
with_items:
- '{{ files_found.stdout_lines }}'
when: '"kernel" in ansible_facts.packages'
tags:
- 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_cron_d
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel; then
find -H /etc/cron.d/ -maxdepth 0 -perm /u+s,g+xwrs,o+xwrt -type d -exec chmod u-s,g-xwrs,o-xwrt {} \;
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Verify Permissions on cron.daily
[ref]rule
To properly set the permissions of /etc/cron.daily, run the command:
$ sudo chmod 0700 /etc/cron.daily Rationale:Service configuration files enable or disable features of their respective services that if configured incorrectly
can lead to insecure and vulnerable configurations. Therefore, service configuration files should have the
correct access rights to prevent unauthorized changes. References:
12, 13, 14, 15, 16, 18, 3, 5, APO01.06, DSS05.04, DSS05.07, DSS06.02, 4.3.3.7.3, SR 2.1, SR 5.2, A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5, CM-6(a), AC-6(1), PR.AC-4, PR.DS-5, SRG-OS-000480-GPOS-00227, 2.2.6, 2.2 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- 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_cron_daily
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Find /etc/cron.daily/ file(s)
ansible.builtin.command: 'find -P /etc/cron.daily/ -maxdepth 0 -perm /u+s,g+xwrs,o+xwrt -type
d '
register: files_found
changed_when: false
failed_when: false
check_mode: false
when: '"kernel" in ansible_facts.packages'
tags:
- 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_cron_daily
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Set permissions for /etc/cron.daily/ file(s)
ansible.builtin.file:
path: '{{ item }}'
mode: u-s,g-xwrs,o-xwrt
state: directory
with_items:
- '{{ files_found.stdout_lines }}'
when: '"kernel" in ansible_facts.packages'
tags:
- 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_cron_daily
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel; then
find -H /etc/cron.daily/ -maxdepth 0 -perm /u+s,g+xwrs,o+xwrt -type d -exec chmod u-s,g-xwrs,o-xwrt {} \;
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Verify Permissions on cron.hourly
[ref]rule
To properly set the permissions of /etc/cron.hourly, run the command:
$ sudo chmod 0700 /etc/cron.hourly Rationale:Service configuration files enable or disable features of their respective services that if configured incorrectly
can lead to insecure and vulnerable configurations. Therefore, service configuration files should have the
correct access rights to prevent unauthorized changes. References:
12, 13, 14, 15, 16, 18, 3, 5, APO01.06, DSS05.04, DSS05.07, DSS06.02, 4.3.3.7.3, SR 2.1, SR 5.2, A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5, CM-6(a), AC-6(1), PR.AC-4, PR.DS-5, SRG-OS-000480-GPOS-00227, 2.2.6, 2.2 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- 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_cron_hourly
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Find /etc/cron.hourly/ file(s)
ansible.builtin.command: 'find -P /etc/cron.hourly/ -maxdepth 0 -perm /u+s,g+xwrs,o+xwrt -type
d '
register: files_found
changed_when: false
failed_when: false
check_mode: false
when: '"kernel" in ansible_facts.packages'
tags:
- 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_cron_hourly
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Set permissions for /etc/cron.hourly/ file(s)
ansible.builtin.file:
path: '{{ item }}'
mode: u-s,g-xwrs,o-xwrt
state: directory
with_items:
- '{{ files_found.stdout_lines }}'
when: '"kernel" in ansible_facts.packages'
tags:
- 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_cron_hourly
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel; then
find -H /etc/cron.hourly/ -maxdepth 0 -perm /u+s,g+xwrs,o+xwrt -type d -exec chmod u-s,g-xwrs,o-xwrt {} \;
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Verify Permissions on cron.monthly
[ref]rule
To properly set the permissions of /etc/cron.monthly, run the command:
$ sudo chmod 0700 /etc/cron.monthly Rationale:Service configuration files enable or disable features of their respective services that if configured incorrectly
can lead to insecure and vulnerable configurations. Therefore, service configuration files should have the
correct access rights to prevent unauthorized changes. References:
12, 13, 14, 15, 16, 18, 3, 5, APO01.06, DSS05.04, DSS05.07, DSS06.02, 4.3.3.7.3, SR 2.1, SR 5.2, A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5, CM-6(a), AC-6(1), PR.AC-4, PR.DS-5, SRG-OS-000480-GPOS-00227, 2.2.6, 2.2 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- 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_cron_monthly
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Find /etc/cron.monthly/ file(s)
ansible.builtin.command: 'find -P /etc/cron.monthly/ -maxdepth 0 -perm /u+s,g+xwrs,o+xwrt -type
d '
register: files_found
changed_when: false
failed_when: false
check_mode: false
when: '"kernel" in ansible_facts.packages'
tags:
- 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_cron_monthly
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Set permissions for /etc/cron.monthly/ file(s)
ansible.builtin.file:
path: '{{ item }}'
mode: u-s,g-xwrs,o-xwrt
state: directory
with_items:
- '{{ files_found.stdout_lines }}'
when: '"kernel" in ansible_facts.packages'
tags:
- 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_cron_monthly
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel; then
find -H /etc/cron.monthly/ -maxdepth 0 -perm /u+s,g+xwrs,o+xwrt -type d -exec chmod u-s,g-xwrs,o-xwrt {} \;
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Verify Permissions on cron.weekly
[ref]rule
To properly set the permissions of /etc/cron.weekly, run the command:
$ sudo chmod 0700 /etc/cron.weekly Rationale:Service configuration files enable or disable features of their respective services that if configured incorrectly
can lead to insecure and vulnerable configurations. Therefore, service configuration files should have the
correct access rights to prevent unauthorized changes. References:
12, 13, 14, 15, 16, 18, 3, 5, APO01.06, DSS05.04, DSS05.07, DSS06.02, 4.3.3.7.3, SR 2.1, SR 5.2, A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5, CM-6(a), AC-6(1), PR.AC-4, PR.DS-5, SRG-OS-000480-GPOS-00227, 2.2.6, 2.2 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- 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_cron_weekly
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Find /etc/cron.weekly/ file(s)
ansible.builtin.command: 'find -P /etc/cron.weekly/ -maxdepth 0 -perm /u+s,g+xwrs,o+xwrt -type
d '
register: files_found
changed_when: false
failed_when: false
check_mode: false
when: '"kernel" in ansible_facts.packages'
tags:
- 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_cron_weekly
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Set permissions for /etc/cron.weekly/ file(s)
ansible.builtin.file:
path: '{{ item }}'
mode: u-s,g-xwrs,o-xwrt
state: directory
with_items:
- '{{ files_found.stdout_lines }}'
when: '"kernel" in ansible_facts.packages'
tags:
- 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_cron_weekly
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel; then
find -H /etc/cron.weekly/ -maxdepth 0 -perm /u+s,g+xwrs,o+xwrt -type d -exec chmod u-s,g-xwrs,o-xwrt {} \;
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Verify Permissions on crontab
[ref]rule
To properly set the permissions of /etc/crontab, run the command:
$ sudo chmod 0600 /etc/crontab Rationale:Service configuration files enable or disable features of their respective services that if configured incorrectly
can lead to insecure and vulnerable configurations. Therefore, service configuration files should have the
correct access rights to prevent unauthorized changes. References:
12, 13, 14, 15, 16, 18, 3, 5, APO01.06, DSS05.04, DSS05.07, DSS06.02, 4.3.3.7.3, SR 2.1, SR 5.2, A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5, CM-6(a), AC-6(1), PR.AC-4, PR.DS-5, SRG-OS-000480-GPOS-00227, 2.2.6, 2.2 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- 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_crontab
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Test for existence /etc/crontab
ansible.builtin.stat:
path: /etc/crontab
register: file_exists
when: '"kernel" in ansible_facts.packages'
tags:
- 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_crontab
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Ensure permission u-xs,g-xwrs,o-xwrt on /etc/crontab
ansible.builtin.file:
path: /etc/crontab
mode: u-xs,g-xwrs,o-xwrt
when:
- '"kernel" in ansible_facts.packages'
- file_exists.stat is defined and file_exists.stat.exists
tags:
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_permissions_crontab
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel; then
chmod u-xs,g-xwrs,o-xwrt /etc/crontab
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
DNS Server
[ref]groupMost organizations have an operational need to run at
least one nameserver. However, there are many common attacks
involving DNS server software, and this server software should
be disabled on any system
on which it is not needed. |
| contains 2 rules |
Disable DNS Server
[ref]groupDNS software should be disabled on any systems which does not
need to be a nameserver. Note that the BIND DNS server software is
not installed on TencentOS Server 4 by default. The remainder of this section
discusses secure configuration of systems which must be
nameservers. |
| contains 2 rules |
Uninstall bind Package
[ref]ruleThe named service is provided by the bind package.
The bind package can be removed with the following command:
$ sudo dnf remove bind Rationale:If there is no need to make DNS server software available,
removing it provides a safeguard against its activation. References:
11, 14, 3, 9, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.05, DSS06.06, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 7.6, A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, A.9.1.2, CM-7(a), CM-7(b), CM-6(a), PR.IP-1, PR.PT-3 Remediation Puppet snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | disable |
|---|
include remove_bind
class remove_bind {
package { 'bind':
ensure => 'purged',
}
}
Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | disable |
|---|
- name: 'Uninstall bind Package: Ensure bind is removed'
ansible.builtin.package:
name: bind
state: absent
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-CM-7(a)
- NIST-800-53-CM-7(b)
- disable_strategy
- low_complexity
- low_disruption
- low_severity
- no_reboot_needed
- package_bind_removed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | disable |
|---|
# CAUTION: This remediation script will remove bind
# from the system, and may remove any packages
# that depend on bind. Execute this
# remediation AFTER testing on a non-production
# system!
if rpm -q --quiet "bind" ; then
dnf remove -y --noautoremove "bind"
fi
|
Disable named Service
[ref]rule
The named service can be disabled with the following command:
$ sudo systemctl mask --now named.service Rationale:All network services involve some risk of compromise due to
implementation flaws and should be disabled if possible. References:
11, 14, 3, 9, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.05, DSS06.06, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 7.6, A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, A.9.1.2, CM-7(a), CM-7(b), CM-6(a), PR.IP-1, PR.PT-3 Remediation Puppet snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | enable |
|---|
include disable_named
class disable_named {
service {'named':
enable => false,
ensure => 'stopped',
}
}
Remediation script: (show)
[customizations.services]
masked = ["named"]
Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | disable |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-CM-7(a)
- NIST-800-53-CM-7(b)
- disable_strategy
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- service_named_disabled
- name: Disable named Service - Disable service named
block:
- name: Disable named Service - Collect systemd Services Present in the System
ansible.builtin.command: systemctl -q list-unit-files --type service
register: service_exists
changed_when: false
failed_when: service_exists.rc not in [0, 1]
check_mode: false
- name: Disable named Service - Ensure named.service is Masked
ansible.builtin.systemd:
name: named.service
state: stopped
enabled: false
masked: true
when: service_exists.stdout_lines is search("named.service", multiline=True)
- name: Unit Socket Exists - named.socket
ansible.builtin.command: systemctl -q list-unit-files named.socket
register: socket_file_exists
changed_when: false
failed_when: socket_file_exists.rc not in [0, 1]
check_mode: false
- name: Disable named Service - Disable Socket named
ansible.builtin.systemd:
name: named.socket
enabled: false
state: stopped
masked: true
when: socket_file_exists.stdout_lines is search("named.socket", multiline=True)
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-CM-7(a)
- NIST-800-53-CM-7(b)
- disable_strategy
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- service_named_disabled
- special_service_block
when: '"kernel" in ansible_facts.packages'
|
FTP Server
[ref]groupFTP is a common method for allowing remote access to
files. Like telnet, the FTP protocol is unencrypted, which means
that passwords and other data transmitted during the session can be
captured and that the session is vulnerable to hijacking.
Therefore, running the FTP server software is not recommended.
However, there are some FTP server configurations which may
be appropriate for some environments, particularly those which
allow only read-only anonymous access as a means of downloading
data available to the public. |
| contains 2 rules |
Disable vsftpd if Possible
[ref]groupTo minimize attack surface, disable vsftpd if at all
possible. |
| contains 2 rules |
Uninstall vsftpd Package
[ref]ruleThe vsftpd package can be removed with the following command: $ sudo dnf remove vsftpd Rationale:Removing the vsftpd package decreases the risk of its
accidental activation. References:
11, 14, 3, 9, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.05, DSS06.06, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 7.6, A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, A.9.1.2, CM-7(a), CM-7(b), CM-6(a), IA-5(1)(c), IA-5(1).1(v), CM-7, CM-7.1(ii), PR.IP-1, PR.PT-3, SRG-OS-000074-GPOS-00042, SRG-OS-000095-GPOS-00049, SRG-OS-000480-GPOS-00227 Remediation Puppet snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | disable |
|---|
include remove_vsftpd
class remove_vsftpd {
package { 'vsftpd':
ensure => 'purged',
}
}
Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | disable |
|---|
- name: 'Uninstall vsftpd Package: Ensure vsftpd is removed'
ansible.builtin.package:
name: vsftpd
state: absent
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-CM-7
- NIST-800-53-CM-7(a)
- NIST-800-53-CM-7(b)
- NIST-800-53-CM-7.1(ii)
- NIST-800-53-IA-5(1)(c)
- NIST-800-53-IA-5(1).1(v)
- disable_strategy
- high_severity
- low_complexity
- low_disruption
- no_reboot_needed
- package_vsftpd_removed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | disable |
|---|
# CAUTION: This remediation script will remove vsftpd
# from the system, and may remove any packages
# that depend on vsftpd. Execute this
# remediation AFTER testing on a non-production
# system!
if rpm -q --quiet "vsftpd" ; then
dnf remove -y --noautoremove "vsftpd"
fi
|
Disable vsftpd Service
[ref]rule
The vsftpd service can be disabled with the following command:
$ sudo systemctl mask --now vsftpd.service Rationale:Running FTP server software provides a network-based avenue
of attack, and should be disabled if not needed.
Furthermore, the FTP protocol is unencrypted and creates
a risk of compromising sensitive information. References:
11, 14, 3, 9, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.05, DSS06.06, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 7.6, A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, A.9.1.2, CM-7(a), CM-7(b), CM-6(a), PR.IP-1, PR.PT-3 Remediation Puppet snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | enable |
|---|
include disable_vsftpd
class disable_vsftpd {
service {'vsftpd':
enable => false,
ensure => 'stopped',
}
}
Remediation script: (show)
[customizations.services]
masked = ["vsftpd"]
Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | disable |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-CM-7(a)
- NIST-800-53-CM-7(b)
- disable_strategy
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- service_vsftpd_disabled
- name: Disable vsftpd Service - Disable service vsftpd
block:
- name: Disable vsftpd Service - Collect systemd Services Present in the System
ansible.builtin.command: systemctl -q list-unit-files --type service
register: service_exists
changed_when: false
failed_when: service_exists.rc not in [0, 1]
check_mode: false
- name: Disable vsftpd Service - Ensure vsftpd.service is Masked
ansible.builtin.systemd:
name: vsftpd.service
state: stopped
enabled: false
masked: true
when: service_exists.stdout_lines is search("vsftpd.service", multiline=True)
- name: Unit Socket Exists - vsftpd.socket
ansible.builtin.command: systemctl -q list-unit-files vsftpd.socket
register: socket_file_exists
changed_when: false
failed_when: socket_file_exists.rc not in [0, 1]
check_mode: false
- name: Disable vsftpd Service - Disable Socket vsftpd
ansible.builtin.systemd:
name: vsftpd.socket
enabled: false
state: stopped
masked: true
when: socket_file_exists.stdout_lines is search("vsftpd.socket", multiline=True)
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-CM-7(a)
- NIST-800-53-CM-7(b)
- disable_strategy
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- service_vsftpd_disabled
- special_service_block
when: '"kernel" in ansible_facts.packages'
|
Web Server
[ref]groupThe web server is responsible for providing access to
content via the HTTP protocol. Web servers represent a significant
security risk because:
- The HTTP port is commonly probed by malicious sources
- Web server software is very complex, and includes a long
history of vulnerabilities
- The HTTP protocol is unencrypted and vulnerable to passive
monitoring
The system's default web server software is Apache 2 and is
provided in the RPM package httpd. |
| contains 2 rules |
Disable Apache if Possible
[ref]groupIf Apache was installed and activated, but the system
does not need to act as a web server, then it should be disabled
and removed from the system. |
| contains 2 rules |
Uninstall httpd Package
[ref]ruleThe httpd package can be removed with the following command:
$ sudo dnf remove httpd Rationale:If there is no need to make the web server software available,
removing it provides a safeguard against its activation. References:
11, 14, 3, 9, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.05, DSS06.06, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 7.6, A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, A.9.1.2, CM-7(a), CM-7(b), CM-6(a), PR.IP-1, PR.PT-3 Remediation Puppet snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | disable |
|---|
include remove_httpd
class remove_httpd {
package { 'httpd':
ensure => 'purged',
}
}
Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | disable |
|---|
- name: 'Uninstall httpd Package: Ensure httpd is removed'
ansible.builtin.package:
name: httpd
state: absent
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-CM-7(a)
- NIST-800-53-CM-7(b)
- disable_strategy
- low_complexity
- low_disruption
- no_reboot_needed
- package_httpd_removed
- unknown_severity
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | disable |
|---|
# CAUTION: This remediation script will remove httpd
# from the system, and may remove any packages
# that depend on httpd. Execute this
# remediation AFTER testing on a non-production
# system!
if rpm -q --quiet "httpd" ; then
dnf remove -y --noautoremove "httpd"
fi
|
Disable httpd Service
[ref]rule
The httpd service can be disabled with the following command:
$ sudo systemctl mask --now httpd.service Rationale:Running web server software provides a network-based avenue
of attack, and should be disabled if not needed. References:
11, 14, 3, 9, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.05, DSS06.06, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 7.6, A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, A.9.1.2, CM-7(a), CM-7(b), CM-6(a), PR.IP-1, PR.PT-3 Remediation Puppet snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | enable |
|---|
include disable_httpd
class disable_httpd {
service {'httpd':
enable => false,
ensure => 'stopped',
}
}
Remediation script: (show)
[customizations.services]
masked = ["httpd"]
Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | disable |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-CM-7(a)
- NIST-800-53-CM-7(b)
- disable_strategy
- low_complexity
- low_disruption
- no_reboot_needed
- service_httpd_disabled
- unknown_severity
- name: Disable httpd Service - Disable service httpd
block:
- name: Disable httpd Service - Collect systemd Services Present in the System
ansible.builtin.command: systemctl -q list-unit-files --type service
register: service_exists
changed_when: false
failed_when: service_exists.rc not in [0, 1]
check_mode: false
- name: Disable httpd Service - Ensure httpd.service is Masked
ansible.builtin.systemd:
name: httpd.service
state: stopped
enabled: false
masked: true
when: service_exists.stdout_lines is search("httpd.service", multiline=True)
- name: Unit Socket Exists - httpd.socket
ansible.builtin.command: systemctl -q list-unit-files httpd.socket
register: socket_file_exists
changed_when: false
failed_when: socket_file_exists.rc not in [0, 1]
check_mode: false
- name: Disable httpd Service - Disable Socket httpd
ansible.builtin.systemd:
name: httpd.socket
enabled: false
state: stopped
masked: true
when: socket_file_exists.stdout_lines is search("httpd.socket", multiline=True)
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-CM-7(a)
- NIST-800-53-CM-7(b)
- disable_strategy
- low_complexity
- low_disruption
- no_reboot_needed
- service_httpd_disabled
- special_service_block
- unknown_severity
when: '"kernel" in ansible_facts.packages'
|
LDAP is a popular directory service, that is, a
standardized way of looking up information from a central database.
TencentOS Server 4 includes software that enables a system to act as both
an LDAP client and server. |
| contains 1 rule |
Configure OpenLDAP Server
[ref]groupThis section details some security-relevant settings
for an OpenLDAP server. |
| contains 1 rule |
Uninstall openldap-servers Package
[ref]ruleThe openldap-servers package is not installed by default on a TencentOS Server 4
system. It is needed only by the OpenLDAP server, not by the
clients which use LDAP for authentication. If the system is not
intended for use as an LDAP Server it should be removed. Rationale:Unnecessary packages should not be installed to decrease the attack
surface of the system. While this software is clearly essential on an LDAP
server, it is not necessary on typical desktop or workstation systems. References:
11, 14, 3, 9, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.05, DSS06.06, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 7.6, A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, A.9.1.2, CM-7(a), CM-7(b), CM-6(a), PR.IP-1, PR.PT-3 Remediation Puppet snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | disable |
|---|
include remove_openldap-servers
class remove_openldap-servers {
package { 'openldap-servers':
ensure => 'purged',
}
}
Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | disable |
|---|
- name: 'Uninstall openldap-servers Package: Ensure openldap-servers is removed'
ansible.builtin.package:
name: openldap-servers
state: absent
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-CM-7(a)
- NIST-800-53-CM-7(b)
- disable_strategy
- low_complexity
- low_disruption
- low_severity
- no_reboot_needed
- package_openldap-servers_removed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | disable |
|---|
# CAUTION: This remediation script will remove openldap-servers
# from the system, and may remove any packages
# that depend on openldap-servers. Execute this
# remediation AFTER testing on a non-production
# system!
if rpm -q --quiet "openldap-servers" ; then
dnf remove -y --noautoremove "openldap-servers"
fi
|
Network Time Protocol
[ref]groupThe Network Time Protocol is used to manage the system
clock over a network. Computer clocks are not very accurate, so
time will drift unpredictably on unmanaged systems. Central time
protocols can be used both to ensure that time is consistent among
a network of systems, and that their time is consistent with the
outside world.
If every system on a network reliably reports the same time, then it is much
easier to correlate log messages in case of an attack. In addition, a number of
cryptographic protocols (such as Kerberos) use timestamps to prevent certain
types of attacks. If your network does not have synchronized time, these
protocols may be unreliable or even unusable.
Depending on the specifics of the network, global time accuracy may be just as
important as local synchronization, or not very important at all. If your
network is connected to the Internet, using a public timeserver (or one
provided by your enterprise) provides globally accurate timestamps which may be
essential in investigating or responding to an attack which originated outside
of your network.
A typical network setup involves a small number of internal systems operating
as NTP servers, and the remainder obtaining time information from those
internal servers.
There is a choice between the daemons ntpd and chronyd, which
are available from the repositories in the ntp and chrony
packages respectively.
The default chronyd daemon can work well when external time references
are only intermittently accessible, can perform well even when the network is
congested for longer periods of time, can usually synchronize the clock faster
and with better time accuracy, and quickly adapts to sudden changes in the rate
of the clock, for example, due to changes in the temperature of the crystal
oscillator. Chronyd should be considered for all systems which are
frequently suspended or otherwise intermittently disconnected and reconnected
to a network. Mobile and virtual systems for example.
The ntpd NTP daemon fully supports NTP protocol version 4 (RFC 5905),
including broadcast, multicast, manycast clients and servers, and the orphan
mode. It also supports extra authentication schemes based on public-key
cryptography (RFC 5906). The NTP daemon (ntpd) should be considered
for systems which are normally kept permanently on. Systems which are required
to use broadcast or multicast IP, or to perform authentication of packets with
the Autokey protocol, should consider using ntpd.
Refer to
https://en.wikipedia.org/wiki/Network_Time_Protocol
for more detailed comparison of features of chronyd
and ntpd daemon features respectively, and for further guidance how to
choose between the two NTP daemons.
The upstream manual pages at
https://chrony-project.org/documentation.html for
chronyd and
http://www.ntp.org for ntpd provide additional
information on the capabilities and configuration of each of the NTP daemons. |
| contains 4 rules |
The Chrony package is installed
[ref]ruleSystem time should be synchronized between all systems in an environment. This is
typically done by establishing an authoritative time server or set of servers and having all
systems synchronize their clocks to them.
The chrony package can be installed with the following command:
$ sudo dnf install chrony Rationale:Time synchronization is important to support time sensitive security mechanisms like
Kerberos and also ensures log files have consistent time records across the enterprise,
which aids in forensic investigations. Remediation Puppet snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | enable |
|---|
include install_chrony
class install_chrony {
package { 'chrony':
ensure => 'installed',
}
}
Remediation script: (show)
[[packages]]
name = "chrony"
version = "*"
Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | enable |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- PCI-DSS-Req-10.4
- PCI-DSSv4-10.6
- PCI-DSSv4-10.6.1
- enable_strategy
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- package_chrony_installed
- name: Ensure chrony is installed
ansible.builtin.package:
name: chrony
state: present
when: '"kernel" in ansible_facts.packages'
tags:
- PCI-DSS-Req-10.4
- PCI-DSSv4-10.6
- PCI-DSSv4-10.6.1
- enable_strategy
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- package_chrony_installed
|
The Chronyd service is enabled
[ref]rulechrony is a daemon which implements the Network Time Protocol (NTP) is designed to
synchronize system clocks across a variety of systems and use a source that is highly
accurate. More information on chrony can be found at
https://chrony-project.org/.
Chrony can be configured to be a client and/or a server.
To enable Chronyd service, you can run:
# systemctl enable chronyd.service
This recommendation only applies if chrony is in use on the system. Rationale:If chrony is in use on the system proper configuration is vital to ensuring time
synchronization is working properly. Remediation Puppet snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | enable |
|---|
include enable_chronyd
class enable_chronyd {
service {'chronyd':
enable => true,
ensure => 'running',
}
}
Remediation script: (show)
[customizations.services]
enabled = ["chronyd"]
Remediation Ansible snippet: (show)
| 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_chronyd_enabled
- name: The Chronyd service is enabled - Enable service chronyd
block:
- name: Gather the package facts
ansible.builtin.package_facts:
manager: auto
- name: The Chronyd service is enabled - Enable Service chronyd
ansible.builtin.systemd:
name: chronyd
enabled: true
state: started
masked: false
when:
- '"chrony" in ansible_facts.packages'
tags:
- enable_strategy
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- service_chronyd_enabled
- special_service_block
when:
- '"kernel" in ansible_facts.packages'
- '"chrony" in ansible_facts.packages'
|
Chrony Configure Pool and Server
[ref]ruleChrony is a daemon which implements the Network Time Protocol (NTP). It is designed to
synchronize system clocks across a variety of systems and use a source that is highly
accurate. More information on chrony can be found at
https://chrony-project.org/.
Chrony can be configured to be a client and/or a server.
Add or edit server or pool lines to /etc/chrony.conf as appropriate:
server <remote-server>
Multiple servers may be configured.Rationale:If chrony is in use on the system proper configuration is vital to ensuring time
synchronization is working properly. Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- NIST-800-53-AU-8(1)(a)
- NIST-800-53-CM-6(a)
- PCI-DSS-Req-10.4.3
- chronyd_configure_pool_and_server
- configure_strategy
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: XCCDF Value var_multiple_time_servers # promote to variable
set_fact:
var_multiple_time_servers: !!str 0.pool.ntp.org,1.pool.ntp.org,2.pool.ntp.org,3.pool.ntp.org
tags:
- always
- name: XCCDF Value var_multiple_time_pools # promote to variable
set_fact:
var_multiple_time_pools: !!str 0.pool.ntp.org,1.pool.ntp.org,2.pool.ntp.org,3.pool.ntp.org
tags:
- always
- name: Chrony Configure Pool and Server - Add missing / update wrong records for
remote time servers
ansible.builtin.lineinfile:
path: /etc/chrony.conf
regexp: ^\s*\bserver\b\s*\b{{ item }}\b$
state: present
line: server {{ item }}
create: true
with_items:
- '{{ var_multiple_time_servers.split(",") }}'
when:
- '"kernel" in ansible_facts.packages'
- '"chrony" in ansible_facts.packages'
tags:
- NIST-800-53-AU-8(1)(a)
- NIST-800-53-CM-6(a)
- PCI-DSS-Req-10.4.3
- chronyd_configure_pool_and_server
- configure_strategy
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Chrony Configure Pool and Server - Add missing / update wrong records for
remote time pools
ansible.builtin.lineinfile:
path: /etc/chrony.conf
regexp: ^\s*\bpool\b\s*\b{{ item }}\b$
state: present
line: pool {{ item }}
create: true
with_items:
- '{{ var_multiple_time_pools.split(",") }}'
when:
- '"kernel" in ansible_facts.packages'
- '"chrony" in ansible_facts.packages'
tags:
- NIST-800-53-AU-8(1)(a)
- NIST-800-53-CM-6(a)
- PCI-DSS-Req-10.4.3
- chronyd_configure_pool_and_server
- configure_strategy
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
Remediation Shell script: (show)
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel && { rpm --quiet -q chrony; }; then
var_multiple_time_servers='0.pool.ntp.org,1.pool.ntp.org,2.pool.ntp.org,3.pool.ntp.org'
var_multiple_time_pools='0.pool.ntp.org,1.pool.ntp.org,2.pool.ntp.org,3.pool.ntp.org'
config_file="/etc/chrony.conf"
# Check and configigure servers in /etc/chrony.conf
IFS="," read -a SERVERS <<< $var_multiple_time_servers
for srv in "${SERVERS[@]}"
do
NTP_SRV=$(grep -w $srv $config_file)
if [[ ! "$NTP_SRV" == "server "* ]]
then
time_server="server $srv"
echo $time_server >> "$config_file"
fi
done
# Check and configure pools in /etc/chrony.conf
IFS="," read -a POOLS <<< $var_multiple_time_pools
for srv in "${POOLS[@]}"
do
NTP_POOL=$(grep -w $srv $config_file)
if [[ ! "$NTP_POOL" == "pool "* ]]
then
time_server="pool $srv"
echo $time_server >> "$config_file"
fi
done
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Ensure that chronyd is running under chrony user account
[ref]rulechrony is a daemon which implements the Network Time Protocol (NTP). It is designed to
synchronize system clocks across a variety of systems and use a source that is highly
accurate. More information on chrony can be found at
https://chrony-project.org/.
Chrony can be configured to be a client and/or a server.
To ensure that chronyd is running under chrony user account,
add or edit the
OPTIONS variable in /etc/sysconfig/chronyd to include -u chrony:
OPTIONS="-u chrony"
This recommendation only applies if chrony is in use on the system.Rationale:If chrony is in use on the system proper configuration is vital to ensuring time synchronization
is working properly. Remediation Shell script: (show)
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel && { rpm --quiet -q chrony; }; then
if grep -q 'OPTIONS=.*' /etc/sysconfig/chronyd; then
# trying to solve cases where the parameter after OPTIONS
#may or may not be enclosed in quotes
sed -i -E -e 's/\s*-u\s*\w+\s*/ /' -e 's/^([\s]*OPTIONS=["]?[^"]*)("?)/\1 -u chrony\2/' /etc/sysconfig/chronyd
else
echo 'OPTIONS="-u chrony"' >> /etc/sysconfig/chronyd
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Obsolete Services
[ref]groupThis section discusses a number of network-visible
services which have historically caused problems for system
security, and for which disabling or severely limiting the service
has been the best available guidance for some time. As a result of
this, many of these services are not installed as part of TencentOS Server 4
by default.
Organizations which are running these services should
switch to more secure equivalents as soon as possible.
If it remains absolutely necessary to run one of
these services for legacy reasons, care should be taken to restrict
the service as much as possible, for instance by configuring host
firewall software such as iptables to restrict access to the
vulnerable service to only those remote hosts which have a known
need to use it. |
| contains 11 rules |
Xinetd
[ref]groupThe xinetd service acts as a dedicated listener for some
network services (mostly, obsolete ones) and can be used to provide access
controls and perform some logging. It has been largely obsoleted by other
features, and it is not installed by default. The older Inetd service
is not even available as part of TencentOS Server 4. |
| contains 2 rules |
Uninstall xinetd Package
[ref]ruleThe xinetd package can be removed with the following command:
$ sudo dnf remove xinetd Rationale:Removing the xinetd package decreases the risk of the
xinetd service's accidental (or intentional) activation. References:
11, 12, 14, 15, 3, 8, 9, APO13.01, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS01.04, DSS05.02, DSS05.03, DSS05.05, DSS06.06, 164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii), 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 7.1, SR 7.6, A.11.2.6, A.12.1.2, A.12.5.1, A.12.6.2, A.13.1.1, A.13.2.1, A.14.1.3, A.14.2.2, A.14.2.3, A.14.2.4, A.6.2.1, A.6.2.2, A.9.1.2, CM-7(a), CM-7(b), CM-6(a), PR.AC-3, PR.IP-1, PR.PT-3, PR.PT-4, R62, 1409, 2.2.4, 2.2 Remediation Puppet snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | disable |
|---|
include remove_xinetd
class remove_xinetd {
package { 'xinetd':
ensure => 'purged',
}
}
Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | disable |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-CM-7(a)
- NIST-800-53-CM-7(b)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.4
- disable_strategy
- low_complexity
- low_disruption
- low_severity
- no_reboot_needed
- package_xinetd_removed
- name: 'Uninstall xinetd Package: Ensure xinetd is removed'
ansible.builtin.package:
name: xinetd
state: absent
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-CM-7(a)
- NIST-800-53-CM-7(b)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.4
- disable_strategy
- low_complexity
- low_disruption
- low_severity
- no_reboot_needed
- package_xinetd_removed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | disable |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel; then
# CAUTION: This remediation script will remove xinetd
# from the system, and may remove any packages
# that depend on xinetd. Execute this
# remediation AFTER testing on a non-production
# system!
if rpm -q --quiet "xinetd" ; then
dnf remove -y --noautoremove "xinetd"
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Disable xinetd Service
[ref]rule
The xinetd service can be disabled with the following command:
$ sudo systemctl mask --now xinetd.service Rationale:The xinetd service provides a dedicated listener service for some programs,
which is no longer necessary for commonly-used network services. Disabling
it ensures that these uncommon services are not running, and also prevents
attacks against xinetd itself. References:
11, 12, 14, 15, 3, 8, 9, APO13.01, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS01.04, DSS05.02, DSS05.03, DSS05.05, DSS06.06, 3.4.7, 164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii), 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 7.1, SR 7.6, A.11.2.6, A.12.1.2, A.12.5.1, A.12.6.2, A.13.1.1, A.13.2.1, A.14.1.3, A.14.2.2, A.14.2.3, A.14.2.4, A.6.2.1, A.6.2.2, A.9.1.2, CM-7(a), CM-7(b), CM-6(a), PR.AC-3, PR.IP-1, PR.PT-3, PR.PT-4, 1409 Remediation Puppet snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | enable |
|---|
include disable_xinetd
class disable_xinetd {
service {'xinetd':
enable => false,
ensure => 'stopped',
}
}
Remediation script: (show)
[customizations.services]
masked = ["xinetd"]
Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | disable |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- NIST-800-171-3.4.7
- NIST-800-53-CM-6(a)
- NIST-800-53-CM-7(a)
- NIST-800-53-CM-7(b)
- disable_strategy
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- service_xinetd_disabled
- name: Disable xinetd Service - Disable service xinetd
block:
- name: Disable xinetd Service - Collect systemd Services Present in the System
ansible.builtin.command: systemctl -q list-unit-files --type service
register: service_exists
changed_when: false
failed_when: service_exists.rc not in [0, 1]
check_mode: false
- name: Disable xinetd Service - Ensure xinetd.service is Masked
ansible.builtin.systemd:
name: xinetd.service
state: stopped
enabled: false
masked: true
when: service_exists.stdout_lines is search("xinetd.service", multiline=True)
- name: Unit Socket Exists - xinetd.socket
ansible.builtin.command: systemctl -q list-unit-files xinetd.socket
register: socket_file_exists
changed_when: false
failed_when: socket_file_exists.rc not in [0, 1]
check_mode: false
- name: Disable xinetd Service - Disable Socket xinetd
ansible.builtin.systemd:
name: xinetd.socket
enabled: false
state: stopped
masked: true
when: socket_file_exists.stdout_lines is search("xinetd.socket", multiline=True)
tags:
- NIST-800-171-3.4.7
- NIST-800-53-CM-6(a)
- NIST-800-53-CM-7(a)
- NIST-800-53-CM-7(b)
- disable_strategy
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- service_xinetd_disabled
- special_service_block
when: '"kernel" in ansible_facts.packages'
|
The Network Information Service (NIS), also known as 'Yellow
Pages' (YP), and its successor NIS+ have been made obsolete by
Kerberos, LDAP, and other modern centralized authentication
services. NIS should not be used because it suffers from security
problems inherent in its design, such as inadequate protection of
important authentication information. |
| contains 2 rules |
Uninstall ypserv Package
[ref]ruleThe ypserv package can be removed with the following command:
$ sudo dnf remove ypserv Rationale:The NIS service provides an unencrypted authentication service which does
not provide for the confidentiality and integrity of user passwords or the
remote session.
Removing the ypserv package decreases the risk of the accidental
(or intentional) activation of NIS or NIS+ services. References:
11, 12, 14, 15, 3, 8, 9, APO13.01, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS01.04, DSS05.02, DSS05.03, DSS05.05, DSS06.06, 164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii), 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 7.1, SR 7.6, A.11.2.6, A.12.1.2, A.12.5.1, A.12.6.2, A.13.1.1, A.13.2.1, A.14.1.3, A.14.2.2, A.14.2.3, A.14.2.4, A.6.2.1, A.6.2.2, A.9.1.2, CM-7(a), CM-7(b), CM-6(a), IA-5(1)(c), PR.AC-3, PR.IP-1, PR.PT-3, PR.PT-4, Req-2.2.2, SRG-OS-000095-GPOS-00049, R62, 2.2.4, 2.2 Remediation Puppet snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | disable |
|---|
include remove_ypserv
class remove_ypserv {
package { 'ypserv':
ensure => 'purged',
}
}
Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | disable |
|---|
- name: 'Uninstall ypserv Package: Ensure ypserv is removed'
ansible.builtin.package:
name: ypserv
state: absent
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-CM-7(a)
- NIST-800-53-CM-7(b)
- NIST-800-53-IA-5(1)(c)
- PCI-DSS-Req-2.2.2
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.4
- disable_strategy
- high_severity
- low_complexity
- low_disruption
- no_reboot_needed
- package_ypserv_removed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | disable |
|---|
# CAUTION: This remediation script will remove ypserv
# from the system, and may remove any packages
# that depend on ypserv. Execute this
# remediation AFTER testing on a non-production
# system!
if rpm -q --quiet "ypserv" ; then
dnf remove -y --noautoremove "ypserv"
fi
|
Disable ypserv Service
[ref]ruleThe ypserv service, which allows the system to act as a client in
a NIS or NIS+ domain, should be disabled.
The ypserv service can be disabled with the following command:
$ sudo systemctl mask --now ypserv.service Rationale:Disabling the ypserv service ensures the system is not acting
as a client in a NIS or NIS+ domain. This service should be disabled
unless in use. Remediation Puppet snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | enable |
|---|
include disable_ypserv
class disable_ypserv {
service {'ypserv':
enable => false,
ensure => 'stopped',
}
}
Remediation script: (show)
[customizations.services]
masked = ["ypserv"]
Remediation Ansible snippet: (show)
| 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
- service_ypserv_disabled
- name: Disable ypserv Service - Disable service ypserv
block:
- name: Disable ypserv Service - Collect systemd Services Present in the System
ansible.builtin.command: systemctl -q list-unit-files --type service
register: service_exists
changed_when: false
failed_when: service_exists.rc not in [0, 1]
check_mode: false
- name: Disable ypserv Service - Ensure ypserv.service is Masked
ansible.builtin.systemd:
name: ypserv.service
state: stopped
enabled: false
masked: true
when: service_exists.stdout_lines is search("ypserv.service", multiline=True)
- name: Unit Socket Exists - ypserv.socket
ansible.builtin.command: systemctl -q list-unit-files ypserv.socket
register: socket_file_exists
changed_when: false
failed_when: socket_file_exists.rc not in [0, 1]
check_mode: false
- name: Disable ypserv Service - Disable Socket ypserv
ansible.builtin.systemd:
name: ypserv.socket
enabled: false
state: stopped
masked: true
when: socket_file_exists.stdout_lines is search("ypserv.socket", multiline=True)
tags:
- disable_strategy
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- service_ypserv_disabled
- special_service_block
when: '"kernel" in ansible_facts.packages'
|
Telnet
[ref]groupThe telnet protocol does not provide confidentiality or integrity
for information transmitted on the network. This includes authentication
information such as passwords. Organizations which use telnet should be
actively working to migrate to a more secure protocol. |
| contains 2 rules |
Uninstall telnet-server Package
[ref]ruleThe telnet-server package can be removed with the following command:
$ sudo dnf remove telnet-server Rationale:It is detrimental for operating systems to provide, or install by default,
functionality exceeding requirements or mission objectives. These
unnecessary capabilities are often overlooked and therefore may remain
insecure. They increase the risk to the platform by providing additional
attack vectors.
The telnet service provides an unencrypted remote access service which does
not provide for the confidentiality and integrity of user passwords or the
remote session. If a privileged user were to login using this service, the
privileged user password could be compromised.
Removing the telnet-server package decreases the risk of the
telnet service's accidental (or intentional) activation. References:
11, 12, 14, 15, 3, 8, 9, APO13.01, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS01.04, DSS05.02, DSS05.03, DSS05.05, DSS06.06, 164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii), 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 7.1, SR 7.6, A.11.2.6, A.12.1.2, A.12.5.1, A.12.6.2, A.13.1.1, A.13.2.1, A.14.1.3, A.14.2.2, A.14.2.3, A.14.2.4, A.6.2.1, A.6.2.2, A.9.1.2, CM-7(a), CM-7(b), CM-6(a), PR.AC-3, PR.IP-1, PR.PT-3, PR.PT-4, Req-2.2.2, SRG-OS-000095-GPOS-00049, R62, 1409, 2.2.4, 2.2 Remediation Puppet snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | disable |
|---|
include remove_telnet-server
class remove_telnet-server {
package { 'telnet-server':
ensure => 'purged',
}
}
Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | disable |
|---|
- name: 'Uninstall telnet-server Package: Ensure telnet-server is removed'
ansible.builtin.package:
name: telnet-server
state: absent
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-CM-7(a)
- NIST-800-53-CM-7(b)
- PCI-DSS-Req-2.2.2
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.4
- disable_strategy
- high_severity
- low_complexity
- low_disruption
- no_reboot_needed
- package_telnet-server_removed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | disable |
|---|
# CAUTION: This remediation script will remove telnet-server
# from the system, and may remove any packages
# that depend on telnet-server. Execute this
# remediation AFTER testing on a non-production
# system!
if rpm -q --quiet "telnet-server" ; then
dnf remove -y --noautoremove "telnet-server"
fi
|
Remove telnet Clients
[ref]ruleThe telnet client allows users to start connections to other systems via
the telnet protocol. Rationale:The telnet protocol is insecure and unencrypted. The use
of an unencrypted transmission medium could allow an unauthorized user
to steal credentials. The ssh package provides an
encrypted session and stronger security and is included in TencentOS Server 4. References:
3.1.13, 164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii), A.8.2.3, A.13.1.1, A.13.2.1, A.13.2.3, A.14.1.2, A.14.1.3, R62, 1409, 2.2.4, 2.2 Remediation Puppet snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | disable |
|---|
include remove_telnet
class remove_telnet {
package { 'telnet':
ensure => 'purged',
}
}
Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | disable |
|---|
- name: 'Remove telnet Clients: Ensure telnet is removed'
ansible.builtin.package:
name: telnet
state: absent
tags:
- NIST-800-171-3.1.13
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.4
- disable_strategy
- low_complexity
- low_disruption
- low_severity
- no_reboot_needed
- package_telnet_removed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | disable |
|---|
# CAUTION: This remediation script will remove telnet
# from the system, and may remove any packages
# that depend on telnet. Execute this
# remediation AFTER testing on a non-production
# system!
if rpm -q --quiet "telnet" ; then
dnf remove -y --noautoremove "telnet"
fi
|
TFTP Server
[ref]groupTFTP is a lightweight version of the FTP protocol which has
traditionally been used to configure networking equipment. However,
TFTP provides little security, and modern versions of networking
operating systems frequently support configuration via SSH or other
more secure protocols. A TFTP server should be run only if no more
secure method of supporting existing equipment can be
found. |
| contains 3 rules |
Uninstall tftp-server Package
[ref]ruleThe tftp-server package can be removed with the following command: $ sudo dnf remove tftp-server Rationale:Removing the tftp-server package decreases the risk of the accidental
(or intentional) activation of tftp services.
If TFTP is required for operational support (such as transmission of router
configurations), its use must be documented with the Information Systems
Security Manager (ISSM), restricted to only authorized personnel, and have
access control rules established. References:
11, 12, 14, 15, 3, 8, 9, APO13.01, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS01.04, DSS05.02, DSS05.03, DSS05.05, DSS06.06, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 7.1, SR 7.6, A.11.2.6, A.12.1.2, A.12.5.1, A.12.6.2, A.13.1.1, A.13.2.1, A.14.1.3, A.14.2.2, A.14.2.3, A.14.2.4, A.6.2.1, A.6.2.2, A.9.1.2, CM-7(a), CM-7(b), CM-6(a), PR.AC-3, PR.IP-1, PR.PT-3, PR.PT-4, SRG-OS-000480-GPOS-00227, R62, 2.2.4, 2.2 Remediation Puppet snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | disable |
|---|
include remove_tftp-server
class remove_tftp-server {
package { 'tftp-server':
ensure => 'purged',
}
}
Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | disable |
|---|
- name: 'Uninstall tftp-server Package: Ensure tftp-server is removed'
ansible.builtin.package:
name: tftp-server
state: absent
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-CM-7(a)
- NIST-800-53-CM-7(b)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.4
- disable_strategy
- high_severity
- low_complexity
- low_disruption
- no_reboot_needed
- package_tftp-server_removed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | disable |
|---|
# CAUTION: This remediation script will remove tftp-server
# from the system, and may remove any packages
# that depend on tftp-server. Execute this
# remediation AFTER testing on a non-production
# system!
if rpm -q --quiet "tftp-server" ; then
dnf remove -y --noautoremove "tftp-server"
fi
|
Remove tftp Daemon
[ref]ruleTrivial File Transfer Protocol (TFTP) is a simple file transfer protocol,
typically used to automatically transfer configuration or boot files between systems.
TFTP does not support authentication and can be easily hacked. The package
tftp is a client program that allows for connections to a tftp server. Rationale:It is recommended that TFTP be removed, unless there is a specific need
for TFTP (such as a boot server). In that case, use extreme caution when configuring
the services. Remediation Puppet snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | disable |
|---|
include remove_tftp
class remove_tftp {
package { 'tftp':
ensure => 'purged',
}
}
Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | disable |
|---|
- name: 'Remove tftp Daemon: Ensure tftp is removed'
ansible.builtin.package:
name: tftp
state: absent
tags:
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.4
- disable_strategy
- low_complexity
- low_disruption
- low_severity
- no_reboot_needed
- package_tftp_removed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | disable |
|---|
# CAUTION: This remediation script will remove tftp
# from the system, and may remove any packages
# that depend on tftp. Execute this
# remediation AFTER testing on a non-production
# system!
if rpm -q --quiet "tftp" ; then
dnf remove -y --noautoremove "tftp"
fi
|
Disable tftp Service
[ref]ruleThe tftp service should be disabled.
The tftp service can be disabled with the following command:
$ sudo systemctl mask --now tftp.service Rationale:Disabling the tftp service ensures the system is not acting
as a TFTP server, which does not provide encryption or authentication. References:
11, 12, 14, 15, 3, 8, 9, APO13.01, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS01.04, DSS05.02, DSS05.03, DSS05.05, DSS06.06, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 7.1, SR 7.6, A.11.2.6, A.12.1.2, A.12.5.1, A.12.6.2, A.13.1.1, A.13.2.1, A.14.1.3, A.14.2.2, A.14.2.3, A.14.2.4, A.6.2.1, A.6.2.2, A.9.1.2, CM-7(a), CM-7(b), CM-6(a), PR.AC-3, PR.IP-1, PR.PT-3, PR.PT-4 Remediation Puppet snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | enable |
|---|
include disable_tftp
class disable_tftp {
service {'tftp':
enable => false,
ensure => 'stopped',
}
}
Remediation script: (show)
[customizations.services]
masked = ["tftp"]
Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | disable |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-CM-7(a)
- NIST-800-53-CM-7(b)
- disable_strategy
- high_severity
- low_complexity
- low_disruption
- no_reboot_needed
- service_tftp_disabled
- name: Disable tftp Service - Disable service tftp
block:
- name: Disable tftp Service - Collect systemd Services Present in the System
ansible.builtin.command: systemctl -q list-unit-files --type service
register: service_exists
changed_when: false
failed_when: service_exists.rc not in [0, 1]
check_mode: false
- name: Disable tftp Service - Ensure tftp.service is Masked
ansible.builtin.systemd:
name: tftp.service
state: stopped
enabled: false
masked: true
when: service_exists.stdout_lines is search("tftp.service", multiline=True)
- name: Unit Socket Exists - tftp.socket
ansible.builtin.command: systemctl -q list-unit-files tftp.socket
register: socket_file_exists
changed_when: false
failed_when: socket_file_exists.rc not in [0, 1]
check_mode: false
- name: Disable tftp Service - Disable Socket tftp
ansible.builtin.systemd:
name: tftp.socket
enabled: false
state: stopped
masked: true
when: socket_file_exists.stdout_lines is search("tftp.socket", multiline=True)
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-CM-7(a)
- NIST-800-53-CM-7(b)
- disable_strategy
- high_severity
- low_complexity
- low_disruption
- no_reboot_needed
- service_tftp_disabled
- special_service_block
when: '"kernel" in ansible_facts.packages'
|
Uninstall rsync Package
[ref]ruleThe rsyncd service can be used to synchronize files between systems over network links.
The rsync package can be removed with the following command:
$ sudo dnf remove rsync Rationale:The rsyncd service presents a security risk as it uses unencrypted protocols for
communication. Remediation Puppet snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | disable |
|---|
include remove_rsync
class remove_rsync {
package { 'rsync':
ensure => 'purged',
}
}
Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | disable |
|---|
- name: 'Uninstall rsync Package: Ensure rsync is removed'
ansible.builtin.package:
name: rsync
state: absent
tags:
- disable_strategy
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- package_rsync_removed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | disable |
|---|
# CAUTION: This remediation script will remove rsync
# from the system, and may remove any packages
# that depend on rsync. Execute this
# remediation AFTER testing on a non-production
# system!
if rpm -q --quiet "rsync" ; then
dnf remove -y --noautoremove "rsync"
fi
|
Ensure rsyncd service is disabled
[ref]rule
The rsyncd service can be disabled with the following command:
$ sudo systemctl mask --now rsyncd.service Rationale:The rsyncd service presents a security risk as it uses unencrypted protocols for
communication. Remediation Puppet snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | enable |
|---|
include disable_rsyncd
class disable_rsyncd {
service {'rsyncd':
enable => false,
ensure => 'stopped',
}
}
Remediation script: (show)
[customizations.services]
masked = ["rsyncd"]
Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | disable |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.4
- disable_strategy
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- service_rsyncd_disabled
- name: Ensure rsyncd service is disabled - Disable service rsyncd
block:
- name: Ensure rsyncd service is disabled - Collect systemd Services Present in
the System
ansible.builtin.command: systemctl -q list-unit-files --type service
register: service_exists
changed_when: false
failed_when: service_exists.rc not in [0, 1]
check_mode: false
- name: Ensure rsyncd service is disabled - Ensure rsyncd.service is Masked
ansible.builtin.systemd:
name: rsyncd.service
state: stopped
enabled: false
masked: true
when: service_exists.stdout_lines is search("rsyncd.service", multiline=True)
- name: Unit Socket Exists - rsyncd.socket
ansible.builtin.command: systemctl -q list-unit-files rsyncd.socket
register: socket_file_exists
changed_when: false
failed_when: socket_file_exists.rc not in [0, 1]
check_mode: false
- name: Ensure rsyncd service is disabled - Disable Socket rsyncd
ansible.builtin.systemd:
name: rsyncd.socket
enabled: false
state: stopped
masked: true
when: socket_file_exists.stdout_lines is search("rsyncd.socket", multiline=True)
tags:
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.4
- disable_strategy
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- service_rsyncd_disabled
- special_service_block
when: '"kernel" in ansible_facts.packages'
|
Print Support
[ref]groupThe Common Unix Printing System (CUPS) service provides both local
and network printing support. A system running the CUPS service can accept
print jobs from other systems, process them, and send them to the appropriate
printer. It also provides an interface for remote administration through a web
browser. The CUPS service is installed and activated by default. The project
homepage and more detailed documentation are available at
http://www.cups.org.
|
| contains 2 rules |
Uninstall CUPS Package
[ref]ruleThe cups package can be removed with the following command:
$ sudo dnf remove cups Rationale:If the system does not need to print jobs or accept print jobs from other systems, it is
recommended that CUPS be removed to reduce the potential attack surface. References:
11, 14, 3, 9, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.05, DSS06.06, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 7.6, A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, A.9.1.2, CM-7(a), CM-7(b), CM-6(a), PR.IP-1, PR.PT-3 Remediation Puppet snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | disable |
|---|
include remove_cups
class remove_cups {
package { 'cups':
ensure => 'purged',
}
}
Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | disable |
|---|
- name: 'Uninstall CUPS Package: Ensure cups is removed'
ansible.builtin.package:
name: cups
state: absent
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-CM-7(a)
- NIST-800-53-CM-7(b)
- disable_strategy
- low_complexity
- low_disruption
- no_reboot_needed
- package_cups_removed
- unknown_severity
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | disable |
|---|
# CAUTION: This remediation script will remove cups
# from the system, and may remove any packages
# that depend on cups. Execute this
# remediation AFTER testing on a non-production
# system!
if rpm -q --quiet "cups" ; then
dnf remove -y --noautoremove "cups"
fi
|
Disable the CUPS Service
[ref]rule
The cups service can be disabled with the following command:
$ sudo systemctl mask --now cups.service Rationale:Turn off unneeded services to reduce attack surface. References:
11, 14, 3, 9, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.05, DSS06.06, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 7.6, A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, A.9.1.2, CM-7(a), CM-7(b), CM-6(a), PR.IP-1, PR.PT-3 Remediation Puppet snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | enable |
|---|
include disable_cups
class disable_cups {
service {'cups':
enable => false,
ensure => 'stopped',
}
}
Remediation script: (show)
[customizations.services]
masked = ["cups"]
Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | disable |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-CM-7(a)
- NIST-800-53-CM-7(b)
- disable_strategy
- low_complexity
- low_disruption
- no_reboot_needed
- service_cups_disabled
- unknown_severity
- name: Disable the CUPS Service - Disable service cups
block:
- name: Disable the CUPS Service - Collect systemd Services Present in the System
ansible.builtin.command: systemctl -q list-unit-files --type service
register: service_exists
changed_when: false
failed_when: service_exists.rc not in [0, 1]
check_mode: false
- name: Disable the CUPS Service - Ensure cups.service is Masked
ansible.builtin.systemd:
name: cups.service
state: stopped
enabled: false
masked: true
when: service_exists.stdout_lines is search("cups.service", multiline=True)
- name: Unit Socket Exists - cups.socket
ansible.builtin.command: systemctl -q list-unit-files cups.socket
register: socket_file_exists
changed_when: false
failed_when: socket_file_exists.rc not in [0, 1]
check_mode: false
- name: Disable the CUPS Service - Disable Socket cups
ansible.builtin.systemd:
name: cups.socket
enabled: false
state: stopped
masked: true
when: socket_file_exists.stdout_lines is search("cups.socket", multiline=True)
tags:
- NIST-800-53-CM-6(a)
- NIST-800-53-CM-7(a)
- NIST-800-53-CM-7(b)
- disable_strategy
- low_complexity
- low_disruption
- no_reboot_needed
- service_cups_disabled
- special_service_block
- unknown_severity
when: '"kernel" in ansible_facts.packages'
|
SSH Server
[ref]groupThe SSH protocol is recommended for remote login and
remote file transfer. SSH provides confidentiality and integrity
for data exchanged between two systems, as well as server
authentication, through the use of public key cryptography. The
implementation included with the system is called OpenSSH, and more
detailed documentation is available from its website,
https://www.openssh.com.
Its server program is called sshd and provided by the RPM package
openssh-server. |
| contains 13 rules |
Configure OpenSSH Server if Necessary
[ref]groupIf the system needs to act as an SSH server, then
certain changes should be made to the OpenSSH daemon configuration
file /etc/ssh/sshd_config. The following recommendations can be
applied to this file. See the sshd_config(5) man page for more
detailed information. |
| contains 10 rules |
Disable Host-Based Authentication
[ref]ruleSSH's cryptographic host-based authentication is
more secure than .rhosts authentication. However, it is
not recommended that hosts unilaterally trust one another, even
within an organization.
The default SSH configuration disables host-based authentication. The appropriate
configuration is used if no value is set for HostbasedAuthentication.
To explicitly disable host-based authentication, add or correct the
following line in
/etc/ssh/sshd_config:
HostbasedAuthentication no Rationale:SSH trust relationships mean a compromise on one host
can allow an attacker to move trivially to other hosts. References:
11, 12, 14, 15, 16, 18, 3, 5, 9, 5.5.6, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.04, DSS05.05, DSS05.07, DSS06.03, DSS06.06, 3.1.12, 164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii), 4.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 7.6, A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, A.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, CIP-003-8 R5.1.1, CIP-003-8 R5.3, CIP-004-6 R2.2.3, CIP-004-6 R2.3, CIP-007-3 R5.1, CIP-007-3 R5.1.2, CIP-007-3 R5.2, CIP-007-3 R5.3.1, CIP-007-3 R5.3.2, CIP-007-3 R5.3.3, AC-3, AC-17(a), CM-7(a), CM-7(b), CM-6(a), PR.AC-4, PR.AC-6, PR.IP-1, PR.PT-3, FIA_UAU.1, SRG-OS-000480-GPOS-00229, 0421, 0422, 0484, 0974, 1173, 1401, 1504, 1505, 1546, 1557, 1558, 1559, 1560, 1561, 8.3.1, 8.3 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- CJIS-5.5.6
- NIST-800-171-3.1.12
- NIST-800-53-AC-17(a)
- NIST-800-53-AC-3
- NIST-800-53-CM-6(a)
- NIST-800-53-CM-7(a)
- NIST-800-53-CM-7(b)
- PCI-DSSv4-8.3
- PCI-DSSv4-8.3.1
- disable_host_auth
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Disable Host-Based Authentication
block:
- name: Check for duplicate values
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
create: true
regexp: (?i)(?i)^\s*HostbasedAuthentication\s+
state: absent
check_mode: true
changed_when: false
register: dupes
- name: Deduplicate values from /etc/ssh/sshd_config
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
create: true
regexp: (?i)(?i)^\s*HostbasedAuthentication\s+
state: absent
when: dupes.found is defined and dupes.found > 1
- name: Insert correct line to /etc/ssh/sshd_config
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
create: true
regexp: (?i)(?i)^\s*HostbasedAuthentication\s+
line: HostbasedAuthentication no
state: present
insertbefore: BOF
validate: /usr/sbin/sshd -t -f %s
when: '"kernel" in ansible_facts.packages'
tags:
- CJIS-5.5.6
- NIST-800-171-3.1.12
- NIST-800-53-AC-17(a)
- NIST-800-53-AC-3
- NIST-800-53-CM-6(a)
- NIST-800-53-CM-7(a)
- NIST-800-53-CM-7(b)
- PCI-DSSv4-8.3
- PCI-DSSv4-8.3.1
- disable_host_auth
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel; then
if [ -e "/etc/ssh/sshd_config" ] ; then
LC_ALL=C sed -i "/^\s*HostbasedAuthentication\s\+/Id" "/etc/ssh/sshd_config"
else
touch "/etc/ssh/sshd_config"
fi
# make sure file has newline at the end
sed -i -e '$a\' "/etc/ssh/sshd_config"
cp "/etc/ssh/sshd_config" "/etc/ssh/sshd_config.bak"
# Insert at the beginning of the file
printf '%s\n' "HostbasedAuthentication no" > "/etc/ssh/sshd_config"
cat "/etc/ssh/sshd_config.bak" >> "/etc/ssh/sshd_config"
# Clean up after ourselves.
rm "/etc/ssh/sshd_config.bak"
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Allow Only SSH Protocol 2
[ref]ruleOnly SSH protocol version 2 connections should be
permitted. The default setting in
/etc/ssh/sshd_config is correct, and can be
verified by ensuring that the following
line appears:
Protocol 2 Warning:
As of openssh-server version 7.4 and above, the only protocol
supported is version 2, and line Protocol 2 in
/etc/ssh/sshd_config is not necessary. Rationale:SSH protocol version 1 is an insecure implementation of the SSH protocol and
has many well-known vulnerability exploits. Exploits of the SSH daemon could provide
immediate root access to the system. References:
1, 12, 15, 16, 5, 8, 5.5.6, APO13.01, DSS01.04, DSS05.02, DSS05.03, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.10, 3.1.13, 3.5.4, 164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii), 4.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.2, 4.3.3.7.4, SR 1.1, SR 1.10, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.6, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 7.1, SR 7.6, A.11.2.6, A.13.1.1, A.13.2.1, A.14.1.3, A.18.1.4, A.6.2.1, A.6.2.2, A.7.1.1, A.9.2.1, A.9.2.2, A.9.2.3, A.9.2.4, A.9.2.6, A.9.3.1, A.9.4.2, A.9.4.3, CIP-003-8 R4.2, CIP-007-3 R5.1, CIP-007-3 R7.1, CM-6(a), AC-17(a), AC-17(2), IA-5(1)(c), SC-13, MA-4(6), PR.AC-1, PR.AC-3, PR.AC-6, PR.AC-7, PR.PT-4, SRG-OS-000074-GPOS-00042, SRG-OS-000480-GPOS-00227, 1483 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- CJIS-5.5.6
- NIST-800-171-3.1.13
- NIST-800-171-3.5.4
- NIST-800-53-AC-17(2)
- NIST-800-53-AC-17(a)
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-5(1)(c)
- NIST-800-53-MA-4(6)
- NIST-800-53-SC-13
- high_severity
- low_complexity
- low_disruption
- no_reboot_needed
- restrict_strategy
- sshd_allow_only_protocol2
- name: Allow Only SSH Protocol 2
block:
- name: Check for duplicate values
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
create: true
regexp: (?i)(?i)^\s*Protocol\s+
state: absent
check_mode: true
changed_when: false
register: dupes
- name: Deduplicate values from /etc/ssh/sshd_config
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
create: true
regexp: (?i)(?i)^\s*Protocol\s+
state: absent
when: dupes.found is defined and dupes.found > 1
- name: Insert correct line to /etc/ssh/sshd_config
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
create: true
regexp: (?i)(?i)^\s*Protocol\s+
line: Protocol 2
state: present
insertbefore: BOF
validate: /usr/sbin/sshd -t -f %s
when:
- '"kernel" in ansible_facts.packages'
- '"openssh-server" in ansible_facts.packages and (((((ansible_facts.packages["openssh-server"]
| last)["epoch"]) != None) | ternary((ansible_facts.packages["openssh-server"]
| last)["epoch"] ~ ":", "0:")) + ((ansible_facts.packages["openssh-server"] |
last)["version"] | split("-") | first)) is version("0:7.0", "<")'
tags:
- CJIS-5.5.6
- NIST-800-171-3.1.13
- NIST-800-171-3.5.4
- NIST-800-53-AC-17(2)
- NIST-800-53-AC-17(a)
- NIST-800-53-CM-6(a)
- NIST-800-53-IA-5(1)(c)
- NIST-800-53-MA-4(6)
- NIST-800-53-SC-13
- high_severity
- low_complexity
- low_disruption
- no_reboot_needed
- restrict_strategy
- sshd_allow_only_protocol2
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel && { ( rpm --quiet -q openssh-server && { real="$(epoch=$(rpm -q --queryformat '%{EPOCH}' openssh-server); version=$(rpm -q --queryformat '%{VERSION}' openssh-server); [ "$epoch" = "(none)" ] && echo "0:$version" || echo "$epoch:$version")"; expected="0:7.0"; [[ "$real" != "$expected" ]] && printf "%s\n%s" "$real" "$expected" | sort -VC; } ); }; then
if [ -e "/etc/ssh/sshd_config" ] ; then
LC_ALL=C sed -i "/^\s*Protocol\s\+/Id" "/etc/ssh/sshd_config"
else
touch "/etc/ssh/sshd_config"
fi
# make sure file has newline at the end
sed -i -e '$a\' "/etc/ssh/sshd_config"
cp "/etc/ssh/sshd_config" "/etc/ssh/sshd_config.bak"
# Insert at the beginning of the file
printf '%s\n' "Protocol 2" > "/etc/ssh/sshd_config"
cat "/etc/ssh/sshd_config.bak" >> "/etc/ssh/sshd_config"
# Clean up after ourselves.
rm "/etc/ssh/sshd_config.bak"
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Disable SSH Access via Empty Passwords
[ref]ruleDisallow SSH login with empty passwords.
The default SSH configuration disables logins with empty passwords. The appropriate
configuration is used if no value is set for PermitEmptyPasswords.
To explicitly disallow SSH login from accounts with empty passwords,
add or correct the following line in
/etc/ssh/sshd_config:
PermitEmptyPasswords no
Any accounts with empty passwords should be disabled immediately, and PAM configuration
should prevent users from being able to assign themselves empty passwords.Rationale:Configuring this setting for the SSH daemon provides additional assurance
that remote login via SSH will require a password, even in the event of
misconfiguration elsewhere. References:
11, 12, 13, 14, 15, 16, 18, 3, 5, 9, 5.5.6, APO01.06, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.04, DSS05.05, DSS05.07, DSS06.02, DSS06.03, DSS06.06, 3.1.1, 3.1.5, 164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii), 4.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 5.2, SR 7.6, A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.12.1.2, A.12.5.1, A.12.6.2, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.14.2.2, A.14.2.3, A.14.2.4, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.1, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5, AC-17(a), CM-7(a), CM-7(b), CM-6(a), PR.AC-4, PR.AC-6, PR.DS-5, PR.IP-1, PR.PT-3, FIA_UAU.1, Req-2.2.4, SRG-OS-000106-GPOS-00053, SRG-OS-000480-GPOS-00229, SRG-OS-000480-GPOS-00227, 1546, 2.2.6, 2.2 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- CJIS-5.5.6
- NIST-800-171-3.1.1
- NIST-800-171-3.1.5
- NIST-800-53-AC-17(a)
- NIST-800-53-CM-6(a)
- NIST-800-53-CM-7(a)
- NIST-800-53-CM-7(b)
- PCI-DSS-Req-2.2.4
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- high_severity
- low_complexity
- low_disruption
- no_reboot_needed
- restrict_strategy
- sshd_disable_empty_passwords
- name: Disable SSH Access via Empty Passwords
block:
- name: Check for duplicate values
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
create: true
regexp: (?i)(?i)^\s*PermitEmptyPasswords\s+
state: absent
check_mode: true
changed_when: false
register: dupes
- name: Deduplicate values from /etc/ssh/sshd_config
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
create: true
regexp: (?i)(?i)^\s*PermitEmptyPasswords\s+
state: absent
when: dupes.found is defined and dupes.found > 1
- name: Insert correct line to /etc/ssh/sshd_config
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
create: true
regexp: (?i)(?i)^\s*PermitEmptyPasswords\s+
line: PermitEmptyPasswords no
state: present
insertbefore: BOF
validate: /usr/sbin/sshd -t -f %s
when: '"kernel" in ansible_facts.packages'
tags:
- CJIS-5.5.6
- NIST-800-171-3.1.1
- NIST-800-171-3.1.5
- NIST-800-53-AC-17(a)
- NIST-800-53-CM-6(a)
- NIST-800-53-CM-7(a)
- NIST-800-53-CM-7(b)
- PCI-DSS-Req-2.2.4
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- high_severity
- low_complexity
- low_disruption
- no_reboot_needed
- restrict_strategy
- sshd_disable_empty_passwords
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel; then
if [ -e "/etc/ssh/sshd_config" ] ; then
LC_ALL=C sed -i "/^\s*PermitEmptyPasswords\s\+/Id" "/etc/ssh/sshd_config"
else
touch "/etc/ssh/sshd_config"
fi
# make sure file has newline at the end
sed -i -e '$a\' "/etc/ssh/sshd_config"
cp "/etc/ssh/sshd_config" "/etc/ssh/sshd_config.bak"
# Insert at the beginning of the file
printf '%s\n' "PermitEmptyPasswords no" > "/etc/ssh/sshd_config"
cat "/etc/ssh/sshd_config.bak" >> "/etc/ssh/sshd_config"
# Clean up after ourselves.
rm "/etc/ssh/sshd_config.bak"
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Disable SSH Support for .rhosts Files
[ref]ruleSSH can emulate the behavior of the obsolete rsh
command in allowing users to enable insecure access to their
accounts via .rhosts files.
The default SSH configuration disables support for .rhosts. The appropriate
configuration is used if no value is set for IgnoreRhosts.
To explicitly disable support for .rhosts files, add or correct the following line in
/etc/ssh/sshd_config:
IgnoreRhosts yes Rationale:SSH trust relationships mean a compromise on one host
can allow an attacker to move trivially to other hosts. References:
11, 12, 14, 15, 16, 18, 3, 5, 9, 5.5.6, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.04, DSS05.05, DSS05.07, DSS06.03, DSS06.06, 3.1.12, 4.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 7.6, A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, A.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, AC-17(a), CM-7(a), CM-7(b), CM-6(a), PR.AC-4, PR.AC-6, PR.IP-1, PR.PT-3, SRG-OS-000480-GPOS-00227, 1546, 2.2.6, 2.2 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- CJIS-5.5.6
- NIST-800-171-3.1.12
- NIST-800-53-AC-17(a)
- NIST-800-53-CM-6(a)
- NIST-800-53-CM-7(a)
- NIST-800-53-CM-7(b)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- sshd_disable_rhosts
- name: Disable SSH Support for .rhosts Files
block:
- name: Check for duplicate values
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
create: true
regexp: (?i)(?i)^\s*IgnoreRhosts\s+
state: absent
check_mode: true
changed_when: false
register: dupes
- name: Deduplicate values from /etc/ssh/sshd_config
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
create: true
regexp: (?i)(?i)^\s*IgnoreRhosts\s+
state: absent
when: dupes.found is defined and dupes.found > 1
- name: Insert correct line to /etc/ssh/sshd_config
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
create: true
regexp: (?i)(?i)^\s*IgnoreRhosts\s+
line: IgnoreRhosts yes
state: present
insertbefore: BOF
validate: /usr/sbin/sshd -t -f %s
when: '"kernel" in ansible_facts.packages'
tags:
- CJIS-5.5.6
- NIST-800-171-3.1.12
- NIST-800-53-AC-17(a)
- NIST-800-53-CM-6(a)
- NIST-800-53-CM-7(a)
- NIST-800-53-CM-7(b)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- sshd_disable_rhosts
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel; then
if [ -e "/etc/ssh/sshd_config" ] ; then
LC_ALL=C sed -i "/^\s*IgnoreRhosts\s\+/Id" "/etc/ssh/sshd_config"
else
touch "/etc/ssh/sshd_config"
fi
# make sure file has newline at the end
sed -i -e '$a\' "/etc/ssh/sshd_config"
cp "/etc/ssh/sshd_config" "/etc/ssh/sshd_config.bak"
# Insert at the beginning of the file
printf '%s\n' "IgnoreRhosts yes" > "/etc/ssh/sshd_config"
cat "/etc/ssh/sshd_config.bak" >> "/etc/ssh/sshd_config"
# Clean up after ourselves.
rm "/etc/ssh/sshd_config.bak"
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Disable SSH Root Login
[ref]ruleThe root user should never be allowed to login to a
system directly over a network.
To disable root login via SSH, add or correct the following line in
/etc/ssh/sshd_config:
PermitRootLogin no Rationale:Even though the communications channel may be encrypted, an additional layer of
security is gained by extending the policy of not logging directly on as root.
In addition, logging in with a user-specific account provides individual
accountability of actions performed on the system and also helps to minimize
direct attack attempts on root's password. References:
1, 11, 12, 13, 14, 15, 16, 18, 3, 5, 5.5.6, APO01.06, DSS05.02, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.02, DSS06.03, DSS06.06, DSS06.10, 3.1.1, 3.1.5, 164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii), 4.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 5.2, A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.18.1.4, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.1, A.9.2.2, A.9.2.3, A.9.2.4, A.9.2.6, A.9.3.1, A.9.4.1, A.9.4.2, A.9.4.3, A.9.4.4, A.9.4.5, CIP-003-8 R5.1.1, CIP-003-8 R5.3, CIP-004-6 R2.2.3, CIP-004-6 R2.3, CIP-007-3 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, CIP-007-3 R5.2, CIP-007-3 R5.3.1, CIP-007-3 R5.3.2, CIP-007-3 R5.3.3, AC-6(2), AC-17(a), IA-2, IA-2(5), CM-7(a), CM-7(b), CM-6(a), PR.AC-1, PR.AC-4, PR.AC-6, PR.AC-7, PR.DS-5, PR.PT-3, FAU_GEN.1, Req-2.2.4, SRG-OS-000109-GPOS-00056, SRG-OS-000480-GPOS-00227, SRG-APP-000148-CTR-000335, SRG-APP-000190-CTR-000500, R33, 1546, 2.2.6, 2.2 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- CJIS-5.5.6
- NIST-800-171-3.1.1
- NIST-800-171-3.1.5
- NIST-800-53-AC-17(a)
- NIST-800-53-AC-6(2)
- NIST-800-53-CM-6(a)
- NIST-800-53-CM-7(a)
- NIST-800-53-CM-7(b)
- NIST-800-53-IA-2
- NIST-800-53-IA-2(5)
- PCI-DSS-Req-2.2.4
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- sshd_disable_root_login
- name: Disable SSH Root Login
block:
- name: Check for duplicate values
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
create: true
regexp: (?i)(?i)^\s*PermitRootLogin\s+
state: absent
check_mode: true
changed_when: false
register: dupes
- name: Deduplicate values from /etc/ssh/sshd_config
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
create: true
regexp: (?i)(?i)^\s*PermitRootLogin\s+
state: absent
when: dupes.found is defined and dupes.found > 1
- name: Insert correct line to /etc/ssh/sshd_config
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
create: true
regexp: (?i)(?i)^\s*PermitRootLogin\s+
line: PermitRootLogin no
state: present
insertbefore: BOF
validate: /usr/sbin/sshd -t -f %s
when: '"kernel" in ansible_facts.packages'
tags:
- CJIS-5.5.6
- NIST-800-171-3.1.1
- NIST-800-171-3.1.5
- NIST-800-53-AC-17(a)
- NIST-800-53-AC-6(2)
- NIST-800-53-CM-6(a)
- NIST-800-53-CM-7(a)
- NIST-800-53-CM-7(b)
- NIST-800-53-IA-2
- NIST-800-53-IA-2(5)
- PCI-DSS-Req-2.2.4
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- sshd_disable_root_login
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel; then
if [ -e "/etc/ssh/sshd_config" ] ; then
LC_ALL=C sed -i "/^\s*PermitRootLogin\s\+/Id" "/etc/ssh/sshd_config"
else
touch "/etc/ssh/sshd_config"
fi
# make sure file has newline at the end
sed -i -e '$a\' "/etc/ssh/sshd_config"
cp "/etc/ssh/sshd_config" "/etc/ssh/sshd_config.bak"
# Insert at the beginning of the file
printf '%s\n' "PermitRootLogin no" > "/etc/ssh/sshd_config"
cat "/etc/ssh/sshd_config.bak" >> "/etc/ssh/sshd_config"
# Clean up after ourselves.
rm "/etc/ssh/sshd_config.bak"
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Disable SSH TCP Forwarding
[ref]ruleThe AllowTcpForwarding parameter specifies whether TCP forwarding is permitted.
To disable TCP forwarding, add or correct the following line in
/etc/ssh/sshd_config:
AllowTcpForwarding no Rationale:Leaving port forwarding enabled can expose the organization to security risks and back-doors. Remediation Ansible snippet: (show)
| 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
- sshd_disable_tcp_forwarding
- name: Disable SSH TCP Forwarding
block:
- name: Check for duplicate values
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
create: true
regexp: (?i)(?i)^\s*AllowTcpForwarding\s+
state: absent
check_mode: true
changed_when: false
register: dupes
- name: Deduplicate values from /etc/ssh/sshd_config
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
create: true
regexp: (?i)(?i)^\s*AllowTcpForwarding\s+
state: absent
when: dupes.found is defined and dupes.found > 1
- name: Insert correct line to /etc/ssh/sshd_config
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
create: true
regexp: (?i)(?i)^\s*AllowTcpForwarding\s+
line: AllowTcpForwarding no
state: present
insertbefore: BOF
validate: /usr/sbin/sshd -t -f %s
when: '"kernel" 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
- sshd_disable_tcp_forwarding
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel; then
if [ -e "/etc/ssh/sshd_config" ] ; then
LC_ALL=C sed -i "/^\s*AllowTcpForwarding\s\+/Id" "/etc/ssh/sshd_config"
else
touch "/etc/ssh/sshd_config"
fi
# make sure file has newline at the end
sed -i -e '$a\' "/etc/ssh/sshd_config"
cp "/etc/ssh/sshd_config" "/etc/ssh/sshd_config.bak"
# Insert at the beginning of the file
printf '%s\n' "AllowTcpForwarding no" > "/etc/ssh/sshd_config"
cat "/etc/ssh/sshd_config.bak" >> "/etc/ssh/sshd_config"
# Clean up after ourselves.
rm "/etc/ssh/sshd_config.bak"
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Disable X11 Forwarding
[ref]ruleThe X11Forwarding parameter provides the ability to tunnel X11 traffic
through the connection to enable remote graphic connections.
SSH has the capability to encrypt remote X11 connections when SSH's
X11Forwarding option is enabled.
The default SSH configuration disables X11Forwarding. The appropriate
configuration is used if no value is set for X11Forwarding.
To explicitly disable X11 Forwarding, add or correct the following line in
/etc/ssh/sshd_config:
X11Forwarding no Rationale:Disable X11 forwarding unless there is an operational requirement to use X11
applications directly. There is a small risk that the remote X11 servers of
users who are logged in via SSH with X11 forwarding could be compromised by
other users on the X11 server. Note that even if X11 forwarding is disabled,
users can always install their own forwarders. Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- NIST-800-53-CM-6(b)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- sshd_disable_x11_forwarding
- name: Disable X11 Forwarding
block:
- name: Check for duplicate values
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
create: true
regexp: (?i)(?i)^\s*X11Forwarding\s+
state: absent
check_mode: true
changed_when: false
register: dupes
- name: Deduplicate values from /etc/ssh/sshd_config
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
create: true
regexp: (?i)(?i)^\s*X11Forwarding\s+
state: absent
when: dupes.found is defined and dupes.found > 1
- name: Insert correct line to /etc/ssh/sshd_config
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
create: true
regexp: (?i)(?i)^\s*X11Forwarding\s+
line: X11Forwarding no
state: present
insertbefore: BOF
validate: /usr/sbin/sshd -t -f %s
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-CM-6(b)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- sshd_disable_x11_forwarding
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel; then
if [ -e "/etc/ssh/sshd_config" ] ; then
LC_ALL=C sed -i "/^\s*X11Forwarding\s\+/Id" "/etc/ssh/sshd_config"
else
touch "/etc/ssh/sshd_config"
fi
# make sure file has newline at the end
sed -i -e '$a\' "/etc/ssh/sshd_config"
cp "/etc/ssh/sshd_config" "/etc/ssh/sshd_config.bak"
# Insert at the beginning of the file
printf '%s\n' "X11Forwarding no" > "/etc/ssh/sshd_config"
cat "/etc/ssh/sshd_config.bak" >> "/etc/ssh/sshd_config"
# Clean up after ourselves.
rm "/etc/ssh/sshd_config.bak"
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Do Not Allow SSH Environment Options
[ref]ruleEnsure that users are not able to override environment variables of the SSH daemon.
The default SSH configuration disables environment processing. The appropriate
configuration is used if no value is set for PermitUserEnvironment.
To explicitly disable Environment options, add or correct the following
/etc/ssh/sshd_config:
PermitUserEnvironment no Rationale:SSH environment options potentially allow users to bypass
access restriction in some configurations. References:
11, 3, 9, 5.5.6, BAI10.01, BAI10.02, BAI10.03, BAI10.05, 3.1.12, 164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii), 4.3.4.3.2, 4.3.4.3.3, SR 7.6, A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, AC-17(a), CM-7(a), CM-7(b), CM-6(a), PR.IP-1, Req-2.2.4, SRG-OS-000480-GPOS-00229, 1546, 2.2.6, 2.2 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- CJIS-5.5.6
- NIST-800-171-3.1.12
- NIST-800-53-AC-17(a)
- NIST-800-53-CM-6(a)
- NIST-800-53-CM-7(a)
- NIST-800-53-CM-7(b)
- PCI-DSS-Req-2.2.4
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- sshd_do_not_permit_user_env
- name: Do Not Allow SSH Environment Options
block:
- name: Check for duplicate values
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
create: true
regexp: (?i)(?i)^\s*PermitUserEnvironment\s+
state: absent
check_mode: true
changed_when: false
register: dupes
- name: Deduplicate values from /etc/ssh/sshd_config
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
create: true
regexp: (?i)(?i)^\s*PermitUserEnvironment\s+
state: absent
when: dupes.found is defined and dupes.found > 1
- name: Insert correct line to /etc/ssh/sshd_config
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
create: true
regexp: (?i)(?i)^\s*PermitUserEnvironment\s+
line: PermitUserEnvironment no
state: present
insertbefore: BOF
validate: /usr/sbin/sshd -t -f %s
when: '"kernel" in ansible_facts.packages'
tags:
- CJIS-5.5.6
- NIST-800-171-3.1.12
- NIST-800-53-AC-17(a)
- NIST-800-53-CM-6(a)
- NIST-800-53-CM-7(a)
- NIST-800-53-CM-7(b)
- PCI-DSS-Req-2.2.4
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- sshd_do_not_permit_user_env
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel; then
if [ -e "/etc/ssh/sshd_config" ] ; then
LC_ALL=C sed -i "/^\s*PermitUserEnvironment\s\+/Id" "/etc/ssh/sshd_config"
else
touch "/etc/ssh/sshd_config"
fi
# make sure file has newline at the end
sed -i -e '$a\' "/etc/ssh/sshd_config"
cp "/etc/ssh/sshd_config" "/etc/ssh/sshd_config.bak"
# Insert at the beginning of the file
printf '%s\n' "PermitUserEnvironment no" > "/etc/ssh/sshd_config"
cat "/etc/ssh/sshd_config.bak" >> "/etc/ssh/sshd_config"
# Clean up after ourselves.
rm "/etc/ssh/sshd_config.bak"
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Enable PAM
[ref]ruleUsePAM Enables the Pluggable Authentication Module interface. If set to “yes” this will
enable PAM authentication using ChallengeResponseAuthentication and
PasswordAuthentication in addition to PAM account and session module processing for all
authentication types.
To enable PAM authentication, add or correct the following line in
/etc/ssh/sshd_config:
UsePAM yes Rationale:When UsePAM is set to yes, PAM runs through account and session types properly. This is
important if you want to restrict access to services based off of IP, time or other factors of
the account. Additionally, you can make sure users inherit certain environment variables
on login or disallow access to the server. Remediation Ansible snippet: (show)
| 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
- sshd_enable_pam
- name: Enable PAM
block:
- name: Check for duplicate values
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
create: true
regexp: (?i)(?i)^\s*UsePAM\s+
state: absent
check_mode: true
changed_when: false
register: dupes
- name: Deduplicate values from /etc/ssh/sshd_config
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
create: true
regexp: (?i)(?i)^\s*UsePAM\s+
state: absent
when: dupes.found is defined and dupes.found > 1
- name: Insert correct line to /etc/ssh/sshd_config
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
create: true
regexp: (?i)(?i)^\s*UsePAM\s+
line: UsePAM yes
state: present
insertbefore: BOF
validate: /usr/sbin/sshd -t -f %s
when: '"kernel" 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
- sshd_enable_pam
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel; then
if [ -e "/etc/ssh/sshd_config" ] ; then
LC_ALL=C sed -i "/^\s*UsePAM\s\+/Id" "/etc/ssh/sshd_config"
else
touch "/etc/ssh/sshd_config"
fi
# make sure file has newline at the end
sed -i -e '$a\' "/etc/ssh/sshd_config"
cp "/etc/ssh/sshd_config" "/etc/ssh/sshd_config.bak"
# Insert at the beginning of the file
printf '%s\n' "UsePAM yes" > "/etc/ssh/sshd_config"
cat "/etc/ssh/sshd_config.bak" >> "/etc/ssh/sshd_config"
# Clean up after ourselves.
rm "/etc/ssh/sshd_config.bak"
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Enable SSH Warning Banner
[ref]ruleTo enable the warning banner and ensure it is consistent
across the system, add or correct the following line in
/etc/ssh/sshd_config:
Banner /etc/issue.net
Another section contains information on how to create an
appropriate system-wide warning banner.Rationale:The warning message reinforces policy awareness during the logon process and
facilitates possible legal action against attackers. Alternatively, systems
whose ownership should not be obvious should ensure usage of a banner that does
not provide easy attribution. References:
5.5.6, DSS05.04, DSS05.10, DSS06.10, 3.1.9, 164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii), 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, SR 1.1, SR 1.10, SR 1.2, SR 1.5, SR 1.7, SR 1.8, SR 1.9, A.18.1.4, A.9.2.1, A.9.2.4, A.9.3.1, A.9.4.2, A.9.4.3, AC-8(a), AC-8(c), AC-17(a), CM-6(a), PR.AC-7, SRG-OS-000023-GPOS-00006, SRG-OS-000228-GPOS-00088 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- CJIS-5.5.6
- NIST-800-171-3.1.9
- NIST-800-53-AC-17(a)
- NIST-800-53-AC-8(a)
- NIST-800-53-AC-8(c)
- NIST-800-53-CM-6(a)
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- sshd_enable_warning_banner_net
- name: Enable SSH Warning Banner
block:
- name: Check for duplicate values
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
create: true
regexp: (?i)(?i)^\s*Banner\s+
state: absent
check_mode: true
changed_when: false
register: dupes
- name: Deduplicate values from /etc/ssh/sshd_config
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
create: true
regexp: (?i)(?i)^\s*Banner\s+
state: absent
when: dupes.found is defined and dupes.found > 1
- name: Insert correct line to /etc/ssh/sshd_config
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
create: true
regexp: (?i)(?i)^\s*Banner\s+
line: Banner /etc/issue.net
state: present
insertbefore: BOF
validate: /usr/sbin/sshd -t -f %s
when: '"kernel" in ansible_facts.packages'
tags:
- CJIS-5.5.6
- NIST-800-171-3.1.9
- NIST-800-53-AC-17(a)
- NIST-800-53-AC-8(a)
- NIST-800-53-AC-8(c)
- NIST-800-53-CM-6(a)
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- sshd_enable_warning_banner_net
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | restrict |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel; then
if [ -e "/etc/ssh/sshd_config" ] ; then
LC_ALL=C sed -i "/^\s*Banner\s\+/Id" "/etc/ssh/sshd_config"
else
touch "/etc/ssh/sshd_config"
fi
# make sure file has newline at the end
sed -i -e '$a\' "/etc/ssh/sshd_config"
cp "/etc/ssh/sshd_config" "/etc/ssh/sshd_config.bak"
# Insert at the beginning of the file
printf '%s\n' "Banner /etc/issue.net" > "/etc/ssh/sshd_config"
cat "/etc/ssh/sshd_config.bak" >> "/etc/ssh/sshd_config"
# Clean up after ourselves.
rm "/etc/ssh/sshd_config.bak"
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Verify Group Who Owns SSH Server config file
[ref]rule
To properly set the group owner of /etc/ssh/sshd_config, run the command:
$ sudo chgrp root /etc/ssh/sshd_config
Rationale:Service configuration files enable or disable features of their respective
services that if configured incorrectly can lead to insecure and vulnerable
configurations. Therefore, service configuration files should be owned by the
correct group to prevent unauthorized changes. References:
12, 13, 14, 15, 16, 18, 3, 5, APO01.06, DSS05.04, DSS05.07, DSS06.02, 4.3.3.7.3, SR 2.1, SR 5.2, A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5, CIP-003-8 R5.1.1, CIP-003-8 R5.3, CIP-004-6 R2.3, CIP-007-3 R2.1, CIP-007-3 R2.2, CIP-007-3 R2.3, CIP-007-3 R5.1, CIP-007-3 R5.1.1, CIP-007-3 R5.1.2, AC-17(a), CM-6(a), AC-6(1), PR.AC-4, PR.DS-5, SRG-OS-000480-GPOS-00227, R50 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- NIST-800-53-AC-17(a)
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- configure_strategy
- file_groupowner_sshd_config
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Set the file_groupowner_sshd_config_newgroup variable if represented by gid
ansible.builtin.set_fact:
file_groupowner_sshd_config_newgroup: '0'
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-AC-17(a)
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- configure_strategy
- file_groupowner_sshd_config
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Test for existence /etc/ssh/sshd_config
ansible.builtin.stat:
path: /etc/ssh/sshd_config
register: file_exists
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-AC-17(a)
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- configure_strategy
- file_groupowner_sshd_config
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Ensure group owner on /etc/ssh/sshd_config
ansible.builtin.file:
path: /etc/ssh/sshd_config
follow: false
group: '{{ file_groupowner_sshd_config_newgroup }}'
when:
- '"kernel" in ansible_facts.packages'
- file_exists.stat is defined and file_exists.stat.exists
tags:
- NIST-800-53-AC-17(a)
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- configure_strategy
- file_groupowner_sshd_config
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel; then
newgroup=""
if getent group "0" >/dev/null 2>&1; then
newgroup="0"
fi
if [[ -z "${newgroup}" ]]; then
>&2 echo "0 is not a defined group on the system"
else
if ! stat -c "%g %G" "/etc/ssh/sshd_config" | grep -E -w -q "0"; then
chgrp --no-dereference "$newgroup" /etc/ssh/sshd_config
fi
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Verify Owner on SSH Server config file
[ref]rule
To properly set the owner of /etc/ssh/sshd_config, run the command:
$ sudo chown root /etc/ssh/sshd_config
Rationale:Service configuration files enable or disable features of their respective
services that if configured incorrectly can lead to insecure and vulnerable
configurations. Therefore, service configuration files should be owned by the
correct group to prevent unauthorized changes. References:
12, 13, 14, 15, 16, 18, 3, 5, APO01.06, DSS05.04, DSS05.07, DSS06.02, 4.3.3.7.3, SR 2.1, SR 5.2, A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5, CIP-003-8 R5.1.1, CIP-003-8 R5.3, CIP-004-6 R2.3, CIP-007-3 R2.1, CIP-007-3 R2.2, CIP-007-3 R2.3, CIP-007-3 R5.1, CIP-007-3 R5.1.1, CIP-007-3 R5.1.2, AC-17(a), CM-6(a), AC-6(1), PR.AC-4, PR.DS-5, SRG-OS-000480-GPOS-00227, R50 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- NIST-800-53-AC-17(a)
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- configure_strategy
- file_owner_sshd_config
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Set the file_owner_sshd_config_newown variable if represented by uid
ansible.builtin.set_fact:
file_owner_sshd_config_newown: '0'
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-AC-17(a)
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- configure_strategy
- file_owner_sshd_config
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Test for existence /etc/ssh/sshd_config
ansible.builtin.stat:
path: /etc/ssh/sshd_config
register: file_exists
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-AC-17(a)
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- configure_strategy
- file_owner_sshd_config
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Ensure owner on /etc/ssh/sshd_config
ansible.builtin.file:
path: /etc/ssh/sshd_config
follow: false
owner: '{{ file_owner_sshd_config_newown }}'
when:
- '"kernel" in ansible_facts.packages'
- file_exists.stat is defined and file_exists.stat.exists
tags:
- NIST-800-53-AC-17(a)
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- configure_strategy
- file_owner_sshd_config
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel; then
newown=""
if id "0" >/dev/null 2>&1; then
newown="0"
fi
if [[ -z "$newown" ]]; then
>&2 echo "0 is not a defined user on the system"
else
if ! stat -c "%u %U" "/etc/ssh/sshd_config" | grep -E -w -q "0"; then
chown --no-dereference "$newown" /etc/ssh/sshd_config
fi
fi
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
Verify Permissions on SSH Server config file
[ref]rule
To properly set the permissions of /etc/ssh/sshd_config, run the command:
$ sudo chmod 0600 /etc/ssh/sshd_config Rationale:Service configuration files enable or disable features of their respective
services that if configured incorrectly can lead to insecure and vulnerable
configurations. Therefore, service configuration files should be owned by the
correct group to prevent unauthorized changes. References:
12, 13, 14, 15, 16, 18, 3, 5, APO01.06, DSS05.04, DSS05.07, DSS06.02, 4.3.3.7.3, SR 2.1, SR 5.2, A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5, CIP-003-8 R5.1.1, CIP-003-8 R5.3, CIP-004-6 R2.3, CIP-007-3 R2.1, CIP-007-3 R2.2, CIP-007-3 R2.3, CIP-007-3 R5.1, CIP-007-3 R5.1.1, CIP-007-3 R5.1.2, AC-17(a), CM-6(a), AC-6(1), PR.AC-4, PR.DS-5, SRG-OS-000480-GPOS-00227, R50, 2.2.6, 2.2 Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- NIST-800-53-AC-17(a)
- 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_sshd_config
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Test for existence /etc/ssh/sshd_config
ansible.builtin.stat:
path: /etc/ssh/sshd_config
register: file_exists
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-AC-17(a)
- 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_sshd_config
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- name: Ensure permission u-xs,g-xwrs,o-xwrt on /etc/ssh/sshd_config
ansible.builtin.file:
path: /etc/ssh/sshd_config
mode: u-xs,g-xwrs,o-xwrt
when:
- '"kernel" in ansible_facts.packages'
- file_exists.stat is defined and file_exists.stat.exists
tags:
- NIST-800-53-AC-17(a)
- NIST-800-53-AC-6(1)
- NIST-800-53-CM-6(a)
- PCI-DSSv4-2.2
- PCI-DSSv4-2.2.6
- configure_strategy
- file_permissions_sshd_config
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
Remediation Shell script: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | configure |
|---|
# Remediation is applicable only in certain platforms
if rpm --quiet -q kernel; then
chmod u-xs,g-xwrs,o-xwrt /etc/ssh/sshd_config
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
System Accounting with auditd
[ref]groupThe audit service provides substantial capabilities
for recording system activities. By default, the service audits about
SELinux AVC denials and certain types of security-relevant events
such as system logins, account modifications, and authentication
events performed by programs such as sudo.
Under its default configuration, auditd has modest disk space
requirements, and should not noticeably impact system performance.
NOTE: The Linux Audit daemon auditd can be configured to use
the augenrules program to read audit rules files (*.rules)
located in /etc/audit/rules.d location and compile them to create
the resulting form of the /etc/audit/audit.rules configuration file
during the daemon startup (default configuration). Alternatively, the auditd
daemon can use the auditctl utility to read audit rules from the
/etc/audit/audit.rules configuration file during daemon startup,
and load them into the kernel. The expected behavior is configured via the
appropriate ExecStartPost directive setting in the
/usr/lib/systemd/system/auditd.service configuration file.
To instruct the auditd daemon to use the augenrules program
to read audit rules (default configuration), use the following setting:
ExecStartPost=-/sbin/augenrules --load
in the /usr/lib/systemd/system/auditd.service configuration file.
In order to instruct the auditd daemon to use the auditctl
utility to read audit rules, use the following setting:
ExecStartPost=-/sbin/auditctl -R /etc/audit/audit.rules
in the /usr/lib/systemd/system/auditd.service configuration file.
Refer to [Service] section of the /usr/lib/systemd/system/auditd.service
configuration file for further details.
Government networks often have substantial auditing
requirements and auditd can be configured to meet these
requirements.
Examining some example audit records demonstrates how the Linux audit system
satisfies common requirements.
The following example from Red Hat Enterprise Linux 7 Documentation available at
https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html-single/selinux_users_and_administrators_guide/index#sect-Security-Enhanced_Linux-Fixing_Problems-Raw_Audit_Messages
shows the substantial amount of information captured in a
two typical "raw" audit messages, followed by a breakdown of the most important
fields. In this example the message is SELinux-related and reports an AVC
denial (and the associated system call) that occurred when the Apache HTTP
Server attempted to access the /var/www/html/file1 file (labeled with
the samba_share_t type):
type=AVC msg=audit(1226874073.147:96): avc: denied { getattr } for pid=2465 comm="httpd"
path="/var/www/html/file1" dev=dm-0 ino=284133 scontext=unconfined_u:system_r:httpd_t:s0
tcontext=unconfined_u:object_r:samba_share_t:s0 tclass=file
type=SYSCALL msg=audit(1226874073.147:96): arch=40000003 syscall=196 success=no exit=-13
a0=b98df198 a1=bfec85dc a2=54dff4 a3=2008171 items=0 ppid=2463 pid=2465 auid=502 uid=48
gid=48 euid=48 suid=48 fsuid=48 egid=48 sgid=48 fsgid=48 tty=(none) ses=6 comm="httpd"
exe="/usr/sbin/httpd" subj=unconfined_u:system_r:httpd_t:s0 key=(null)
msg=audit(1226874073.147:96)- The number in parentheses is the unformatted time stamp (Epoch time)
for the event, which can be converted to standard time by using the
date command.
{ getattr }- The item in braces indicates the permission that was denied.
getattr
indicates the source process was trying to read the target file's status information.
This occurs before reading files. This action is denied due to the file being
accessed having the wrong label. Commonly seen permissions include getattr,
read, and write.
comm="httpd"- The executable that launched the process. The full path of the executable is
found in the
exe= section of the system call (SYSCALL) message,
which in this case, is exe="/usr/sbin/httpd".
path="/var/www/html/file1"- The path to the object (target) the process attempted to access.
scontext="unconfined_u:system_r:httpd_t:s0"- The SELinux context of the process that attempted the denied action. In
this case, it is the SELinux context of the Apache HTTP Server, which is running
in the
httpd_t domain.
tcontext="unconfined_u:object_r:samba_share_t:s0"- The SELinux context of the object (target) the process attempted to access.
In this case, it is the SELinux context of
file1. Note: the samba_share_t
type is not accessible to processes running in the httpd_t domain.
- From the system call (
SYSCALL) message, two items are of interest:
success=no: indicates whether the denial (AVC) was enforced or not.
success=no indicates the system call was not successful (SELinux denied
access). success=yes indicates the system call was successful - this can
be seen for permissive domains or unconfined domains, such as initrc_t
and kernel_t.
exe="/usr/sbin/httpd": the full path to the executable that launched
the process, which in this case, is exe="/usr/sbin/httpd".
|
| contains 2 rules |
Ensure the audit-libs package as a part of audit Subsystem is Installed
[ref]ruleThe audit-libs package should be installed. Rationale:The auditd service is an access monitoring and accounting daemon, watching system calls to audit any access, in comparison with potential local access control policy such as SELinux policy. References:
CIP-004-6 R3.3, CIP-007-3 R6.5, AC-7(a), AU-7(1), AU-7(2), AU-14, AU-12(2), AU-2(a), CM-6(a), Req-10.2.1, SRG-OS-000062-GPOS-00031, SRG-OS-000037-GPOS-00015, SRG-OS-000038-GPOS-00016, SRG-OS-000039-GPOS-00017, SRG-OS-000040-GPOS-00018, SRG-OS-000041-GPOS-00019, SRG-OS-000042-GPOS-00021, SRG-OS-000051-GPOS-00024, SRG-OS-000054-GPOS-00025, SRG-OS-000122-GPOS-00063, SRG-OS-000254-GPOS-00095, SRG-OS-000255-GPOS-00096, SRG-OS-000337-GPOS-00129, SRG-OS-000348-GPOS-00136, SRG-OS-000349-GPOS-00137, SRG-OS-000350-GPOS-00138, SRG-OS-000351-GPOS-00139, SRG-OS-000352-GPOS-00140, SRG-OS-000353-GPOS-00141, SRG-OS-000354-GPOS-00142, SRG-OS-000358-GPOS-00145, SRG-OS-000365-GPOS-00152, SRG-OS-000392-GPOS-00172, SRG-OS-000475-GPOS-00220 Remediation Puppet snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | enable |
|---|
include install_audit-libs
class install_audit-libs {
package { 'audit-libs':
ensure => 'installed',
}
}
Remediation script: (show)
[[packages]]
name = "audit-libs"
version = "*"
Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | enable |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- NIST-800-53-AC-7(a)
- NIST-800-53-AU-12(2)
- NIST-800-53-AU-14
- NIST-800-53-AU-2(a)
- NIST-800-53-AU-7(1)
- NIST-800-53-AU-7(2)
- NIST-800-53-CM-6(a)
- PCI-DSS-Req-10.2.1
- enable_strategy
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- package_audit-libs_installed
- name: Ensure audit-libs is installed
ansible.builtin.package:
name: audit-libs
state: present
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-AC-7(a)
- NIST-800-53-AU-12(2)
- NIST-800-53-AU-14
- NIST-800-53-AU-2(a)
- NIST-800-53-AU-7(1)
- NIST-800-53-AU-7(2)
- NIST-800-53-CM-6(a)
- PCI-DSS-Req-10.2.1
- enable_strategy
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- package_audit-libs_installed
|
Ensure the audit Subsystem is Installed
[ref]ruleThe audit package should be installed. Rationale:The auditd service is an access monitoring and accounting daemon, watching system calls to audit any access, in comparison with potential local access control policy such as SELinux policy. References:
164.308(a)(1)(ii)(D), 164.308(a)(5)(ii)(C), 164.310(a)(2)(iv), 164.310(d)(2)(iii), 164.312(b), CIP-004-6 R3.3, CIP-007-3 R6.5, AC-7(a), AU-7(1), AU-7(2), AU-14, AU-12(2), AU-2(a), CM-6(a), FAU_GEN.1, Req-10.1, SRG-OS-000062-GPOS-00031, SRG-OS-000037-GPOS-00015, SRG-OS-000038-GPOS-00016, SRG-OS-000039-GPOS-00017, SRG-OS-000040-GPOS-00018, SRG-OS-000041-GPOS-00019, SRG-OS-000042-GPOS-00021, SRG-OS-000051-GPOS-00024, SRG-OS-000054-GPOS-00025, SRG-OS-000122-GPOS-00063, SRG-OS-000254-GPOS-00095, SRG-OS-000255-GPOS-00096, SRG-OS-000337-GPOS-00129, SRG-OS-000348-GPOS-00136, SRG-OS-000349-GPOS-00137, SRG-OS-000350-GPOS-00138, SRG-OS-000351-GPOS-00139, SRG-OS-000352-GPOS-00140, SRG-OS-000353-GPOS-00141, SRG-OS-000354-GPOS-00142, SRG-OS-000358-GPOS-00145, SRG-OS-000365-GPOS-00152, SRG-OS-000392-GPOS-00172, SRG-OS-000475-GPOS-00220, R33, R73, 0582, 0846, 10.2.1, 10.2 Remediation Puppet snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | enable |
|---|
include install_audit
class install_audit {
package { 'audit':
ensure => 'installed',
}
}
Remediation script: (show)
[[packages]]
name = "audit"
version = "*"
Remediation Ansible snippet: (show)
| Complexity: | low |
|---|
| Disruption: | low |
|---|
| Reboot: | false |
|---|
| Strategy: | enable |
|---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- NIST-800-53-AC-7(a)
- NIST-800-53-AU-12(2)
- NIST-800-53-AU-14
- NIST-800-53-AU-2(a)
- NIST-800-53-AU-7(1)
- NIST-800-53-AU-7(2)
- NIST-800-53-CM-6(a)
- PCI-DSS-Req-10.1
- PCI-DSSv4-10.2
- PCI-DSSv4-10.2.1
- enable_strategy
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- package_audit_installed
- name: Ensure audit is installed
ansible.builtin.package:
name: audit
state: present
when: '"kernel" in ansible_facts.packages'
tags:
- NIST-800-53-AC-7(a)
- NIST-800-53-AU-12(2)
- NIST-800-53-AU-14
- NIST-800-53-AU-2(a)
- NIST-800-53-AU-7(1)
- NIST-800-53-AU-7(2)
- NIST-800-53-CM-6(a)
- PCI-DSS-Req-10.1
- PCI-DSSv4-10.2
- PCI-DSSv4-10.2.1
- enable_strategy
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- package_audit_installed
|