## Guide to the Secure Configuration of Red Hat Enterprise Linux 7

> with profile Standard Docker Host Security Profile
> This profile contains rules to ensure standard security baseline of Red Hat Enterprise Linux 7 system running the docker daemon. This discussion is currently being held on open-scap-list@redhat.com and scap-security-guide@lists.fedorahosted.org.

The SCAP Security Guide Project
https://www.open-scap.org/security-policies/scap-security-guide
This guide presents a catalog of security-relevant configuration settings for Red Hat Enterprise Linux 7. 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 7, which provides required settings for US Department of Defense systems, is one example of a baseline created from this guidance.

This benchmark is a direct port of a SCAP Security Guide benchmark developed for Red Hat Enterprise Linux. It has been modified through an automated process to remove specific dependencies on Red Hat Enterprise Linux and to function with CentOS. The result is a generally useful SCAP Security Guide benchmark with the following caveats:

- CentOS is not an exact copy of Red Hat Enterprise Linux. There may be configuration differences that produce false positives and/or false negatives. If this occurs please file a bug report.
- CentOS has its own build system, compiler options, patchsets, and is a community supported, non-commercial operating system. CentOS does not inherit certifications or evaluations from Red Hat Enterprise Linux. As such, some configuration rules (such as those requiring FIPS 140-2 encryption) will continue to fail on CentOS.

Members of the CentOS community are invited to participate in OpenSCAP and SCAP Security Guide development. Bug reports and patches can be sent to GitHub: https://github.com/OpenSCAP/scap-security-guide. The mailing list is at https://fedorahosted.org/mailman/listinfo/scap-security-guide.

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 Title | Standard Docker Host Security Profile
Profile ID | xccdf_org.ssgproject.content_profile_docker-host

## Revision History

Current version: 0.1.31

- draft (as of 2017-08-11)

## Platforms

- cpe:/o:redhat:enterprise_linux:7
- cpe:/o:centos:centos:7
- cpe:/o:redhat:enterprise_linux:7::client
- cpe:/o:redhat:enterprise_linux:7::computenode

## Table of Contents

1. System Settings

1. SELinux

2. Services

1. Docker Service

## Checklist

contains 6 rules

### System Settings [ref]group

Contains rules that check correct system settings.

contains 4 rules

### 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 7, 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.
For more information on SELinux, see https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/SELinux_Users_and_Administrators_Guide

contains 4 rules

#### Ensure SELinux Not Disabled in /etc/default/grub [ref]rule

SELinux can be disabled at boot time by an argument in `/etc/default/grub`. 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

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

Remediation Shell script: (show)

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

    sed -i --follow-symlinks "s/selinux=0//gI" /etc/default/grub /etc/grub2.cfg /etc/grub.d/*
    sed -i --follow-symlinks "s/enforcing=0//gI" /etc/default/grub /etc/grub2.cfg /etc/grub.d/*

#### 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: high

References: AC-3, AC-3(3), AC-3(4), AC-4, AC-6, AU-9, SI-6(a), 2165, 2696, 1.4.2, SRG-OS-000445-GPOS-00199

Remediation Shell script: (show)

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

    var_selinux_state="enforcing"

    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
        $sed_command "s/$key.*/$formatted_output/g" $config_file
      else
        echo -ne "\n# Per $cce: Set $formatted_output in $config_file" >> $config_file
        echo -ne "\n$formatted_output" >> $config_file
      fi

    }

    replace_or_append '/etc/sysconfig/selinux' '^SELINUX=' $var_selinux_state 'CCE-27334-2' '%s=%s'

#### 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: high

References: AC-3, AC-3(3), AC-3(4), AC-4, AC-6, AU-9, SI-6(a), 2696, 1.4.3, SRG-OS-000445-GPOS-00199

Remediation Shell script: (show)

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

    var_selinux_policy_name="targeted"

    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
        $sed_command "s/$key.*/$formatted_output/g" $config_file
      else
        echo -ne "\n# Per $cce: Set $formatted_output in $config_file" >> $config_file
        echo -ne "\n$formatted_output" >> $config_file
      fi

    }

    replace_or_append '/etc/sysconfig/selinux' '^SELINUXTYPE=' $var_selinux_policy_name 'CCE-27279-9' '%s=%s'

#### Ensure SELinux support is enabled in Docker [ref]rule

To enable the SELinux for the Docker service, the Docker service must be configured to run the Docker daemon with `--selinux-enabled` option. In `/etc/sysconfig/docker` configuration file, add or correct the following line to enable SELinux support in the Docker daemon:

    OPTIONS='--selinux-enabled'

Rationale:

If SELinux is not explicitely enabled in the Docker daemon configuration, Docker does not use SELinux which means Docker runs unconfined, and SELinux will not provide security separation for Docker container processes. However enabling SELinux for the Docker service prevents an attacker or rogue container from attacking other container processes and content as well as prevents taking over the host operating system.

Severity: high

### 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 7 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 7 system and provides guidance about which ones can be safely disabled.
Red Hat Enterprise Linux 7 provides a convenient minimal install option that essentially installs the bare necessities for a functional system. When building Red Hat Enterprise Linux 7 systems, it is highly recommended to select the minimal packages and then build up the system from there.

contains 2 rules

### Docker Service [ref]group

The docker service is necessary to create containers, which are self-sufficient and self-contained applications using the resource isolation features of the kernel.

contains 2 rules

#### Enable the Docker service [ref]rule

The docker service is commonly needed to create containers. The `docker` service can be enabled with the following command:

    $ sudo systemctl enable docker.service

Rationale:

To be able to find any problems with misconfiguration of the docker daemon and running containers, the docker service has to be enabled.

Severity: medium

References: http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-53r4.pdf, http://iase.disa.mil/stigs/cci/Pages/index.aspx, http://iase.disa.mil/stigs/srgs/Pages/index.aspx

#### Use direct-lvm with the Device Mapper Storage Driver [ref]rule

To use Docker in production with the device mapper storage driver, the Docker daemon should be configured to use direct-lvm instead of loopback device as a storage. For setting up the LVM and configuring Docker, see the Docker Device Mapper Storage Documentation.

Rationale:

For using Docker in production, the device mapper storage driver with loopback devices is discouraged. The suggested way of configuring device mapper storage driver is direct-lvm. Choosing the right storage driver and backing filesystem is crucial to stability and performance.

Severity: low

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.