Guide to the Secure Configuration of Red Hat Enterprise Linux 6

with profile Red Hat Corporate Profile for Certified Cloud Providers (RH CCP)
This is a *draft* SCAP profile for Red Hat Certified Cloud Providers

This guide presents a catalog of security-relevant configuration settings for Red Hat Enterprise Linux 6. It is a rendering of content structured in the eXtensible Configuration Checklist Description Format (XCCDF) in order to support security automation. The SCAP content is is available in the scap-security-guide package which is developed at https://www.open-scap.org/security-policies/scap-security-guide.

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

Revision History

Current version: 0.1.36

  • draft (as of 2017-08-29)

Platforms

  • cpe:/o:redhat:enterprise_linux:6
  • cpe:/o:redhat:enterprise_linux:6::client
  • cpe:/o:redhat:enterprise_linux:6::computenode

Table of Contents

  1. System Settings
    1. Installing and Maintaining Software
    2. File Permissions and Masks
    3. SELinux
    4. Account and Access Control
    5. Network Configuration and Firewalls
    6. System Accounting with auditd
  2. Services
    1. Obsolete Services
    2. Base Services
    3. Cron and At Daemons
    4. SSH Server
    5. Avahi Server

Checklist

contains 94 rules

System Settings   [ref]group

Contains rules that check correct system settings.

contains 65 rules

Installing and Maintaining Software   [ref]group

The following sections contain information on security-relevant choices during the initial operating system installation process and the setup of software updates.

contains 9 rules

Disk Partitioning   [ref]group

To ensure separation and protection of data, there are top-level system directories which should be placed on their own physical partition or logical volume. The installer's default partitioning scheme creates separate logical volumes for /, /boot, and swap.

  • If starting with any of the default layouts, check the box to "Review and modify partitioning." This allows for the easy creation of additional logical volumes inside the volume group already created, though it may require making /'s logical volume smaller to create space. In general, using logical volumes is preferable to using partitions because they can be more easily adjusted later.
  • If creating a custom layout, create the partitions mentioned in the previous paragraph (which the installer will require anyway), as well as separate ones described in the following sections.
If a system has already been installed, and the default partitioning scheme was used, it is possible but nontrivial to modify it to create separate logical volumes for the directories listed above. The Logical Volume Manager (LVM) makes this possible. See the LVM HOWTO at http://tldp.org/HOWTO/LVM-HOWTO/ for more detailed information on LVM.

contains 4 rules

Ensure /tmp Located On Separate Partition   [ref]rule

The /tmp directory is a world-writable directory used for temporary file storage. Ensure it has its own partition or logical volume at installation time, or migrate it using LVM.

Rationale:

The /tmp partition is used as temporary storage by many programs. Placing /tmp in its own partition enables the setting of more restrictive mount options, which can help protect programs which use it.

Severity:  low

Identifiers:  CCE-26435-8, DISA FSO RHEL-06-000001

References:  SC-32, 1208

Ensure /var Located On Separate Partition   [ref]rule

The /var directory is used by daemons and other system services to store frequently-changing data. Ensure that /var has its own partition or logical volume at installation time, or migrate it using LVM.

Rationale:

Ensuring that /var is mounted on its own partition enables the setting of more restrictive mount options. This helps protect system services such as daemons or other programs which use it. It is not uncommon for the /var directory to contain world-writable directories installed by other software packages.

Severity:  low

Identifiers:  CCE-26639-5, DISA FSO RHEL-06-000002

References:  SC-32, 1208

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

System logs are stored in the /var/log directory. Ensure that it has its own partition or logical volume at installation time, or migrate it using LVM.

Rationale:

Placing /var/log in its own partition enables better separation between log files and other files in /var/.

Severity:  low

Identifiers:  CCE-26215-4, DISA FSO RHEL-06-000003

References:  AU-9, SC-32, 1208

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

Audit logs are stored in the /var/log/audit directory. Ensure that it has its own partition or logical volume at installation time, or migrate it later using LVM. Make absolutely certain that it is large enough to store all audit logs that will be created by the auditing daemon.

Rationale:

Placing /var/log/audit in its own partition enables better separation between audit files and other files, and helps ensure that auditing cannot be halted due to the partition running out of space.

Severity:  low

Identifiers:  CCE-26436-6, DISA FSO RHEL-06-000004

References:  AU-4, AU-9, SC-32, 137, 138, 1208

Updating Software   [ref]group

The yum command line tool is used to install and update software packages. The system also provides a graphical software update tool in the System menu, in the Administration submenu, called Software Update.

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

contains 4 rules

Ensure Red Hat GPG Key Installed   [ref]rule

To ensure the system can cryptographically verify base software packages come from Red Hat (and to connect to the Red Hat Network to receive them), the Red Hat GPG key must properly be installed. To install the Red Hat GPG key, run:

$ sudo subscription-manager register
If the system is not connected to the Internet or an RHN Satellite, then install the Red Hat GPG key from trusted media such as the Red Hat installation CD-ROM or DVD. Assuming the disc is mounted in /media/cdrom, use the following command as the root user to import it into the keyring:
$ sudo rpm --import /media/cdrom/RPM-GPG-KEY

Rationale:

The Red Hat GPG key is necessary to cryptographically verify packages are from Red Hat.

Severity:  high

Identifiers:  CCE-26506-6, DISA FSO RHEL-06-000008

References:  SI-7, MA-1(b), 351, Req-6.2

Remediation Shell script:   (show)

# The two fingerprints below are retrieved from https://access.redhat.com/security/team/key
readonly REDHAT_RELEASE_2_FINGERPRINT="567E 347A D004 4ADE 55BA 8A5F 199E 2F91 FD43 1D51"
readonly REDHAT_AUXILIARY_FINGERPRINT="43A6 E49C 4A38 F4BE 9ABF 2A53 4568 9C88 2FA6 58E0"
# Location of the key we would like to import (once it's integrity verified)
readonly REDHAT_RELEASE_KEY="/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release"

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

# Verify /etc/pki/rpm-gpg directory permissions are safe
if [ "${RPM_GPG_DIR_PERMS}" -le "755" ]
then
  # If they are safe, try to obtain fingerprints from the key file
  # (to ensure there won't be e.g. CRC error).
  IFS=$'\n' GPG_OUT=($(gpg --with-fingerprint "${REDHAT_RELEASE_KEY}" | grep 'Key fingerprint ='))
  GPG_RESULT=$?
  # No CRC error, safe to proceed
  if [ "${GPG_RESULT}" -eq "0" ]
  then
    tr -s ' ' <<< "${GPG_OUT}" | grep -vE "${REDHAT_RELEASE_2_FINGERPRINT}|${REDHAT_AUXILIARY_FINGERPRINT}" || {
      # If file doesn't contains any keys with unknown fingerprint, import it
      rpm --import "${REDHAT_RELEASE_KEY}"
    }
  fi
fi
Remediation Ansible snippet:   (show)

Complexity:medium
Disruption:medium
Strategy:restrict
- name: "Read permission of GPG key directory"
  stat:
    path: /etc/pki/rpm-gpg/
  register: gpg_key_directory_permission
  check_mode: no
  tags:
    - ensure_redhat_gpgkey_installed
    - high_severity
    - restrict_strategy
    - medium_complexity
    - medium_disruption
    - CCE-26506-6
    - NIST-800-53-SI-7
    - NIST-800-53-MA-1(b)
    - PCI-DSS-Req-6.2

# It should fail if it doesn't find any fingerprints in file - maybe file was not parsed well.

- name: Read signatures in GPG key
  shell: gpg --with-fingerprint '/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release' | grep 'Key fingerprint =' | tr -s ' ' | sed 's;.*= ;;g'
  changed_when: False
  register: gpg_fingerprints
  check_mode: no
  tags:
    - ensure_redhat_gpgkey_installed
    - high_severity
    - restrict_strategy
    - medium_complexity
    - medium_disruption
    - CCE-26506-6
    - NIST-800-53-SI-7
    - NIST-800-53-MA-1(b)
    - PCI-DSS-Req-6.2

- name: Set Fact - Valid fingerprints
  set_fact:
     gpg_valid_fingerprints: ("567E 347A D004 4ADE 55BA 8A5F 199E 2F91 FD43 1D51" "43A6 E49C 4A38 F4BE 9ABF 2A53 4568 9C88 2FA6 58E0")
  tags:
    - ensure_redhat_gpgkey_installed
    - high_severity
    - restrict_strategy
    - medium_complexity
    - medium_disruption
    - CCE-26506-6
    - NIST-800-53-SI-7
    - NIST-800-53-MA-1(b)
    - PCI-DSS-Req-6.2

- name: Import RedHat GPG key
  rpm_key:
    state: present
    key: /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
  when:
    (gpg_key_directory_permission.stat.mode <= '0755')
    and (( gpg_fingerprints.stdout_lines | difference(gpg_valid_fingerprints)) | length == 0)
    and (gpg_fingerprints.stdout_lines | length > 0)
    and (ansible_distribution == "RedHat")
  tags:
    - ensure_redhat_gpgkey_installed
    - high_severity
    - restrict_strategy
    - medium_complexity
    - medium_disruption
    - CCE-26506-6
    - NIST-800-53-SI-7
    - NIST-800-53-MA-1(b)
    - PCI-DSS-Req-6.2

Ensure gpgcheck Enabled In Main Yum Configuration   [ref]rule

The gpgcheck option controls whether RPM packages' signatures are always checked prior to installation. To configure yum to check package signatures before installing them, ensure the following line appears in /etc/yum.conf in the [main] section:

gpgcheck=1

Rationale:

Ensuring the validity of packages' cryptographic signatures prior to installation ensures the authenticity of the software and protects against malicious tampering.

Severity:  medium

Identifiers:  CCE-26709-6, DISA FSO RHEL-06-000013

References:  SI-7, MA-1(b), 352, 663, Req-6.2

Remediation Shell script:   (show)

# Function to replace configuration setting in config file or add the configuration setting if
# it does not exist.
#
# Expects four arguments:
#
# config_file:		Configuration file that will be modified
# key:			Configuration option to change
# value:		Value of the configuration option to change
# cce:			The CCE identifier or '@CCENUM@' if no CCE identifier exists
#
# Optional arugments:
#
# format:		Optional argument to specify the format of how key/value should be
# 			modified/appended in the configuration file. The default is key = value.
#
# Example Call(s):
#
#     With default format of 'key = value':
#     replace_or_append '/etc/sysctl.conf' '^kernel.randomize_va_space' '2' '@CCENUM@'
#
#     With custom key/value format:
#     replace_or_append '/etc/sysconfig/selinux' '^SELINUX=' 'disabled' '@CCENUM@' '%s=%s'
#
#     With a variable:
#     replace_or_append '/etc/sysconfig/selinux' '^SELINUX=' $var_selinux_state '@CCENUM@' '%s=%s'
#
function replace_or_append {
  local config_file=$1
  local key=$2
  local value=$3
  local cce=$4
  local format=$5

  # Check sanity of the input
  if [ $# -lt "3" ]
  then
        echo "Usage: replace_or_append 'config_file_location' 'key_to_search' 'new_value'"
        echo
        echo "If symlinks need to be taken into account, add yes/no to the last argument"
        echo "to allow to 'follow_symlinks'."
        echo "Aborting."
        exit 1
  fi

  # Test if the config_file is a symbolic link. If so, use --follow-symlinks with sed.
  # Otherwise, regular sed command will do.
  if test -L $config_file; then
    sed_command="sed -i --follow-symlinks"
  else
    sed_command="sed -i"
  fi

  # Test that the cce arg is not empty or does not equal @CCENUM@.
  # If @CCENUM@ exists, it means that there is no CCE assigned.
  if ! [ "x$cce" = x ] && [ "$cce" != '@CCENUM@' ]; then
    cce="CCE-${cce}"
  else
    cce="CCE"
  fi

  # Strip any search characters in the key arg so that the key can be replaced without
  # adding any search characters to the config file.
  stripped_key=$(sed "s/[\^=\$,;+]*//g" <<< $key)

  # If there is no print format specified in the last arg, use the default format.
  if ! [ "x$format" = x ] ; then
    printf -v formatted_output "$format" "$stripped_key" "$value"
  else
    formatted_output="$stripped_key = $value"
  fi

  # If the key exists, change it. Otherwise, add it to the config_file.
  if `grep -qi "$key" $config_file` ; then
    eval '$sed_command "s/$key.*/$formatted_output/g" $config_file'
  else
    # \n is precaution for case where file ends without trailing newline
    echo -e "\n# Per $cce: Set $formatted_output in $config_file" >> $config_file
    echo -e "$formatted_output" >> $config_file
  fi

}

replace_or_append '/etc/yum.conf' '^gpgcheck' '1' 'CCE-26709-6'
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:medium
- name: "Check existence of yum on Fedora"
  stat:
    path: /etc/yum.conf
  register: yum_config_file
  check_mode: no
  when: ansible_distribution == "Fedora"

# Old versions of Fedora use yum

- name: "Ensure GPG check is globally activated (yum)"
  ini_file:
    dest: "{{item}}"
    section: main
    option: gpgcheck
    value: 1
    create: False
  with_items: "/etc/yum.conf"
  when: ansible_distribution == "RedHat" or yum_config_file.stat.exists
  tags:
    - ensure_gpgcheck_globally_activated
    - medium_severity
    - unknown_strategy
    - low_complexity
    - medium_disruption
    - CCE-26709-6
    - NIST-800-53-SI-7
    - NIST-800-53-MA-1(b)
    - PCI-DSS-Req-6.2

- name: "Ensure GPG check is globally activated (dnf)"
  ini_file:
    dest: "{{item}}"
    section: main
    option: gpgcheck
    value: 1
    create: False
  with_items: "/etc/dnf/dnf.conf"
  when: ansible_distribution == "Fedora"
  tags:
    - ensure_gpgcheck_globally_activated
    - medium_severity
    - unknown_strategy
    - low_complexity
    - medium_disruption
    - CCE-26709-6
    - NIST-800-53-SI-7
    - NIST-800-53-MA-1(b)
    - PCI-DSS-Req-6.2

Ensure gpgcheck Enabled For All Yum Package Repositories   [ref]rule

To ensure signature checking is not disabled for any repos, remove any lines from files in /etc/yum.repos.d of the form:

gpgcheck=0

Rationale:

Ensuring all packages' cryptographic signatures are valid prior to installation ensures the authenticity of the software and protects against malicious tampering.

Severity:  low

Identifiers:  CCE-26647-8, DISA FSO RHEL-06-000015

References:  SI-7, MA-1(b), 352, 663, Req-6.2

Remediation Shell script:   (show)

sed -i 's/gpgcheck=.*/gpgcheck=1/g' /etc/yum.repos.d/*
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:medium
#
- name: Find All Yum Repositories
  find:
    paths: "/etc/yum.repos.d/"
    patterns: "*.repo"
  register: yum_find

- name: Ensure gpgcheck Enabled For All Yum Package Repositories
  with_items: "{{ yum_find.files }}"
  lineinfile:
    create: yes
    dest: "{{ item.path }}"
    regexp: '^gpgcheck'
    line: 'gpgcheck=1'
  tags:
    - ensure_gpgcheck_never_disabled
    - low_severity
    - unknown_strategy
    - low_complexity
    - medium_disruption
    - CCE-26647-8
    - NIST-800-53-SI-7
    - NIST-800-53-MA-1(b)
    - PCI-DSS-Req-6.2

Ensure Software Patches Installed   [ref]rule

If the system is joined to the Red Hat Network, a Red Hat Satellite Server, or a yum server, run the following command to install updates:

$ sudo yum update
If the system is not configured to use one of these sources, updates (in the form of RPM packages) can be manually downloaded from the Red Hat Network and installed using rpm.

Rationale:

Installing software updates is a fundamental mitigation against the exploitation of publicly-known vulnerabilities.

Severity:  medium

Identifiers:  CCE-27635-2, DISA FSO RHEL-06-000011

References:  SI-2, MA-1(b), 1227, 1233, Req-6.2

Remediation Shell script:   (show)

Complexity:low
Disruption:high
Reboot:true
Strategy:patch
yum -y update
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:high
Reboot:true
Strategy:patch
- name: "Security patches are up to date"
  package:
    name: "*"
    state: "latest"
  tags:
    - security_patches_up_to_date
    - medium_severity
    - patch_strategy
    - low_complexity
    - high_disruption
    - CCE-27635-2
    - NIST-800-53-SI-2
    - NIST-800-53-MA-1(b)
    - PCI-DSS-Req-6.2

Software Integrity Checking   [ref]group

Both the AIDE (Advanced Intrusion Detection Environment) software and the RPM package management system provide mechanisms for verifying the integrity of installed software. AIDE uses snapshots of file metadata (such as hashes) and compares these to current system files in order to detect changes. The RPM package management system can conduct integrity checks by comparing information in its metadata database with files installed on the system.

Integrity checking cannot prevent intrusions, but can detect that they have occurred. Requirements for software integrity checking may be highly dependent on the environment in which the system will be used. Snapshot-based approaches such as AIDE may induce considerable overhead in the presence of frequent software updates.

contains 1 rule

Verify Integrity with AIDE   [ref]group

AIDE conducts integrity checks by comparing information about files with previously-gathered information. Ideally, the AIDE database is created immediately after initial system configuration, and then again after any software update. AIDE is highly configurable, with further configuration information located in /usr/share/doc/aide-VERSION.

contains 1 rule

Install AIDE   [ref]rule

Install the AIDE package with the command:

$ sudo yum install aide

Rationale:

The AIDE package must be installed if it is to be available for integrity checking.

Severity:  medium

Identifiers:  CCE-27024-9, DISA FSO RHEL-06-000016

References:  CM-3(d), CM-3(e), CM-6(d), SC-28, SI-7, 1069, Req-11.5

Remediation Shell script:   (show)

Complexity:low
Disruption:low
Strategy:enable
# Function to install or uninstall packages on RHEL and Fedora systems.
#
# Example Call(s):
#
#     package_command install aide
#     package_command remove telnet-server
#
function package_command {

# Load function arguments into local variables
local package_operation=$1
local package=$2

# Check sanity of the input
if [ $# -ne "2" ]
then
  echo "Usage: package_command 'install/uninstall' 'rpm_package_name"
  echo "Aborting."
  exit 1
fi

# If dnf is installed, use dnf; otherwise, use yum
if [ -f "/usr/bin/dnf" ] ; then
  install_util="/usr/bin/dnf"
else
  install_util="/usr/bin/yum"
fi

if [ "$package_operation" != 'remove' ] ; then
  # If the rpm is not installed, install the rpm
  if ! /bin/rpm -q --quiet $package; then
    $install_util -y $package_operation $package
  fi
else
  # If the rpm is installed, uninstall the rpm
  if /bin/rpm -q --quiet $package; then
    $install_util -y $package_operation $package
  fi
fi

}

package_command install aide
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:low
Strategy:enable
- name: "Ensure aide is installed"
  package:
    name="{{item}}"
    state=present
  with_items:
    - aide
  tags:
    - package_aide_installed
    - medium_severity
    - enable_strategy
    - low_complexity
    - low_disruption
    - CCE-27024-9
    - NIST-800-53-CM-3(d)
    - NIST-800-53-CM-3(e)
    - NIST-800-53-CM-6(d)
    - NIST-800-53-SC-28
    - NIST-800-53-SI-7
    - PCI-DSS-Req-11.5

Remediation Puppet snippet:   (show)

Complexity:low
Disruption:low
Strategy:enable
include install_aide

class install_aide {
  package { 'aide':
    ensure => 'installed',
  }
}
Remediation Anaconda snippet:   (show)

Complexity:low
Disruption:low
Strategy:enable

package --add=aide

File Permissions and Masks   [ref]group

Traditional Unix security relies heavily on file and directory permissions to prevent unauthorized users from reading or modifying files to which they should not have access.

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

The following command prints a list of all xfs partitions on the local system, which is the default filesystem for Red Hat Enterprise Linux 7 installations:

$ mount -t xfs | awk '{print $3}'
For any systems that use a different local filesystem type, modify this command as appropriate.

contains 19 rules

Restrict Dynamic Mounting and Unmounting of Filesystems   [ref]group

Linux includes a number of facilities for the automated addition and removal of filesystems on a running system. These facilities may be necessary in many environments, but this capability also carries some risk -- whether direct risk from allowing users to introduce arbitrary filesystems, or risk that software flaws in the automated mount facility itself could allow an attacker to compromise the system.

This command can be used to list the types of filesystems that are available to the currently executing kernel:

$ find /lib/modules/`uname -r`/kernel/fs -type f -name '*.ko'
If these filesystems are not required then they can be explicitly disabled in a configuratio file in /etc/modprobe.d.

contains 1 rule

Disable the Automounter   [ref]rule

The autofs daemon mounts and unmounts filesystems, such as user home directories shared via NFS, on demand. In addition, autofs can be used to handle removable media, and the default configuration provides the cdrom device as /misc/cd. However, this method of providing access to removable media is not common, so autofs can almost always be disabled if NFS is not in use. Even if NFS is required, it may be possible to configure filesystem mounts statically by editing /etc/fstab rather than relying on the automounter.

The autofs service can be disabled with the following command:

$ sudo chkconfig autofs off

Rationale:

Disabling the automounter permits the administrator to statically control filesystem mounting through /etc/fstab.

Severity:  low

Identifiers:  CCE-26976-1, DISA FSO RHEL-06-000526

References:  AC-19(a), AC-19(d), AC-19(e), 366

Remediation Shell script:   (show)

Complexity:low
Disruption:low
Strategy:disable
# Function to enable/disable and start/stop services on RHEL and Fedora systems.
#
# Example Call(s):
#
#     service_command enable bluetooth
#     service_command disable bluetooth.service
#
#     Using xinetd:
#     service_command disable rsh.socket xinetd=rsh
#
function service_command {

# Load function arguments into local variables
local service_state=$1
local service=$2
local xinetd=$(echo $3 | cut -d'=' -f2)

# Check sanity of the input
if [ $# -lt "2" ]
then
  echo "Usage: service_command 'enable/disable' 'service_name.service'"
  echo
  echo "To enable or disable xinetd services add \'xinetd=service_name\'"
  echo "as the last argument"  
  echo "Aborting."
  exit 1
fi

# If systemctl is installed, use systemctl command; otherwise, use the service/chkconfig commands
if [ -f "/usr/bin/systemctl" ] ; then
  service_util="/usr/bin/systemctl"
else
  service_util="/sbin/service"
  chkconfig_util="/sbin/chkconfig"
fi

# If disable is not specified in arg1, set variables to enable services.
# Otherwise, variables are to be set to disable services.
if [ "$service_state" != 'disable' ] ; then
  service_state="enable"
  service_operation="start"
  chkconfig_state="on"
else
  service_state="disable"
  service_operation="stop"
  chkconfig_state="off"
fi

# If chkconfig_util is not empty, use chkconfig/service commands.
if ! [ "x$chkconfig_util" = x ] ; then
  $service_util $service $service_operation
  $chkconfig_util --level 0123456 $service $chkconfig_state
else
  $service_util $service_operation $service
  $service_util $service_state $service
fi

# Test if local variable xinetd is empty using non-bashism.
# If empty, then xinetd is not being used.
if ! [ "x$xinetd" = x ] ; then
  grep -qi disable /etc/xinetd.d/$xinetd && \

  if ! [ "$service_operation" != 'disable' ] ; then
    sed -i "s/disable.*/disable         = no/gI" /etc/xinetd.d/$xinetd
  else
    sed -i "s/disable.*/disable         = yes/gI" /etc/xinetd.d/$xinetd
  fi
fi

}

service_command disable autofs
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:low
Strategy:disable
- name: "Disable service autofs"
  service:
    name="{{item}}"
    enabled="no"
    state="stopped"
  with_items:
    - autofs
  tags:
    - service_autofs_disabled
    - low_severity
    - disable_strategy
    - low_complexity
    - low_disruption
    - CCE-26976-1
    - NIST-800-53-AC-19(a)
    - NIST-800-53-AC-19(d)
    - NIST-800-53-AC-19(e)

Verify Permissions on Important Files and Directories   [ref]group

Permissions for many files on a system must be set restrictively to ensure sensitive information is properly protected. This section discusses important permission restrictions which can be verified to ensure that no harmful discrepancies have arisen.

contains 16 rules
contains 12 rules

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.

Severity:  medium

Identifiers:  CCE-26947-2, DISA FSO RHEL-06-000033

References:  AC-6, 225, Req-8.7.c

Remediation Shell script:   (show)

chown root /etc/shadow

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.

Severity:  medium

Identifiers:  CCE-26967-0, DISA FSO RHEL-06-000034

References:  AC-6, 225, Req-8.7.c

Remediation Shell script:   (show)

chgrp root /etc/shadow

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.

Severity:  medium

Identifiers:  CCE-26992-8, DISA FSO RHEL-06-000035

References:  AC-6, 225, Req-8.7.c

Remediation Shell script:   (show)

Complexity:low
Disruption:low
Strategy:configure
chmod 0000 /etc/shadow
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:low
Strategy:configure
- name: "Ensure permission 0000 on /etc/shadow"
  file:
    path="{{item}}"
    mode=0000
  with_items:
    - /etc/shadow
  tags:
    - file_permissions_etc_shadow
    - medium_severity
    - configure_strategy
    - low_complexity
    - low_disruption
    - CCE-26992-8
    - NIST-800-53-AC-6
    - PCI-DSS-Req-8.7.c

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.

Severity:  medium

Identifiers:  CCE-26822-7, DISA FSO RHEL-06-000042

References:  AC-6, Req-8.7.c

Remediation Shell script:   (show)

Complexity:low
Disruption:low
Strategy:configure

chown root /etc/group
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:low
Strategy:configure

- name: Find /etc/group file(s)
  find:
    paths: "{{ '/etc/group' | dirname }}"
    patterns: "{{ '/etc/group' | basename }}"
  register: files_found
  tags:
    - file_owner_etc_group
    - medium_severity
    - configure_strategy
    - low_complexity
    - low_disruption
    - CCE-26822-7
    - NIST-800-53-AC-6
    - PCI-DSS-Req-8.7.c

- name: Set user ownership to root
  file:
    path: "{{ item.path }}"
    owner: root
  with_items:
    - "{{ files_found.files }}"
  tags:
    - file_owner_etc_group
    - medium_severity
    - configure_strategy
    - low_complexity
    - low_disruption
    - CCE-26822-7
    - NIST-800-53-AC-6
    - PCI-DSS-Req-8.7.c

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.

Severity:  medium

Identifiers:  CCE-26930-8, DISA FSO RHEL-06-000043

References:  AC-6, 225, Req-8.7.c

Remediation Shell script:   (show)

Complexity:low
Disruption:low
Strategy:configure

chgrp root /etc/group
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:low
Strategy:configure

- name: Find /etc/group file(s)
  find:
    paths: "{{ '/etc/group' | dirname }}"
    patterns: "{{ '/etc/group' | basename }}"
  register: files_found
  tags:
    - file_groupowner_etc_group
    - medium_severity
    - configure_strategy
    - low_complexity
    - low_disruption
    - CCE-26930-8
    - NIST-800-53-AC-6
    - PCI-DSS-Req-8.7.c

- name: Set group ownership to root
  file:
    path: "{{ item.path }}"
    group: root
  with_items:
    - "{{ files_found.files }}"
  tags:
    - file_groupowner_etc_group
    - medium_severity
    - configure_strategy
    - low_complexity
    - low_disruption
    - CCE-26930-8
    - NIST-800-53-AC-6
    - PCI-DSS-Req-8.7.c

Verify Permissions on group File   [ref]rule

To properly set the permissions of /etc/group, run the command:

$ sudo chmod 644 /etc/group

Rationale:

The /etc/group file contains information regarding groups that are configured on the system. Protection of this file is important for system security.

Severity:  medium

Identifiers:  CCE-26954-8, DISA FSO RHEL-06-000044

References:  AC-6, 225, Req-8.7.c

Remediation Shell script:   (show)

Complexity:low
Disruption:low
Strategy:configure

chmod 0644 /etc/group
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:low
Strategy:configure

- name: Find /etc/group file(s)
  find:
    paths: "{{ '/etc/group' | dirname }}"
    patterns: "{{ '/etc/group' | basename }}"
  register: files_found
  tags:
    - file_permissions_etc_group
    - medium_severity
    - configure_strategy
    - low_complexity
    - low_disruption
    - CCE-26954-8
    - NIST-800-53-AC-6
    - PCI-DSS-Req-8.7.c

- name: Set permissions
  file:
    path: "{{ item.path }}"
    mode: 0644
  with_items:
    - "{{ files_found.files }}"
  tags:
    - file_permissions_etc_group
    - medium_severity
    - configure_strategy
    - low_complexity
    - low_disruption
    - CCE-26954-8
    - NIST-800-53-AC-6
    - PCI-DSS-Req-8.7.c

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.

Severity:  medium

Identifiers:  CCE-27026-4, DISA FSO RHEL-06-000036

References:  AC-6, 366

Remediation Shell script:   (show)

Complexity:low
Disruption:low
Strategy:configure

chown root /etc/gshadow
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:low
Strategy:configure

- name: Find /etc/gshadow file(s)
  find:
    paths: "{{ '/etc/gshadow' | dirname }}"
    patterns: "{{ '/etc/gshadow' | basename }}"
  register: files_found
  tags:
    - file_owner_etc_gshadow
    - medium_severity
    - configure_strategy
    - low_complexity
    - low_disruption
    - CCE-27026-4
    - NIST-800-53-AC-6

- name: Set user ownership to root
  file:
    path: "{{ item.path }}"
    owner: root
  with_items:
    - "{{ files_found.files }}"
  tags:
    - file_owner_etc_gshadow
    - medium_severity
    - configure_strategy
    - low_complexity
    - low_disruption
    - CCE-27026-4
    - NIST-800-53-AC-6

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.

Severity:  medium

Identifiers:  CCE-26975-3, DISA FSO RHEL-06-000037

References:  AC-6, 225

Remediation Shell script:   (show)

Complexity:low
Disruption:low
Strategy:configure

chgrp root /etc/gshadow
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:low
Strategy:configure

- name: Find /etc/gshadow file(s)
  find:
    paths: "{{ '/etc/gshadow' | dirname }}"
    patterns: "{{ '/etc/gshadow' | basename }}"
  register: files_found
  tags:
    - file_groupowner_etc_gshadow
    - medium_severity
    - configure_strategy
    - low_complexity
    - low_disruption
    - CCE-26975-3
    - NIST-800-53-AC-6

- name: Set group ownership to root
  file:
    path: "{{ item.path }}"
    group: root
  with_items:
    - "{{ files_found.files }}"
  tags:
    - file_groupowner_etc_gshadow
    - medium_severity
    - configure_strategy
    - low_complexity
    - low_disruption
    - CCE-26975-3
    - NIST-800-53-AC-6

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.

Severity:  medium

Identifiers:  CCE-26951-4, DISA FSO RHEL-06-000038

References:  AC-6, 225

Remediation Shell script:   (show)

Complexity:low
Disruption:low
Strategy:configure

chmod 0000 /etc/gshadow
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:low
Strategy:configure

- name: Find /etc/gshadow file(s)
  find:
    paths: "{{ '/etc/gshadow' | dirname }}"
    patterns: "{{ '/etc/gshadow' | basename }}"
  register: files_found
  tags:
    - file_permissions_etc_gshadow
    - medium_severity
    - configure_strategy
    - low_complexity
    - low_disruption
    - CCE-26951-4
    - NIST-800-53-AC-6

- name: Set permissions
  file:
    path: "{{ item.path }}"
    mode: 0000
  with_items:
    - "{{ files_found.files }}"
  tags:
    - file_permissions_etc_gshadow
    - medium_severity
    - configure_strategy
    - low_complexity
    - low_disruption
    - CCE-26951-4
    - NIST-800-53-AC-6

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.

Severity:  medium

Identifiers:  CCE-26953-0, DISA FSO RHEL-06-000039

References:  AC-6, 225, Req-8.7.c

Remediation Shell script:   (show)

Complexity:low
Disruption:low
Strategy:configure

chown root /etc/passwd
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:low
Strategy:configure

- name: Find /etc/passwd file(s)
  find:
    paths: "{{ '/etc/passwd' | dirname }}"
    patterns: "{{ '/etc/passwd' | basename }}"
  register: files_found
  tags:
    - file_owner_etc_passwd
    - medium_severity
    - configure_strategy
    - low_complexity
    - low_disruption
    - CCE-26953-0
    - NIST-800-53-AC-6
    - PCI-DSS-Req-8.7.c

- name: Set user ownership to root
  file:
    path: "{{ item.path }}"
    owner: root
  with_items:
    - "{{ files_found.files }}"
  tags:
    - file_owner_etc_passwd
    - medium_severity
    - configure_strategy
    - low_complexity
    - low_disruption
    - CCE-26953-0
    - NIST-800-53-AC-6
    - PCI-DSS-Req-8.7.c

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.

Severity:  medium

Identifiers:  CCE-26856-5, DISA FSO RHEL-06-000040

References:  AC-6, 225, Req-8.7.c

Remediation Shell script:   (show)

Complexity:low
Disruption:low
Strategy:configure

chgrp root /etc/passwd
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:low
Strategy:configure

- name: Find /etc/passwd file(s)
  find:
    paths: "{{ '/etc/passwd' | dirname }}"
    patterns: "{{ '/etc/passwd' | basename }}"
  register: files_found
  tags:
    - file_groupowner_etc_passwd
    - medium_severity
    - configure_strategy
    - low_complexity
    - low_disruption
    - CCE-26856-5
    - NIST-800-53-AC-6
    - PCI-DSS-Req-8.7.c

- name: Set group ownership to root
  file:
    path: "{{ item.path }}"
    group: root
  with_items:
    - "{{ files_found.files }}"
  tags:
    - file_groupowner_etc_passwd
    - medium_severity
    - configure_strategy
    - low_complexity
    - low_disruption
    - CCE-26856-5
    - NIST-800-53-AC-6
    - PCI-DSS-Req-8.7.c

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.

Severity:  medium

Identifiers:  CCE-26868-0, DISA FSO RHEL-06-000041

References:  AC-6, 225, Req-8.7.c

Remediation Shell script:   (show)

Complexity:low
Disruption:low
Strategy:configure

chmod 0644 /etc/passwd
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:low
Strategy:configure

- name: Find /etc/passwd file(s)
  find:
    paths: "{{ '/etc/passwd' | dirname }}"
    patterns: "{{ '/etc/passwd' | basename }}"
  register: files_found
  tags:
    - file_permissions_etc_passwd
    - medium_severity
    - configure_strategy
    - low_complexity
    - low_disruption
    - CCE-26868-0
    - NIST-800-53-AC-6
    - PCI-DSS-Req-8.7.c

- name: Set permissions
  file:
    path: "{{ item.path }}"
    mode: 0644
  with_items:
    - "{{ files_found.files }}"
  tags:
    - file_permissions_etc_passwd
    - medium_severity
    - configure_strategy
    - low_complexity
    - low_disruption
    - CCE-26868-0
    - NIST-800-53-AC-6
    - PCI-DSS-Req-8.7.c

Verify File Permissions Within Some Important Directories   [ref]group

Some directories contain files whose confidentiality or integrity is notably important and may also be susceptible to misconfiguration over time, particularly if unpackaged software is installed. As such, an argument exists to verify that files' permissions within these directories remain configured correctly and restrictively.

contains 4 rules

Verify that Shared Library Files Have Restrictive Permissions   [ref]rule

System-wide shared library files, which are linked to executables during process load time or run time, are stored in the following directories by default:

/lib
/lib64
/usr/lib
/usr/lib64
Kernel modules, which can be added to the kernel during runtime, are stored in /lib/modules. All files in these directories should not be group-writable or world-writable. If any file in these directories is found to be group-writable or world-writable, correct its permission with the following command:
$ sudo chmod go-w FILE

Rationale:

Files from shared library directories are loaded into the address space of processes (including privileged ones) or of the kernel itself at runtime. Restrictive permissions are necessary to protect the integrity of the system.

Severity:  medium

Identifiers:  CCE-27381-3, DISA FSO RHEL-06-000045

References:  AC-6, 1499

Remediation Shell script:   (show)

DIRS="/lib /lib64 /usr/lib /usr/lib64"
for dirPath in $DIRS; do
	find "$dirPath" -perm /022 -type f -exec chmod go-w '{}' \;
done
Remediation Ansible snippet:   (show)

Complexity:high
Disruption:medium
Strategy:restrict
- name: "Read list of world and group writable files in libraries directories"
  shell: "find /lib /lib64 /usr/lib /usr/lib64 -perm /022 -type f"
  register: world_writable_library_files
  changed_when: False
  failed_when: False
  check_mode: no
  tags:
    - file_permissions_library_dirs
    - medium_severity
    - restrict_strategy
    - high_complexity
    - medium_disruption
    - CCE-27381-3
    - NIST-800-53-AC-6

- name: "Disable world/group writability to library files"
  file:
    path: "{{item}}"
    mode: "go-w"
  with_items: "{{ world_writable_library_files.stdout_lines }}"
  when: world_writable_library_files.stdout_lines | length > 0
  tags:
    - file_permissions_library_dirs
    - medium_severity
    - restrict_strategy
    - high_complexity
    - medium_disruption
    - CCE-27381-3
    - NIST-800-53-AC-6

Verify that Shared Library Files Have Root Ownership   [ref]rule

System-wide shared library files, which are linked to executables during process load time or run time, are stored in the following directories by default:

/lib
/lib64
/usr/lib
/usr/lib64
Kernel modules, which can be added to the kernel during runtime, are also stored in /lib/modules. All files in these directories should be owned by the root user. If the directory, or any file in these directories, is found to be owned by a user other than root correct its ownership with the following command:
$ sudo chown root FILE

Rationale:

Files from shared library directories are loaded into the address space of processes (including privileged ones) or of the kernel itself at runtime. Proper ownership is necessary to protect the integrity of the system.

Severity:  medium

Identifiers:  CCE-27424-1, DISA FSO RHEL-06-000046

References:  AC-6, 1499

Remediation Shell script:   (show)

for LIBDIR in /usr/lib /usr/lib64 /lib /lib64
do
  if [ -d $LIBDIR ]
  then
    find -L $LIBDIR \! -user root -exec chown root {} \; 
  fi
done
Remediation Ansible snippet:   (show)

Complexity:medium
Disruption:medium
Strategy:restrict
- name: "Read list libraries without root ownership"
  shell: "find -L /usr/lib /usr/lib64 /lib /lib64 \\! -user root"
  register: libraries_not_owned_by_root
  changed_when: False
  failed_when: False
  check_mode: no
  tags:
    - file_ownership_library_dirs
    - medium_severity
    - restrict_strategy
    - medium_complexity
    - medium_disruption
    - CCE-27424-1
    - NIST-800-53-AC-6

- name: "Set ownership of system libraries to root"
  file:
    path: "{{item}}"
    owner: "root"
  with_items: "{{ libraries_not_owned_by_root.stdout_lines }}"
  when: libraries_not_owned_by_root | length > 0
  tags:
    - file_ownership_library_dirs
    - medium_severity
    - restrict_strategy
    - medium_complexity
    - medium_disruption
    - CCE-27424-1
    - NIST-800-53-AC-6

Verify that System Executables Have Restrictive Permissions   [ref]rule

System executables are stored in the following directories by default:

/bin
/sbin
/usr/bin
/usr/libexec
/usr/local/bin
/usr/local/sbin
/usr/sbin
All files in these directories should not be group-writable or world-writable. If any file FILE in these directories is found to be group-writable or world-writable, correct its permission with the following command:
$ sudo chmod go-w FILE

Rationale:

System binaries are executed by privileged users, as well as system services, and restrictive permissions are necessary to ensure execution of these programs cannot be co-opted.

Severity:  medium

Identifiers:  CCE-27289-8, DISA FSO RHEL-06-000047

References:  AC-6, 1499

Remediation Shell script:   (show)

DIRS="/bin /usr/bin /usr/local/bin /sbin /usr/sbin /usr/local/sbin /usr/libexec"
for dirPath in $DIRS; do
	find "$dirPath" -perm /022 -exec chmod go-w '{}' \;
done
Remediation Ansible snippet:   (show)

Complexity:medium
Disruption:medium
Strategy:restrict
- name: "Read list of world and group writable system executables"
  shell: "find /bin /usr/bin /usr/local/bin /sbin /usr/sbin /usr/local/sbin /usr/libexec -perm /022 -type f"
  register: world_writable_library_files
  changed_when: False
  failed_when: False
  check_mode: no
  tags:
    - file_permissions_binary_dirs
    - medium_severity
    - restrict_strategy
    - medium_complexity
    - medium_disruption
    - CCE-27289-8
    - NIST-800-53-AC-6

- name: "Remove world/group writability of system executables"
  file:
    path: "{{item}}"
    mode: "go-w"
  with_items: "{{ world_writable_library_files.stdout_lines }}"
  when: world_writable_library_files.stdout_lines | length > 0
  tags:
    - file_permissions_binary_dirs
    - medium_severity
    - restrict_strategy
    - medium_complexity
    - medium_disruption
    - CCE-27289-8
    - NIST-800-53-AC-6

Verify that System Executables Have Root Ownership   [ref]rule

System executables are stored in the following directories by default:

/bin
/sbin
/usr/bin
/usr/libexec
/usr/local/bin
/usr/local/sbin
/usr/sbin
All files in these directories should be owned by the root user. If any file FILE in these directories is found to be owned by a user other than root, correct its ownership with the following command:
$ sudo chown root FILE

Rationale:

System binaries are executed by privileged users as well as system services, and restrictive permissions are necessary to ensure that their execution of these programs cannot be co-opted.

Severity:  medium

Identifiers:  CCE-27623-8, DISA FSO RHEL-06-000048

References:  AC-6, 1499

Remediation Shell script:   (show)

find /bin/ \
/usr/bin/ \
/usr/local/bin/ \
/sbin/ \
/usr/sbin/ \
/usr/local/sbin/ \
/usr/libexec \
\! -user root -execdir chown root {} \;
Remediation Ansible snippet:   (show)

Complexity:medium
Disruption:medium
Strategy:restrict
- name: "Read list of system executables without root ownership"
  shell: "find /bin/ /usr/bin/ /usr/local/bin/ /sbin/ /usr/sbin/ /usr/local/sbin/ /usr/libexec \\! -user root"
  register: no_root_system_executables
  changed_when: False
  failed_when: False
  check_mode: no
  tags:
    - file_ownership_binary_dirs
    - medium_severity
    - restrict_strategy
    - medium_complexity
    - medium_disruption
    - CCE-27623-8
    - NIST-800-53-AC-6

- name: "Set ownership to root of system executables"
  file:
    path: "{{item}}"
    owner: "root"
  with_items: "{{ no_root_system_executables.stdout_lines }}"
  when: no_root_system_executables.stdout_lines | length > 0
  tags:
    - file_ownership_binary_dirs
    - medium_severity
    - restrict_strategy
    - medium_complexity
    - medium_disruption
    - CCE-27623-8
    - NIST-800-53-AC-6

Restrict Programs from Dangerous Execution Patterns   [ref]group

The recommendations in this section are designed to ensure that the system's features to protect against potentially dangerous program execution are activated. These protections are applied at the system initialization or kernel level, and defend against certain types of badly-configured or compromised programs.

contains 2 rules

Enable ExecShield   [ref]group

ExecShield describes kernel features that provide protection against exploitation of memory corruption errors such as buffer overflows. These features include random placement of the stack and other memory regions, prevention of execution in memory that should only hold data, and special handling of text buffers. These protections are enabled by default and controlled through sysctl variables kernel.exec-shield and kernel.randomize_va_space.

contains 2 rules

Enable ExecShield   [ref]rule

To set the runtime status of the kernel.exec-shield kernel parameter, run the following command:

$ sudo sysctl -w kernel.exec-shield=1
If this is not the system's default value, add the following line to /etc/sysctl.conf:
kernel.exec-shield = 1

Rationale:

ExecShield uses the segmentation feature on all x86 systems to prevent execution in memory higher than a certain address. It writes an address as a limit in the code segment descriptor, to control where code can be executed, on a per-process basis. When the kernel places a process's memory regions such as the stack and heap higher than this address, the hardware prevents execution in that address range.

Severity:  medium

Identifiers:  CCE-27007-4, DISA FSO RHEL-06-000079

References:  SC-39, 2530

Remediation Shell script:   (show)

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable


#
# Set runtime for kernel.exec-shield
#
/sbin/sysctl -q -n -w kernel.exec-shield=1

#
# If kernel.exec-shield present in /etc/sysctl.conf, change value to "1"
#	else, add "kernel.exec-shield = 1" to /etc/sysctl.conf
#
# Function to replace configuration setting in config file or add the configuration setting if
# it does not exist.
#
# Expects four arguments:
#
# config_file:		Configuration file that will be modified
# key:			Configuration option to change
# value:		Value of the configuration option to change
# cce:			The CCE identifier or '@CCENUM@' if no CCE identifier exists
#
# Optional arugments:
#
# format:		Optional argument to specify the format of how key/value should be
# 			modified/appended in the configuration file. The default is key = value.
#
# Example Call(s):
#
#     With default format of 'key = value':
#     replace_or_append '/etc/sysctl.conf' '^kernel.randomize_va_space' '2' '@CCENUM@'
#
#     With custom key/value format:
#     replace_or_append '/etc/sysconfig/selinux' '^SELINUX=' 'disabled' '@CCENUM@' '%s=%s'
#
#     With a variable:
#     replace_or_append '/etc/sysconfig/selinux' '^SELINUX=' $var_selinux_state '@CCENUM@' '%s=%s'
#
function replace_or_append {
  local config_file=$1
  local key=$2
  local value=$3
  local cce=$4
  local format=$5

  # Check sanity of the input
  if [ $# -lt "3" ]
  then
        echo "Usage: replace_or_append 'config_file_location' 'key_to_search' 'new_value'"
        echo
        echo "If symlinks need to be taken into account, add yes/no to the last argument"
        echo "to allow to 'follow_symlinks'."
        echo "Aborting."
        exit 1
  fi

  # Test if the config_file is a symbolic link. If so, use --follow-symlinks with sed.
  # Otherwise, regular sed command will do.
  if test -L $config_file; then
    sed_command="sed -i --follow-symlinks"
  else
    sed_command="sed -i"
  fi

  # Test that the cce arg is not empty or does not equal @CCENUM@.
  # If @CCENUM@ exists, it means that there is no CCE assigned.
  if ! [ "x$cce" = x ] && [ "$cce" != '@CCENUM@' ]; then
    cce="CCE-${cce}"
  else
    cce="CCE"
  fi

  # Strip any search characters in the key arg so that the key can be replaced without
  # adding any search characters to the config file.
  stripped_key=$(sed "s/[\^=\$,;+]*//g" <<< $key)

  # If there is no print format specified in the last arg, use the default format.
  if ! [ "x$format" = x ] ; then
    printf -v formatted_output "$format" "$stripped_key" "$value"
  else
    formatted_output="$stripped_key = $value"
  fi

  # If the key exists, change it. Otherwise, add it to the config_file.
  if `grep -qi "$key" $config_file` ; then
    eval '$sed_command "s/$key.*/$formatted_output/g" $config_file'
  else
    # \n is precaution for case where file ends without trailing newline
    echo -e "\n# Per $cce: Set $formatted_output in $config_file" >> $config_file
    echo -e "$formatted_output" >> $config_file
  fi

}

replace_or_append '/etc/sysctl.conf' '^kernel.exec-shield' "1" 'CCE-27007-4'
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
- name: Ensure sysctl kernel.exec-shield is set to 1
  sysctl:
    name: kernel.exec-shield
    value: 1
    state: present
    reload: yes
  tags:
    - sysctl_kernel_exec_shield
    - medium_severity
    - disable_strategy
    - low_complexity
    - medium_disruption
    - CCE-27007-4
    - NIST-800-53-SC-39

Enable Randomized Layout of Virtual Address Space   [ref]rule

To set the runtime status of the kernel.randomize_va_space kernel parameter, run the following command:

$ sudo sysctl -w kernel.randomize_va_space=2
If this is not the system's default value, add the following line to /etc/sysctl.conf:
kernel.randomize_va_space = 2

Rationale:

Address space layout randomization (ASLR) makes it more difficult for an attacker to predict the location of attack code they have introduced into a process's address space during an attempt at exploitation. Additionally, ASLR makes it more difficult for an attacker to know the location of existing code in order to re-purpose it using return oriented programming (ROP) techniques.

Severity:  medium

Identifiers:  CCE-26999-3, DISA FSO RHEL-06-000078

References:  SC-30(2)

Remediation Shell script:   (show)

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable


#
# Set runtime for kernel.randomize_va_space
#
/sbin/sysctl -q -n -w kernel.randomize_va_space=2

#
# If kernel.randomize_va_space present in /etc/sysctl.conf, change value to "2"
#	else, add "kernel.randomize_va_space = 2" to /etc/sysctl.conf
#
# Function to replace configuration setting in config file or add the configuration setting if
# it does not exist.
#
# Expects four arguments:
#
# config_file:		Configuration file that will be modified
# key:			Configuration option to change
# value:		Value of the configuration option to change
# cce:			The CCE identifier or '@CCENUM@' if no CCE identifier exists
#
# Optional arugments:
#
# format:		Optional argument to specify the format of how key/value should be
# 			modified/appended in the configuration file. The default is key = value.
#
# Example Call(s):
#
#     With default format of 'key = value':
#     replace_or_append '/etc/sysctl.conf' '^kernel.randomize_va_space' '2' '@CCENUM@'
#
#     With custom key/value format:
#     replace_or_append '/etc/sysconfig/selinux' '^SELINUX=' 'disabled' '@CCENUM@' '%s=%s'
#
#     With a variable:
#     replace_or_append '/etc/sysconfig/selinux' '^SELINUX=' $var_selinux_state '@CCENUM@' '%s=%s'
#
function replace_or_append {
  local config_file=$1
  local key=$2
  local value=$3
  local cce=$4
  local format=$5

  # Check sanity of the input
  if [ $# -lt "3" ]
  then
        echo "Usage: replace_or_append 'config_file_location' 'key_to_search' 'new_value'"
        echo
        echo "If symlinks need to be taken into account, add yes/no to the last argument"
        echo "to allow to 'follow_symlinks'."
        echo "Aborting."
        exit 1
  fi

  # Test if the config_file is a symbolic link. If so, use --follow-symlinks with sed.
  # Otherwise, regular sed command will do.
  if test -L $config_file; then
    sed_command="sed -i --follow-symlinks"
  else
    sed_command="sed -i"
  fi

  # Test that the cce arg is not empty or does not equal @CCENUM@.
  # If @CCENUM@ exists, it means that there is no CCE assigned.
  if ! [ "x$cce" = x ] && [ "$cce" != '@CCENUM@' ]; then
    cce="CCE-${cce}"
  else
    cce="CCE"
  fi

  # Strip any search characters in the key arg so that the key can be replaced without
  # adding any search characters to the config file.
  stripped_key=$(sed "s/[\^=\$,;+]*//g" <<< $key)

  # If there is no print format specified in the last arg, use the default format.
  if ! [ "x$format" = x ] ; then
    printf -v formatted_output "$format" "$stripped_key" "$value"
  else
    formatted_output="$stripped_key = $value"
  fi

  # If the key exists, change it. Otherwise, add it to the config_file.
  if `grep -qi "$key" $config_file` ; then
    eval '$sed_command "s/$key.*/$formatted_output/g" $config_file'
  else
    # \n is precaution for case where file ends without trailing newline
    echo -e "\n# Per $cce: Set $formatted_output in $config_file" >> $config_file
    echo -e "$formatted_output" >> $config_file
  fi

}

replace_or_append '/etc/sysctl.conf' '^kernel.randomize_va_space' "2" 'CCE-26999-3'
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
- name: Ensure sysctl kernel.randomize_va_space is set to 2
  sysctl:
    name: kernel.randomize_va_space
    value: 2
    state: present
    reload: yes
  tags:
    - sysctl_kernel_randomize_va_space
    - medium_severity
    - disable_strategy
    - low_complexity
    - medium_disruption
    - CCE-26999-3
    - NIST-800-53-SC-30(2)

SELinux   [ref]group

SELinux is a feature of the Linux kernel which can be used to guard against misconfigured or compromised programs. SELinux enforces the idea that programs should be limited in what files they can access and what actions they can take.

The default SELinux policy, as configured on Red Hat Enterprise Linux 6, has been sufficiently developed and debugged that it should be usable on almost any Red Hat machine with minimal configuration and a small amount of system administrator training. This policy prevents system services - including most of the common network-visible services such as mail servers, FTP servers, and DNS servers - from accessing files which those services have no valid reason to access. This action alone prevents a huge amount of possible damage from network attacks against services, from trojaned software, and so forth.

This guide recommends that SELinux be enabled using the default (targeted) policy on every Red Hat system, unless that system has unusual requirements which make a stronger policy appropriate.

contains 4 rules

Ensure SELinux Not Disabled in /etc/grub.conf   [ref]rule

SELinux can be disabled at boot time by an argument in /etc/grub.conf. Remove any instances of selinux=0 from the kernel arguments in that file to prevent SELinux from being disabled at boot.

Rationale:

Disabling a major host protection feature, such as SELinux, at boot time prevents it from confining system services at boot time. Further, it increases the chances that it will remain off during system operation.

Severity:  medium

Identifiers:  CCE-26956-3, DISA FSO RHEL-06-000017

References:  AC-3, AC-3(3), AC-6, AU-9, 22, 32

Remediation Shell script:   (show)

sed -i --follow-symlinks "s/selinux=0//gI" /etc/grub.conf
sed -i --follow-symlinks "s/enforcing=0//gI" /etc/grub.conf
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:low
Strategy:restrict
- name: Ensure SELinux Not Disabled in /etc/default/grub
  replace:
    dest: /etc/default/grub
    regexp: selinux=0
  tags:
    - enable_selinux_bootloader
    - medium_severity
    - restrict_strategy
    - low_complexity
    - low_disruption
    - CCE-26956-3
    - NIST-800-53-AC-3
    - NIST-800-53-AC-3(3)
    - NIST-800-53-AC-6
    - NIST-800-53-AU-9

Ensure SELinux State is Enforcing   [ref]rule

The SELinux state should be set to enforcing at system boot time. In the file /etc/selinux/config, add or correct the following line to configure the system to boot into enforcing mode:

SELINUX=enforcing

Rationale:

Setting the SELinux state to enforcing ensures SELinux is able to confine potentially compromised processes to the security policy, which is designed to prevent them from causing damage to the system or further elevating their privileges.

Severity:  medium

Identifiers:  CCE-26969-6, DISA FSO RHEL-06-000020

References:  AC-3, AC-3(3), AC-4, AC-6, AU-9, 22, 32, 26

Remediation Shell script:   (show)


var_selinux_state="enforcing"
# Function to replace configuration setting in config file or add the configuration setting if
# it does not exist.
#
# Expects four arguments:
#
# config_file:		Configuration file that will be modified
# key:			Configuration option to change
# value:		Value of the configuration option to change
# cce:			The CCE identifier or '@CCENUM@' if no CCE identifier exists
#
# Optional arugments:
#
# format:		Optional argument to specify the format of how key/value should be
# 			modified/appended in the configuration file. The default is key = value.
#
# Example Call(s):
#
#     With default format of 'key = value':
#     replace_or_append '/etc/sysctl.conf' '^kernel.randomize_va_space' '2' '@CCENUM@'
#
#     With custom key/value format:
#     replace_or_append '/etc/sysconfig/selinux' '^SELINUX=' 'disabled' '@CCENUM@' '%s=%s'
#
#     With a variable:
#     replace_or_append '/etc/sysconfig/selinux' '^SELINUX=' $var_selinux_state '@CCENUM@' '%s=%s'
#
function replace_or_append {
  local config_file=$1
  local key=$2
  local value=$3
  local cce=$4
  local format=$5

  # Check sanity of the input
  if [ $# -lt "3" ]
  then
        echo "Usage: replace_or_append 'config_file_location' 'key_to_search' 'new_value'"
        echo
        echo "If symlinks need to be taken into account, add yes/no to the last argument"
        echo "to allow to 'follow_symlinks'."
        echo "Aborting."
        exit 1
  fi

  # Test if the config_file is a symbolic link. If so, use --follow-symlinks with sed.
  # Otherwise, regular sed command will do.
  if test -L $config_file; then
    sed_command="sed -i --follow-symlinks"
  else
    sed_command="sed -i"
  fi

  # Test that the cce arg is not empty or does not equal @CCENUM@.
  # If @CCENUM@ exists, it means that there is no CCE assigned.
  if ! [ "x$cce" = x ] && [ "$cce" != '@CCENUM@' ]; then
    cce="CCE-${cce}"
  else
    cce="CCE"
  fi

  # Strip any search characters in the key arg so that the key can be replaced without
  # adding any search characters to the config file.
  stripped_key=$(sed "s/[\^=\$,;+]*//g" <<< $key)

  # If there is no print format specified in the last arg, use the default format.
  if ! [ "x$format" = x ] ; then
    printf -v formatted_output "$format" "$stripped_key" "$value"
  else
    formatted_output="$stripped_key = $value"
  fi

  # If the key exists, change it. Otherwise, add it to the config_file.
  if `grep -qi "$key" $config_file` ; then
    eval '$sed_command "s/$key.*/$formatted_output/g" $config_file'
  else
    # \n is precaution for case where file ends without trailing newline
    echo -e "\n# Per $cce: Set $formatted_output in $config_file" >> $config_file
    echo -e "$formatted_output" >> $config_file
  fi

}

replace_or_append '/etc/sysconfig/selinux' '^SELINUX=' $var_selinux_state 'CCE-26969-6' '%s=%s'

fixfiles onboot
fixfiles -f relabel
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:low
Strategy:restrict
- name: "Ensure SELinux State is Enforcing (persistent)"
  selinux:
    state: enforcing
  tags:
    - selinux_state
    - medium_severity
    - restrict_strategy
    - low_complexity
    - low_disruption
    - CCE-26969-6
    - NIST-800-53-AC-3
    - NIST-800-53-AC-3(3)
    - NIST-800-53-AC-4
    - NIST-800-53-AC-6
    - NIST-800-53-AU-9

Configure SELinux Policy   [ref]rule

The SELinux targeted policy is appropriate for general-purpose desktops and servers, as well as systems in many other roles. To configure the system to use this policy, add or correct the following line in /etc/selinux/config:

SELINUXTYPE=targeted
Other policies, such as mls, provide additional security labeling and greater confinement but are not compatible with many general-purpose use cases.

Rationale:

Setting the SELinux policy to targeted or a more specialized policy ensures the system will confine processes that are likely to be targeted for exploitation, such as network or system services. Note: During the development or debugging of SELinux modules, it is common to temporarily place non-production systems in permissive mode. In such temporary cases, SELinux policies should be developed, and once work is completed, the system should be reconfigured to targeted.

Severity:  low

Identifiers:  CCE-26875-5, DISA FSO RHEL-06-000023

References:  AC-3, AC-3(3), AC-4, AC-6, AU-9, 22, 32

Remediation Shell script:   (show)


var_selinux_policy_name="targeted"
# Function to replace configuration setting in config file or add the configuration setting if
# it does not exist.
#
# Expects four arguments:
#
# config_file:		Configuration file that will be modified
# key:			Configuration option to change
# value:		Value of the configuration option to change
# cce:			The CCE identifier or '@CCENUM@' if no CCE identifier exists
#
# Optional arugments:
#
# format:		Optional argument to specify the format of how key/value should be
# 			modified/appended in the configuration file. The default is key = value.
#
# Example Call(s):
#
#     With default format of 'key = value':
#     replace_or_append '/etc/sysctl.conf' '^kernel.randomize_va_space' '2' '@CCENUM@'
#
#     With custom key/value format:
#     replace_or_append '/etc/sysconfig/selinux' '^SELINUX=' 'disabled' '@CCENUM@' '%s=%s'
#
#     With a variable:
#     replace_or_append '/etc/sysconfig/selinux' '^SELINUX=' $var_selinux_state '@CCENUM@' '%s=%s'
#
function replace_or_append {
  local config_file=$1
  local key=$2
  local value=$3
  local cce=$4
  local format=$5

  # Check sanity of the input
  if [ $# -lt "3" ]
  then
        echo "Usage: replace_or_append 'config_file_location' 'key_to_search' 'new_value'"
        echo
        echo "If symlinks need to be taken into account, add yes/no to the last argument"
        echo "to allow to 'follow_symlinks'."
        echo "Aborting."
        exit 1
  fi

  # Test if the config_file is a symbolic link. If so, use --follow-symlinks with sed.
  # Otherwise, regular sed command will do.
  if test -L $config_file; then
    sed_command="sed -i --follow-symlinks"
  else
    sed_command="sed -i"
  fi

  # Test that the cce arg is not empty or does not equal @CCENUM@.
  # If @CCENUM@ exists, it means that there is no CCE assigned.
  if ! [ "x$cce" = x ] && [ "$cce" != '@CCENUM@' ]; then
    cce="CCE-${cce}"
  else
    cce="CCE"
  fi

  # Strip any search characters in the key arg so that the key can be replaced without
  # adding any search characters to the config file.
  stripped_key=$(sed "s/[\^=\$,;+]*//g" <<< $key)

  # If there is no print format specified in the last arg, use the default format.
  if ! [ "x$format" = x ] ; then
    printf -v formatted_output "$format" "$stripped_key" "$value"
  else
    formatted_output="$stripped_key = $value"
  fi

  # If the key exists, change it. Otherwise, add it to the config_file.
  if `grep -qi "$key" $config_file` ; then
    eval '$sed_command "s/$key.*/$formatted_output/g" $config_file'
  else
    # \n is precaution for case where file ends without trailing newline
    echo -e "\n# Per $cce: Set $formatted_output in $config_file" >> $config_file
    echo -e "$formatted_output" >> $config_file
  fi

}

replace_or_append '/etc/sysconfig/selinux' '^SELINUXTYPE=' $var_selinux_policy_name 'CCE-26875-5' '%s=%s'
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:low
Strategy:restrict
- name: "Configure SELinux Policy"
  selinux:
    policy: targeted
  tags:
    - selinux_policytype
    - low_severity
    - restrict_strategy
    - low_complexity
    - low_disruption
    - CCE-26875-5
    - NIST-800-53-AC-3
    - NIST-800-53-AC-3(3)
    - NIST-800-53-AC-4
    - NIST-800-53-AC-6
    - NIST-800-53-AU-9

Ensure No Device Files are Unknown to SELinux   [ref]rule

Device files, which are used for communication with important system resources, should be labeled with proper SELinux types. If any device files carry the SELinux type device_t, report the bug so that policy can be corrected. Supply information about what the device is and what programs use it.

Rationale:

If a device file carries the SELinux type device_t, then SELinux cannot properly restrict access to the device file.

Severity:  low

Identifiers:  CCE-26774-0, DISA FSO RHEL-06-000025

References:  AC-6, AU-9, CM-7, 22, 32

Account and Access Control   [ref]group

In traditional Unix security, if an attacker gains shell access to a certain login account, they can perform any action or access any file to which that account has access. Therefore, making it more difficult for unauthorized people to gain shell access to accounts, particularly to privileged accounts, is a necessary part of securing a system. This section introduces mechanisms for restricting access to accounts under Red Hat Enterprise Linux 6.

contains 24 rules

Protect Accounts by Restricting Password-Based Login   [ref]group

Conventionally, Unix shell accounts are accessed by providing a username and password to a login program, which tests these values for correctness using the /etc/passwd and /etc/shadow files. Password-based login is vulnerable to guessing of weak passwords, and to sniffing and man-in-the-middle attacks against passwords entered over a network or at an insecure console. Therefore, mechanisms for accessing accounts by entering usernames and passwords should be restricted to those which are operationally necessary.

contains 8 rules

Restrict Root Logins   [ref]group

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

contains 2 rules

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

Some accounts are not associated with a human user of the system, and exist to perform some administrative function. 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 UID_MIN, where value of the UID_MIN directive is set in /etc/login.defs configuration file. In the default configuration UID_MIN is set to 500, thus system accounts are those user accounts with a user ID less than 500. The user ID is stored in the third field. If any system account SYSACCT (other than root) has a login shell, disable it with the command:

$ sudo usermod -s /sbin/nologin SYSACCT

Warning:  Do not perform the steps in this section on the root account. Doing so might cause the system to become inaccessible.
Rationale:

Ensuring shells are not given to system accounts upon login makes it more difficult for attackers to make use of system accounts.

Severity:  medium

Identifiers:  CCE-26966-2

References:  AC-2, 178

Verify Only Root Has UID 0   [ref]rule

If any account other than root has a UID of 0, this misconfiguration should be investigated and the accounts other than root should be removed or have their UID changed.

Rationale:

An account has root authority if it has a UID of 0. Multiple accounts with a UID of 0 afford more opportunity for potential intruders to guess a password for a privileged account. Proper configuration of sudo is recommended to afford multiple system administrators access to root privileges in an accountable manner.

Severity:  medium

Identifiers:  CCE-26971-2, DISA FSO RHEL-06-000032

References:  AC-6, IA-2(1), 366

Remediation Shell script:   (show)

awk -F: '$3 == 0 && $1 != "root" { print $1 }' /etc/passwd | xargs passwd -l

Verify Proper Storage and Existence of Password Hashes   [ref]group

By default, password hashes for local accounts are stored in the second field (colon-separated) in /etc/shadow. This file should be readable only by processes running with root credentials, preventing users from casually accessing others' password hashes and attempting to crack them. However, it remains possible to misconfigure the system and store password hashes in world-readable files such as /etc/passwd, or to even store passwords themselves in plaintext on the system. Using system-provided tools for password change/creation should allow administrators to avoid such misconfiguration.

contains 2 rules

Prevent Log In to Accounts With Empty Password   [ref]rule

If an account is configured for password authentication but does not have an assigned password, it may be possible to log onto the account without authentication. Remove any instances of the nullok option in /etc/pam.d/system-auth to prevent logins with empty passwords.

Rationale:

If an account has an empty password, anyone could log in and run commands with the privileges of that account. Accounts with empty passwords should never be used in operational environments.

Severity:  high

Identifiers:  CCE-27038-9, DISA FSO RHEL-06-000030

References:  IA-5(b), IA-5(c), IA-5(1)(a), Req-8.2.3

Remediation Shell script:   (show)

sed --follow-symlinks -i 's/\<nullok\>//g' /etc/pam.d/system-auth
sed --follow-symlinks -i 's/\<nullok\>//g' /etc/pam.d/password-auth
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:medium
Strategy:configure
- name: "Prevent Log In to Accounts With Empty Password - system-auth"
  replace:
    dest: /etc/pam.d/system-auth
    follow: yes
    regexp: 'nullok'
  tags:
    - no_empty_passwords
    - high_severity
    - configure_strategy
    - low_complexity
    - medium_disruption
    - CCE-27038-9
    - NIST-800-53-IA-5(b)
    - NIST-800-53-IA-5(c)
    - NIST-800-53-IA-5(1)(a)
    - PCI-DSS-Req-8.2.3

- name: "Prevent Log In to Accounts With Empty Password - password-auth"
  replace:
    dest: /etc/pam.d/password-auth
    follow: yes
    regexp: 'nullok'
  tags:
    - no_empty_passwords
    - high_severity
    - configure_strategy
    - low_complexity
    - medium_disruption
    - CCE-27038-9
    - NIST-800-53-IA-5(b)
    - NIST-800-53-IA-5(c)
    - NIST-800-53-IA-5(1)(a)
    - PCI-DSS-Req-8.2.3

Verify All Account Password Hashes are Shadowed   [ref]rule

If any password hashes are stored in /etc/passwd (in the second field, instead of an x), the cause of this misconfiguration should be investigated. The account should have its password reset and the hash should be properly stored, or the account should be deleted entirely.

Rationale:

The hashes for all user account passwords should be stored in the file /etc/shadow and never in /etc/passwd, which is readable by all users.

Severity:  medium

Identifiers:  CCE-26476-2, DISA FSO RHEL-06-000031

References:  IA-5(h), 201, Req-8.2.1

Set Password Expiration Parameters   [ref]group

The file /etc/login.defs controls several password-related settings. Programs such as passwd, su, and login consult /etc/login.defs to determine behavior with regard to password aging, expiration warnings, and length. See the man page login.defs(5) for more information.

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

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

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

$ sudo chage -M 180 -m 7 -W 7 USER

contains 4 rules

Protect Accounts by Configuring PAM   [ref]group

PAM, or Pluggable Authentication Modules, is a system which implements modular authentication for Linux programs. PAM provides a flexible and configurable architecture for authentication, and it should be configured to minimize exposure to unnecessary risk. This section contains guidance on how to accomplish that.

PAM is implemented as a set of shared objects which are loaded and invoked whenever an application wishes to authenticate a user. Typically, the application must be running as root in order to take advantage of PAM, because PAM's modules often need to be able to access sensitive stores of account information, such as /etc/shadow. Traditional privileged network listeners (e.g. sshd) or SUID programs (e.g. sudo) already meet this requirement. An SUID root application, userhelper, is provided so that programs which are not SUID or privileged themselves can still take advantage of PAM.

PAM looks in the directory /etc/pam.d for application-specific configuration information. For instance, if the program login attempts to authenticate a user, then PAM's libraries follow the instructions in the file /etc/pam.d/login to determine what actions should be taken.

One very important file in /etc/pam.d is /etc/pam.d/system-auth. This file, which is included by many other PAM configuration files, defines 'default' system authentication measures. Modifying this file is a good way to make far-reaching authentication changes, for instance when implementing a centralized authentication service.

Warning:  Be careful when making changes to PAM's configuration files. The syntax for these files is complex, and modifications can have unexpected consequences. The default configurations shipped with applications should be sufficient for most users.
Warning:  Running authconfig or system-config-authentication will re-write the PAM configuration files, destroying any manually made changes and replacing them with a series of system defaults. One reference to the configuration file syntax can be found at http://www.kernel.org/pub/linux/libs/pam/Linux-PAM-html/sag-configuration-file.html.
contains 11 rules

Set Password Quality Requirements   [ref]group

The default pam_cracklib 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 man page pam_cracklib(8) provides information on the capabilities and configuration of each.

contains 6 rules

Set Password Quality Requirements, if using pam_cracklib   [ref]group

The pam_cracklib PAM module can be configured to meet requirements for a variety of policies.

For example, to configure pam_cracklib to require at least one uppercase character, lowercase character, digit, and other (special) character, locate the following line in /etc/pam.d/system-auth:

password requisite pam_cracklib.so try_first_pass retry=3
and then alter it to read:
password required pam_cracklib.so try_first_pass retry=3 maxrepeat=3 minlen=14 dcredit=-1 ucredit=-1 ocredit=-1 lcredit=-1 difok=4
If no such line exists, add one as the first line of the password section in /etc/pam.d/system-auth. The arguments can be modified to ensure compliance with your organization's security policy. Discussion of each parameter follows.

Warning:  Note that the password quality requirements are not enforced for the root account for some reason.
contains 6 rules

Set Password Retry Prompts Permitted Per-Session   [ref]rule

To configure the number of retry prompts that are permitted per-session:

Edit the pam_cracklib.so statement in /etc/pam.d/system-auth to show retry=3, or a lower value if site policy is more restrictive.

The DoD requirement is a maximum of 3 prompts per session.

Rationale:

Setting the password retry prompts that are permitted on a per-session basis to a low value requires some software, such as SSH, to re-connect. This can slow down and draw additional attention to some types of password-guessing attacks. Note that this is different from account lockout, which is provided by the pam_faillock module.

Severity:  low

Identifiers:  CCE-27123-9

References:  IA-5(c), 1092

Set Password Strength Minimum Digit Characters   [ref]rule

The pam_cracklib 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_cracklib will grant +1 additional length credit for each digit. Add dcredit=-1 after pam_cracklib.so to require use of a digit in passwords.

Rationale:

Requiring digits makes password guessing attacks more difficult by ensuring a larger search space.

Severity:  low

Identifiers:  CCE-26374-9, DISA FSO RHEL-06-000056

References:  IA-5(b), IA-5(c), 194, Req-8.2.3

Remediation Shell script:   (show)


var_password_pam_dcredit="-1"

if grep -q "dcredit=" /etc/pam.d/system-auth; then
	sed -i --follow-symlinks "s/\(dcredit *= *\).*/\1$var_password_pam_dcredit/" /etc/pam.d/system-auth
else
	sed -i --follow-symlinks "/pam_cracklib.so/ s/$/ dcredit=$var_password_pam_dcredit/" /etc/pam.d/system-auth
fi

Set Password Strength Minimum Uppercase Characters   [ref]rule

The pam_cracklib 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_cracklib will grant +1 additional length credit for each uppercase character. Add ucredit=-1 after pam_cracklib.so to require use of an upper case character in passwords.

Rationale:

Requiring a minimum number of uppercase characters makes password guessing attacks more difficult by ensuring a larger search space.

Severity:  low

Identifiers:  CCE-26601-5, DISA FSO RHEL-06-000057

References:  IA-5(b), IA-5(c), IA-5(1)(a), 192, 3.5.7, Req-8.2.3

Remediation Shell script:   (show)


var_password_pam_ucredit="-2"

if grep -q "ucredit=" /etc/pam.d/system-auth; then   
	sed -i --follow-symlinks "s/\(ucredit *= *\).*/\1$var_password_pam_ucredit/" /etc/pam.d/system-auth
else
	sed -i --follow-symlinks "/pam_cracklib.so/ s/$/ ucredit=$var_password_pam_ucredit/" /etc/pam.d/system-auth
fi

Set Password Strength Minimum Special Characters   [ref]rule

The pam_cracklib 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_cracklib will grant +1 additional length credit for each special character. Add ocredit=-2 after pam_cracklib.so to require use of a special character in passwords.

Rationale:

Requiring a minimum number of special characters makes password guessing attacks more difficult by ensuring a larger search space.

Severity:  low

Identifiers:  CCE-26409-3, DISA FSO RHEL-06-000058

References:  IA-5(b), IA-5(c), IA-5(1)(a), 1619, 266

Remediation Shell script:   (show)


var_password_pam_ocredit="-2"

if grep -q "ocredit=" /etc/pam.d/system-auth; then   
	sed -i --follow-symlinks "s/\(ocredit *= *\).*/\1$var_password_pam_ocredit/" /etc/pam.d/system-auth
else
	sed -i --follow-symlinks "/pam_cracklib.so/ s/$/ ocredit=$var_password_pam_ocredit/" /etc/pam.d/system-auth
fi

Set Password Strength Minimum Lowercase Characters   [ref]rule

The pam_cracklib 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_cracklib will grant +1 additional length credit for each lowercase character. Add lcredit=-1 after pam_cracklib.so to require use of a lowercase character in passwords.

Rationale:

Requiring a minimum number of lowercase characters makes password guessing attacks more difficult by ensuring a larger search space.

Severity:  low

Identifiers:  CCE-26631-2, DISA FSO RHEL-06-000059

References:  IA-5(b), IA-5(c), IA-5(1)(a), 193, Req-8.2.3

Remediation Shell script:   (show)


var_password_pam_lcredit="-2"

if grep -q "lcredit=" /etc/pam.d/system-auth; then   
	sed -i --follow-symlinks "s/\(lcredit *= *\).*/\1$var_password_pam_lcredit/" /etc/pam.d/system-auth
else
	sed -i --follow-symlinks "/pam_cracklib.so/ s/$/ lcredit=$var_password_pam_lcredit/" /etc/pam.d/system-auth
fi

Set Password Strength Minimum Different Characters   [ref]rule

The pam_cracklib module's difok parameter controls requirements for usage of different characters during a password change. Add difok=3 after pam_cracklib.so to require differing characters when changing passwords. The DoD requirement is 4.

Rationale:

Requiring a minimum number of different characters during password changes ensures that newly changed passwords should not resemble previously compromised ones. Note that passwords which are changed on compromised systems will still be compromised, however.

Severity:  low

Identifiers:  CCE-26615-5, DISA FSO RHEL-06-000060

References:  IA-5(b), IA-5(c), IA-5(1)(b), 195

Remediation Shell script:   (show)


var_password_pam_difok="3"

if grep -q "difok=" /etc/pam.d/system-auth; then   
	sed -i --follow-symlinks "s/\(difok *= *\).*/\1$var_password_pam_difok/" /etc/pam.d/system-auth
else
	sed -i --follow-symlinks "/pam_cracklib.so/ s/$/ difok=$var_password_pam_difok/" /etc/pam.d/system-auth
fi

Set Lockouts for Failed Password Attempts   [ref]group

The pam_faillock PAM module provides the capability to lock out user accounts after a number of failed login attempts. Its documentation is available in /usr/share/doc/pam-VERSION/txts/README.pam_faillock.

Warning:  Locking out user accounts presents the risk of a denial-of-service attack. The lockout policy must weigh whether the risk of such a denial-of-service attack outweighs the benefits of thwarting password guessing attacks.
contains 2 rules

Set Deny For Failed Password Attempts   [ref]rule

To configure the system to lock out accounts after a number of incorrect login attempts using pam_faillock.so, modify the content of both /etc/pam.d/system-auth and /etc/pam.d/password-auth as follows:

  • Add the following line immediately before the pam_unix.so statement in the AUTH section:
    auth required pam_faillock.so preauth silent deny=5 unlock_time=604800 fail_interval=900
  • Add the following line immediately after the pam_unix.so statement in the AUTH section:
    auth [default=die] pam_faillock.so authfail deny=5 unlock_time=604800 fail_interval=900
  • Add the following line immediately before the pam_unix.so statement in the ACCOUNT section:
    account required pam_faillock.so

Rationale:

Locking out user accounts after a number of incorrect attempts prevents direct password guessing attacks.

Severity:  medium

Identifiers:  CCE-26844-1, DISA FSO RHEL-06-000061

References:  AC-7(a), 44, Req-8.1.6

Remediation Shell script:   (show)


var_accounts_passwords_pam_faillock_deny="5"

AUTH_FILES[0]="/etc/pam.d/system-auth"
AUTH_FILES[1]="/etc/pam.d/password-auth"

# This script fixes absence of pam_faillock.so in PAM stack or the
# absense of deny=[0-9]+ in pam_faillock.so arguments
# When inserting auth pam_faillock.so entries,
# the entry with preauth argument will be added before pam_unix.so module
# and entry with authfail argument will be added before pam_deny.so module.

# The placement of pam_faillock.so entries will not be changed
# if they are already present

for pamFile in "${AUTH_FILES[@]}"
do
	
	# pam_faillock.so already present?
	if grep -q "^auth.*pam_faillock.so.*" $pamFile; then

		# pam_faillock.so present, deny directive present?
		if grep -q "^auth.*[default=die].*pam_faillock.so.*authfail.*deny=" $pamFile; then

			# both pam_faillock.so & deny present, just correct deny directive value
			sed -i --follow-symlinks "s/\(^auth.*required.*pam_faillock.so.*preauth.*silent.*\)\(deny *= *\).*/\1\2$var_accounts_passwords_pam_faillock_deny/" $pamFile
			sed -i --follow-symlinks "s/\(^auth.*[default=die].*pam_faillock.so.*authfail.*\)\(deny *= *\).*/\1\2$var_accounts_passwords_pam_faillock_deny/" $pamFile

		# pam_faillock.so present, but deny directive not yet
		else

			# append correct deny value to appropriate places
			sed -i --follow-symlinks "/^auth.*required.*pam_faillock.so.*preauth.*silent.*/ s/$/ deny=$var_accounts_passwords_pam_faillock_deny/" $pamFile
			sed -i --follow-symlinks "/^auth.*[default=die].*pam_faillock.so.*authfail.*/ s/$/ deny=$var_accounts_passwords_pam_faillock_deny/" $pamFile
		fi

	# pam_faillock.so not present yet
	else

		# insert pam_faillock.so preauth row with proper value of the 'deny' option before pam_unix.so
		sed -i --follow-symlinks "/^auth.*pam_unix.so.*/i auth        required      pam_faillock.so preauth silent deny=$var_accounts_passwords_pam_faillock_deny" $pamFile
		# insert pam_faillock.so authfail row with proper value of the 'deny' option before pam_deny.so, after all modules which determine authentication outcome.
		sed -i --follow-symlinks "/^auth.*pam_deny.so.*/i auth        [default=die] pam_faillock.so authfail deny=$var_accounts_passwords_pam_faillock_deny" $pamFile
	fi

	# add pam_faillock.so into account phase
	if ! grep -q "^account.*required.*pam_faillock.so" $pamFile; then
		sed -i --follow-symlinks "/^account.*required.*pam_unix.so/i account     required      pam_faillock.so" $pamFile
	fi
done

Limit Password Reuse   [ref]rule

Do not allow users to reuse recent passwords. This can be accomplished by using the remember option for the pam_unix or pam_pwhistory PAM modules. In the file /etc/pam.d/system-auth, append remember=5 to the line which refers to the pam_unix.so or pam_pwhistory.somodule, as shown below:

  • for the pam_unix.so case:
    password sufficient pam_unix.so existing_options remember=5
  • for the pam_pwhistory.so case:
    password requisite pam_pwhistory.so existing_options remember=5
The DoD STIG requirement is 5 passwords.

Rationale:

Preventing re-use of previous passwords helps ensure that a compromised password is not re-used by a user.

Severity:  medium

Identifiers:  CCE-26741-9, DISA FSO RHEL-06-000274

References:  IA-5(f), IA-5(1)(e), 200, Req-8.2.5

Remediation Shell script:   (show)


var_password_pam_unix_remember="5"

if grep -q "remember=" /etc/pam.d/system-auth; then   
	sed -i --follow-symlinks "s/\(^password.*sufficient.*pam_unix.so.*\)\(\(remember *= *\)[^ $]*\)/\1remember=$var_password_pam_unix_remember/" /etc/pam.d/system-auth
else
	sed -i --follow-symlinks "/^password[[:space:]]\+sufficient[[:space:]]\+pam_unix.so/ s/$/ remember=$var_password_pam_unix_remember/" /etc/pam.d/system-auth
fi

Set Password Hashing Algorithm   [ref]group

The system's default algorithm for storing password hashes in /etc/shadow is SHA-512. This can be configured in several locations.

contains 3 rules

Set Password Hashing Algorithm in /etc/pam.d/system-auth   [ref]rule

In /etc/pam.d/system-auth, the password section of the file controls which PAM modules execute during a password change. Set the pam_unix.so module in the password section to include the argument sha512, as shown below:

password    sufficient    pam_unix.so sha512 other arguments...
This will help ensure when local users change their passwords, hashes for the new passwords will be generated using the SHA-512 algorithm. This is the default.

Rationale:

Using a stronger hashing algorithm makes password cracking attacks more difficult.

Severity:  medium

Identifiers:  CCE-26303-8, DISA FSO RHEL-06-000062

References:  IA-5(b), IA-5(c), IA-5(1)(c), IA-7, 803, Req-8.2.1

Remediation Shell script:   (show)

if ! grep -q "^password.*sufficient.*pam_unix.so.*sha512" /etc/pam.d/system-auth; then   
	sed -i --follow-symlinks "/^password.*sufficient.*pam_unix.so/ s/$/ sha512/" /etc/pam.d/system-auth
fi

Set Password Hashing Algorithm in /etc/login.defs   [ref]rule

In /etc/login.defs, add or correct the following line to ensure the system will use SHA-512 as the hashing algorithm:

ENCRYPT_METHOD SHA512

Rationale:

Using a stronger hashing algorithm makes password cracking attacks more difficult.

Severity:  medium

Identifiers:  CCE-27228-6, DISA FSO RHEL-06-000063

References:  IA-5(b), IA-5(c), IA-5(1)(c), IA-7, 803, Req-8.2.1

Remediation Shell script:   (show)

if grep --silent ^ENCRYPT_METHOD /etc/login.defs ; then
	sed -i 's/^ENCRYPT_METHOD.*/ENCRYPT_METHOD SHA512/g' /etc/login.defs
else
	echo "" >> /etc/login.defs
	echo "ENCRYPT_METHOD SHA512" >> /etc/login.defs
fi
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:low
Strategy:restrict
- name: Set Password Hashing Algorithm in /etc/login.defs
  lineinfile:
      dest: /etc/login.defs
      regexp: ^#?ENCRYPT_METHOD
      line: ENCRYPT_METHOD SHA512
      state: present
  tags:
    - set_password_hashing_algorithm_logindefs
    - medium_severity
    - restrict_strategy
    - low_complexity
    - low_disruption
    - CCE-27228-6
    - NIST-800-53-IA-5(b)
    - NIST-800-53-IA-5(c)
    - NIST-800-53-IA-5(1)(c)
    - NIST-800-53-IA-7
    - PCI-DSS-Req-8.2.1

Set Password Hashing Algorithm in /etc/libuser.conf   [ref]rule

In /etc/libuser.conf, add or correct the following line in its [defaults] section to ensure the system will use the SHA-512 algorithm for password hashing:

crypt_style = sha512

Rationale:

Using a stronger hashing algorithm makes password cracking attacks more difficult.

Severity:  medium

Identifiers:  CCE-27229-4, DISA FSO RHEL-06-000064

References:  IA-5(b), IA-5(c), IA-5(1)(c), IA-7, 803, Req-8.2.1

Remediation Ansible snippet:   (show)

Complexity:low
Disruption:low
Strategy:restrict
- name: Set Password Hashing Algorithm in /etc/libuser.conf
  lineinfile:
    dest: /etc/libuser.conf
    insertafter: "^.default]"
    regexp: ^#?crypt_style
    line: crypt_style = sha512
    state: present
  tags:
    - set_password_hashing_algorithm_libuserconf
    - medium_severity
    - restrict_strategy
    - low_complexity
    - low_disruption
    - CCE-27229-4
    - NIST-800-53-IA-5(b)
    - NIST-800-53-IA-5(c)
    - NIST-800-53-IA-5(1)(c)
    - NIST-800-53-IA-7
    - PCI-DSS-Req-8.2.1

Protect Physical Console Access   [ref]group

It is impossible to fully protect a system from an attacker with physical access, so securing the space in which the system is located should be considered a necessary step. However, there are some steps which, if taken, make it more difficult for an attacker to quickly or undetectably modify a system from its console.

contains 5 rules

Set Boot Loader Password   [ref]group

During the boot process, the boot loader is responsible for starting the execution of the kernel and passing options to it. The boot loader allows for the selection of different kernels - possibly on different partitions or media. The default Red Hat Enterprise Linux boot loader for x86 systems is called GRUB. Options it can pass to the kernel include single-user mode, which provides root access without any authentication, and the ability to disable SELinux. To prevent local users from modifying the boot parameters and endangering security, protect the boot loader configuration with a password and ensure its configuration file's permissions are set properly.

contains 4 rules

Verify /etc/grub.conf User Ownership   [ref]rule

The file /etc/grub.conf should be owned by the root user to prevent destruction or modification of the file. To properly set the owner of /etc/grub.conf, run the command:

$ sudo chown root /etc/grub.conf

Rationale:

Only root should be able to modify important boot parameters.

Severity:  medium

Identifiers:  CCE-26995-1, DISA FSO RHEL-06-000065

References:  AC-6(7), 225, Req-7.1

Remediation Shell script:   (show)

chown root /etc/grub.conf

Verify /etc/grub.conf Group Ownership   [ref]rule

The file /etc/grub.conf should be group-owned by the root group to prevent destruction or modification of the file. To properly set the group owner of /etc/grub.conf, run the command:

$ sudo chgrp root /etc/grub.conf

Rationale:

The root group is a highly-privileged group. Furthermore, the group-owner of this file should not have any access privileges anyway.

Severity:  medium

Identifiers:  CCE-27022-3, DISA FSO RHEL-06-000066

References:  AC-6(7), 225, Req-7.1

Remediation Shell script:   (show)

chgrp root /etc/grub.conf

Verify /boot/grub/grub.conf Permissions   [ref]rule

File permissions for /boot/grub/grub.conf should be set to 600, which is the default. To properly set the permissions of /boot/grub/grub.conf, run the command:

$ sudo chmod 600 /boot/grub/grub.conf

Rationale:

Proper permissions ensure that only the root user can modify important boot parameters.

Severity:  medium

Identifiers:  CCE-26949-8, DISA FSO RHEL-06-000067

References:  AC-6(7), 225

Remediation Shell script:   (show)

chmod 600 /boot/grub/grub.conf

Set Boot Loader Password   [ref]rule

The grub boot loader should have password protection enabled to protect boot-time settings. To do so, select a password and then generate a hash from it by running the following command:

$ grub-crypt --sha-512
When prompted to enter a password, insert the following line into /etc/grub.conf immediately after the header comments. (Use the output from grub-crypt as the value of password-hash):
password --encrypted password-hash
NOTE: To meet FISMA Moderate, the bootloader password MUST differ from the root password.

Rationale:

Password protection on the boot loader configuration ensures users with physical access cannot trivially alter important bootloader settings. These include which kernel to use, and whether to enter single-user mode.

Severity:  medium

Identifiers:  CCE-26911-8, DISA FSO RHEL-06-000068

References:  IA-2(1), IA-5(e) AC-3, 213

Require Authentication for Single User Mode   [ref]rule

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

To require entry of the root password even if the system is started in single-user mode, add or correct the following line in the file /etc/sysconfig/init:

SINGLE=/sbin/sulogin

Rationale:

This prevents attackers with physical access from trivially bypassing security on the machine and gaining root access. Such accesses are further prevented by configuring the bootloader password.

Severity:  medium

Identifiers:  CCE-27040-5, DISA FSO RHEL-06-000069

References:  IA-2(1), AC-3, 213

Remediation Shell script:   (show)

grep -q ^SINGLE /etc/sysconfig/init && \
  sed -i "s/SINGLE.*/SINGLE=\/sbin\/sulogin/g" /etc/sysconfig/init
if ! [ $? -eq 0 ]; then
    echo "SINGLE=/sbin/sulogin" >> /etc/sysconfig/init
fi

Network Configuration and Firewalls   [ref]group

Most machines 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 8 rules

IPv6   [ref]group

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 1 rule

Disable Support for IPv6 Unless Needed   [ref]group

Despite configuration that suggests support for IPv6 has been disabled, link-local IPv6 address auto-configuration occurs even when only an IPv4 address is assigned. The only way to effectively prevent execution of the IPv6 networking stack is to instruct the system not to activate the IPv6 kernel module.

contains 1 rule

Disable IPv6 Networking Support Automatic Loading   [ref]rule

To prevent the IPv6 kernel module (ipv6) from binding to the IPv6 networking stack, add the following line to /etc/modprobe.d/disabled.conf (or another file in /etc/modprobe.d):

options ipv6 disable=1
This permits the IPv6 module to be loaded (and thus satisfy other modules that depend on it), while disabling support for the IPv6 protocol.

Rationale:

Any unnecessary network stacks - including IPv6 - should be disabled, to reduce the vulnerability to exploitation.

Severity:  medium

Identifiers:  CCE-27153-6, DISA FSO RHEL-06-000098

References:  CM-7, 1551

Remediation Shell script:   (show)


# Prevent the IPv6 kernel module (ipv6) from loading the IPv6 networking stack
echo "options ipv6 disable=1" > /etc/modprobe.d/ipv6.conf

# Since according to: https://access.redhat.com/solutions/72733
# "ipv6 disable=1" options doesn't always disable the IPv6 networking stack from
# loading, instruct also sysctl configuration to disable IPv6 according to:
# https://access.redhat.com/solutions/8709#rhel6disable

declare -a IPV6_SETTINGS=("net.ipv6.conf.all.disable_ipv6" "net.ipv6.conf.default.disable_ipv6")

for setting in ${IPV6_SETTINGS[@]}
do
	# Set runtime =1 for setting
	/sbin/sysctl -q -n -w "$setting=1"

	# If setting is present in /etc/sysctl.conf, change value to "1"
	# else, add "$setting = 1" to /etc/sysctl.conf
	if grep -q ^"$setting" /etc/sysctl.conf ; then
		sed -i "s/^$setting.*/$setting = 1/g" /etc/sysctl.conf
	else
		echo "" >> /etc/sysctl.conf
		echo "# Set $setting = 1 per security requirements" >> /etc/sysctl.conf
		echo "$setting = 1" >> /etc/sysctl.conf
	fi
done

iptables and ip6tables   [ref]group

A host-based firewall called netfilter is included as part of the Linux kernel distributed with the system. It is activated by default. This firewall is controlled by the program iptables, and the entire capability is frequently referred to by this name. An analogous program called ip6tables handles filtering for IPv6.

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

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

contains 3 rules

Inspect and Activate Default Rules   [ref]group

View the currently-enforced iptables rules by running the command:

$ sudo iptables -nL --line-numbers
The command is analogous for ip6tables.

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

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

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

contains 2 rules

Verify ip6tables Enabled if Using IPv6   [ref]rule

The ip6tables service can be enabled with the following command:

$ sudo chkconfig --level 2345 ip6tables on

Rationale:

The ip6tables service provides the system's host-based firewalling capability for IPv6 and ICMPv6.

Severity:  medium

Identifiers:  CCE-27006-6, DISA FSO RHEL-06-000103

References:  AC-4, CA-3(c), CM-7, 32, 66, 1115, 1118, 1092, 1117, 1098, 1100, 1097, 1414

Remediation Shell script:   (show)

Complexity:low
Disruption:low
Strategy:enable
# Function to enable/disable and start/stop services on RHEL and Fedora systems.
#
# Example Call(s):
#
#     service_command enable bluetooth
#     service_command disable bluetooth.service
#
#     Using xinetd:
#     service_command disable rsh.socket xinetd=rsh
#
function service_command {

# Load function arguments into local variables
local service_state=$1
local service=$2
local xinetd=$(echo $3 | cut -d'=' -f2)

# Check sanity of the input
if [ $# -lt "2" ]
then
  echo "Usage: service_command 'enable/disable' 'service_name.service'"
  echo
  echo "To enable or disable xinetd services add \'xinetd=service_name\'"
  echo "as the last argument"  
  echo "Aborting."
  exit 1
fi

# If systemctl is installed, use systemctl command; otherwise, use the service/chkconfig commands
if [ -f "/usr/bin/systemctl" ] ; then
  service_util="/usr/bin/systemctl"
else
  service_util="/sbin/service"
  chkconfig_util="/sbin/chkconfig"
fi

# If disable is not specified in arg1, set variables to enable services.
# Otherwise, variables are to be set to disable services.
if [ "$service_state" != 'disable' ] ; then
  service_state="enable"
  service_operation="start"
  chkconfig_state="on"
else
  service_state="disable"
  service_operation="stop"
  chkconfig_state="off"
fi

# If chkconfig_util is not empty, use chkconfig/service commands.
if ! [ "x$chkconfig_util" = x ] ; then
  $service_util $service $service_operation
  $chkconfig_util --level 0123456 $service $chkconfig_state
else
  $service_util $service_operation $service
  $service_util $service_state $service
fi

# Test if local variable xinetd is empty using non-bashism.
# If empty, then xinetd is not being used.
if ! [ "x$xinetd" = x ] ; then
  grep -qi disable /etc/xinetd.d/$xinetd && \

  if ! [ "$service_operation" != 'disable' ] ; then
    sed -i "s/disable.*/disable         = no/gI" /etc/xinetd.d/$xinetd
  else
    sed -i "s/disable.*/disable         = yes/gI" /etc/xinetd.d/$xinetd
  fi
fi

}

service_command enable ip6tables
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:low
Strategy:enable
- name: "Enable service ip6tables"
  service:
    name="{{item}}"
    enabled="yes"
    state="started"
  with_items:
    - ip6tables
  tags:
    - service_ip6tables_enabled
    - medium_severity
    - enable_strategy
    - low_complexity
    - low_disruption
    - CCE-27006-6
    - NIST-800-53-AC-4
    - NIST-800-53-CA-3(c)
    - NIST-800-53-CM-7

Verify iptables Enabled   [ref]rule

The iptables service can be enabled with the following command:

$ sudo chkconfig --level 2345 iptables on

Rationale:

The iptables service provides the system's host-based firewalling capability for IPv4 and ICMP.

Severity:  medium

Identifiers:  CCE-27018-1, DISA FSO RHEL-06-000117

References:  AC-4, CA-3(c), CM-7, 32, 66, 1115, 1118, 1092, 1117, 1098, 1100, 1097, 1414

Remediation Shell script:   (show)

Complexity:low
Disruption:low
Strategy:enable
# Function to enable/disable and start/stop services on RHEL and Fedora systems.
#
# Example Call(s):
#
#     service_command enable bluetooth
#     service_command disable bluetooth.service
#
#     Using xinetd:
#     service_command disable rsh.socket xinetd=rsh
#
function service_command {

# Load function arguments into local variables
local service_state=$1
local service=$2
local xinetd=$(echo $3 | cut -d'=' -f2)

# Check sanity of the input
if [ $# -lt "2" ]
then
  echo "Usage: service_command 'enable/disable' 'service_name.service'"
  echo
  echo "To enable or disable xinetd services add \'xinetd=service_name\'"
  echo "as the last argument"  
  echo "Aborting."
  exit 1
fi

# If systemctl is installed, use systemctl command; otherwise, use the service/chkconfig commands
if [ -f "/usr/bin/systemctl" ] ; then
  service_util="/usr/bin/systemctl"
else
  service_util="/sbin/service"
  chkconfig_util="/sbin/chkconfig"
fi

# If disable is not specified in arg1, set variables to enable services.
# Otherwise, variables are to be set to disable services.
if [ "$service_state" != 'disable' ] ; then
  service_state="enable"
  service_operation="start"
  chkconfig_state="on"
else
  service_state="disable"
  service_operation="stop"
  chkconfig_state="off"
fi

# If chkconfig_util is not empty, use chkconfig/service commands.
if ! [ "x$chkconfig_util" = x ] ; then
  $service_util $service $service_operation
  $chkconfig_util --level 0123456 $service $chkconfig_state
else
  $service_util $service_operation $service
  $service_util $service_state $service
fi

# Test if local variable xinetd is empty using non-bashism.
# If empty, then xinetd is not being used.
if ! [ "x$xinetd" = x ] ; then
  grep -qi disable /etc/xinetd.d/$xinetd && \

  if ! [ "$service_operation" != 'disable' ] ; then
    sed -i "s/disable.*/disable         = no/gI" /etc/xinetd.d/$xinetd
  else
    sed -i "s/disable.*/disable         = yes/gI" /etc/xinetd.d/$xinetd
  fi
fi

}

service_command enable iptables
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:low
Strategy:enable
- name: "Enable service iptables"
  service:
    name="{{item}}"
    enabled="yes"
    state="started"
  with_items:
    - iptables
  tags:
    - service_iptables_enabled
    - medium_severity
    - enable_strategy
    - low_complexity
    - low_disruption
    - CCE-27018-1
    - NIST-800-53-AC-4
    - NIST-800-53-CA-3(c)
    - NIST-800-53-CM-7

Strengthen the Default Ruleset   [ref]group

The default rules can be strengthened. The system scripts that activate the firewall rules expect them to be defined in the configuration files iptables and ip6tables in the directory /etc/sysconfig. Many of the lines in these files are similar to the command line arguments that would be provided to the programs /sbin/iptables or /sbin/ip6tables - but some are quite different.

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

The following alterations can be made directly to /etc/sysconfig/iptables and /etc/sysconfig/ip6tables. Instructions apply to both unless otherwise noted. Language and address conventions for regular iptables are used throughout this section; configuration for ip6tables will be either analogous or explicitly covered.

Warning:  The program system-config-securitylevel allows additional services to penetrate the default firewall rules and automatically adjusts /etc/sysconfig/iptables. This program is only useful if the default ruleset meets your security requirements. Otherwise, this program should not be used to make changes to the firewall configuration because it re-writes the saved configuration file.
contains 1 rule

Set Default iptables Policy for Incoming Packets   [ref]rule

To set the default policy to DROP (instead of ACCEPT) for the built-in INPUT chain which processes incoming packets, add or correct the following line in /etc/sysconfig/iptables:

:INPUT DROP [0:0]

Rationale:

In iptables the default policy is applied only after all the applicable rules in the table are examined for a match. Setting the default policy to DROP implements proper design for a firewall, i.e. any packets which are not explicitly permitted should not be accepted.

Severity:  medium

Identifiers:  CCE-26444-0, DISA FSO RHEL-06-000120

References:  CM-7, 66, 1109, 1154, 1414

Remediation Shell script:   (show)

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

Uncommon Network Protocols   [ref]group

The system includes support for several network protocols which are not commonly used. Although security vulnerabilities in kernel networking code are not frequently discovered, the consequences can be dramatic. Ensuring uncommon network protocols are disabled reduces the system's risk to attacks targeted at its implementation of those protocols.

Warning:  Although these protocols are not commonly used, avoid disruption in your network environment by ensuring they are not needed prior to disabling them.
contains 4 rules

Disable DCCP Support   [ref]rule

The Datagram Congestion Control Protocol (DCCP) is a relatively new transport layer protocol, designed to support streaming media and telephony. To configure the system to prevent the dccp kernel module from being loaded, add the following line to a file in the directory /etc/modprobe.d:

install dccp /bin/true

Rationale:

Disabling DCCP protects the system against exploitation of any flaws in its implementation.

Severity:  medium

Identifiers:  CCE-26448-1, DISA FSO RHEL-06-000124

References:  CM-7, 382

Remediation Shell script:   (show)

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
if grep --silent "^install dccp" /etc/modprobe.d/dccp.conf ; then
	sed -i 's/^install dccp.*/install dccp /bin/true/g' /etc/modprobe.d/dccp.conf
else
	echo -e "\n# Disable per security requirements" >> /etc/modprobe.d/dccp.conf
	echo "install dccp /bin/true" >> /etc/modprobe.d/dccp.conf
fi
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
- name: "Ensure kernel module 'dccp' is disabled"
  lineinfile:
    create=yes
    dest="/etc/modprobe.d/{{item}}.conf"
    regexp="{{item}}"
    line="install {{item}} /bin/true"
  with_items:
    - dccp
  tags:
    - kernel_module_dccp_disabled
    - medium_severity
    - disable_strategy
    - low_complexity
    - medium_disruption
    - CCE-26448-1
    - NIST-800-53-CM-7

Disable SCTP Support   [ref]rule

The Stream Control Transmission Protocol (SCTP) is a transport layer protocol, designed to support the idea of message-oriented communication, with several streams of messages within one connection. To configure the system to prevent the sctp kernel module from being loaded, add the following line to a file in the directory /etc/modprobe.d:

install sctp /bin/true

Rationale:

Disabling SCTP protects the system against exploitation of any flaws in its implementation.

Severity:  medium

Identifiers:  CCE-26410-1, DISA FSO RHEL-06-000125

References:  CM-7, 382

Remediation Shell script:   (show)

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
if grep --silent "^install sctp" /etc/modprobe.d/sctp.conf ; then
	sed -i 's/^install sctp.*/install sctp /bin/true/g' /etc/modprobe.d/sctp.conf
else
	echo -e "\n# Disable per security requirements" >> /etc/modprobe.d/sctp.conf
	echo "install sctp /bin/true" >> /etc/modprobe.d/sctp.conf
fi
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
- name: "Ensure kernel module 'sctp' is disabled"
  lineinfile:
    create=yes
    dest="/etc/modprobe.d/{{item}}.conf"
    regexp="{{item}}"
    line="install {{item}} /bin/true"
  with_items:
    - sctp
  tags:
    - kernel_module_sctp_disabled
    - medium_severity
    - disable_strategy
    - low_complexity
    - medium_disruption
    - CCE-26410-1
    - NIST-800-53-CM-7

Disable RDS Support   [ref]rule

The Reliable Datagram Sockets (RDS) protocol is a transport layer protocol designed to provide reliable high- bandwidth, low-latency communications between nodes in a cluster. To configure the system to prevent the rds kernel module from being loaded, add the following line to a file in the directory /etc/modprobe.d:

install rds /bin/true

Rationale:

Disabling RDS protects the system against exploitation of any flaws in its implementation.

Severity:  low

Identifiers:  CCE-26239-4, DISA FSO RHEL-06-000126

References:  CM-7, 382

Remediation Shell script:   (show)

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
if grep --silent "^install rds" /etc/modprobe.d/rds.conf ; then
	sed -i 's/^install rds.*/install rds /bin/true/g' /etc/modprobe.d/rds.conf
else
	echo -e "\n# Disable per security requirements" >> /etc/modprobe.d/rds.conf
	echo "install rds /bin/true" >> /etc/modprobe.d/rds.conf
fi
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
- name: "Ensure kernel module 'rds' is disabled"
  lineinfile:
    create=yes
    dest="/etc/modprobe.d/{{item}}.conf"
    regexp="{{item}}"
    line="install {{item}} /bin/true"
  with_items:
    - rds
  tags:
    - kernel_module_rds_disabled
    - low_severity
    - disable_strategy
    - low_complexity
    - medium_disruption
    - CCE-26239-4
    - NIST-800-53-CM-7

Disable TIPC Support   [ref]rule

The Transparent Inter-Process Communication (TIPC) protocol is designed to provide communications between nodes in a cluster. To configure the system to prevent the tipc kernel module from being loaded, add the following line to a file in the directory /etc/modprobe.d:

install tipc /bin/true

Rationale:

Disabling TIPC protects the system against exploitation of any flaws in its implementation.

Severity:  medium

Identifiers:  CCE-26696-5, DISA FSO RHEL-06-000127

References:  CM-7, 382

Remediation Shell script:   (show)

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
if grep --silent "^install tipc" /etc/modprobe.d/tipc.conf ; then
	sed -i 's/^install tipc.*/install tipc /bin/true/g' /etc/modprobe.d/tipc.conf
else
	echo -e "\n# Disable per security requirements" >> /etc/modprobe.d/tipc.conf
	echo "install tipc /bin/true" >> /etc/modprobe.d/tipc.conf
fi
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:medium
Reboot:true
Strategy:disable
- name: "Ensure kernel module 'tipc' is disabled"
  lineinfile:
    create=yes
    dest="/etc/modprobe.d/{{item}}.conf"
    regexp="{{item}}"
    line="install {{item}} /bin/true"
  with_items:
    - tipc
  tags:
    - kernel_module_tipc_disabled
    - medium_severity
    - disable_strategy
    - low_complexity
    - medium_disruption
    - CCE-26696-5
    - NIST-800-53-CM-7

System Accounting with auditd   [ref]group

The audit service provides substantial capabilities for recording system activities. By default, the service audits about SELinux AVC denials and certain types of security-relevant events such as system logins, account modifications, and authentication events performed by programs such as sudo. Under its default configuration, auditd has modest disk space requirements, and should not noticeably impact system performance.

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 Fedora Documentation available at http://docs.fedoraproject.org/en-US/Fedora/13/html/Security-Enhanced_Linux/sect-Security-Enhanced_Linux-Fixing_Problems-Raw_Audit_Messages.html 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 1 rule

Configure auditd Rules for Comprehensive Auditing   [ref]group

The auditd program can perform comprehensive monitoring of system activity. This section describes recommended configuration settings for comprehensive auditing, but a full description of the auditing system's capabilities is beyond the scope of this guide. The mailing list linux-audit@redhat.com exists to facilitate community discussion of the auditing system.

The audit subsystem supports extensive collection of events, including:

  • Tracing of arbitrary system calls (identified by name or number) on entry or exit.
  • Filtering by PID, UID, call success, system call argument (with some limitations), etc.
  • Monitoring of specific files for modifications to the file's contents or metadata.

Auditing rules at startup are controlled by the file /etc/audit/audit.rules. Add rules to it to meet the auditing requirements for your organization. Each line in /etc/audit/audit.rules represents a series of arguments that can be passed to auditctl and can be individually tested during runtime. See documentation in /usr/share/doc/audit-VERSION and in the related man pages for more details.

If copying any example audit rulesets from /usr/share/doc/audit-VERSION, be sure to comment out the lines containing arch= which are not appropriate for your system's architecture. Then review and understand the following rules, ensuring rules are activated as needed for the appropriate architecture.

After reviewing all the rules, reading the following sections, and editing as needed, the new rules can be activated as follows:
$ sudo service auditd restart

contains 1 rule

System Audit Logs Must Have Mode 0640 or Less Permissive   [ref]rule

If log_group in /etc/audit/auditd.conf is set to a group other than the root group account, change the mode of the audit log files with the following command:

$ sudo chmod 0640 audit_file

Otherwise, change the mode of the audit log files with the following command:
$ sudo chmod 0600 audit_file

Rationale:

If users can write to audit logs, audit trails can be modified or destroyed.

Severity:  low

Identifiers:  CCE-27243-5, DISA FSO RHEL-06-000383

References:  AC-6, AU-1(b), AU-9, IR-5, 166, Req-10.5

Remediation Shell script:   (show)


if `grep -q ^log_group /etc/audit/auditd.conf` ; then
  GROUP=$(awk -F "=" '/log_group/ {print $2}' /etc/audit/auditd.conf | tr -d ' ')
  if ! [ "${GROUP}" == 'root' ] ; then
    chmod 0640 /var/log/audit/audit.log
    chmod 0440 /var/log/audit/audit.log.*
  else
    chmod 0600 /var/log/audit/audit.log
    chmod 0400 /var/log/audit/audit.log.*
  fi

  chmod 0640 /etc/audit/audit*
  chmod 0640 /etc/audit/rules.d/*
else
  chmod 0600 /var/log/audit/audit.log
  chmod 0400 /var/log/audit/audit.log.*
  chmod 0640 /etc/audit/audit*
  chmod 0640 /etc/audit/rules.d/*
fi

Services   [ref]group

The best protection against vulnerable software is running less software. This section describes how to review the software which Red Hat Enterprise Linux 6 installs on a system and disable software which is not needed. It then enumerates the software packages installed on a default Red Hat Enterprise Linux 6 system and provides guidance about which ones can be safely disabled.

Red Hat Enterprise Linux 6 provides a convenient minimal install option that essentially installs the bare necessities for a functional system. When building Red Hat Enterprise Linux 6 systems, it is highly recommended to select the minimal packages and then build up the system from there.

contains 29 rules

Obsolete Services   [ref]group

This section discusses a number of network-visible services which have historically caused problems for system security, and for which disabling or severely limiting the service has been the best available guidance for some time. As a result of this, many of these services are not installed as part of Red Hat Enterprise Linux 6 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 12 rules

Xinetd   [ref]group

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

contains 2 rules

Disable xinetd Service   [ref]rule

The xinetd service can be disabled with the following command:

$ sudo chkconfig xinetd off

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.

Severity:  medium

Identifiers:  CCE-27046-2, DISA FSO RHEL-06-000203

References:  CM-7, 305

Remediation Shell script:   (show)

Complexity:low
Disruption:low
Strategy:disable
# Function to enable/disable and start/stop services on RHEL and Fedora systems.
#
# Example Call(s):
#
#     service_command enable bluetooth
#     service_command disable bluetooth.service
#
#     Using xinetd:
#     service_command disable rsh.socket xinetd=rsh
#
function service_command {

# Load function arguments into local variables
local service_state=$1
local service=$2
local xinetd=$(echo $3 | cut -d'=' -f2)

# Check sanity of the input
if [ $# -lt "2" ]
then
  echo "Usage: service_command 'enable/disable' 'service_name.service'"
  echo
  echo "To enable or disable xinetd services add \'xinetd=service_name\'"
  echo "as the last argument"  
  echo "Aborting."
  exit 1
fi

# If systemctl is installed, use systemctl command; otherwise, use the service/chkconfig commands
if [ -f "/usr/bin/systemctl" ] ; then
  service_util="/usr/bin/systemctl"
else
  service_util="/sbin/service"
  chkconfig_util="/sbin/chkconfig"
fi

# If disable is not specified in arg1, set variables to enable services.
# Otherwise, variables are to be set to disable services.
if [ "$service_state" != 'disable' ] ; then
  service_state="enable"
  service_operation="start"
  chkconfig_state="on"
else
  service_state="disable"
  service_operation="stop"
  chkconfig_state="off"
fi

# If chkconfig_util is not empty, use chkconfig/service commands.
if ! [ "x$chkconfig_util" = x ] ; then
  $service_util $service $service_operation
  $chkconfig_util --level 0123456 $service $chkconfig_state
else
  $service_util $service_operation $service
  $service_util $service_state $service
fi

# Test if local variable xinetd is empty using non-bashism.
# If empty, then xinetd is not being used.
if ! [ "x$xinetd" = x ] ; then
  grep -qi disable /etc/xinetd.d/$xinetd && \

  if ! [ "$service_operation" != 'disable' ] ; then
    sed -i "s/disable.*/disable         = no/gI" /etc/xinetd.d/$xinetd
  else
    sed -i "s/disable.*/disable         = yes/gI" /etc/xinetd.d/$xinetd
  fi
fi

}

service_command disable xinetd
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:low
Strategy:disable
- name: "Disable service xinetd"
  service:
    name="{{item}}"
    enabled="no"
    state="stopped"
  with_items:
    - xinetd
  tags:
    - service_xinetd_disabled
    - medium_severity
    - disable_strategy
    - low_complexity
    - low_disruption
    - CCE-27046-2
    - NIST-800-53-CM-7

Uninstall xinetd Package   [ref]rule

The xinetd package can be uninstalled with the following command:

$ sudo yum erase xinetd

Rationale:

Removing the xinetd package decreases the risk of the xinetd service's accidental (or intentional) activation.

Severity:  low

Identifiers:  CCE-27005-8, DISA FSO RHEL-06-000204

References:  CM-7, 305

Remediation Shell script:   (show)

Complexity:low
Disruption:low
Strategy:disable
# Function to install or uninstall packages on RHEL and Fedora systems.
#
# Example Call(s):
#
#     package_command install aide
#     package_command remove telnet-server
#
function package_command {

# Load function arguments into local variables
local package_operation=$1
local package=$2

# Check sanity of the input
if [ $# -ne "2" ]
then
  echo "Usage: package_command 'install/uninstall' 'rpm_package_name"
  echo "Aborting."
  exit 1
fi

# If dnf is installed, use dnf; otherwise, use yum
if [ -f "/usr/bin/dnf" ] ; then
  install_util="/usr/bin/dnf"
else
  install_util="/usr/bin/yum"
fi

if [ "$package_operation" != 'remove' ] ; then
  # If the rpm is not installed, install the rpm
  if ! /bin/rpm -q --quiet $package; then
    $install_util -y $package_operation $package
  fi
else
  # If the rpm is installed, uninstall the rpm
  if /bin/rpm -q --quiet $package; then
    $install_util -y $package_operation $package
  fi
fi

}

package_command remove xinetd
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:low
Strategy:disable
- name: "Ensure xinetd is removed"
  package:
    name="{{item}}"
    state=absent
  with_items:
    - xinetd
  tags:
    - package_xinetd_removed
    - low_severity
    - disable_strategy
    - low_complexity
    - low_disruption
    - CCE-27005-8
    - NIST-800-53-CM-7

Remediation Puppet snippet:   (show)

Complexity:low
Disruption:low
Strategy:disable
include remove_xinetd

class remove_xinetd {
  package { 'xinetd':
    ensure => 'purged',
  }
}
Remediation Anaconda snippet:   (show)

Complexity:low
Disruption:low
Strategy:disable

package --remove=xinetd

Telnet   [ref]group

The 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

Disable telnet Service   [ref]rule

The telnet service can be disabled with the following command:

$ sudo chkconfig telnet off

Rationale:

The telnet protocol uses unencrypted network communication, which means that data from the login session, including passwords and all other information transmitted during the session, can be stolen by eavesdroppers on the network. The telnet protocol is also subject to man-in-the-middle attacks.

Severity:  high

Identifiers:  CCE-26836-7, DISA FSO RHEL-06-000211

References:  CM-7, IA-5(1)(c), 68, 1436, 197, 877, 888

Uninstall telnet-server Package   [ref]rule

The telnet-server package can be uninstalled with the following command:

$ sudo yum erase telnet-server

Rationale:

Removing the telnet-server package decreases the risk of the telnet service's accidental (or intentional) activation.

Severity:  high

Identifiers:  CCE-27073-6, DISA FSO RHEL-06-000206

References:  CM-7, 305, 381

Remediation Shell script:   (show)

Complexity:low
Disruption:low
Strategy:disable
# Function to install or uninstall packages on RHEL and Fedora systems.
#
# Example Call(s):
#
#     package_command install aide
#     package_command remove telnet-server
#
function package_command {

# Load function arguments into local variables
local package_operation=$1
local package=$2

# Check sanity of the input
if [ $# -ne "2" ]
then
  echo "Usage: package_command 'install/uninstall' 'rpm_package_name"
  echo "Aborting."
  exit 1
fi

# If dnf is installed, use dnf; otherwise, use yum
if [ -f "/usr/bin/dnf" ] ; then
  install_util="/usr/bin/dnf"
else
  install_util="/usr/bin/yum"
fi

if [ "$package_operation" != 'remove' ] ; then
  # If the rpm is not installed, install the rpm
  if ! /bin/rpm -q --quiet $package; then
    $install_util -y $package_operation $package
  fi
else
  # If the rpm is installed, uninstall the rpm
  if /bin/rpm -q --quiet $package; then
    $install_util -y $package_operation $package
  fi
fi

}

package_command remove telnet-server
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:low
Strategy:disable
- name: "Ensure telnet-server is removed"
  package:
    name="{{item}}"
    state=absent
  with_items:
    - telnet-server
  tags:
    - package_telnet-server_removed
    - high_severity
    - disable_strategy
    - low_complexity
    - low_disruption
    - CCE-27073-6
    - NIST-800-53-CM-7

Remediation Puppet snippet:   (show)

Complexity:low
Disruption:low
Strategy:disable
include remove_telnet-server

class remove_telnet-server {
  package { 'telnet-server':
    ensure => 'purged',
  }
}
Remediation Anaconda snippet:   (show)

Complexity:low
Disruption:low
Strategy:disable

package --remove=telnet-server

Rlogin, Rsh, and Rexec   [ref]group

The Berkeley r-commands are legacy services which allow cleartext remote access and have an insecure trust model.

contains 4 rules

Uninstall rsh-server Package   [ref]rule

The rsh-server package can be uninstalled with the following command:

$ sudo yum erase rsh-server

Rationale:

The rsh-server package provides several obsolete and insecure network services. Removing it decreases the risk of those services' accidental (or intentional) activation.

Severity:  high

Identifiers:  CCE-27062-9, DISA FSO RHEL-06-000213

References:  CM-7, 305, 381

Remediation Shell script:   (show)

Complexity:low
Disruption:low
Strategy:disable
# Function to install or uninstall packages on RHEL and Fedora systems.
#
# Example Call(s):
#
#     package_command install aide
#     package_command remove telnet-server
#
function package_command {

# Load function arguments into local variables
local package_operation=$1
local package=$2

# Check sanity of the input
if [ $# -ne "2" ]
then
  echo "Usage: package_command 'install/uninstall' 'rpm_package_name"
  echo "Aborting."
  exit 1
fi

# If dnf is installed, use dnf; otherwise, use yum
if [ -f "/usr/bin/dnf" ] ; then
  install_util="/usr/bin/dnf"
else
  install_util="/usr/bin/yum"
fi

if [ "$package_operation" != 'remove' ] ; then
  # If the rpm is not installed, install the rpm
  if ! /bin/rpm -q --quiet $package; then
    $install_util -y $package_operation $package
  fi
else
  # If the rpm is installed, uninstall the rpm
  if /bin/rpm -q --quiet $package; then
    $install_util -y $package_operation $package
  fi
fi

}

package_command remove rsh-server
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:low
Strategy:disable
- name: "Ensure rsh-server is removed"
  package:
    name="{{item}}"
    state=absent
  with_items:
    - rsh-server
  tags:
    - package_rsh-server_removed
    - high_severity
    - disable_strategy
    - low_complexity
    - low_disruption
    - CCE-27062-9
    - NIST-800-53-CM-7

Remediation Puppet snippet:   (show)

Complexity:low
Disruption:low
Strategy:disable
include remove_rsh-server

class remove_rsh-server {
  package { 'rsh-server':
    ensure => 'purged',
  }
}
Remediation Anaconda snippet:   (show)

Complexity:low
Disruption:low
Strategy:disable

package --remove=rsh-server

Disable rexec Service   [ref]rule

The rexec service, which is available with the rsh-server package and runs as a service through xinetd, should be disabled. The rexec service can be disabled with the following command:

$ sudo chkconfig rexec off

Rationale:

The rexec service uses unencrypted network communications, which means that data from the login session, including passwords and all other information transmitted during the session, can be stolen by eavesdroppers on the network.

Severity:  high

Identifiers:  CCE-27208-8, DISA FSO RHEL-06-000216

References:  CM-7, 68, 1436

Disable rsh Service   [ref]rule

The rsh service, which is available with the rsh-server package and runs as a service through xinetd, should be disabled. The rsh service can be disabled with the following command:

$ sudo chkconfig rsh off

Rationale:

The rsh service uses unencrypted network communications, which means that data from the login session, including passwords and all other information transmitted during the session, can be stolen by eavesdroppers on the network.

Severity:  high

Identifiers:  CCE-26994-4, DISA FSO RHEL-06-000214

References:  CM-7, IA-5(1)(c), 68, 1436

Disable rlogin Service   [ref]rule

The rlogin service, which is available with the rsh-server package and runs as a service through xinetd, should be disabled. The rlogin service can be disabled with the following command:

$ sudo chkconfig rlogin off

Rationale:

The rlogin service uses unencrypted network communications, which means that data from the login session, including passwords and all other information transmitted during the session, can be stolen by eavesdroppers on the network.

Severity:  high

Identifiers:  CCE-26865-6, DISA FSO RHEL-06-000218

References:  CM-7, IA-5(1)(c), 1436

NIS   [ref]group

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]rule

The ypserv package can be uninstalled with the following command:

$ sudo yum erase ypserv

Rationale:

Removing the ypserv package decreases the risk of the accidental (or intentional) activation of NIS or NIS+ services.

Severity:  medium

Identifiers:  CCE-27079-3, DISA FSO RHEL-06-000220

References:  CM-7, 305, 381

Remediation Shell script:   (show)

Complexity:low
Disruption:low
Strategy:disable
# Function to install or uninstall packages on RHEL and Fedora systems.
#
# Example Call(s):
#
#     package_command install aide
#     package_command remove telnet-server
#
function package_command {

# Load function arguments into local variables
local package_operation=$1
local package=$2

# Check sanity of the input
if [ $# -ne "2" ]
then
  echo "Usage: package_command 'install/uninstall' 'rpm_package_name"
  echo "Aborting."
  exit 1
fi

# If dnf is installed, use dnf; otherwise, use yum
if [ -f "/usr/bin/dnf" ] ; then
  install_util="/usr/bin/dnf"
else
  install_util="/usr/bin/yum"
fi

if [ "$package_operation" != 'remove' ] ; then
  # If the rpm is not installed, install the rpm
  if ! /bin/rpm -q --quiet $package; then
    $install_util -y $package_operation $package
  fi
else
  # If the rpm is installed, uninstall the rpm
  if /bin/rpm -q --quiet $package; then
    $install_util -y $package_operation $package
  fi
fi

}

package_command remove ypserv
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:low
Strategy:disable
- name: "Ensure ypserv is removed"
  package:
    name="{{item}}"
    state=absent
  with_items:
    - ypserv
  tags:
    - package_ypserv_removed
    - medium_severity
    - disable_strategy
    - low_complexity
    - low_disruption
    - CCE-27079-3
    - NIST-800-53-CM-7

Remediation Puppet snippet:   (show)

Complexity:low
Disruption:low
Strategy:disable
include remove_ypserv

class remove_ypserv {
  package { 'ypserv':
    ensure => 'purged',
  }
}
Remediation Anaconda snippet:   (show)

Complexity:low
Disruption:low
Strategy:disable

package --remove=ypserv

Disable ypbind Service   [ref]rule

The ypbind service, which allows the system to act as a client in a NIS or NIS+ domain, should be disabled. The ypbind service can be disabled with the following command:

$ sudo chkconfig ypbind off

Rationale:

Disabling the ypbind service ensures the system is not acting as a client in a NIS or NIS+ domain.

Severity:  medium

Identifiers:  CCE-26894-6, DISA FSO RHEL-06-000221

References:  CM-7, 305

Remediation Shell script:   (show)

Complexity:low
Disruption:low
Strategy:disable
# Function to enable/disable and start/stop services on RHEL and Fedora systems.
#
# Example Call(s):
#
#     service_command enable bluetooth
#     service_command disable bluetooth.service
#
#     Using xinetd:
#     service_command disable rsh.socket xinetd=rsh
#
function service_command {

# Load function arguments into local variables
local service_state=$1
local service=$2
local xinetd=$(echo $3 | cut -d'=' -f2)

# Check sanity of the input
if [ $# -lt "2" ]
then
  echo "Usage: service_command 'enable/disable' 'service_name.service'"
  echo
  echo "To enable or disable xinetd services add \'xinetd=service_name\'"
  echo "as the last argument"  
  echo "Aborting."
  exit 1
fi

# If systemctl is installed, use systemctl command; otherwise, use the service/chkconfig commands
if [ -f "/usr/bin/systemctl" ] ; then
  service_util="/usr/bin/systemctl"
else
  service_util="/sbin/service"
  chkconfig_util="/sbin/chkconfig"
fi

# If disable is not specified in arg1, set variables to enable services.
# Otherwise, variables are to be set to disable services.
if [ "$service_state" != 'disable' ] ; then
  service_state="enable"
  service_operation="start"
  chkconfig_state="on"
else
  service_state="disable"
  service_operation="stop"
  chkconfig_state="off"
fi

# If chkconfig_util is not empty, use chkconfig/service commands.
if ! [ "x$chkconfig_util" = x ] ; then
  $service_util $service $service_operation
  $chkconfig_util --level 0123456 $service $chkconfig_state
else
  $service_util $service_operation $service
  $service_util $service_state $service
fi

# Test if local variable xinetd is empty using non-bashism.
# If empty, then xinetd is not being used.
if ! [ "x$xinetd" = x ] ; then
  grep -qi disable /etc/xinetd.d/$xinetd && \

  if ! [ "$service_operation" != 'disable' ] ; then
    sed -i "s/disable.*/disable         = no/gI" /etc/xinetd.d/$xinetd
  else
    sed -i "s/disable.*/disable         = yes/gI" /etc/xinetd.d/$xinetd
  fi
fi

}

service_command disable ypbind
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:low
Strategy:disable
- name: "Disable service ypbind"
  service:
    name="{{item}}"
    enabled="no"
    state="stopped"
  with_items:
    - ypbind
  tags:
    - service_ypbind_disabled
    - medium_severity
    - disable_strategy
    - low_complexity
    - low_disruption
    - CCE-26894-6
    - NIST-800-53-CM-7

TFTP Server   [ref]group

TFTP 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 2 rules

Disable tftp Service   [ref]rule

The tftp service should be disabled. The tftp service can be disabled with the following command:

$ sudo chkconfig tftp off

Rationale:

Disabling the tftp service ensures the system is not acting as a TFTP server, which does not provide encryption or authentication.

Severity:  medium

Identifiers:  CCE-27055-3, DISA FSO RHEL-06-000223

References:  CM-7, 1436

Remediation Shell script:   (show)

Complexity:low
Disruption:low
Strategy:disable
# Function to enable/disable and start/stop services on RHEL and Fedora systems.
#
# Example Call(s):
#
#     service_command enable bluetooth
#     service_command disable bluetooth.service
#
#     Using xinetd:
#     service_command disable rsh.socket xinetd=rsh
#
function service_command {

# Load function arguments into local variables
local service_state=$1
local service=$2
local xinetd=$(echo $3 | cut -d'=' -f2)

# Check sanity of the input
if [ $# -lt "2" ]
then
  echo "Usage: service_command 'enable/disable' 'service_name.service'"
  echo
  echo "To enable or disable xinetd services add \'xinetd=service_name\'"
  echo "as the last argument"  
  echo "Aborting."
  exit 1
fi

# If systemctl is installed, use systemctl command; otherwise, use the service/chkconfig commands
if [ -f "/usr/bin/systemctl" ] ; then
  service_util="/usr/bin/systemctl"
else
  service_util="/sbin/service"
  chkconfig_util="/sbin/chkconfig"
fi

# If disable is not specified in arg1, set variables to enable services.
# Otherwise, variables are to be set to disable services.
if [ "$service_state" != 'disable' ] ; then
  service_state="enable"
  service_operation="start"
  chkconfig_state="on"
else
  service_state="disable"
  service_operation="stop"
  chkconfig_state="off"
fi

# If chkconfig_util is not empty, use chkconfig/service commands.
if ! [ "x$chkconfig_util" = x ] ; then
  $service_util $service $service_operation
  $chkconfig_util --level 0123456 $service $chkconfig_state
else
  $service_util $service_operation $service
  $service_util $service_state $service
fi

# Test if local variable xinetd is empty using non-bashism.
# If empty, then xinetd is not being used.
if ! [ "x$xinetd" = x ] ; then
  grep -qi disable /etc/xinetd.d/$xinetd && \

  if ! [ "$service_operation" != 'disable' ] ; then
    sed -i "s/disable.*/disable         = no/gI" /etc/xinetd.d/$xinetd
  else
    sed -i "s/disable.*/disable         = yes/gI" /etc/xinetd.d/$xinetd
  fi
fi

}

service_command disable tftp
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:low
Strategy:disable
- name: "Disable service tftp"
  service:
    name="{{item}}"
    enabled="no"
    state="stopped"
  with_items:
    - tftp
  tags:
    - service_tftp_disabled
    - medium_severity
    - disable_strategy
    - low_complexity
    - low_disruption
    - CCE-27055-3
    - NIST-800-53-CM-7

Uninstall tftp-server Package   [ref]rule

The tftp-server package can be removed with the following command:

$ sudo yum erase tftp-server

Rationale:

Removing the tftp-server package decreases the risk of the accidental (or intentional) activation of tftp services.

Severity:  medium

Identifiers:  CCE-26946-4, DISA FSO RHEL-06-000222

References:  CM-7, 305

Remediation Shell script:   (show)

Complexity:low
Disruption:low
Strategy:disable
# Function to install or uninstall packages on RHEL and Fedora systems.
#
# Example Call(s):
#
#     package_command install aide
#     package_command remove telnet-server
#
function package_command {

# Load function arguments into local variables
local package_operation=$1
local package=$2

# Check sanity of the input
if [ $# -ne "2" ]
then
  echo "Usage: package_command 'install/uninstall' 'rpm_package_name"
  echo "Aborting."
  exit 1
fi

# If dnf is installed, use dnf; otherwise, use yum
if [ -f "/usr/bin/dnf" ] ; then
  install_util="/usr/bin/dnf"
else
  install_util="/usr/bin/yum"
fi

if [ "$package_operation" != 'remove' ] ; then
  # If the rpm is not installed, install the rpm
  if ! /bin/rpm -q --quiet $package; then
    $install_util -y $package_operation $package
  fi
else
  # If the rpm is installed, uninstall the rpm
  if /bin/rpm -q --quiet $package; then
    $install_util -y $package_operation $package
  fi
fi

}

package_command remove tftp-server
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:low
Strategy:disable
- name: "Ensure tftp-server is removed"
  package:
    name="{{item}}"
    state=absent
  with_items:
    - tftp-server
  tags:
    - package_tftp-server_removed
    - medium_severity
    - disable_strategy
    - low_complexity
    - low_disruption
    - CCE-26946-4
    - NIST-800-53-CM-7

Remediation Puppet snippet:   (show)

Complexity:low
Disruption:low
Strategy:disable
include remove_tftp-server

class remove_tftp-server {
  package { 'tftp-server':
    ensure => 'purged',
  }
}
Remediation Anaconda snippet:   (show)

Complexity:low
Disruption:low
Strategy:disable

package --remove=tftp-server

Base Services   [ref]group

This section addresses the base services that are installed on a Red Hat Enterprise Linux 6 default installation which are not covered in other sections. Some of these services listen on the network and should be treated with particular discretion. Other services are local system utilities that may or may not be extraneous. In general, system services should be disabled if not required.

contains 5 rules

Disable Automatic Bug Reporting Tool (abrtd)   [ref]rule

The Automatic Bug Reporting Tool (abrtd) daemon collects and reports crash data when an application crash is detected. Using a variety of plugins, abrtd can email crash reports to system administrators, log crash reports to files, or forward crash reports to a centralized issue tracking system such as RHTSupport. The abrtd service can be disabled with the following command:

$ sudo chkconfig abrtd off

Rationale:

Mishandling crash data could expose sensitive information about vulnerabilities in software executing on the local system, as well as sensitive information from within a process's address space or registers.

Severity:  low

Identifiers:  CCE-27247-6, DISA FSO RHEL-06-000261

References:  CM-7, 381

Remediation Shell script:   (show)

Complexity:low
Disruption:low
Strategy:disable
# Function to enable/disable and start/stop services on RHEL and Fedora systems.
#
# Example Call(s):
#
#     service_command enable bluetooth
#     service_command disable bluetooth.service
#
#     Using xinetd:
#     service_command disable rsh.socket xinetd=rsh
#
function service_command {

# Load function arguments into local variables
local service_state=$1
local service=$2
local xinetd=$(echo $3 | cut -d'=' -f2)

# Check sanity of the input
if [ $# -lt "2" ]
then
  echo "Usage: service_command 'enable/disable' 'service_name.service'"
  echo
  echo "To enable or disable xinetd services add \'xinetd=service_name\'"
  echo "as the last argument"  
  echo "Aborting."
  exit 1
fi

# If systemctl is installed, use systemctl command; otherwise, use the service/chkconfig commands
if [ -f "/usr/bin/systemctl" ] ; then
  service_util="/usr/bin/systemctl"
else
  service_util="/sbin/service"
  chkconfig_util="/sbin/chkconfig"
fi

# If disable is not specified in arg1, set variables to enable services.
# Otherwise, variables are to be set to disable services.
if [ "$service_state" != 'disable' ] ; then
  service_state="enable"
  service_operation="start"
  chkconfig_state="on"
else
  service_state="disable"
  service_operation="stop"
  chkconfig_state="off"
fi

# If chkconfig_util is not empty, use chkconfig/service commands.
if ! [ "x$chkconfig_util" = x ] ; then
  $service_util $service $service_operation
  $chkconfig_util --level 0123456 $service $chkconfig_state
else
  $service_util $service_operation $service
  $service_util $service_state $service
fi

# Test if local variable xinetd is empty using non-bashism.
# If empty, then xinetd is not being used.
if ! [ "x$xinetd" = x ] ; then
  grep -qi disable /etc/xinetd.d/$xinetd && \

  if ! [ "$service_operation" != 'disable' ] ; then
    sed -i "s/disable.*/disable         = no/gI" /etc/xinetd.d/$xinetd
  else
    sed -i "s/disable.*/disable         = yes/gI" /etc/xinetd.d/$xinetd
  fi
fi

}

service_command disable abrtd
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:low
Strategy:disable
- name: "Disable service abrtd"
  service:
    name="{{item}}"
    enabled="no"
    state="stopped"
  with_items:
    - abrtd
  tags:
    - service_abrtd_disabled
    - low_severity
    - disable_strategy
    - low_complexity
    - low_disruption
    - CCE-27247-6
    - NIST-800-53-CM-7

Disable ntpdate Service (ntpdate)   [ref]rule

The ntpdate service sets the local hardware clock by polling NTP servers when the system boots. It synchronizes to the NTP servers listed in /etc/ntp/step-tickers or /etc/ntp.conf and then sets the local hardware clock to the newly synchronized system time. The ntpdate service can be disabled with the following command:

$ sudo chkconfig ntpdate off

Rationale:

The ntpdate service may only be suitable for systems which are rebooted frequently enough that clock drift does not cause problems between reboots. In any event, the functionality of the ntpdate service is now available in the ntpd program and should be considered deprecated.

Severity:  low

Identifiers:  CCE-27256-7, DISA FSO RHEL-06-000265

References:  CM-7, 382

Remediation Shell script:   (show)

Complexity:low
Disruption:low
Strategy:disable
# Function to enable/disable and start/stop services on RHEL and Fedora systems.
#
# Example Call(s):
#
#     service_command enable bluetooth
#     service_command disable bluetooth.service
#
#     Using xinetd:
#     service_command disable rsh.socket xinetd=rsh
#
function service_command {

# Load function arguments into local variables
local service_state=$1
local service=$2
local xinetd=$(echo $3 | cut -d'=' -f2)

# Check sanity of the input
if [ $# -lt "2" ]
then
  echo "Usage: service_command 'enable/disable' 'service_name.service'"
  echo
  echo "To enable or disable xinetd services add \'xinetd=service_name\'"
  echo "as the last argument"  
  echo "Aborting."
  exit 1
fi

# If systemctl is installed, use systemctl command; otherwise, use the service/chkconfig commands
if [ -f "/usr/bin/systemctl" ] ; then
  service_util="/usr/bin/systemctl"
else
  service_util="/sbin/service"
  chkconfig_util="/sbin/chkconfig"
fi

# If disable is not specified in arg1, set variables to enable services.
# Otherwise, variables are to be set to disable services.
if [ "$service_state" != 'disable' ] ; then
  service_state="enable"
  service_operation="start"
  chkconfig_state="on"
else
  service_state="disable"
  service_operation="stop"
  chkconfig_state="off"
fi

# If chkconfig_util is not empty, use chkconfig/service commands.
if ! [ "x$chkconfig_util" = x ] ; then
  $service_util $service $service_operation
  $chkconfig_util --level 0123456 $service $chkconfig_state
else
  $service_util $service_operation $service
  $service_util $service_state $service
fi

# Test if local variable xinetd is empty using non-bashism.
# If empty, then xinetd is not being used.
if ! [ "x$xinetd" = x ] ; then
  grep -qi disable /etc/xinetd.d/$xinetd && \

  if ! [ "$service_operation" != 'disable' ] ; then
    sed -i "s/disable.*/disable         = no/gI" /etc/xinetd.d/$xinetd
  else
    sed -i "s/disable.*/disable         = yes/gI" /etc/xinetd.d/$xinetd
  fi
fi

}

service_command disable ntpdate
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:low
Strategy:disable
- name: "Disable service ntpdate"
  service:
    name="{{item}}"
    enabled="no"
    state="stopped"
  with_items:
    - ntpdate
  tags:
    - service_ntpdate_disabled
    - low_severity
    - disable_strategy
    - low_complexity
    - low_disruption
    - CCE-27256-7
    - NIST-800-53-CM-7

Disable Odd Job Daemon (oddjobd)   [ref]rule

The oddjobd service exists to provide an interface and access control mechanism through which specified privileged tasks can run tasks for unprivileged client applications. Communication with oddjobd through the system message bus. The oddjobd service can be disabled with the following command:

$ sudo chkconfig oddjobd off

Rationale:

The oddjobd service may provide necessary functionality in some environments, and can be disabled if it is not needed. Execution of tasks by privileged programs, on behalf of unprivileged ones, has traditionally been a source of privilege escalation security issues.

Severity:  low

Identifiers:  CCE-27257-5, DISA FSO RHEL-06-000266

References:  CM-7, 381

Remediation Shell script:   (show)

Complexity:low
Disruption:low
Strategy:disable
# Function to enable/disable and start/stop services on RHEL and Fedora systems.
#
# Example Call(s):
#
#     service_command enable bluetooth
#     service_command disable bluetooth.service
#
#     Using xinetd:
#     service_command disable rsh.socket xinetd=rsh
#
function service_command {

# Load function arguments into local variables
local service_state=$1
local service=$2
local xinetd=$(echo $3 | cut -d'=' -f2)

# Check sanity of the input
if [ $# -lt "2" ]
then
  echo "Usage: service_command 'enable/disable' 'service_name.service'"
  echo
  echo "To enable or disable xinetd services add \'xinetd=service_name\'"
  echo "as the last argument"  
  echo "Aborting."
  exit 1
fi

# If systemctl is installed, use systemctl command; otherwise, use the service/chkconfig commands
if [ -f "/usr/bin/systemctl" ] ; then
  service_util="/usr/bin/systemctl"
else
  service_util="/sbin/service"
  chkconfig_util="/sbin/chkconfig"
fi

# If disable is not specified in arg1, set variables to enable services.
# Otherwise, variables are to be set to disable services.
if [ "$service_state" != 'disable' ] ; then
  service_state="enable"
  service_operation="start"
  chkconfig_state="on"
else
  service_state="disable"
  service_operation="stop"
  chkconfig_state="off"
fi

# If chkconfig_util is not empty, use chkconfig/service commands.
if ! [ "x$chkconfig_util" = x ] ; then
  $service_util $service $service_operation
  $chkconfig_util --level 0123456 $service $chkconfig_state
else
  $service_util $service_operation $service
  $service_util $service_state $service
fi

# Test if local variable xinetd is empty using non-bashism.
# If empty, then xinetd is not being used.
if ! [ "x$xinetd" = x ] ; then
  grep -qi disable /etc/xinetd.d/$xinetd && \

  if ! [ "$service_operation" != 'disable' ] ; then
    sed -i "s/disable.*/disable         = no/gI" /etc/xinetd.d/$xinetd
  else
    sed -i "s/disable.*/disable         = yes/gI" /etc/xinetd.d/$xinetd
  fi
fi

}

service_command disable oddjobd
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:low
Strategy:disable
- name: "Disable service oddjobd"
  service:
    name="{{item}}"
    enabled="no"
    state="stopped"
  with_items:
    - oddjobd
  tags:
    - service_oddjobd_disabled
    - low_severity
    - disable_strategy
    - low_complexity
    - low_disruption
    - CCE-27257-5
    - NIST-800-53-CM-7

Disable Apache Qpid (qpidd)   [ref]rule

The qpidd service provides high speed, secure, guaranteed delivery services. It is an implementation of the Advanced Message Queuing Protocol. By default the qpidd service will bind to port 5672 and listen for connection attempts. The qpidd service can be disabled with the following command:

$ sudo chkconfig qpidd off

Rationale:

The qpidd service is automatically installed when the "base" package selection is selected during installation. The qpidd service listens for network connections, which increases the attack surface of the system. If the system is not intended to receive AMQP traffic, then the qpidd service is not needed and should be disabled or removed.

Severity:  low

Identifiers:  CCE-26928-2, DISA FSO RHEL-06-000267

References:  CM-7, 382

Remediation Shell script:   (show)

Complexity:low
Disruption:low
Strategy:disable
# Function to enable/disable and start/stop services on RHEL and Fedora systems.
#
# Example Call(s):
#
#     service_command enable bluetooth
#     service_command disable bluetooth.service
#
#     Using xinetd:
#     service_command disable rsh.socket xinetd=rsh
#
function service_command {

# Load function arguments into local variables
local service_state=$1
local service=$2
local xinetd=$(echo $3 | cut -d'=' -f2)

# Check sanity of the input
if [ $# -lt "2" ]
then
  echo "Usage: service_command 'enable/disable' 'service_name.service'"
  echo
  echo "To enable or disable xinetd services add \'xinetd=service_name\'"
  echo "as the last argument"  
  echo "Aborting."
  exit 1
fi

# If systemctl is installed, use systemctl command; otherwise, use the service/chkconfig commands
if [ -f "/usr/bin/systemctl" ] ; then
  service_util="/usr/bin/systemctl"
else
  service_util="/sbin/service"
  chkconfig_util="/sbin/chkconfig"
fi

# If disable is not specified in arg1, set variables to enable services.
# Otherwise, variables are to be set to disable services.
if [ "$service_state" != 'disable' ] ; then
  service_state="enable"
  service_operation="start"
  chkconfig_state="on"
else
  service_state="disable"
  service_operation="stop"
  chkconfig_state="off"
fi

# If chkconfig_util is not empty, use chkconfig/service commands.
if ! [ "x$chkconfig_util" = x ] ; then
  $service_util $service $service_operation
  $chkconfig_util --level 0123456 $service $chkconfig_state
else
  $service_util $service_operation $service
  $service_util $service_state $service
fi

# Test if local variable xinetd is empty using non-bashism.
# If empty, then xinetd is not being used.
if ! [ "x$xinetd" = x ] ; then
  grep -qi disable /etc/xinetd.d/$xinetd && \

  if ! [ "$service_operation" != 'disable' ] ; then
    sed -i "s/disable.*/disable         = no/gI" /etc/xinetd.d/$xinetd
  else
    sed -i "s/disable.*/disable         = yes/gI" /etc/xinetd.d/$xinetd
  fi
fi

}

service_command disable qpidd
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:low
Strategy:disable
- name: "Disable service qpidd"
  service:
    name="{{item}}"
    enabled="no"
    state="stopped"
  with_items:
    - qpidd
  tags:
    - service_qpidd_disabled
    - low_severity
    - disable_strategy
    - low_complexity
    - low_disruption
    - CCE-26928-2
    - NIST-800-53-CM-7

Disable Network Router Discovery Daemon (rdisc)   [ref]rule

The rdisc service implements the client side of the ICMP Internet Router Discovery Protocol (IRDP), which allows discovery of routers on the local subnet. If a router is discovered then the local routing table is updated with a corresponding default route. By default this daemon is disabled. The rdisc service can be disabled with the following command:

$ sudo chkconfig rdisc off

Rationale:

General-purpose systems typically have their network and routing information configured statically by a system administrator. Workstations or some special-purpose systems often use DHCP (instead of IRDP) to retrieve dynamic network configuration information.

Severity:  low

Identifiers:  CCE-27261-7, DISA FSO RHEL-06-000268

References:  AC-4, CM-7, 382

Remediation Shell script:   (show)

Complexity:low
Disruption:low
Strategy:disable
# Function to enable/disable and start/stop services on RHEL and Fedora systems.
#
# Example Call(s):
#
#     service_command enable bluetooth
#     service_command disable bluetooth.service
#
#     Using xinetd:
#     service_command disable rsh.socket xinetd=rsh
#
function service_command {

# Load function arguments into local variables
local service_state=$1
local service=$2
local xinetd=$(echo $3 | cut -d'=' -f2)

# Check sanity of the input
if [ $# -lt "2" ]
then
  echo "Usage: service_command 'enable/disable' 'service_name.service'"
  echo
  echo "To enable or disable xinetd services add \'xinetd=service_name\'"
  echo "as the last argument"  
  echo "Aborting."
  exit 1
fi

# If systemctl is installed, use systemctl command; otherwise, use the service/chkconfig commands
if [ -f "/usr/bin/systemctl" ] ; then
  service_util="/usr/bin/systemctl"
else
  service_util="/sbin/service"
  chkconfig_util="/sbin/chkconfig"
fi

# If disable is not specified in arg1, set variables to enable services.
# Otherwise, variables are to be set to disable services.
if [ "$service_state" != 'disable' ] ; then
  service_state="enable"
  service_operation="start"
  chkconfig_state="on"
else
  service_state="disable"
  service_operation="stop"
  chkconfig_state="off"
fi

# If chkconfig_util is not empty, use chkconfig/service commands.
if ! [ "x$chkconfig_util" = x ] ; then
  $service_util $service $service_operation
  $chkconfig_util --level 0123456 $service $chkconfig_state
else
  $service_util $service_operation $service
  $service_util $service_state $service
fi

# Test if local variable xinetd is empty using non-bashism.
# If empty, then xinetd is not being used.
if ! [ "x$xinetd" = x ] ; then
  grep -qi disable /etc/xinetd.d/$xinetd && \

  if ! [ "$service_operation" != 'disable' ] ; then
    sed -i "s/disable.*/disable         = no/gI" /etc/xinetd.d/$xinetd
  else
    sed -i "s/disable.*/disable         = yes/gI" /etc/xinetd.d/$xinetd
  fi
fi

}

service_command disable rdisc
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:low
Strategy:disable
- name: "Disable service rdisc"
  service:
    name="{{item}}"
    enabled="no"
    state="stopped"
  with_items:
    - rdisc
  tags:
    - service_rdisc_disabled
    - low_severity
    - disable_strategy
    - low_complexity
    - low_disruption
    - CCE-27261-7
    - NIST-800-53-AC-4
    - NIST-800-53-CM-7

Cron and At Daemons   [ref]group

The cron and at services are used to allow commands to be executed at a later time. The cron service is required by almost all systems to perform necessary maintenance tasks, while at may or may not be required on a given system. Both daemons should be configured defensively.

contains 1 rule

Disable At Service (atd)   [ref]rule

The at and batch commands can be used to schedule tasks that are meant to be executed only once. This allows delayed execution in a manner similar to cron, except that it is not recurring. The daemon atd keeps track of tasks scheduled via at and batch, and executes them at the specified time. The atd service can be disabled with the following command:

$ sudo chkconfig atd off

Rationale:

The atd service could be used by an unsophisticated insider to carry out activities outside of a normal login session, which could complicate accountability. Furthermore, the need to schedule tasks with at or batch is not common.

Severity:  low

Identifiers:  CCE-27249-2, DISA FSO RHEL-06-000262

References:  CM-7, 381

Remediation Shell script:   (show)

Complexity:low
Disruption:low
Strategy:disable
# Function to enable/disable and start/stop services on RHEL and Fedora systems.
#
# Example Call(s):
#
#     service_command enable bluetooth
#     service_command disable bluetooth.service
#
#     Using xinetd:
#     service_command disable rsh.socket xinetd=rsh
#
function service_command {

# Load function arguments into local variables
local service_state=$1
local service=$2
local xinetd=$(echo $3 | cut -d'=' -f2)

# Check sanity of the input
if [ $# -lt "2" ]
then
  echo "Usage: service_command 'enable/disable' 'service_name.service'"
  echo
  echo "To enable or disable xinetd services add \'xinetd=service_name\'"
  echo "as the last argument"  
  echo "Aborting."
  exit 1
fi

# If systemctl is installed, use systemctl command; otherwise, use the service/chkconfig commands
if [ -f "/usr/bin/systemctl" ] ; then
  service_util="/usr/bin/systemctl"
else
  service_util="/sbin/service"
  chkconfig_util="/sbin/chkconfig"
fi

# If disable is not specified in arg1, set variables to enable services.
# Otherwise, variables are to be set to disable services.
if [ "$service_state" != 'disable' ] ; then
  service_state="enable"
  service_operation="start"
  chkconfig_state="on"
else
  service_state="disable"
  service_operation="stop"
  chkconfig_state="off"
fi

# If chkconfig_util is not empty, use chkconfig/service commands.
if ! [ "x$chkconfig_util" = x ] ; then
  $service_util $service $service_operation
  $chkconfig_util --level 0123456 $service $chkconfig_state
else
  $service_util $service_operation $service
  $service_util $service_state $service
fi

# Test if local variable xinetd is empty using non-bashism.
# If empty, then xinetd is not being used.
if ! [ "x$xinetd" = x ] ; then
  grep -qi disable /etc/xinetd.d/$xinetd && \

  if ! [ "$service_operation" != 'disable' ] ; then
    sed -i "s/disable.*/disable         = no/gI" /etc/xinetd.d/$xinetd
  else
    sed -i "s/disable.*/disable         = yes/gI" /etc/xinetd.d/$xinetd
  fi
fi

}

service_command disable atd
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:low
Strategy:disable
- name: "Disable service atd"
  service:
    name="{{item}}"
    enabled="no"
    state="stopped"
  with_items:
    - atd
  tags:
    - service_atd_disabled
    - low_severity
    - disable_strategy
    - low_complexity
    - low_disruption
    - CCE-27249-2
    - NIST-800-53-CM-7

SSH Server   [ref]group

The SSH protocol is recommended for remote login and remote file transfer. SSH provides confidentiality and integrity for data exchanged between two systems, as well as server authentication, through the use of public key cryptography. The implementation included with the system is called OpenSSH, and more detailed documentation is available from its website, http://www.openssh.org. Its server program is called sshd and provided by the RPM package openssh-server.

contains 10 rules

Configure OpenSSH Server if Necessary   [ref]group

If the system needs to act as an SSH server, then certain changes should be made to the OpenSSH daemon configuration file /etc/ssh/sshd_config. The following recommendations can be applied to this file. See the sshd_config(5) man page for more detailed information.

contains 10 rules

Allow Only SSH Protocol 2   [ref]rule

Only SSH protocol version 2 connections should be permitted. The default setting in /etc/ssh/sshd_config is correct, and can be verified by ensuring that the following line appears:

Protocol 2

Rationale:

SSH protocol version 1 suffers from design flaws that result in security vulnerabilities and should not be used.

Severity:  high

Identifiers:  CCE-27072-8, DISA FSO RHEL-06-000227

References:  AC-3(10), IA-5(1)(c), 776, 774, 1436

Remediation Shell script:   (show)

# Function to replace configuration setting in config file or add the configuration setting if
# it does not exist.
#
# Expects four arguments:
#
# config_file:		Configuration file that will be modified
# key:			Configuration option to change
# value:		Value of the configuration option to change
# cce:			The CCE identifier or '@CCENUM@' if no CCE identifier exists
#
# Optional arugments:
#
# format:		Optional argument to specify the format of how key/value should be
# 			modified/appended in the configuration file. The default is key = value.
#
# Example Call(s):
#
#     With default format of 'key = value':
#     replace_or_append '/etc/sysctl.conf' '^kernel.randomize_va_space' '2' '@CCENUM@'
#
#     With custom key/value format:
#     replace_or_append '/etc/sysconfig/selinux' '^SELINUX=' 'disabled' '@CCENUM@' '%s=%s'
#
#     With a variable:
#     replace_or_append '/etc/sysconfig/selinux' '^SELINUX=' $var_selinux_state '@CCENUM@' '%s=%s'
#
function replace_or_append {
  local config_file=$1
  local key=$2
  local value=$3
  local cce=$4
  local format=$5

  # Check sanity of the input
  if [ $# -lt "3" ]
  then
        echo "Usage: replace_or_append 'config_file_location' 'key_to_search' 'new_value'"
        echo
        echo "If symlinks need to be taken into account, add yes/no to the last argument"
        echo "to allow to 'follow_symlinks'."
        echo "Aborting."
        exit 1
  fi

  # Test if the config_file is a symbolic link. If so, use --follow-symlinks with sed.
  # Otherwise, regular sed command will do.
  if test -L $config_file; then
    sed_command="sed -i --follow-symlinks"
  else
    sed_command="sed -i"
  fi

  # Test that the cce arg is not empty or does not equal @CCENUM@.
  # If @CCENUM@ exists, it means that there is no CCE assigned.
  if ! [ "x$cce" = x ] && [ "$cce" != '@CCENUM@' ]; then
    cce="CCE-${cce}"
  else
    cce="CCE"
  fi

  # Strip any search characters in the key arg so that the key can be replaced without
  # adding any search characters to the config file.
  stripped_key=$(sed "s/[\^=\$,;+]*//g" <<< $key)

  # If there is no print format specified in the last arg, use the default format.
  if ! [ "x$format" = x ] ; then
    printf -v formatted_output "$format" "$stripped_key" "$value"
  else
    formatted_output="$stripped_key = $value"
  fi

  # If the key exists, change it. Otherwise, add it to the config_file.
  if `grep -qi "$key" $config_file` ; then
    eval '$sed_command "s/$key.*/$formatted_output/g" $config_file'
  else
    # \n is precaution for case where file ends without trailing newline
    echo -e "\n# Per $cce: Set $formatted_output in $config_file" >> $config_file
    echo -e "$formatted_output" >> $config_file
  fi

}

replace_or_append '/etc/ssh/sshd_config' '^Protocol' '2' 'CCE-27072-8' '%s %s'
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:low
Strategy:restrict

- name: "Allow Only SSH Protocol 2"
  lineinfile:
    dest: /etc/ssh/sshd_config
    regexp: "^Protocol [0-9]"
    line: "Protocol 2"
    validate: sshd -t -f %s
  #notify: :reload ssh
  tags:
    - sshd_allow_only_protocol2
    - high_severity
    - restrict_strategy
    - low_complexity
    - low_disruption
    - CCE-27072-8
    - NIST-800-53-AC-3(10)
    - NIST-800-53-IA-5(1)(c)

Set SSH Idle Timeout Interval   [ref]rule

SSH allows administrators to set an idle timeout interval. After this interval has passed, the idle user will be automatically logged out.

To set an idle timeout interval, edit the following line in /etc/ssh/sshd_config as follows:

ClientAliveInterval 300
The timeout interval is given in seconds. To have a timeout of 15 minutes, set interval to 900.

If a shorter timeout has already been set for the login shell, that value will preempt any SSH setting made here. Keep in mind that some processes may stop SSH from correctly detecting that the user is idle.

Rationale:

Causing idle users to be automatically logged out guards against compromises one system leading trivially to compromises on another.

Severity:  low

Identifiers:  CCE-26919-1, DISA FSO RHEL-06-000230

References:  AC-2(5), SA-8, Req-8.1.8, 879, 1133

Remediation Shell script:   (show)


sshd_idle_timeout_value="300"

grep -q ^ClientAliveInterval /etc/ssh/sshd_config && \
  sed -i "s/ClientAliveInterval.*/ClientAliveInterval $sshd_idle_timeout_value/g" /etc/ssh/sshd_config
if ! [ $? -eq 0 ]; then
    echo "ClientAliveInterval $sshd_idle_timeout_value" >> /etc/ssh/sshd_config
fi
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:low
Strategy:restrict
- name: Set SSH Idle Timeout Interval
  lineinfile:
    create: yes
    dest: /etc/ssh/sshd_config
    regexp: ^ClientAliveInterval
    line: ClientAliveInterval 300
    validate: sshd -t -f %s
  #notify: restart sshd
  tags:
    - sshd_set_idle_timeout
    - low_severity
    - restrict_strategy
    - low_complexity
    - low_disruption
    - CCE-26919-1
    - NIST-800-53-AC-2(5)
    - NIST-800-53-SA-8
    - PCI-DSS-Req-8.1.8

Set SSH Client Alive Count   [ref]rule

To ensure the SSH idle timeout occurs precisely when the ClientAliveCountMax is set, edit /etc/ssh/sshd_config as follows:

ClientAliveCountMax 0

Rationale:

This ensures a user login will be terminated as soon as the ClientAliveCountMax is reached.

Severity:  low

Identifiers:  CCE-26282-4, DISA FSO RHEL-06-000231

References:  AC-2(5), SA-8, 879, 1133

Remediation Shell script:   (show)

grep -q ^ClientAliveCountMax /etc/ssh/sshd_config && \
  sed -i "s/ClientAliveCountMax.*/ClientAliveCountMax 0/g" /etc/ssh/sshd_config
if ! [ $? -eq 0 ]; then
    echo "ClientAliveCountMax 0" >> /etc/ssh/sshd_config
fi
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:low
Strategy:restrict
- name: Set SSH Client Alive Count
  lineinfile:
    create: yes
    dest: /etc/ssh/sshd_config
    regexp: ^ClientAliveCountMax
    line: ClientAliveCountMax 0
    validate: sshd -t -f %s
  #notify: restart sshd
  tags:
    - sshd_set_keepalive
    - low_severity
    - restrict_strategy
    - low_complexity
    - low_disruption
    - CCE-26282-4
    - NIST-800-53-AC-2(5)
    - NIST-800-53-SA-8

Disable SSH Support for .rhosts Files   [ref]rule

SSH can emulate the behavior of the obsolete rsh command in allowing users to enable insecure access to their accounts via .rhosts files.

To ensure this behavior is disabled, add or correct the following line in /etc/ssh/sshd_config:

IgnoreRhosts yes

Rationale:

SSH trust relationships mean a compromise on one host can allow an attacker to move trivially to other hosts.

Severity:  medium

Identifiers:  CCE-27124-7, DISA FSO RHEL-06-000234

References:  AC-3, 765, 766

Remediation Shell script:   (show)

# Function to replace configuration setting in config file or add the configuration setting if
# it does not exist.
#
# Expects four arguments:
#
# config_file:		Configuration file that will be modified
# key:			Configuration option to change
# value:		Value of the configuration option to change
# cce:			The CCE identifier or '@CCENUM@' if no CCE identifier exists
#
# Optional arugments:
#
# format:		Optional argument to specify the format of how key/value should be
# 			modified/appended in the configuration file. The default is key = value.
#
# Example Call(s):
#
#     With default format of 'key = value':
#     replace_or_append '/etc/sysctl.conf' '^kernel.randomize_va_space' '2' '@CCENUM@'
#
#     With custom key/value format:
#     replace_or_append '/etc/sysconfig/selinux' '^SELINUX=' 'disabled' '@CCENUM@' '%s=%s'
#
#     With a variable:
#     replace_or_append '/etc/sysconfig/selinux' '^SELINUX=' $var_selinux_state '@CCENUM@' '%s=%s'
#
function replace_or_append {
  local config_file=$1
  local key=$2
  local value=$3
  local cce=$4
  local format=$5

  # Check sanity of the input
  if [ $# -lt "3" ]
  then
        echo "Usage: replace_or_append 'config_file_location' 'key_to_search' 'new_value'"
        echo
        echo "If symlinks need to be taken into account, add yes/no to the last argument"
        echo "to allow to 'follow_symlinks'."
        echo "Aborting."
        exit 1
  fi

  # Test if the config_file is a symbolic link. If so, use --follow-symlinks with sed.
  # Otherwise, regular sed command will do.
  if test -L $config_file; then
    sed_command="sed -i --follow-symlinks"
  else
    sed_command="sed -i"
  fi

  # Test that the cce arg is not empty or does not equal @CCENUM@.
  # If @CCENUM@ exists, it means that there is no CCE assigned.
  if ! [ "x$cce" = x ] && [ "$cce" != '@CCENUM@' ]; then
    cce="CCE-${cce}"
  else
    cce="CCE"
  fi

  # Strip any search characters in the key arg so that the key can be replaced without
  # adding any search characters to the config file.
  stripped_key=$(sed "s/[\^=\$,;+]*//g" <<< $key)

  # If there is no print format specified in the last arg, use the default format.
  if ! [ "x$format" = x ] ; then
    printf -v formatted_output "$format" "$stripped_key" "$value"
  else
    formatted_output="$stripped_key = $value"
  fi

  # If the key exists, change it. Otherwise, add it to the config_file.
  if `grep -qi "$key" $config_file` ; then
    eval '$sed_command "s/$key.*/$formatted_output/g" $config_file'
  else
    # \n is precaution for case where file ends without trailing newline
    echo -e "\n# Per $cce: Set $formatted_output in $config_file" >> $config_file
    echo -e "$formatted_output" >> $config_file
  fi

}

replace_or_append '/etc/ssh/sshd_config' '^IgnoreRhosts' 'yes' 'CCE-27124-7' '%s %s'
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:low
Strategy:restrict
- name: Disable SSH Support for .rhosts Files
  lineinfile:
    create: yes
    dest: /etc/ssh/sshd_config
    regexp: ^IgnoreRhosts
    line: IgnoreRhosts yes
    validate: sshd -t -f %s
  tags:
    - sshd_disable_rhosts
    - medium_severity
    - restrict_strategy
    - low_complexity
    - low_disruption
    - CCE-27124-7
    - NIST-800-53-AC-3

Disable Host-Based Authentication   [ref]rule

SSH's cryptographic host-based authentication is more secure than .rhosts authentication. However, it is not recommended that hosts unilaterally trust one another, even within an organization.

To disable host-based authentication, add or correct the following line in /etc/ssh/sshd_config:

HostbasedAuthentication no

Rationale:

SSH trust relationships mean a compromise on one host can allow an attacker to move trivially to other hosts.

Severity:  medium

Identifiers:  CCE-27091-8, DISA FSO RHEL-06-000236

References:  AC-3, 765, 766

Remediation Shell script:   (show)

grep -q ^HostbasedAuthentication /etc/ssh/sshd_config && \
  sed -i "s/HostbasedAuthentication.*/HostbasedAuthentication no/g" /etc/ssh/sshd_config
if ! [ $? -eq 0 ]; then
    echo "HostbasedAuthentication no" >> /etc/ssh/sshd_config
fi
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:low
Strategy:restrict
- name: Disable Host-Based Authentication
  lineinfile:
    create: yes
    dest: /etc/ssh/sshd_config
    regexp: ^HostbasedAuthentication
    line: HostbasedAuthentication no
  tags:
    - disable_host_auth
    - medium_severity
    - restrict_strategy
    - low_complexity
    - low_disruption
    - CCE-27091-8
    - NIST-800-53-AC-3

Disable SSH Access via Empty Passwords   [ref]rule

To explicitly disallow remote login from accounts with empty passwords, add or correct the following line in /etc/ssh/sshd_config:

PermitEmptyPasswords no
Any accounts with empty passwords should be disabled immediately, and PAM configuration should prevent users from being able to assign themselves empty passwords.

Rationale:

Configuring this setting for the SSH daemon provides additional assurance that remote login via SSH will require a password, even in the event of misconfiguration elsewhere.

Severity:  high

Identifiers:  CCE-26887-0, DISA FSO RHEL-06-000239

References:  AC-3, 765, 766

Remediation Shell script:   (show)

grep -q ^PermitEmptyPasswords /etc/ssh/sshd_config && \
  sed -i "s/PermitEmptyPasswords.*/PermitEmptyPasswords no/g" /etc/ssh/sshd_config
if ! [ $? -eq 0 ]; then
    echo "PermitEmptyPasswords no" >> /etc/ssh/sshd_config
fi
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:low
Strategy:restrict
- name: Diable SSH Access via Empty Passwords
  lineinfile:
    create: yes
    dest: /etc/ssh/sshd_config
    regexp: ^PermitEmptyPasswords
    line: PermitEmptyPasswords no
    validate: sshd -t -f %s
  tags:
    - sshd_disable_empty_passwords
    - high_severity
    - restrict_strategy
    - low_complexity
    - low_disruption
    - CCE-26887-0
    - NIST-800-53-AC-3

Enable SSH Warning Banner   [ref]rule

To enable the warning banner and ensure it is consistent across the system, add or correct the following line in /etc/ssh/sshd_config:

Banner /etc/issue
Another section contains information on how to create an appropriate system-wide warning banner.

Rationale:

The warning message reinforces policy awareness during the login process and facilitates possible legal action against attackers. Alternatively, systems whose ownership should not be obvious should ensure usage of a banner that does not provide easy attribution.

Severity:  medium

Identifiers:  CCE-27112-2, DISA FSO RHEL-06-000240

References:  AC-8(a), 48

Remediation Shell script:   (show)

grep -q ^Banner /etc/ssh/sshd_config && \
  sed -i "s/Banner.*/Banner \/etc\/issue/g" /etc/ssh/sshd_config
if ! [ $? -eq 0 ]; then
    echo "Banner /etc/issue" >> /etc/ssh/sshd_config
fi
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:low
Strategy:restrict
- name: Enable SSH Warning Banner
  lineinfile:
    create: yes
    dest: /etc/ssh/sshd_config
    regexp: ^Banner
    line: Banner /etc/issue
    validate: sshd -t -f %s
  tags:
    - sshd_enable_warning_banner
    - medium_severity
    - restrict_strategy
    - low_complexity
    - low_disruption
    - CCE-27112-2
    - NIST-800-53-AC-8(a)

Do Not Allow SSH Environment Options   [ref]rule

To ensure users are not able to present environment options to the SSH daemon, add or correct the following line in /etc/ssh/sshd_config:

PermitUserEnvironment no

Rationale:

SSH environment options potentially allow users to bypass access restriction in some configurations.

Severity:  low

Identifiers:  CCE-27201-3, DISA FSO RHEL-06-000241

References:  1414

Remediation Shell script:   (show)

grep -q ^PermitUserEnvironment /etc/ssh/sshd_config && \
  sed -i "s/PermitUserEnvironment.*/PermitUserEnvironment no/g" /etc/ssh/sshd_config
if ! [ $? -eq 0 ]; then
    echo "PermitUserEnvironment no" >> /etc/ssh/sshd_config
fi
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:low
Strategy:restrict
- name: Do Not Allow SSH Environment Options
  lineinfile:
    create: yes
    dest: /etc/ssh/sshd_config
    regexp: ^PermitUserEnvironment
    line: PermitUserEnvironment no
    validate: sshd -t -f %s
  tags:
    - sshd_do_not_permit_user_env
    - low_severity
    - restrict_strategy
    - low_complexity
    - low_disruption
    - CCE-27201-3

Use Only Approved Ciphers   [ref]rule

Limit the ciphers to those algorithms which are FIPS-approved. Counter (CTR) mode is also preferred over cipher-block chaining (CBC) mode. The following line in /etc/ssh/sshd_config demonstrates use of FIPS-approved ciphers:

Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,3des-cbc,aes192-cbc,aes256-cbc
The man page sshd_config(5) contains a list of supported ciphers.

Rationale:

Approved algorithms should impart some level of confidence in their implementation. These are also required for compliance.

Severity:  medium

Identifiers:  CCE-26555-3, DISA FSO RHEL-06-000243

References:  AC-3, AC-17(2), SI-7, IA-5(1)(c), IA-7, 803, 1144, 1145, 1146

Remediation Shell script:   (show)

grep -q ^Ciphers /etc/ssh/sshd_config && \
  sed -i "s/Ciphers.*/Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,3des-cbc,aes192-cbc,aes256-cbc/g" /etc/ssh/sshd_config
if ! [ $? -eq 0 ]; then
    echo "Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,3des-cbc,aes192-cbc,aes256-cbc" >> /etc/ssh/sshd_config
fi
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:low
Strategy:restrict
- name: Use Only Approved Ciphers
  lineinfile:
    create: yes
    dest: /etc/ssh/sshd_config
    regexp: ^Ciphers
    line: Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,3des-cbc,aes192-cbc,aes256-cbc
    validate: sshd -t -f %s
  #notify: restart sshd
  tags:
    - sshd_use_approved_ciphers
    - medium_severity
    - restrict_strategy
    - low_complexity
    - low_disruption
    - CCE-26555-3
    - NIST-800-53-AC-3
    - NIST-800-53-AC-17(2)
    - NIST-800-53-SI-7
    - NIST-800-53-IA-5(1)(c)
    - NIST-800-53-IA-7

Avahi Server   [ref]group

The Avahi daemon implements the DNS Service Discovery and Multicast DNS protocols, which provide service and host discovery on a network. It allows a system to automatically identify resources on the network, such as printers or web servers. This capability is also known as mDNSresponder and is a major part of Zeroconf networking.

contains 1 rule

Disable Avahi Server if Possible   [ref]group

Because the Avahi daemon service keeps an open network port, it is subject to network attacks. Disabling it can reduce the system's vulnerability to such attacks.

contains 1 rule

Disable Avahi Server Software   [ref]rule

The avahi-daemon service can be disabled with the following command:

$ sudo chkconfig avahi-daemon off

Rationale:

Because the Avahi daemon service keeps an open network port, it is subject to network attacks. Its functionality is convenient but is only appropriate if the local network can be trusted.

Severity:  low

Identifiers:  CCE-27087-6, DISA FSO RHEL-06-000246

References:  CM-7, 366

Remediation Shell script:   (show)

Complexity:low
Disruption:low
Strategy:disable
# Function to enable/disable and start/stop services on RHEL and Fedora systems.
#
# Example Call(s):
#
#     service_command enable bluetooth
#     service_command disable bluetooth.service
#
#     Using xinetd:
#     service_command disable rsh.socket xinetd=rsh
#
function service_command {

# Load function arguments into local variables
local service_state=$1
local service=$2
local xinetd=$(echo $3 | cut -d'=' -f2)

# Check sanity of the input
if [ $# -lt "2" ]
then
  echo "Usage: service_command 'enable/disable' 'service_name.service'"
  echo
  echo "To enable or disable xinetd services add \'xinetd=service_name\'"
  echo "as the last argument"  
  echo "Aborting."
  exit 1
fi

# If systemctl is installed, use systemctl command; otherwise, use the service/chkconfig commands
if [ -f "/usr/bin/systemctl" ] ; then
  service_util="/usr/bin/systemctl"
else
  service_util="/sbin/service"
  chkconfig_util="/sbin/chkconfig"
fi

# If disable is not specified in arg1, set variables to enable services.
# Otherwise, variables are to be set to disable services.
if [ "$service_state" != 'disable' ] ; then
  service_state="enable"
  service_operation="start"
  chkconfig_state="on"
else
  service_state="disable"
  service_operation="stop"
  chkconfig_state="off"
fi

# If chkconfig_util is not empty, use chkconfig/service commands.
if ! [ "x$chkconfig_util" = x ] ; then
  $service_util $service $service_operation
  $chkconfig_util --level 0123456 $service $chkconfig_state
else
  $service_util $service_operation $service
  $service_util $service_state $service
fi

# Test if local variable xinetd is empty using non-bashism.
# If empty, then xinetd is not being used.
if ! [ "x$xinetd" = x ] ; then
  grep -qi disable /etc/xinetd.d/$xinetd && \

  if ! [ "$service_operation" != 'disable' ] ; then
    sed -i "s/disable.*/disable         = no/gI" /etc/xinetd.d/$xinetd
  else
    sed -i "s/disable.*/disable         = yes/gI" /etc/xinetd.d/$xinetd
  fi
fi

}

service_command disable avahi-daemon
Remediation Ansible snippet:   (show)

Complexity:low
Disruption:low
Strategy:disable
- name: "Disable service avahi-daemon"
  service:
    name="{{item}}"
    enabled="no"
    state="stopped"
  with_items:
    - avahi-daemon
  tags:
    - service_avahi-daemon_disabled
    - low_severity
    - disable_strategy
    - low_complexity
    - low_disruption
    - CCE-27087-6
    - NIST-800-53-CM-7

Red Hat and Red Hat Enterprise Linux are either registered trademarks or trademarks of Red Hat, Inc. in the United States and other countries. All other names are registered trademarks or trademarks of their respective companies.