This example security guidance has been created to demonstrate SCAP functionality on Linux.

Applicable platforms

  • cpe:/o:redhat:enterprise_linux:6

Version: 0.2

Revision history

  • draft (as of 2011-10-12)

1. Introduction

The purpose of this guide is to provide security configuration recommendations for the Red Hat Enterprise Linux (RHEL) 6 operating system. The guidance provided here is applicable to desktop systems. Recommended settings for the basic operating system are provided, as well as for many commonly-used services that the system can host in a network environment.

The guide is intended for system administrators. Readers are assumed to possess basic system administration skills for Unix-like systems, as well as some familiarity with Red Hat's documentation and administration conventions. Some instructions within this guide are complex. All directions should be followed completely and with understanding of their effects in order to avoid serious adverse effects on the system and its security.

2. General Principles

The following general principles motivate much of the advice in this guide and should also influence any configuration decisions that are not explicitly covered.

2.1. Encrypt Transmitted Data Whenever Possible

Data transmitted over a network, whether wired or wireless, is susceptible to passive monitoring. Whenever practical solutions for encrypting such data exist, they should be applied. Even if data is expected to be transmitted only over a local network, it should still be encrypted. Encrypting authentication data, such as passwords, is particularly important. Networks of RHEL machines can and should be configured so that no unencrypted authentication data is ever transmitted between machines.

2.2. Minimize Software to Minimize Vulnerability

The simplest way to avoid vulnerabilities in software is to avoid installing that software. On RHEL, the RPM Package Manager (originally Red Hat Package Manager, abbreviated RPM) allows detailed management of the set of software packages installed on a system. Installed software contributes to system vulnerability in several ways. Packages that include setuid programs may provide local attackers a potential path to privilege escalation. Packages that include network services may give this opportunity to network-based attackers. Packages that include programs which are predictably executed by local users (e.g. after graphical login) may provide opportunities for trojan horses or other attack code to be run undetected. The number of software packages installed on a system can almost always be significantly pruned to include only the software for which there is an environmental or operational need.

2.3. Run Different Network Services on Separate Systems

Whenever possible, a server should be dedicated to serving exactly one network service. This limits the number of other services that can be compromised in the event that an attacker is able to successfully exploit a software flaw in one network service.

2.4. Configure Security Tools to Improve System Robustness

Several tools exist which can be effectively used to improve a system's resistance to and detection of unknown attacks. These tools can improve robustness against attack at the cost of relatively little configuration effort. In particular, this guide recommends and discusses the use of Iptables for host-based firewalling, SELinux for protection against vulnerable services, and a logging and auditing infrastructure for detection of problems.

2.5. Least Privilege

Grant the least privilege necessary for user accounts and software to perform tasks. For example, do not allow users except those that need administrator access to use sudo. Another example is to limit logins on server systems to only those administrators who need to log into them in order to perform administration tasks. Using SELinux also follows the principle of least privilege: SELinux policy can confine software to perform only actions on the system that are specifically allowed. This can be far more restrictive than the actions permissible by the traditional Unix permissions model.

3. System-wide Configuration

Table of Contents

3.1. Installing and Maintaining Software

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

3.1.1. Initial Installation Recommendations

The recommendations here apply to a clean installation of the system, where any previous installations are wiped out. The sections presented here are in the same order that the installer presents, but only installation choices with security implications are covered. Many of the configuration choices presented here can also be applied after the system is installed. The choices can also be automatically applied via Kickstart files.

3.1.1.1. Disk Partitioning

Some system directories should be placed on their own partitions (or logical volumes). This allows for better separation and protection of data.
The installer’s default partitioning scheme creates separate partitions (or 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.

3.1.1.1.1. Create Separate Partition or Logical Volume for /tmp

The /tmp directory is a world-writable directory used for temporary file storage. Ensure that it has its own partition or logical volume.

Because software may need to use /tmp to temporarily store large files, ensure that it is of adequate size. For a modern, general-purpose system, 10GB should be adequate. Smaller or larger sizes could be used, depending on the availability of space on the drive and the system’s operating requirements

3.1.1.1.1.a. Ensure that /tmp has its own partition or logical volume

The /tmp directory is a world-writable directory used for temporary file storage. Ensure that it has its own partition or logical volume.

Security identifiers

  • CCE-14161-4

3.1.1.1.2. Create Separate Partition or Logical Volume for /var

The /var directory is used by daemons and other system services to store frequently-changing data. It is not uncommon for the /var directory to contain world-writable directories, installed by other software packages. Ensure that /var has its own partition or logical volume.

Because the yum package manager and other software uses /var to temporarily store large files, ensure that it is of adequate size. For a modern, general-purpose system, 10GB should be adequate.

3.1.1.1.2.a. Ensure that /var has its own partition or logical volume

The /var directory is used by daemons and other system services to store frequently-changing data. It is not uncommon for the /var directory to contain world-writable directories, installed by other software packages. Ensure that /var has its own partition or logical volume.

Security identifiers

  • CCE-14777-7

3.1.1.1.3. Create Separate Partition or Logical Volume for /var/log

System logs are stored in the /var/log directory. Ensure that it has its own partition or logical volume.
See 2.6 for more information about logging and auditing.

3.1.1.1.3.a. Ensure that /var/log has its own partition or logical volume

System logs are stored in the /var/log directory. Ensure that it has its own partition or logical volume.

Security identifiers

  • CCE-14011-1

3.1.1.1.4. Create Separate Partition or Logical Volume for /var/log/audit

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

3.1.1.1.4.a. Ensure that /var/log/audit has its own partition or logical volume

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

Security identifiers

  • CCE-14171-3

3.1.1.1.5. Create Separate Partition or Logical Volume for /home if Using Local Home Directories

If user home directories will be stored locally, create a separate partition for /home. If /home will be mounted from another system such as an NFS server, then creating a separate partition is not necessary at this time, and the mountpoint can instead be configured later.

3.1.1.1.5.a. Ensure that /home has its own partition or logical volume

If user home directories will be stored locally, create a separate partition for /home. If /home will be mounted from another system such as an NFS server, then creating a separate partition is not necessary at this time, and the mountpoint can instead be configured later.

Security identifiers

  • CCE-14559-9

3.1.1.2. Boot Loader Configuration

Check the box to "Use a boot loader password" and create a password. Once this password is set, anyone who wishes to change the boot loader configuration will need to enter it. Assigning a boot loader password prevents a local user with physical access from altering the boot loader configuration at system startup.

3.1.1.3. First-boot Configuration

The system presents more configuration options during the first boot after installation. For the screens listed, implement the security-related recommendations:

  • Set Up Software Updates - If the system is connected to the Internet now, click 'Yes, I'd like to register now.' This will require a connection to either the Red Hat Network servers or their proxies or satellites.

  • Create User - If the system will require a local user account, it can be created here. Even if the system will be using a network-wide authentication system, do not click on the 'Use Network Login...' button. Manually applying configuration later is preferable.

  • Kdump - Leave Kdump off unless the feature is required, such as for kernel development and testing.

  • Firewall - Leave set to 'Enabled.' Only check the 'Trusted Services' that this system needs to serve. Uncheck the default selection of SSH if the system does not need to serve SSH.

  • SELinux - Leave SELinux set to 'Enforcing' mode.

3.1.2. Updating Software

The yum command line tool is used to install and update software packages. Yum replaces the up2date utility used in previous system releases. The system also provides PackageKit, which is a graphical package manager. It consists of several graphical interfaces that can be opened from the GNOME panel menu, or from the Notification Area when PackageKit alerts you that updates are available.
It is recommended that these tools be used to keep systems up to date with the latest security patches.

3.1.2.1. Ensure Red Hat GPG Keys are Installed

To ensure that the system can cryptographically verify update packages (and also connect to the Red Hat Network to receive them if desired) run the following command to ensure that the system has the Red Hat GPG keys properly installed:

$ rpm -q gpg-pubkey

The command should return the strings:

gpg-pubkey-fd431d51-4ae0493b
gpg-pubkey-2fa658e0-45700c69
corresponding to these keys:
gpg(Red Hat, Inc. (release key 2) <security@redhat.com>)
gpg(Red Hat, Inc. (auxiliary key) <security@redhat.com>)

3.1.2.1.a. Red Hat GPG Keys are Installed

The GPG keys should be installed.

Security identifiers

  • CCE-14440-2

3.1.2.2. Configure Connection to the RHN RPM Repositories

The first step in configuring a system for updates is to register with the Red Hat Network (RHN). For most systems, this is done during the initial installation. Successfully registered systems will appear on the RHN web site. If the system is not listed, run the Red Hat Subscription Manager tool, which can be found in the System => Administration menu in the top management bar. or on the command line:

# subscription-manager register --username admin-example --password secret

Follow the prompts on the screen. If successful, the system will appear on the RHN web site and be subscribed to one or more software update channels. Additionally, a new daemon, rhnsd, will be enabled.

If the system will not have access to the Internet, it will not be able to directly subscribe to the RHN update repository. Updates will have to be downloaded from the RHN web site manually. The command line tool yum and the graphical front-end PackageKit can be configured to handle this situation.

3.1.2.3. Disable the rhnsd Daemon

The rhnsd daemon polls the Red Hat Network web site for scheduled actions. Unless it is actually necessary to schedule updates remotely through the RHN website, it is recommended that the service be disabled.

The rhnsd daemon is enabled by default, but until the system has been registered with the Red Hat Network, it will not run. However, once the registration process is complete, the rhnsd daemon will run in the background and periodically call the rhn check utility. It is the rhn check utility that communicates with the Red Hat Network web site.

This utility is not required for the system to be able to access and install system updates. Once the system has been registered, either use the provided yum-updatesd service or create a cron job to automatically apply updates.

3.1.2.3.a. Disable the rhnsd Daemon

The rhnsd service should be disabled.

Security identifiers

  • CCE-3416-5

3.1.2.4. Obtain Software Package Updates with yum

The yum update utility can be run by hand from the command line, called through one of the provided front-end tools, or configured to run automatically at specified intervals.

3.1.2.4.1. Manually Update Packages Where Appropriate

The following command prints a list of packages that need to be updated:

# yum check-update

To actually install these updates, run:

# yum update

3.1.2.4.2. Configure Automatic Update Retrieval and Installation with Cron

Create the file yum.cron, make it executable, and place it in /etc/cron.daily:

#!/bin/sh
/usr/bin/yum -R 120 -e 0 -d 0 -y update yum
/usr/bin/yum -R 10 -e 0 -d 0 -y update

This particular script instructs yum to update any packages it finds. Placing the script in /etc/cron.daily ensures its daily execution. To only apply updates once a week, place the script in /etc/cron.weekly instead.

3.1.2.4.3. Ensure Package Signature Checking is Globally Activated

The gpgcheck option should be used to ensure that checking of an RPM package’s signature always occurs prior to its installation.

To force yum to check package signatures before installing them, ensure that the following line appears in /etc/yum.conf in the [main] section:

gpgcheck=1

3.1.2.4.3.a. gpgcheck is Globally Activated

The gpgcheck option should be used to ensure that checking of an RPM package’s signature always occurs prior to its installation.

To force yum to check package signatures before installing them, ensure that the following line appears in /etc/yum.conf in the [main] section:

gpgcheck=1

Security identifiers

  • CCE-14914-6

3.1.2.4.4. Ensure Package Signature Checking is Not Disabled For Any Repos

To ensure that signature checking is not disabled for any repos, ensure that the following line DOES NOT appear in any repo configuration files in /etc/yum.repos.d or elsewhere:

gpgcheck=0

3.1.2.4.4.a. Package Signature Checking is Not Disabled For Any Repos

To ensure that signature checking is not disabled for any repos, ensure that the following line DOES NOT appear in any repo configuration files in /etc/yum.repos.d or elsewhere:

gpgcheck=0

Security identifiers

  • CCE-14813-0

3.1.2.4.5. Ensure Repodata Signature Checking is Globally Activated

The repo_gpgcheck option should be used to ensure that checking of a signature on repodata is performed prior to using it.

To force yum to check the signature on repodata sent by a repository prior to using it, ensure that the following line appears in /etc/yum.conf in the [main] section:

repo_gpgcheck=1

3.1.2.4.6. Ensure Repodata Signature Checking is Not Disabled For Any Repos

To ensure that signature checking is not disabled for any repos, ensure that the following line DOES NOT appear in any repo configuration files in /etc/yum.repos.d or elsewhere:

repo_gpgcheck=0

Note: Red Hat’s repositories support signatures on repodata, but some public repositories do not. If a repository does not support signature checking on repodata, then this risk must be weighed against the value of using the repository.

3.1.3. Software Integrity Checking

Integrity checking cannot prevent intrusions into your system, but can detect that they have occurred. Any integrity checking software should be configured before the system is deployed and able to provides services to users. Ideally, the integrity checking database would be built before the system is connected to any network, though this may prove impractical due to registration and software updates.

3.1.3.1. Verify Package Integrity Using RPM

The RPM package management system includes the ability to verify the integrity of installed packages by comparing the installed files with information about the files taken from the package metadata stored in the RPM database. Although an attacker could corrupt the RPM database (analogous to attacking the AIDE database as described above), this check can still reveal modification of important files.

To determine which files on the system differ from what is expected by the RPM database:

# rpm -Va

A “c” in the second column indicates that a file is a configuration file (and may be expected to change). In order to exclude configuration files from this list, run:

# rpm -Va | awk '$2!="c" {print $0}'

The man page rpm(8) describes the format of the output. Any files that do not match the expected output demand further investigation if the system is being seriously examined. This check could also be run as a cron job.

3.1.3.1.a. Package Integrity is correct according to package management system

Verify the integrity of installed packages by comparing the installed files with information about the files taken from the package metadata stored in the RPM database.

Security identifiers

  • CCE-14931-0

3.2. File Permissions and Masks

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. Adhere to the principle of least privilege — configure each file, directory, and filesystem to allow only the access needed in order for that file to serve its purpose.

However, Linux systems contain a large number of files, so it is often prohibitively time-consuming to ensure that every file on a machine has exactly the permissions needed. This section introduces several permission restrictions which are almost always appropriate for system security, and which are easy to test and correct.

Note: 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 ext2, ext3 or ext4 partition on a given machine. 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 ext2, ext3 and ext4 partitions on a given machine:

$ mount -t ext2,ext3,ext4 | awk '{print $3}'

If your site uses a local filesystem type other than those, you will need to modify this command.

3.2.1. Verify Permissions on Important Files and Directories

Permissions for many files on a system should be set to conform to system policy. This section discusses important permission restrictions which should be checked on a regular basis to ensure that no harmful discrepancies have arisen.

3.2.1.1. Verify Permissions on passwd, shadow, group and gshadow Files

Many utilities need read access to the passwd file in order to function properly, but read access to the shadow file allows malicious attacks against system passwords, and should never be enabled.

3.2.1.1.a. User ownership of 'shadow' file

The /etc/shadow file should be owned by root.

Security identifiers

  • CCE-3918-0

3.2.1.1.b. Group ownership of 'shadow' file

The /etc/shadow file should be owned by root.

Security identifiers

  • CCE-3988-3

3.2.1.1.c. User ownership of 'group' file

The /etc/group file should be owned by root.

Security identifiers

  • CCE-3276-3

3.2.1.1.d. Group ownership of 'group' file

The /etc/group file should be owned by root.

Security identifiers

  • CCE-3883-6

3.2.1.1.e. User ownership of 'gshadow' file

The /etc/gshadow file should be owned by root.

Security identifiers

  • CCE-4210-1

3.2.1.1.f. Group ownership of 'gshadow' file

The /etc/gshadow file should be owned by root.

Security identifiers

  • CCE-4064-2

3.2.1.1.g. User ownership of 'passwd' file

The /etc/passwd file should be owned by root.

Security identifiers

  • CCE-3958-6

3.2.1.1.h. Group ownership of 'passwd' file

The /etc/passwd file should be owned by root.

Security identifiers

  • CCE-3495-9

3.2.1.1.i. Permissions on 'shadow' file

File permissions for /etc/shadow should be set correctly.

Security identifiers

  • CCE-4130-1

3.2.1.1.j. Permissions on 'group' file

File permissions for /etc/group should be set correctly.

Security identifiers

  • CCE-3967-7

3.2.1.1.k. Permissions on 'gshadow' file

File permissions for /etc/gshadow should be set correctly.

Security identifiers

  • CCE-3932-1

3.2.1.1.l. Permissions on 'passwd' file

File permissions for /etc/passwd should be set correctly.

Security identifiers

  • CCE-3566-7

3.2.1.2. Verify that All World-Writable Directories Have Sticky Bits Set

When the so-called 'sticky bit' is set on a directory, only the owner of a given file may remove that file from the directory. Without the sticky bit, any user with write access to a directory may remove any file in the directory. Setting the sticky bit prevents users from removing each other's files. In cases where there is no reason for a directory to be world-writable, a better solution is to remove that permission rather than to set the sticky bit. However, if a directory is used by a particular application, consult that application's documentation instead of blindly changing modes.

3.2.1.2.a. All World-Writable Directories Have Sticky Bits Set

The sticky bit should be set for all world-writable directories.

Security identifiers

  • CCE-3399-3

3.2.1.3. Find Unauthorized World-Writable Files

Data in world-writable files can be modified by any user on the system. In almost all circumstances, files can be configured using a combination of user and group permissions to support whatever legitimate access is needed without the risk caused by world-writable files.

It is generally a good idea to remove global (other) write access to a file when it is discovered. However, check with documentation for specific applications before making changes. Also, monitor for recurring world-writable files, as these may be symptoms of a misconfigured application or user account.

3.2.1.3.a. Unauthorized World-Writable Files

The world-write permission should be disabled for all files.

Security identifiers

  • CCE-3795-2

3.2.1.4. Find Unauthorized SUID/SGID System Executables

The following command discovers and prints any setuid or setgid files on local partitions. Run it once for each local partition:

find PART -xdev \( -perm -4000 -o -perm -2000 \) -type f -print

If the file does not require a setuid or setgid bit, then these bits can be removed with the command:

chmod -s file

The following table contains all setuid and setgid files which are expected to be on a stock system. To reduce system risk, the packages containing these files may be removed in some cases; alternatively, the setuid or setgid bit on these files may be disabled to reduce system risk if only an administrator requires their functionality.

File Set-UID Set-GID
/bin/cgexec - cgred
/bin/fusermount root -
/bin/mount root -
/bin/ping6 root -
/bin/ping root -
/bin/su root -
/bin/umount root -
/lib64/dbus-1/dbus-daemon-launch-helper root -
/lib/dbus-1/dbus-daemon-launch-helper root -
/sbin/mount.ecryptfs_private root -
/sbin/mount.nfs root -
/sbin/netreport - root
/sbin/pam_timestamp_check root -
/sbin/unix_chkpwd root -
/usr/bin/at root -
/usr/bin/chage root -
/usr/bin/chfn root -
/usr/bin/chsh root -
/usr/bin/crontab root root
/usr/bin/gnomine - games
/usr/bin/gpasswd root -
/usr/bin/iagno - games
/usr/bin/kgrantpty root -
/usr/bin/kpac_dhcp_helper root -
/usr/bin/ksu root -
/usr/bin/locate - slocate
/usr/bin/lockfile - mail
/usr/bin/newgrp root -
/usr/bin/newrole root -
/usr/bin/passwd root -
/usr/bin/pkexec root -
/usr/bin/rcp root -
/usr/bin/rlogin root -
/usr/bin/rsh root -
/usr/bin/same-gnome - games
/usr/bin/screen - screen
/usr/bin/sperl5.10.1 root -
/usr/bin/ssh-agent - nobody
/usr/bin/staprun root -
/usr/bin/sudoedit root -
/usr/bin/sudo root -
/usr/bin/wall - tty
/usr/bin/write - tty
/usr/bin/Xorg root -
/usr/lib64/amanda/calcsize root -
/usr/lib64/amanda/dumper root -
/usr/lib64/amanda/killpgrp root -
/usr/lib64/amanda/planner root -
/usr/lib64/amanda/rundump root -
/usr/lib64/amanda/runtar root -
/usr/lib64/nspluginwrapper/plugin-config root -
/usr/lib64/vte/gnome-pty-helper - utmp
/usr/lib/amanda/calcsize root -
/usr/lib/amanda/dumper root -
/usr/lib/amanda/killpgrp root -
/usr/lib/amanda/planner root -
/usr/lib/amanda/rundump root -
/usr/lib/amanda/runtar root -
/usr/libexec/kde4/kdesud - root
/usr/libexec/mc/cons.saver vcsa -
/usr/libexec/openssh/ssh-keysign root -
/usr/libexec/polkit-1/polkit-agent-helper-1 root -
/usr/libexec/pt_chown root -
/usr/libexec/pulse/proximity-helper root -
/usr/libexec/utempter/utempter - utmp
/usr/lib/mailman/cgi-bin/admindb - mailman
/usr/lib/mailman/cgi-bin/admin - mailman
/usr/lib/mailman/cgi-bin/confirm - mailman
/usr/lib/mailman/cgi-bin/create - mailman
/usr/lib/mailman/cgi-bin/edithtml - mailman
/usr/lib/mailman/cgi-bin/listinfo - mailman
/usr/lib/mailman/cgi-bin/options - mailman
/usr/lib/mailman/cgi-bin/private - mailman
/usr/lib/mailman/cgi-bin/rmlist - mailman
/usr/lib/mailman/cgi-bin/roster - mailman
/usr/lib/mailman/cgi-bin/subscribe - mailman
/usr/lib/mailman/mail/mailman - mailman
/usr/lib/nspluginwrapper/plugin-config root -
/usr/lib/vte/gnome-pty-helper - utmp
/usr/sbin/amcheck root -
/usr/sbin/lockdev - lock
/usr/sbin/postdrop - postdrop
/usr/sbin/postqueue - postdrop
/usr/sbin/sendmail.sendmail - smmsp
/usr/sbin/seunshare root -
/usr/sbin/suexec root -
/usr/sbin/userhelper root -
/usr/sbin/usernetctl root -

3.2.1.4.a. Unauthorized SGID System Executables

The sgid bit should not be set for all files.

Security identifiers

  • CCE-14340-4

3.2.1.4.b. Unauthorized SUID System Executables

The suid bit should not be set for all files.

Security identifiers

  • CCE-14340-4

3.2.1.5. Find and Repair Unowned Files

The following command will discover and print any files on local partitions which do not belong to a valid user and a valid group. Run it once for each local partition PART:

# find PART -xdev \( -nouser -o -nogroup \) -print

If this command prints any results, investigate each reported file and either assign it to an appropriate user and group or remove it. Unowned files are not directly exploitable, but they are generally a sign that something is wrong with some system process. They may be caused by an intruder, by incorrect software installation or draft software removal, or by failure to remove all files belonging to a deleted account. The files should be repaired so that they will not cause problems when accounts are created in the future, and the problem which led to unowned files should be discovered and addressed.

3.2.1.5.a. Files unowned by any user

All files should be owned by a user

Security identifiers

  • CCE-4223-4

3.2.1.5.b. Files unowned by any group

All files should be owned by a group

Security identifiers

  • CCE-3573-3

3.2.1.6. Verify that All World-Writable Directories Have Proper Ownership

Locate any directories in local partitions which are world-writable and ensure that they are owned by root or another system account. The following command will discover and print these (assuming only system accounts have a uid lower than 500). Run it once for each local partition PART:

# find PART -xdev -type d -perm -0002 -uid +500 -print

If this command produces any output, investigate why the current owner is not root or another system account.

Allowing a user account to own a world-writeable directory is undesirable because it allows the owner of that directory to remove or replace any files that may be placed in the directory by other users.

3.2.1.6.a. World writable directories not owned by a system account

All world writable directories should be owned by a system user

Security identifiers

  • CCE-14794-2

3.2.2. Restrict Programs from Dangerous Execution Patterns

The recommendations in this section provide broad protection against information disclosure or other misbehavior. These protections are applied at the system initialization or kernel level, and defend against certain types of badly-configured or compromised programs.

3.2.2.1. Set Daemon umask

The file /etc/rc.d/init.d/functions which is used by most or all shell scripts in the /etc/init.d directory, set an umask. The system umask must be set to at least 022, or daemon processes may create world-writable files. The more restrictive setting 027 protects files, including temporary files and log files, from unauthorized reading by unprivileged users on the system.

If a particular daemon needs a less restrictive umask, consider editing the startup script or sysconfig file of that daemon to make a specific exception.

3.2.2.1.a. Daemon umask setting

The daemon umask should be set as appropriate

Security identifiers

  • CCE-4220-0

3.2.2.2. Disable Core Dumps

A core dump file is the memory image of an executable program when it was terminated by the operating system due to errant behavior. In most cases, only software developers would legitimately need to access these files. The core dump files may also contain sensitive information, or unnecessarily occupy large amounts of disk space.

By default, the system sets a soft limit to stop the creation of core dump files for all users. However, compliance with this limit is voluntary; it is a default intended only to protect users from the annoyance of generating unwanted core files. Users can increase the allowed core file size up to the hard limit, which is unlimited by default. Once a hard limit is set in /etc/security/limits.conf,

* hard core 0

the user cannot increase that limit within his own session. If access to core dumps is required, consider restricting them to only certain users or groups. See the limits.conf man page for more information.

3.2.2.2.a. Disable Core Dumps for all users

Core dumps for all users should be disabled

Security identifiers

  • CCE-4225-9

3.2.2.3. Ensure SUID Core Dumps are Disabled

The sysctl variable fs.suid_dumpable controls whether the kernel allows core dumps from these programs at all. It should be checked to ensure that it has not been enabled at any time during system operation. To check this, issue the command:

# sysctl fs.suid_dumpable

The output should indicate that the setting is 0. (Use of the -n option causes output to consist of only the value, which may make automated checking easier.)

3.2.2.3.a. Disable Core Dumps for SUID programs

Core dumps for setuid programs should be disabled

Security identifiers

  • CCE-4247-3

3.2.2.4. Enable ExecShield

ExecShield comprises a number of kernel features to provide protection against 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. This protection is enabled by default, but the sysctl variables kernel.exec-shield and kernel.randomize va space should be checked to ensure that it has not been disabled.

To check that ExecShield (including random placement of virtual memory regions) is currently running, issue the following commands:

# sysctl kernel.exec-shield
# sysctl kernel.randomize_va_space

The output should indicate that the setting of kernel.exec-shield is 1 and the setting of kernel.randomize_va_space is 2. (Use of the -n option causes output to consist of only the value, which may make automated checking easier.)

3.2.2.4.a. ExecShield is enabled (runtime)

ExecShield should be enabled

Security identifiers

  • CCE-4168-1

3.2.2.4.b. ExecShield randomized placement of virtual memory regions is enabled (runtime)

ExecShield randomized placement of virtual memory regions should be enabled

Security identifiers

  • CCE-4146-7

3.3. Account and Access Control

In traditional Unix security, if an attacker gains shell access to a certain login account, he 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..

3.3.1. Protect Accounts by Restricting Password-Based Login

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.

3.3.1.1. Restrict Root Logins to System Console

Edit the file /etc/securetty. Ensure that the file contains only the following lines:

  • The primary system console device:
    console

  • The virtual console devices:
    tty1 tty2 tty3 tty4 tty5 tty6 ...

  • If required by your organization, the deprecated virtual console interface may be retained for backwards compatibility:
    vc/1 vc/2 vc/3 vc/4 vc/5 vc/6 ...

  • If required by your organization, the serial consoles may be added:
    ttyS0 ttyS1

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 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 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.

3.3.1.1.a. Root logins to virtual console are not permited

Root logins through the virtual console devices should be disabled

Security identifiers

  • CCE-3485-0

3.3.1.1.b. Root logins to serial ports are not permited

Root logins on serial ports should be disabled.

Security identifiers

  • CCE-4256-4

3.3.1.2. Configure su to Restrict the Root Access

  1. Ensure that the group wheel exists, and that the usernames of all administrators who should be allowed to execute commands as root are members of that group.

    # grep ^wheel /etc/group

  2. Edit the file /etc/pam.d/su. Add, uncomment, or correct the line:
    auth required pam_wheel.so use_uid

The su command allows a user to gain the privileges of another user by entering the password for that user's account. It is desirable to restrict the root user so that only known administrators are ever allowed to access the root account. This restricts password-guessing against the root account by unauthorized users or by accounts which have been compromised.

By convention, the group wheel contains all users who are allowed to run privileged commands. The PAM module pam_wheel.so is used to restrict root access to this set of users.

3.3.1.2.a. The 'wheel' group should exist

Ensure that the group wheel exists

Security identifiers

  • CCE-14088-9

3.3.1.2.b. Access to the root account via su is restricted to the wheel group

Command access to the root account should be restricted to the wheel group.

Security identifiers

  • CCE-15047-4

3.3.1.3. Configure sudo to Improve Auditing of Root Access

  1. Ensure that the group wheel exists, and that the usernames of all administrators who should be allowed to execute commands as root are members of that group.

    # grep ^wheel /etc/group

  2. Edit the file /etc/sudoers. Add, uncomment, or correct the line:

    %wheel ALL=(ALL) ALL


The sudo command allows fine-grained control over which users can execute commands using other accounts. The primary benefit of sudo when configured as above is that it provides an audit trail of every command run by a privileged user. It is possible for a malicious administrator to circumvent this restriction, but, if there is an established procedure that all root commands are run using sudo, then it is easy for an auditor to detect unusual behavior when this procedure is not followed.

Editing /etc/sudoers by hand can be dangerous, since a configuration error may make it impossible to access the root account remotely. The recommended means of editing this file is using the visudo command, which checks the file's syntax for correctness before allowing it to be saved.

Note that sudo allows any attacker who gains access to the password of an administrator account to run commands as root. This is a downside which must be weighed against the benefits of increased audit capability and of being able to heavily restrict the use of the high-value root password (which can be logistically difficult to change often). As a basic precaution, never use the NOPASSWD directive, which would allow anyone with access to an administrator account to execute commands as root without knowing the administrator's password.

The sudo command has many options which can be used to further customize its behavior. See the sudoers(5) man page for details.

3.3.1.4. Block Shell and Login Access for Non-Root System Accounts

Using /etc/passwd, obtain a listing of all users, their UIDs, and their shells, for instance by running:

# awk -F: '{print $1 ":" $3 ":" $7}' /etc/passwd

Identify the system accounts from this listing. These will primarily be the accounts with UID numbers less than 500, other than root.

For each identified system account SYSACCT , lock the account:

# usermod -L SYSACCT
and disable its shell:

# usermod -s /sbin/nologin SYSACCT

These are the accounts which are not associated with a human user of the system, but which exist to perform some administrative function. Make it more difficult for an attacker to use these accounts by locking their passwords and by setting their shells to some non-valid shell. The default non-valid shell is /sbin/nologin, but any command which will exit with a failure status and disallow execution of any further commands, such as /bin/false or /dev/null, will work.

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

3.3.1.4.a. Login Access for Non-Root System Accounts is blocked

Login access to non-root system accounts should be disabled

Security identifiers

  • CCE-3987-5

3.3.1.5. Verify that No Accounts Have Empty Password Fields

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

Run the command:

# awk -F: '($2 == "") {print}' /etc/shadow

If this produces any output, fix the problem by locking each account or by setting a password.

3.3.1.5.a. No Accounts Have Empty Password Fields

Login access to accounts without passwords should be disabled

Security identifiers

  • CCE-4238-2

3.3.1.6. Verify that All Account Password Hashes are Shadowed

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.

To ensure that no password hashes are stored in /etc/passwd, the following command should have no output:

# awk -F: '($2 != "x") {print}' /etc/passwd

3.3.1.6.a. All Account Password Hashes are Shadowed

Check that passwords are shadowed

Security identifiers

  • CCE-14300-8

3.3.1.7. Verify that No Non-Root Accounts Have UID 0

In general, the best practice solution for auditing use of the root account is to restrict the set of cases in which root must be accessed anonymously by requiring use of su or sudo in almost all cases. Some sites choose to have more than one account with UID 0 in order to differentiate between administrators, but this practice may have unexpected side effects, and is therefore not recommended.

This command will print all password file entries for accounts with UID 0:

# awk -F: '($3 == "0") {print}' /etc/passwd

This should print only one line, for the user root. If any other lines appear, ensure that these additional UID-0 accounts are authorized, and that there is a good reason for them to exist.

3.3.1.7.a. No Non-Root Accounts Have UID 0

Anonymous root logins should be disabled

Security identifiers

  • CCE-4009-7

3.3.1.8. Set Password Expiration Parameters

Edit the file /etc/login.defs to specify password expiration settings for new accounts. Add or correct the following lines:

PASS_MAX_DAYS=180
PASS_MIN_DAYS=7
PASS_WARN_AGE=7

For each existing human user USER , modify the current expiration settings to match these:

# chage -M 180 -m 7 -W 7 USER

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.

3.3.1.8.a. Minimum password age

The minimum password age should be set appropriately

Security identifiers

  • CCE-4180-6

3.3.1.8.b. Maximum password age

The maximum password age should be set to: 180

Security identifiers

  • CCE-4092-3

3.3.1.8.c. Password warn age

The password warn age should be set to: 7

Security identifiers

  • CCE-4097-2

3.3.2. Protect Accounts by Configuring PAM

PAM, or Pluggable Authentication Modules, is a system which implements modular authentication for Linux programs. PAM is well-integrated into Linux's authentication architecture, making it difficult to remove, but it can be configured to minimize your system's exposure to unnecessary risk. This section contains guidance on how to accomplish that, and how to ensure that the modules used by your PAM configuration do what they are supposed to do.

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. 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. Another important file is password-auth. It contains just the same things as system-auth except modules that make sense only for local services are removed (used for sshd for example)

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.

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. The 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.

3.3.2.1. Set Password Quality Requirements

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 pam_passwdqc PAM module provides the ability to enforce even more stringent password strength requirements. It is provided in an RPM of the same name.

The man pages pam_cracklib(8) and pam_passwdqc(8) provide information on the capabilities and configuration of each.

3.3.2.1.1. Password Quality Requirements Set By pam_cracklib module

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.

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 and /etc/pam.d/password-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 minlen=14 dcredit=-1 ucredit=-1 ocredit=-1 lcredit=0

If necessary, modify the arguments to ensure compliance with your organization’s security policy.

The man page pam_cracklib(8) provide information on the capabilities and configuration.

Note that the password quality requirements are not enforced for the root account for some reason.

3.3.2.1.1.a. Password retry Requirements

The password retry should meet minimum requirements

Security identifiers

  • CCE-15054-0

3.3.2.1.1.b. Password minlen Requirements

The password minlen should meet minimum requirements

3.3.2.1.1.c. The password strength parameters should require a minimum number of digits

The password dcredit should meet minimum requirements

Security identifiers

  • CCE-14113-5

3.3.2.1.1.d. The password strength parameters should require a minimum number of uppercase characters

The password ucredit should meet minimum requirements

Security identifiers

  • CCE-14672-0

3.3.2.1.1.e. The password strength parameters should require a minimum number of special characters

The password strength parameters should require a minimum number of special characters

Security identifiers

  • CCE-14122-6

3.3.2.1.1.f. Set Password lcredit Requirements

The password strength parameters should require a minimum number of lowercase characters

Security identifiers

  • CCE-14712-4

3.3.2.1.1.g. The password strength parameters should require new passwords to difer from old ones by a minimum number of characters

The password difok should meet minimum requirements

Security identifiers

  • CCE-14701-7

3.3.2.1.2. Set Password Quality Requirements, if using pam_passwdqc

If password strength stronger than that guaranteed by pam_cracklib is required, configure PAM to use pam_passwdqc.

To activate pam_passwdqc, locate the following line in /etc/pam.d/system-auth:

password requisite pam_cracklib.so try_first_pass retry=3

and then replace it with the line:

password requisite pam_passwdqc.so min=disabled,disabled,16,12,8

If necessary, modify the arguments (min=disabled,disabled,16,12,8) to ensure compliance with your organization’s security policy. Configuration options are described in the man page pam_passwdqc(8) and also in /usr/share/doc/pam_passwdqc-version. The minimum lengths provided here supercede that specified by the argument PASS_MIN_LEN in login.defs.

The options given in the example above set a minimum length for each of the password “classes” that pam_passwdqc recognizes. Setting a particular minimum value to disabled will stop users from choosing a password that falls into that category alone.

3.3.2.1.2.a. The password strength parameters should be configured using pam_passwdqc

pam_passwdqc "min" should be configured as described by the policy

3.3.2.2. Set Lockouts for Failed Password Attempts

The pam_tally2 PAM module provides the capability to lock out user accounts after a number of failed login attempts. Its documentation is available in the man page pam_tally2(8).

If locking out accounts after a number of incorrect login attempts is required by your security policy, implement use of pam_tally2.so for the relevant PAM-aware programs such as login, sshd, and vsftpd.

Find the following line in /etc/pam.d/system-auth:

auth sufficient pam_unix.so nullok try_first_pass

and then change it so that it reads as follows:

auth required pam_unix.so nullok try_first_pass

In the same file, comment out or delete the lines:

auth requisite pam_succeed_if.so uid >= 500 quiet
auth required pam_deny.so
After changing /etc/pam.d/system-auth as described above, perform the same set of changes in /etc/pam.d/password-auth as well.
To enforce password lockout, add the following to the individual programs' configuration files in /etc/pam.d. First, add to end of the auth lines:

auth required pam_tally2.so deny=5 onerr=fail

Second, add to the end of the account lines:

account required pam_tally2.so

Adjust the deny argument to conform to your system security policy. The pam_tally2 utility can be used to unlock user accounts as follows:

# /sbin/pam_tally2 --user username --reset

Locking out user accounts presents the risk of a denial-of-service attack. The security policy regarding system lockout must weigh whether the risk of such a denial-of-service attack outweighs the benefits of thwarting password guessing attacks. The pam_tally2 utility can be run from a cron job on a hourly or daily basis to try and offset this risk.

3.3.2.3. Use pam_deny.so to Quickly Deny Access to a Service

In order to deny access to a service SVCNAME via PAM, edit the file /etc/pam.d/SVCNAME . Prepend this line to the beginning of the file:

auth requisite pam_deny.so

Under most circumstances, there are better ways to disable a service than to deny access via PAM. However, this should suffice as a way to quickly make a service unavailable to future users (existing sessions which have already been authenticated, are not affected). The requisite tag tells PAM that, if the named module returns failure, authentication should fail, and PAM should immediately stop processing the configuration file. The pam_deny.so module always returns failure regardless of its input.

3.3.2.4. Ensure the Password Hashing Algorithm is SHA-512

The default algorithm for storing password hashes in /etc/shadow is SHA-512, but a weaker algorithm could have been configured.

In order to configure the system to use the SHA-512 algorithm, issue the command:

# /usr/sbin/authconfig --passalgo=sha512 --update

When users changes their passwords, hashes for the new passwords will be generated using the SHA-512 algorithm.

3.3.2.4.a. Password hashing algorithm

The password hashing algorithm should be set to sha512

Security identifiers

  • CCE-14063-2

3.3.2.5. Limit Password Reuse

Do not allow users to reuse recent passwords. This can be accomplished by using the remember option for the pam_unix PAM module. In order to prevent a user from re-using any of his or her last 5 passwords, locate the
password requisite pam_cracklib.so ...
or
password requisite pam_passwdqc.so ...
line in /etc/pam.d/system-auth, and add the following line immediately below:
password requisite pam_pwhistory.so use_authtok remember=5
Old (and thus no longer valid) passwords are stored in the file /etc/security/opasswd.

3.3.2.5.a. Limit password reuse

The passwords to remember should be set to: 5

Security identifiers

  • CCE-14939-3

3.3.3. Secure Session Configuration Files for Login Accounts

When a user logs into a Unix account, the system configures the user's session by reading a number of files. Many of these files are located in the user's home directory, and may have weak permissions as a result of user error or misconfiguration. If an attacker can modify or even read certain types of account configuration information, he can often gain full access to the affected user's account. Therefore, it is important to test and correct configuration file permissions for interactive accounts, particularly those of privileged users such as root or system administrators.

3.3.3.1. Ensure that No Dangerous Directories Exist in Root's Path

The active path of the root account can be obtained by starting a new root shell and running:

# echo $PATH
This will produce a colon-separated list of directories in the path. For each directory DIR in the path, ensure that DIR is not equal to a single . character. Also ensure that there are no 'empty' elements in the path, such as in these examples:

PATH=:/bin
PATH=/bin:
PATH=/bin::/sbin

These empty elements have the same effect as a single . character.

For each element in the path, run:

# ls -ld DIR

and ensure that write permissions are disabled for group and other.

It is important to prevent root from executing unknown or untrusted programs, since such programs could contain malicious code. Therefore, root should not run programs installed by unprivileged users. Since root may often be working inside untrusted directories, the . character, which represents the current directory, should never be in the root path, nor should any directory which can be written to by an unprivileged or semi-privileged (system) user.

It is a good practice for administrators to always execute privileged commands by typing the full path to the command.

3.3.3.1.a. No Dangerous Directories Exist in Root's PATH variable

The PATH variable should be set correctly for user root

Security identifiers

  • CCE-3301-9

3.3.3.1.b. The PATH variable for root does not include any world-writable or group-writable directories

Check each directory in root's path and make use it does not grant write permission to group and other

Security identifiers

  • CCE-14957-5

3.3.3.2. Ensure that User Home Directories are not Group-Writable or World-Readable

For each human user USER of the system, view the permissions of the user's home directory:

# ls -ld /home/USER

Ensure that the directory is not group-writable and that it is not world-readable. If necessary, repair the permissions:

# chmod g-w /home/USER
# chmod o-rwx /home/USER

User home directories contain many configuration files which affect the behavior of a user's account. No user should ever have write permission to another user's home directory. Group shared directories can be configured in subdirectories or elsewhere in the filesystem if they are needed. Typically, user home directories should not be world-readable. If a subset of users need read access to one another's home directories, this can be provided using groups.

This section recommends modifying user home directories. Notify your user community, and solicit input if appropriate, before making this type of change.

3.3.3.2.a. User Home Directories are not Group-Writable or World-Readable

File permissions should be set correctly for the home directories for all user accounts.

Security identifiers

  • CCE-4090-7

3.3.3.3. Ensure that User Dot-Files are not World-writable

For each human user USER of the system, view the permissions of all dot-files in the user's home directory:

# ls -ld /home/USER/.[A-Za-z0-9]*

Ensure that none of these files are group- or world-writable. Correct each misconfigured file FILE by executing:

# chmod go-w /home/USER/FILE

A user who can modify another user's configuration files can likely execute commands with the other user's privileges, including stealing data, destroying files, or launching further attacks on the system.

This section recommends modifying user home directories. Notify your user community, and solicit input if appropriate, before making this type of change.

3.3.3.3.a. User Home Directories are not Group-Writable or World-Readable

File permissions should be set correctly for the home directories for all user accounts.

3.3.3.4. Ensure that Users Have Sensible Umask Values

  1. Edit the global configuration files /etc/profile, /etc/bashrc, and /etc/csh.cshrc. Add or correct the line:

    umask 077

  2. Edit the user definitions file /etc/login.defs. Add or correct the line:

    UMASK 077

  3. View the additional configuration files /etc/csh.login and /etc/profile.d/*, and ensure that none of these files redefine the umask to a more permissive value unless there is a good reason for it.

  4. Edit the root shell configuration files /root/.bashrc, /root/.bash profile, /root/.cshrc, and /root/.tcshrc. Add or correct the line:

    umask 077

With a default umask setting of 077, files and directories created by users will not be readable by any other user on the system. Users who wish to make specific files group- or world-readable can accomplish this using the chmod command. Additionally, users can make all their files readable to their group by default by setting a umask of 027 in their shell configuration files. If default per-user groups exist (that is, if every user has a default group whose name is the same as that user's username and whose only member is the user), then it may even be safe for users to select a umask of 007, making it very easy to intentionally share files with group s of which the user is a member.

In addition, it may be necessary to change root's umask temporarily in order to install software or files which must be readable by other users, or to change the default umasks of certain service accounts such as the FTP user. However, setting a restrictive default protects the files of users who have not taken steps to make their files more available, and preventing files from being inadvertently shared.

This sections recommends modifying user home directories. Notify your user community, and solicit input if appropriate, before making this type of change.

3.3.3.4.a. The default umask for all users is set correctly in /etc/bashrc

The default umask for all users for the bash shell should be set to: 022

Security identifiers

  • CCE-3844-8

3.3.3.4.b. The default umask for all users is set correctly in /etc/csh.cshrc

The default umask for all users for the csh shell should be set to: 022

Security identifiers

  • CCE-4227-5

3.3.3.4.c. The default umask for all users is set correctly in /etc/login.defs

The default umask for all users should be set to: 077

Security identifiers

  • CCE-14107-7

3.3.3.4.d. The default umask for all users is set correctly in /etc/profile

The default umask for all users should be set to: 022

Security identifiers

  • CCE-14847-8

3.3.3.5. Ensure that Users do not Have .netrc Files

For each human user USER of the system, ensure that the user has no .netrc file. The command:

# ls -l /home/USER/.netrc

should return the error 'No such file or directory'. If any user has such a file, approach that user to discuss removing this file.

The .netrc file is a configuration file used to make unattended logins to other systems via FTP. When this file exists, it frequently contains unencrypted passwords which may be used to attack other systems.

This section recommends modifying user home directories. Notify your user community, and solicit input if appropriate, before making this type of change.

3.3.3.5.a. No ~/.netrc files exist

No user's home directory should contain a .netrc file

3.3.4. Protect Physical Console Access

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.

3.3.4.1. Set BIOS Password

The BIOS (on x86 systems) is the first code to execute during system startup and controls many important system parameters, including which devices the system will try to boot from, and in which order. Assign a password to prevent any unauthorized changes to the BIOS configuration. The exact steps will vary depending on your machine, but are likely to include:

  1. Reboot the machine.

  2. Press the appropriate key during the initial boot screen (F2 is typical)

  3. Navigate the BIOS configuration menu to add a password.

The exact process will be system-specific and the system's hardware manual may provide detailed instructions. This password should prevent attackers with physical access from attempting to change important parameters. However, an attacker with physical access can usually clear the BIOS password. The password should be written down and stored in a physically-secure location, such as a safe, in the event that it is forgotten and must be retrieved.

3.3.4.2. Boot Loader Password

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. 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, the boot loader configuration should be protected with a password.

The default RHEL boot loader for x86 systems is called GRUB. To protect its configuration:

  1. Select a password and then generate a hash from it by running:

    # grub-crypt --sha-512

  2. Insert the following line into /boot/grub/grub.conf immediately after the header comments. (Use the output from grub-crypt as the value of password-hash ):

    password --encrypted password-hash

  3. Verify the permissions on /boot/grub/grub.conf (which is a symlink to ../boot/grub/grub.conf):

    # chown root:root /boot/grub/grub.conf
    # chmod 600 /boot/grub/grub.conf

Boot loaders for other platforms should offer a similar password protection feature.

3.3.4.2.a. Boot Loader user owner

Boot Loader configuration file should be owned by root.

Security identifiers

  • CCE-4144-2

3.3.4.2.b. Boot Loader group owner

Boot Loader configuration file should be owned by group root.

Security identifiers

  • CCE-4197-0

3.3.4.2.c. Permissions on boot loader

Boot Loader configuration file permissions should be set correctly.

Security identifiers

  • CCE-3923-0

3.3.4.2.d. Enable Boot Loader Password

The grub boot loader should have sha-512 password protection enabled

Security identifiers

  • CCE-3818-2

3.3.4.3. Require Authentication for Single-User Mode

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. This provides a trivial mechanism of bypassing security on the machine and gaining root access.

To require entry of the root password even if the system is started in single-user mode, change the SINGLE value in /etc/sysconfig/init as follows:

SINGLE=/sbin/sulogin

3.3.4.3.a. Require Authentication for Single-User Mode

A password should be required to boot into single-user mode.

Security identifiers

  • CCE-4241-6

3.3.4.4. Disable Interactive Boot

Edit the file /etc/sysconfig/init. Add or correct the setting:

PROMPT=no
The PROMPT option allows the console user to perform an interactive system startup, in which it is possible to select the set of services which are started on boot. Using interactive boot, the console user could disable auditing, firewalls, or other services, weakening system security.

3.3.4.4.a. Disable Interactive Boot

The ability for users to perform interactive startups should be disabled.

Security identifiers

  • CCE-4245-7

3.3.4.5. Implement Inactivity Time-out for Login Shells

If the system does not run X Windows, then the login shells can be configured to automatically log users out after a period of inactivity. The following instructions are not practical for systems which run X Windows, as they will close terminal windows in the X environment.

To implement a 15-minute idle time-out for the default /bin/bash shell, create a new file tmout.sh in the directory /etc/profile.d with the following lines:

TMOUT=900
readonly TMOUT
export TMOUT

To implement a 15-minute idle time-out for the tcsh shell, create a new file autologout.csh in the directory /etc/profile.d with the following line:

set -r autologout=15

Similar actions should be taken for any other login shells used.

The example time-out here of 15 minutes should be adjusted to whatever your security policy requires. The readonly line for bash and the -r option for tcsh can be omitted if policy allows users to override the value.

The automatic shell logout only occurs when the shell is the foreground process. If, for example, a vi session is left idle, then automatic logout would not occur.

When logging in through a remote connection, as with SSH, it may be more effective to set the timeout value directly through that service.

3.3.4.5.a. Enforce an inactivity timeout for Bourne shells

Bourne shells should be closed after 15 minutes of inactivity.

3.3.4.5.b. Enforce an inactivity timeout for C shells

C shells should be closed after 15 minutes of inactivity.

3.3.4.6. Configure Screen Locking

When a user must temporarily leave an account logged-in, screen locking should be employed to prevent passersby from abusing the account. User education and training is particularly important for screen locking to be effective.

A policy should be implemented that trains all users to lock the screen when they plan to temporarily step away from a logged-in account. Automatic screen locking is only meant as a safeguard for those cases where a user forgot to lock the screen.

3.3.4.6.1. Configure GUI Screen Locking

In the default GNOME desktop, the screen can be locked by choosing Lock Screen from the System menu.

The gconftool-2 program can be used to enforce mandatory screen locking settings for the default GNOME environment. Run the following commands to enforce idle activation of the screen saver, screen locking, a blank-screen screensaver, and 15-minute idle activation time:

# gconftool-2 --direct --config-source xml:readwrite:/etc/gconf/gconf.xml.mandatory --type bool --set /apps/gnome-screensaver/idle_activation_enabled true
# gconftool-2 --direct --config-source xml:readwrite:/etc/gconf/gconf.xml.mandatory --type bool --set /apps/gnome-screensaver/lock_enabled true
# gconftool-2 --direct --config-source xml:readwrite:/etc/gconf/gconf.xml.mandatory --type string --set /apps/gnome-screensaver/mode blank-only
# gconftool-2 --direct --config-source xml:readwrite:/etc/gconf/gconf.xml.mandatory --type int --set /desktop/gnome/session/idle_delay 15

The default setting of 15 minutes for idle activation is reasonable for many office environments, but the setting should conform to whatever policy is defined. The screensaver mode blank-only is selected to conceal the contents of the display from passersby.

Because users should be trained to lock the screen when they step away from the computer, the automatic locking feature is only meant as a backup. The Lock Screen icon from the System menu can also be dragged to the taskbar in order to facilitate even more convenient screen-locking.

The root account cannot be screen-locked, but this should have no practical effect as the root account should never be used to log into an X Windows environment, and should only be used to for direct login via console in emergency circumstances.

For more information about configuring GNOME screensaver, see http://live.gnome.org/GnomeScreensaver. For more information about enforcing preferences in the GNOME environment using the GConf configuration system, see http://www.gnome.org/projects/gconf and the man page gconftool-2(1).

3.3.4.6.1.a. Implement Inactivity Time-out for GNOME

The idle time-out value for GNOME desktop lockout should be 15 minutes

Security identifiers

  • CCE-3315-9

3.3.4.6.1.b. The gnome desktop screensaver should be enabled.

Idle activation of the screen saver should be enabled

Security identifiers

  • CCE-14604-3

3.3.4.6.1.c. Lock the screensaver with a password

The screensaver should ask for a password

Security identifiers

  • CCE-14023-6

3.3.4.6.1.d. Implement blank screen saver

The screen saver should be blank

Security identifiers

  • CCE-14735-5

3.3.4.6.2. Configure Console Screen Locking

A console screen locking mechanism is provided in the vlock package, which is not installed by default. If the ability to lock console screens is necessary, install the vlock package:

# yum install vlock

Instruct users to invoke the program when necessary, in order to prevent passersby from abusing their login:
$ vlock

The -a option can be used to prevent switching to other virtual consoles.

3.3.4.6.2.a. Configure console screen locking

The vlock package should be installed

Security identifiers

  • CCE-3910-7

3.3.4.7. Disable Unnecessary Ports

Though unusual, some systems may be managed only remotely and yet also exposed to risk from attackers with direct physical access to them. In these cases, reduce an attacker’s access to the system by disabling unnecessary external ports (e.g. USB, FireWire, NIC) in the system’s BIOS.

Disable ports on the system which are not necessary for normal system operation. The exact steps will vary depending on your machine, but are likely to include:

  1. Reboot the machine.

  2. Press the appropriate key during the initial boot screen (F2 is typical).

  3. Navigate the BIOS conguration menu to disable ports, such as USB, FireWire, and NIC.

Disabling USB ports is particularly unusual and will cause problems for important input devices such as keyboards or mice attached to the system.

3.3.5. Use a Centralized Authentication Service

A centralized authentication service is any method of maintaining central control over account and authentication data and of keeping this data synchronized between machines. Such services can range in complexity from a script which pushes centrally-generated password files out to all machines, to a managed scheme such as LDAP or Kerberos.

If authentication information is not centrally managed, it quickly becomes inconsistent, leading to out-of-date credentials and forgotten accounts which should have been deleted. In addition, many older protocols (such as NFS) make use of the UID to identify users over a network. This is not a good practice, and these protocols should be avoided if possible. However, since most sites must still make use of some older protocols, having consistent UIDs and GIDs site-wide is a significant benefit.

Centralized authentication services do have the disadvantage that authentication information must be transmitted over a network, leading to a risk that credentials may be intercepted or manipulated. Therefore, these services must be deployed carefully. The following precautions should be taken when configuring any authentication service:

  • Ensure that authentication information and any sensitive account information are never sent over the network unencrypted.

  • Ensure that the root account has a local password, to allow recovery in case of network outage or authentication server failure.

This guide recommends the use of LDAP. Kerberos is also a good choice for a centralized authentication service, but a description of its configuration is beyond the scope of this guide. The NIS service is not recommended, and should be considered obsolete.

3.3.6. Warning Banners for System Accesses

Each system should expose as little information about itself as possible.

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

Many organizations implement security policies that require a system banner provide notice of the system's ownership, provide warning to unauthorized users, and remind authorized users of their consent to monitoring.

3.3.6.1. Modify the System Login Banner

The contents of the file /etc/issue are displayed on the screen just above the login prompt for users logging directly into a terminal. Remote login programs such as SSH or FTP can be configured to display /etc/issue as well.

By default, the system will display the version of the OS, the kernel version, and the host name.

Edit /etc/issue. Replace the default text with a message compliant with the local site policy or a legal disclaimer.

3.3.6.1.a. Modify the System Login Banner

The system login banner text should be:

Security identifiers

  • CCE-4060-0

3.3.6.2. Implement a GUI Warning Banner

In the default graphical environment, users logging directly into the system are greeted with a login screen provided by the GNOME display manager. The warning banner should be displayed in this graphical environment for these users.

Configure the banner using the following commands:
# gconftool-2 --direct --config-source xml:readwrite:/etc/gconf/gconf.xml.mandatory --type bool --set /apps/gdm/simple-greeter/banner_message_enable true
# gconftool-2 --direct --config-source xml:readwrite:/etc/gconf/gconf.xml.mandatory --type string --set /apps/gdm/simple-greeter/banner_message_text 'YOUR_TEXT'

3.3.6.2.a. Implement a GUI Warning Banner

The direct gnome login warning banner text should be set appropriately

Security identifiers

  • CCE-4188-9

3.4. SELinux

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 RHEL6, should be usable on almost any RHEL 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 RHEL system, unless that system has requirements which make a stronger policy appropriate.

3.4.1. How SELinux Works

In the traditional Linux/Unix security model, known as Discretionary Access Control (DAC), processes run under a user and group identity, and enjoy that user and group's access rights to all files and other objects on the system. This system brings with it a number of security problems, most notably: that processes frequently do not need and should not have the full rights of the user who ran them; that user and group access rights are not very granular, and may require administrators to allow too much access in order to allow the access that is needed; that the Unix filesystem contains many resources (such as temporary directories and world-readable files) which are accessible to users who have no legitimate reason to access them; and that legitimate users can easily provide open access to their own resources through confusion or carelessness.

SELinux provides a Mandatory Access Control (MAC) system that greatly augments the DAC model. Under SELinux, every process and every object (e.g. file, socket, pipe) on the system is given a security context, a label which include detailed type information about the object. The kernel allows processes to access objects only if that access is explicitly allowed by the policy in effect. The policy defines transitions, so that a user can be allowed to run software, but the software can run under a different context than the user's default. This automatically limits the damage that the software can do to files accessible by the calling user — the user does not need to take any action to gain this benefit.

For an action to occur, both the traditional DAC permissions must be satisifed as well as SELinux's MAC rules. If either do not permit the action, then it will not be allowed. In this way, SELinux rules can only make a system's permissions more restrictive and secure.

SELinux requires a complex policy in order to allow all the actions required of a system under normal operation. Three such policies have been designed for use with RHEL6, and are included with the system. In increasing order of power and complexity, they are: targeted, strict (which is newly not provided as an individual package but is part of targeted policy package. The process of making strict policy is described later) and mls. The targeted SELinux policy consists mostly of Type Enforcement (TE) rules, and a small number of Role-Based Access Control (RBAC) rules. It restricts the actions of many types of programs, but leaves interactive users largely unaffected. The strict policy also uses TE and RBAC rules, but on more programs and more aggressively. The mls policy implements Multi-Level Security (MLS), which introduces even more kinds of labels — sensitivity and category — and rules that govern access based on these.

The remainder of this section provides guidance for the configuration of the targeted policy and the administration of systems under this policy. Some pointers will be provided for readers who are interested in further strengthening their systems by using one of the stricter policies provided with RHEL6 or in writing their own policy.

3.4.2. Enable SELinux

The SELinux is enabled by default on RHEL6. The file /etc/selinux/config should contain the following lines for targeted policy:

SELINUX=enforcing
SELINUXTYPE=targeted
Edit the file /boot/grub/grub.conf. Ensure that the following arguments DO NOT appear on any kernel command line in the file:

selinux=0 or enforcing=0
The directive SELINUX=enforcing enables SELinux at boot time. If SELinux is causing a lot of problems or preventing the system from booting, it is possible to boot into the warning-only mode SELINUX=permissive for debugging purposes. Make certain to change the mode back to enforcing after debugging, set the filesystems to be relabeled for consistency using the command touch /.autorelabel, and reboot.

However, the RHEL6 default SELinux configuration should be sufficiently reasonable that most systems will boot without serious problems. Some applications that require deep or unusual system privileges, may not be compatible with SELinux in its default configuration. However, this should be uncommon, and SELinux's application support continues to improve. In other cases, SELinux may reveal unusual or insecure program behavior by design.

The directive SELINUXTYPE=targeted configures SELinux to use the default targeted policy.

The SELinux boot mode specified in /etc/selinux/config can be overridden by command-line arguments passed to the kernel. It is necessary to check grub.conf to ensure that this has not been done and to protect the bootloader against unauthorized configuration change.

3.4.2.a. SELinux should NOT be disabled in /boot/grub/grub.conf.

SELinux should NOT be disabled in /boot/grub/grub.conf. Check that selinux=0 is not found

Security identifiers

  • CCE-3977-6

3.4.2.b. Proper SELinux state

The SELinux state should be set appropriately

Security identifiers

  • CCE-3999-0

3.4.2.c. Proper SELinux policy

The SELinux policy should be set appropriately.

Security identifiers

  • CCE-3624-4

3.4.2.4. Ensure SELinux is Properly Enabled

Run the command:

$ /usr/sbin/sestatus

If the system is properly configured, the output should indicate:

  • SELinux status: enabled

  • Current mode: enforcing

  • Mode from config file: enforcing

  • Policy from config file: targeted

3.4.3. Disable Unnecessary SELinux Daemons

Several daemons are installed by default as part of the RHEL6 SELinux support mechanism. These daemons may improve the system's ability to enforce SELinux policy in a useful fashion, but may also represent unnecessary code running on the machine, increasing system risk. If these daemons are available in your RHEL6 installation and are not needed on your system, they should be disabled.

3.4.3.1. Remove SETroubleshoot if Possible

Is there a mission-critical reason to allow users to view SELinux denial information using the sealert GUI? If not, remove the setroubleshoot packages:
$ yum remove setroubleshoot-\*


The setroubleshoot, which is newly D-Bus system service, is a facility for notifying the desktop user of SELinux denials in a user-friendly fashion. SELinux errors may provide important information about intrusion attempts in progress, or may give information about SELinux configuration problems which are preventing correct system operation. In order to maintain a secure and usable SELinux installation, error logging and notification is necessary.
However, setroubleshoot is a service which has complex functionality, which runs a daemon and uses D-Bus to distribute information which may be sensitive, or even to allow users to modify SELinux settings. This guide recommends removing setroubleshoot and using the kernel audit functionality to monitor SELinux's behavior.

3.4.3.1.a. Remove SETroubleshoot

The setroubleshoot-server package should not be installed.

3.4.3.2. Disable MCS Translation Service (mcstrans) if Possible

Unless there is some overriding need for the convenience of category label translation, disable the MCS translation service:

# chkconfig mcstrans off

The mcstransd daemon provides the category label translation information defined in /etc/selinux/targeted/setrans.conf to client processes which request this information.

Category labelling is unlikely to be used except in sites with special requirements. Therefore, it should be disabled in order to reduce the amount of potentially vulnerable code running on the system.

3.4.3.2.a. Disable MCS Translation Service (mcstrans) if Possible

The mcstrans service should be disabled.

Security identifiers

  • CCE-3668-1

3.4.3.3. Restorecon Service (restorecond)

The restorecond daemon monitors a list of files which are frequently created or modified on running systems, and whose SELinux contexts are not set correctly. It looks for creation events related to files listed either in /etc/selinux/restorecond.conf or restorecond_user.conf , and sets the contexts ofthose files when they are discovered.

The restorecond program is fairly simple, so it brings low risk, but, in its default configuration, does not add much value to a system. An automated program such as restorecond may be used to monitor problematic files for context problems, or system administrators may be trained to check file contexts of newly-created files using the command ls -lZ, and to repair contexts manually using the restorecon command.

This guide makes no recommendation either for or against the use of restorecond.

3.4.4. Check for Unconfined Daemons

Daemons that SELinux policy does not know about will inherit the context of the parent process. Because daemons are launched during startup and descend from the init process, they inherit the initrc_t context. This is a problem because it may cause AVC denials, or it could allow privileges that the daemon does not require.

To check for unconfined daemons, run the following command:

# ps -eZ | egrep "initrc" | egrep -vw "tr|ps|egrep|bash|awk" | tr ':' ' ' | awk '{ print $NF }'

It should produce no output in a well-configured system.

3.4.5. Check for Unlabeled Device Files

Device files are used for communication with important system resources. SELinux contexts should exist for these. If a device file is not labeled, then misconfiguration is likely.

To check for unlabeled device files, run the following command:
# ls -Z /dev | grep unlabeled_t

It should produce no output in a well-configured system.

3.4.6. Debugging SELinux Policy Errors

SELinux's default policies have improved significantly over time, and most systems should have few problems using the targeted SELinux policy. However, policy problems may still occasionally prevent accesses which should be allowed. This is especially true if your site runs any custom or heavily modified applications.

This section gives some brief guidance on discovering and repairing SELinux-related access problems. Guidance given here is necessarily draft, but should provide a starting point for debugging.

If you suspect that a permission error or other failure may be caused by SELinux (and are certain that misconfiguration of the traditional Unix permissions are not the cause of the problem), search the audit logs for AVC events:

# ausearch -m AVC,USER_AVC -sv no

The output of this command will be a set of events. The timestamp, along with the comm and pid fields, should indicate which line describes the problem.

Look up the context under which the process is running. Assuming the process ID is PID , find the context by running:

# ps -p PID -Z

The AVC denial message should identify the offending file or directory. The name field should contain the filename (not the full pathname by default), and the ino field can be used to search by inode, if necessary. Assuming the file is FILE , find its SELinux context:

# ls -Z FILE

An administrator should suspect an SELinux misconfiguration whenever a program gets a 'permission denied' error but the standard Unix permissions appear to be correct, or a program fails mysteriously on a task which seems to involve file access or network communication.

As described earlier, SELinux augments each process with a context providing detailed type information about that process. The contexts under which processes run may be referred to as subject contexts. Similarly, each filesystem object is given a context.

The targeted policy consists of a set of rules, each of which allows a subject type to perform some operation on a given object type. The kernel stores information about these access decisions in an structure known as an Access Vector Cache (AVC), so authorization decisions made by the system are audited with the type AVC. It is also possible for userspace modules to implement their own policies based on SELinux, and these decisions are audited with the type USER_AVC.

AVC denials are logged by the kernel audit facility (see Section 2.6.2 for configuration guidance on this subsystem) and may also be visible via setroubleshoot. This guide recommends the use of the audit userspace utilities to find AVC errors. It is possible to manually locate these errors by looking in the file /var/log/audit/audit.log or in /var/log/messages (depending on the syslog configuration in effect), but the ausearch tool allows finegrained searching on audit event types, which may be necessary if system call auditing is enabled as well. The command line above tells ausearch to look for kernel or userspace AVC messages (-m AVC,USER AVC) where the access attempt did not succeed (-sv no).

If an AVC denial occurs when it should not have, the problem is generally one of the following:

  • The program is running with the wrong subject context. This could happen as a result of an incorrect context on the program's executable file, which could happen if 3rd party software is installed and not given appropriate SELinux file contexts.

  • The file has the wrong object context because the current file's context does not match the specification. This can occur when files are created or modified in certain ways. It is not atypical for configuration files to get the wrong contexts after a system configuration change performed by an administrator. To repair the file, use the command:

    # restorecon -v FILE
    This should produce output indicating that the file's context has been changed. The /usr/bin/chcon program can be used to manually change a file's context, but this is problematic because the change will not persist if it does not agree with the policy-defined contexts applied by restorecon.

  • The file has the wrong object context because the specification is either incorrect or does not match the way the file is being used on this system. In this case, it will be necessary to change the system file contexts.

    Run the system-config-selinux tool, and go to the 'File Labeling' menu. This will give a list of files and wildcards corresponding to file labelling rules on the system. Add a rule which maps the file in question to the desired context. As an alternative, file contexts can be modified from the command line using the semanage(8) tool.

  • The program and file have the correct contexts, but the policy should allow some operation between those two contexts which is currently not allowed. In this case, it will be necessary to modify the SELinux policy.

    Run the system-config-selinux tool, and go to the 'Boolean' menu. If your configuration is supported, but is not the Red Hat default, then there will be a boolean allowing real-time modification of the SELinux policy to fix the problem. Browse through the items in this menu, looking for one which is related to the service which is not working. As an alternative, SELinux booleans can be modified from the command line using the getsebool(8) and setsebool(8) tools.

    If there is no boolean, it will be necessary to create and load a policy module. A simple way to build a policy module is to use the audit2allow tool. This tool can take input in the format of AVC denial messages, and generate syntactically correct Type Enforcement rules which would be sufficient to prevent those denials. For example, to generate and display rules which would allow all kernel denials seen in the past fitfteen minutes, run:

    # ausearch -m AVC -sv no -ts recent | audit2allow

    It is possible to use audit2allow to directly create a module package suitable for loading into the kernel policy. To do this, invoke audit2allow with the -M flag:

    # ausearch -m AVC -sv no -ts recent | audit2allow -M localmodule

    If this is successful, several lines of output should appear. Review the generated TE rules in the file localmodule .te and ensure that they express what you wish to allow.

    The file localmodule .pp should also have been created. This file is a policy module package that can be loaded into the kernel. To do so, use system-config-selinux, go to the 'Policy Module' menu and use the 'Add' button to enable your module package in SELinux, or load it from the command line using semodule(8):

    # semodule -i localmodule .pp

    In RHEL5, if you created a local policy, you needed to switch to permissive mode globally to better debugging sometimes. This is no longer needed in RHEL6. The permissive domains was implemented which means only a domain can become permissive.

    semanage -a permissive DOMAIN

    Section 45.2 of [9] covers this procedure in detail.

3.4.7. Further Strengthening

The recommendations up to this point have discussed how to configure and maintain a system under the default configuration of the targeted policy, which constrains only the actions of daemons and system software. This guide strongly recommends that any site which is not currently using SELinux at all transition to the targeted policy, to gain the substantial security benefits provided by that policy.

However, the default policy provides only a subset of the full security gains available from using SELinux. In particular, the SELinux policy is also capable of constraining the actions of interactive users, of providing compartmented access by sensitivity level (MLS) and/or category (MCS), and of restricting certain types of system actions using booleans beyond the RHEL6 defaults.

This section introduces other uses of SELinux which may be possible, and provides links to some outside resources about their use. Detailed description of how to implement these steps is beyond the scope of this guide.

3.4.7.1. Strengthen the Default SELinux Boolean Configuration

SELinux booleans are used to enable or disable segments of policy to comply with site policy. Booleans may apply to the entire system or to an individual daemon. For instance, the boolean allow execstack, if enabled, allows programs to make part of their stack memory region executable. The boolean ftp home dir allows ftpd processes to access user home directories, and applies only to daemons which implement FTP.

The command

$ getsebool -a

$ semanage boolean -l


lists the values of all SELinux booleans on the system. Section 2.4.5 discussed loosening boolean values in order to debug functionality problems which occur under more restrictive defaults. It is also useful to examine and strengthen the boolean settings, to disable functionality which is not required by legitimate programs on your system, but which might be symptomatic of an attack.

See the manpages booleans(8), getsebool(8), setsebool(8) and semanage(8) for general information about booleans. There are also manual pages for several subsystems which discuss the use of SELinux with those systems. Examples include ftpd selinux(8), httpd selinux(8), and nfs_selinux(8). Another good reference is the html documentation distributed with the selinux-policy RPM. This documentation is stored under

/usr/share/doc/selinux-policy-version/html/

The pages global tunables.html and global booleans.html may be useful when examining booleans.

3.4.7.2. Use a Stronger Policy

Using a stronger policy can greatly enhance security, but will generally require customization to be compatible with the particular system's purpose, and this may be costly or time consuming. Under the targeted policy, interactive processes are given the type unconfined t, so interactive users are not constrained by SELinux even if they attempt to take strange or malicious actions.
Previously, in RHEL5, we had strict policy which could be installed using selinux-policy-strict package. In RHEL6, we combine strict and targeted policy together. There exist two SELinux policy modules - unconfined.pp and unconfineduser.pp policy modules. These two modules are optional, and removing it gives you the equivalent of strict policy. Firstly, you can just remove unconfined.pp policy module. You will be closer to strict policy but this leaves only user domains unconfined, along with some domains that do not make sense to confine (anaconda, firstboot, kernel,rpm) and also unconfined_t user will be exist.
# semodule -d unconfined
# seinfo -aunconfined_domain_type -x | tail -n +2 | wc -l
Then you can disable all unconfined domains by disabling unconfineduser module which is equal strict policy. In this case, you need to setup all your users as confined users, before removing the unconfineduser module using semanage tool
# semanage login -m -s staff_u root
# semanage login -m -s staff_u __default__
# semanage user -d unconfined_u
# semanage user -m -R "staff_r system_r sysadm_r" staff_u
# semodule -d unconfineduser

Note: One of the RHEL6 features are Confined Users. This means, unconfined.pp and unconfineduser.pp policy modules can be used and an user can be confined even so. All this magic lie in adding login mappings between linux users and SELinux confined users.
# semanage login -a -s user_u -r s0-s0:c0.c1023 USERNAME1
# semanage login -a -s staff_u -r s0-s0:c0.c1023 USERNAME2


The mls policy type can be used to enforce sensitivity or category labelling, and requires site-specific configuration of these labels in order to be useful. To use this policy, install the appropriate policy module:
# yum install selinux-policy-mls
Then edit /etc/selinux/config and correct the line:
SELINUXTYPE=mls
Configure the system to boot into run level 3 by default:
sed -i "s/^id:5:initdefault:/id:3:initdefault:/g" /etc/inittab
Note: Switching between policies typically requires the entire disk to be relabelled, so that files get the appropriate SELinux contexts under the new policy. Add autorelabel flag
touch /.autorelabel; reboot
and boot with the additional grub command-line options
enforcing=0
to relabel the disk, then reboot normally.

3.4.8. SELinux References

  • NSA SELinux resources:

    • Web page: http://www.nsa.gov/selinux/

    • Mailing list: selinux@tycho.nsa.gov
      List information at: http://www.nsa.gov/selinux/info/list.cfm

  • Fedora SELinux resources:

    • FAQ: http://docs.fedoraproject.org/selinux-faq/

    • Wiki: http://fedoraproject.org/wiki/SELinux/

    • Mailing list: fedora-selinux-list@redhat.com
      List information at: https://www.redhat.com/mailman/listinfo/fedora-selinux-list

  • Chapters 43–45 of Red Hat Enterprise Linux 5: Deployment Guide [9]

  • The book SELinux by Example: Using Security Enhanced Linux [13]

3.5. Network Configuration and Firewalls

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 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.

3.5.1. Kernel Parameters which Affect Networking

The sysctl utility is used to set a number of parameters which affect the operation of the Linux kernel. Several of these parameters are specific to networking, and the configuration options in this section are recommended.

3.5.1.1. Network Parameters for Hosts Only

Is this system going to be used as a firewall or gateway to pass IP traffic between different networks?
If not, edit the file /etc/sysctl.conf and add or correct the following lines:

net.ipv4.ip forward = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
These settings disable hosts from performing network functionality which is only appropriate for routers.

3.5.1.1.a. Default setting for sending ICMP redirects is configured to be disabled (runtime)

The default setting for sending ICMP redirects should be disabled for network interfaces.

Security identifiers

  • CCE-4151-7

3.5.1.1.b. Sending ICMP redirects for all interfaces is configured to be disabled

Sending ICMP redirects should be disabled for all interfaces.

Security identifiers

  • CCE-4155-8

3.5.1.1.c. IP forwarding is configured to be disabled

IP forwarding should be disabled.

Security identifiers

  • CCE-3561-8

3.5.1.2. Network Parameters for Hosts and Routers

Edit the file /etc/sysctl.conf and add or correct the following lines:

net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.secure_redirects = 0
net.ipv4.conf.all.log_martians = 0
net.ipv4.conf.default.accept_source_route = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.default.secure_redirects = 0
net.ipv4.conf.default.log_martians = 0
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.icmp_ignore_bogus_error_responses = 1
net.ipv4.tcp_syncookies = 1
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1

These options improve Linux's ability to defend against certain types of IPv4 protocol attacks.

The accept source route, accept redirects, and secure redirects options are turned off to disable IPv4 protocol features which are considered to have few legitimate uses and to be easy to abuse.

The net.ipv4.conf.all.log martians option logs several types of suspicious packets, such as spoofed packets, source-routed packets, and redirects.

The icmp echo ignore broadcasts icmp ignore bogus error messages options protect against ICMP attacks.

The tcp syncookies option uses a cryptographic feature called SYN cookies to allow machines to continue to accept legitimate connections when faced with a SYN flood attack. See [12] for further information on this option.

The rp filter option enables RFC-recommended source validation. It should not be used on machines which are routers for very complicated networks, but is helpful for end hosts and routers serving small networks.

For more information on any of these, see the kernel source documentation file /Documentation/networking/ip-sysctl.txt.

3.5.1.2.a. Accepting source routed packets for all interfaces is configured (runtime)

Accepting source routed packets should be: 0 for all interfaces as appropriate.

Security identifiers

  • CCE-4236-6

3.5.1.2.b. Accepting ICMP redirects for all interfaces is configured (runtime)

Accepting ICMP redirects should be: 0 for all interfaces as appropriate.

Security identifiers

  • CCE-4217-6

3.5.1.2.c. Accepting "secure" ICMP redirects for all interfaces is configured (runtime)

Accepting "secure" ICMP redirects (those from gateways listed in the default gateways list) should be: 0 for all interfaces as appropriate.

Security identifiers

  • CCE-3472-8

3.5.1.2.d. Logging of "martian" packets for all interfaces is configured (runtime)

Logging of "martian" packets (those with impossible addresses) should be: 0 for all interfaces as appropriate.

Security identifiers

  • CCE-4320-8

3.5.1.2.e. Default accepting of source routed packets is configured (runtime)

The default setting for accepting source routed packets should be: 0 for all interfaces as appropriate.

Security identifiers

  • CCE-4091-5

3.5.1.2.f. Default accepting ICMP redirects is configured (runtime)

The default setting for accepting ICMP redirects should be: 0 for all interfaces as appropriate.

Security identifiers

  • CCE-4186-3

3.5.1.2.g. Default accepting of "secure" ICMP redirects is configured (runtime)

The default setting for accepting "secure" ICMP redirects (those from gateways listed in the default gateways list) should be: 0 for all interfaces as appropriate.

Security identifiers

  • CCE-3339-9

3.5.1.2.h. Default logging of "martian" packets for all interfaces is configured (runtime)

Logging of "martian" packets (those with impossible addresses) should be: 0 for all interfaces as appropriate.

3.5.1.2.i. Ignoring ICMP echo requests is configured (runtime)

Ignoring ICMP echo requests (pings) sent to broadcast / multicast addresses should be: 1 for all interfaces as appropriate.

Security identifiers

  • CCE-3644-2

3.5.1.2.j. Ignoring bogus ICMP responses is configured (runtime)

Ignoring bogus ICMP responses to broadcasts should be: 1 for all interfaces as appropriate.

Security identifiers

  • CCE-4133-5

3.5.1.2.k. Sending TCP syncookies is configured (runtime)

Sending TCP syncookies should be: 1 for all interfaces as appropriate.

Security identifiers

  • CCE-4265-5

3.5.1.2.l. Performing source validation by reverse path is configured (runtime)

Performing source validation by reverse path should be: 1 for all interfaces as appropriate.

Security identifiers

  • CCE-4080-8

3.5.1.2.m. The default setting for performing source validation by reverse path is configured (runtime)

The default setting for performing source validation by reverse path should be: 1 for all interfaces as appropriate.

Security identifiers

  • CCE-3840-6

3.5.2. Wireless Networking

Wireless networking (sometimes referred to as 802.11 or Wi-Fi) presents a serious security risk to sensitive or classified systems and networks. Wireless networking hardware is much more likely to be included in laptop or portable systems than desktops or servers. Bluetooth serves a different purpose and possesses a much shorter range, but it still presents serious security risks.

Removal of hardware is the only way to absolutely ensure that the wireless capability remains disabled. If it is completely impractical to remove the wireless hardware, and site policy still allows the device to enter sensitive spaces, every effort to disable the capability via software should be made. In general, acquisition policy should include provisions to prevent the purchase of equipment that will be used in sensitive spaces and includes wireless capabilities.

If it is impossible to remove the wireless hardware from the device in question, disable as much of it as possible through software. Note that software methods do not prevent malicious software or careless system administrators from re-activating the devices with absolute certainty.

3.5.2.1. Remove Wireless Hardware if Possible

Identifying the wireless hardware is the first step in removing it. The system's hardware manual should contain information on its wireless capabilities.

Wireless hardware included with a laptop typically takes the form of a mini-PCI card or PC card. Other forms include devices which plug into USB or Ethernet ports, but these should be readily apparent and easy to remove from the base system.

A PC Card (originally called a PCMCIA card) is designed to be easy to remove, though it may be hidden when inserted into the system. Frequently, there will be one or more buttons near the card slot that, when pressed, eject the card from the system. If no card is ejected, the slot is empty.

A mini-PCI card is approximately credit-card sized and typically accessible via a removable panel on the underside of the laptop. Removing the panel may require simple tools.

In addition to manually inspecting the hardware, it is also possible to query the system for its installed hardware devices. The commands /sbin/lspci and /sbin/lsusb will show a list of all recognized devices on their respective buses, and this may indicate the presence of a wireless device.

3.5.2.2. Disable Wireless in BIOS

Some laptops that include built-in wireless support offer the ability to disable the device through the BIOS. This is system-specific; consult your hardware manual or explore the BIOS setup during boot.

3.5.2.3. Deactivate Wireless Interfaces

Deactivating the wireless interfaces should prevent normal usage of the wireless capability.

First, identify the interfaces available with the command:

# ip link ls

Additionally,the following command may also be used to determine whether wireless support ('extensions') is included for a particular interface, though this may not always be a clear indicator:

# iwconfig

After identifying any wireless interfaces (which may have names like wlan0, ath0, wifi0, or eth0), deactivate the interface with the command:

# ip link set interface down

These changes will only last until the next reboot. To disable the interface for future boots, locate its configuration file /etc/sysconfig/network-scripts/ifcfg-interface and add or replace configuration directives to match the following:
ONBOOT=no
USERCTL=no
NM_CONTROLLED=no

3.5.2.3.a. Deactivate Wireless Interfaces

All wireless interfaces should be disabled.

Security identifiers

  • CCE-4276-2

3.5.3. IPv6

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.

3.5.3.1. Disable Support for IPv6 unless Needed

Because the IPv6 networking code is relatively new and complex, it is particularly important that it be disabled unless needed. Despite configuration that suggests support for IPv6 has been disabled, link-local IPv6 address autoconfiguration occurs even when only an IPv4 address is assigned. The only way to effectively prevent execution of the IPv6 networking stack is to prevent the kernel from loading the IPv6 kernel module.

3.5.3.1.1. Disable Automatic Loading of IPv6 Kernel Module

To prevent the IPv6 kernel module (ipv6) from being loaded, create /etc/modprobe.d/ipv6.conf with the following content:

install ipv6 /bin/true

When the kernel requests the ipv6 module, this line will direct the system to run the program /bin/true instead.

3.5.3.1.1.a. Disable Automatic Loading of IPv6 Kernel Module

Automatic loading of the IPv6 kernel module should be disabled.

Security identifiers

  • CCE-3562-6

3.5.3.1.2. Disable Interface Usage of IPv6

To prevent configuration of IPv6 for all interfaces, add or correct the following line in /etc/sysconfig/network:

IPV6INIT=no

For each network interface IFACE , add or correct the following lines in /etc/sysconfig/network-scripts/ifcfg-IFACE as an additional prevention mechanism:

IPV6INIT=no

If it becomes necessary later to configure IPv6, only the interfaces requiring it should be enabled.

3.5.3.2. Configure IPv6 Settings if Necessary

A major feature of IPv6 is the extent to which systems implementing it can automatically configure their networking devices using information from the network. From a security perspective, manually configuring important configuration information is always preferable to accepting it from the network in an unauthenticated fashion.

3.5.3.2.1. Disable Automatic Configuration

Disable the system's acceptance of router advertisements and redirects by adding or correcting the following line in /etc/sysconfig/network (note that this does not disable sending router solicitations):

IPV6_AUTOCONF=no

3.5.3.2.1.a. Configure IPv6 autoconfiguration

The default setting for IPv6 autoconfiguration should be: no.

3.5.3.2.2. Manually Assign Global IPv6 Address

To manually assign an IP address for an interface IFACE, edit the file /etc/sysconfig/network-scripts/ ifcfg-IFACE. Add or correct the following line (substituting the correct IPv6 address):

IPV6ADDR=2001:0DB8::ABCD/64

Manually assigning an IP address is preferable to accepting one from routers or from the network otherwise. The example address here is an IPv6 address reserved for documentation purposes, as defined by RFC3849.

3.5.3.2.3. Use Privacy Extensions for Address if Necessary

To introduce randomness into the automatic generation of IPv6 addresses, add or correct the following line in /etc/sysconfig/network-scripts/ifcfg-IFACE:

IPV6_PRIVACY=rfc3041

Automatically-generated IPv6 addresses are based on the underlying hardware (e.g. Ethernet) address, and so it becomes possible to track a piece of hardware over its lifetime using its traffic. If it is important for a system's IP address to not trivially reveal its hardware address, this setting should be applied.

3.5.3.2.4. Manually Assign IPv6 Router Address

Edit the file /etc/sysconfig/network-scripts/ifcfg-IFACE , and add or correct the following line (substituting your gateway IP as appropriate):

IPV6_DEFAULTGW=2001:0DB8::0001

Router addresses should be manually set and not accepted via any autoconfiguration or router advertisement.

3.5.3.2.5. Limit Network-Transmitted Configuration

Add the following lines to /etc/sysctl.conf to limit the configuration information requested from other systems, and accepted from the network:

net.ipv6.conf.default.router_solicitations = 0
net.ipv6.conf.default.accept_ra_rtr_pref = 0
net.ipv6.conf.default.accept_ra_pinfo = 0
net.ipv6.conf.default.accept_ra_defrtr = 0
net.ipv6.conf.default.autoconf = 0
net.ipv6.conf.default.dad_transmits = 0
net.ipv6.conf.default.max_addresses = 1

The router solicitations setting determines how many router solicitations are sent when bringing up the interface. If addresses are statically assigned, there is no need to send any solicitations.

The accept_ra_pinfo setting controls whether the system will accept prefix info from the router.

The accept_ra_defrtr setting controls whether the system will accept Hop Limit settings from a router advertisement. Setting it to 0 prevents a router from changing your default IPv6 Hop Limit for outgoing packets.

The autoconf setting controls whether router advertisements can cause the system to assign a global unicast address to an interface.

The dad_transmits setting determines how many neighbor solicitations to send out per address (global and link-local) when bringing up an interface to ensure the desired address is unique on the network.

The max_addresses setting determines how many global unicast IPv6 addresses can be assigned to each interface. The default is 16, but it should be set to exactly the number of statically configured global addresses required.

3.5.3.2.5.a. Configure number of sent router solicitations

The default number of sent router solicitations should be: 0 for all interfaces.

3.5.3.2.5.b. Configure whether to accept router preference

Router preference should be accepted by default: 0

3.5.3.2.5.c. Configure whether to accept path information

Path information should be accepted by default: 0

3.5.3.2.5.d. Configure whether to accept default router information

Default router information should be accepted by default: 0

3.5.3.2.5.e. Configure whether to autoconfigure addresses

Addresses should be autoconfigured by default: 0

3.5.3.2.5.f. Configure number of duplicate address detection probes

Number of duplicate address detection probes should be by default: 0

3.5.3.2.5.g. Configure maximum number of autoconfigured addresses

Maximum number of autoconfigured addresses be by default: 1

3.5.4. TCP Wrapper

TCP Wrapper is a library which provides simple access control and standardized logging for supported applications which accept connections over a network. Historically, TCP Wrapper was used to support inetd services. Now that inetd is deprecated, TCP Wrapper supports only services which were built to make use of the libwrap library. To determine whether a given executable daemon /path/to/daemon supports TCP Wrapper, check the documentation, or run:

$ ldd /path/to/daemon | grep libwrap.so

If this command returns any output, then the daemon probably supports TCP Wrapper.

An alternative to TCP Wrapper support is packet filtering using iptables. Note that iptables works at the network level, while TCP Wrapper works at the application level. This means that iptables filtering is more efficient and more resistant to flaws in the software being protected, but TCP Wrapper provides support for logging, banners, and other application-level tricks which iptables cannot provide.

3.5.4.1. How TCP Wrapper Protects Services

TCP Wrapper provides access control for the system's network services using two configuration files. When a connection is attempted:

  1. The file /etc/hosts.allow is searched for a rule matching the connection. If one is found, the connection is allowed.

  2. Otherwise, the file /etc/hosts.deny is searched for a rule matching the connection. If one is found, the connection is rejected.

  3. If no matching rules are found in either file, then the connection is allowed. By default, TCP Wrapper does not block access to any services.


In the simplest case, each rule in /etc/hosts.allow and /etc/hosts.deny takes the form:

daemon : client

where daemon is the name of the server process for which the connection is destined, and client is the partial or full hostname or IP address of the client. It is valid for daemon and client to contain one item, a comma-separated list of items, or a special keyword like ALL, which matches any service or client. (See the hosts_access(5) manpage for a list of other keywords.)

Note: Partial hostnames start at the root domain and are delimited by the . character. So the client machine host03.dev.example.com, with IP address 10.7.2.3, could be matched by any of the specifications:

.example.com
.dev.example.com
10.7.2.

3.5.4.2. Reject All Connections From Other Hosts if Appropriate

Restrict all connections to non-public services to localhost only. Suppose pubsrv1 and pubsrv2 are the names of daemons which must be accessed remotely. Configure TCP Wrapper as follows.

Edit /etc/hosts.allow. Add the following lines:

pubsrv1 ,pubsrv2 : ALL
ALL: localhost

Edit /etc/hosts.deny. Add the following line:

ALL: ALL

These rules deny connections to all TCP Wrapper enabled services from any host other than localhost, but allow connections from anywhere to the services which must be publicly accessible. (If no public services exist, the first line in /etc/hosts.allow may be omitted.)

3.5.4.2.a. Reject Connections in TCP Wrapper by Default

TCP wrapper should be configured to reject connections that were not explicitly allowed

3.5.4.3. Allow Connections Only From Hosts in This Domain if Appropriate

For each daemon, domainsrv , which only needs to be contacted from inside the local domain, example.com , configure TCP Wrapper to deny remote connections.

Edit /etc/hosts.allow. Add the following line:

domainsrv : .example.com

Edit /etc/hosts.deny. Add the following line:

domainsrv : ALL

There are many possible examples of services which need to communicate only within the local domain. If a machine is a local compute server, it may be necessary for users to connect via SSH from their desktop workstations, but not from outside the domain. In that case, you should protect the daemon sshd using this method. As another example, RPC-based services such as NFS might be enabled within the domain only, in which case the daemon portmap should be protected.

Note: This example protects only the service domainsrv . No filtering is done on other services unless a line is entered into /etc/hosts.deny which refers to those services by name, or which restricts the special service ALL.

3.5.4.4. Monitor Syslog for Relevant Connections and Failures

Ensure that the following line exists in /etc/rsyslog.conf. (This is the default, so it is likely to be correct if the configuration has not been modified):

authpriv.* /var/log/secure

Configure logwatch or other log monitoring tools to periodically summarize failed connections reported by TCP Wrapper at the facility authpriv.info.

By default, TCP Wrapper audits all rejected connections at the facility authpriv, level info. In the log file, TCP Wrapper rejections will contain the substring:

daemon [pid ]: refused connect from ipaddr

These lines can be used to detect malicious scans, and to debug failures resulting from an incorrect TCP Wrapper configuration.

If appropriate, it is possible to change the syslog facility and level used by a given TCP Wrapper rule by adding the severity option to each desired configuration line in /etc/hosts.deny:

daemon : client : severity facility.level

By default, successful connections are not logged by TCP Wrapper.

3.5.4.5. Further Resources

For more information about TCP Wrapper, see the tcpd(8) and hosts_access(5) manpages and the documentation directory /usr/share/doc/tcp_wrappers-version.

Some information may be available from the Tools section of the author's website, http://www.porcupine.org, and from the RHEL6 Security Guide.

3.5.5. Iptables and Ip6tables

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.

3.5.5.1. Inspect and Activate Default Rules

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

# iptables -nL --line-numbers

The command is analogous for the ip6tables program.

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):

# service iptables restart
# chkconfig iptables on

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 similar, with its input rules 2 and 5 and forward rule 1 reflecting protocol naming and addressing differences.

3.5.5.1.a. ip6tables service is enabled

The ip6tables service should be enabled.

Security identifiers

  • CCE-4167-3

3.5.5.1.b. iptables service is enabled

The iptables service should be enabled.

Security identifiers

  • CCE-4189-7

3.5.5.2. Understand the Default Ruleset

Understanding and creating firewall rules can be a challenging activity, filled with corner cases and difficult-to debug problems. Because of this, administrators should develop a thorough understanding of the default ruleset before carefully modifying it.

The default ruleset is divided into three sections, each of which is called a chain: INPUT, FORWARD and OUTPUT. Each of these chains is built-in.

  • The INPUT chain is activated on packets destined for (i.e., addressed to) the system.

  • The OUTPUT chain is activated on packets which are originating from the system.

  • The FORWARD chain is activated for packets that the system will process and send through another interface, if so configured.


A packet starts at the first rule in the appropriate chain and proceeds until it matches a rule. If a match occurs, then control will jump to the specified target. The default ruleset uses the built-in targets ACCEPT and REJECT. Jumping to the target ACCEPT means to allow the packet through, while REJECT means to drop the packet and send an error message to the sending host. A related target called DROP means to drop the packet without even sending an error message.

The default policy for all of the built-in chains (shown after their names in the rule output above) is set to ACCEPT. This means that if no rules in the chain match the packets, they are allowed through. Because no rules at all are written for the OUTPUT chain, this means that iptables does not stop any packets originating from the system.

The INPUT chain tries to match, in order, the following rules for both iptables and ip6tables:

  • Rule 1, allows inbound packets that are part of a session initiated by the system.

  • Rule 2 explicitly allows all icmp packet types.

  • Rule 3 appears to accept all packets. However, this appears true only because the rules are not presented in verbose mode. Executing the command

    # iptables -vnL --line-numbers

    reveals that this rule applies only to the loopback (lo) interface (see column in), while all other rules apply to all interfaces. Thus, packets not coming from the loopback interface do not match and proceed to the next rule.

  • Rule 4 allows inbound connections in tcp port 22, which is the SSH protocol.

  • Rule 5 rejects all other packets and sends an error message to the sender. Because this is the last rule and matches any packet, it effectively prevents any packet from reaching the chain's default ACCEPT target. Preventing the acceptance of any packet that is not explicitly allowed is proper design for a firewall.

3.5.5.3. Strengthen the Default Ruleset

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. If the construction of the default ruleset meets your requirements, system-config-firewall-tui may be used to customize it, to the extent the tool allows it.

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.

The program system-config-firewall-tui automatically adjusts /etc/sysconfig/iptables . This program is only useful if the construction of 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.

3.5.5.3.1. Change the Default Policies

Change the default policy to DROP (from ACCEPT) for the INPUT and FORWARD built-in chains:

*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]

Changing the default policy in this way implements proper design for a firewall, i.e. any packets which are not explicitly permitted should not be accepted.

3.5.5.3.1.a. The default policy for ip*tables INPUT table should be set appropriately

Change the default policy to DROP (from ACCEPT) for the INPUT built-in chain.

3.5.5.3.1.b. The default policy for ip*tables FORWARD table should be set appropriately

Change the default policy to DROP (from ACCEPT) for the FORWARD built-in chain.

3.5.5.3.2. Restrict ICMP Message Types

In /etc/sysconfig/iptables, the accepted ICMP messages types can be restricted. To accept only ICMP echo reply, destination unreachable, and time exceeded messages, remove the line:

-A INPUT -p icmp -j ACCEPT

and insert the lines:
-A INPUT -p icmp --icmp-type echo-reply -j ACCEPT
-A INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT
-A INPUT -p icmp --icmp-type time-exceeded -j ACCEPT

To allow the system to respond to pings, also insert the following line:

-A INPUT -p icmp --icmp-type echo-request -j ACCEPT

Ping responses can also be limited to certain networks or hosts by using the -s option in the previous rule.

Because IPv6 depends so heavily on ICMPv6, it is preferable to deny the ICMPv6 packets you know you don't need (e.g. ping requests) in /etc/sysconfig/ip6tables, while letting everything else through:

-A INPUT -p icmpv6 --icmpv6-type echo-request -j DROP
If you are going to statically configure the machine's address, it should ignore Router Advertisements which could add another IPv6 address to the interface or alter important network settings:

-A INPUT -p icmpv6 --icmpv6-type router-advertisement -j DROP

Restricting other ICMPv6 message types in /etc/sysconfig/ip6tables is not recommended because the operation of IPv6 depends heavily on ICMPv6. Thus, more care must be taken when blocking ICMPv6 types.

3.5.5.3.2.a. Restrict ICMP message types

Accept only some ICMP messages in the INPUT built-in chain.

3.5.5.3.3. Log and Drop Packets with Suspicious Source Addresses

Packets with non-routable source addresses should be rejected, as they may indicate spoofing. Because the modified policy will reject non-matching packets, you only need to add these rules if you are interested in also logging these spoofing or suspicious attempts before they are dropped. If you do choose to log various suspicious traffic, add identical rules with a target of DROP after each LOG.

To log and then drop these IPv4 packets, insert the following rules in /etc/sysconfig/iptables (excepting any that are intentionally used):

-A INPUT -i eth0 -s 10.0.0.0/8 -j LOG --log-prefix "IP DROP SPOOF A: "
-A INPUT -i eth0 -s 172.16.0.0/12 -j LOG --log-prefix "IP DROP SPOOF B: "
-A INPUT -i eth0 -s 192.168.0.0/16 -j LOG --log-prefix "IP DROP SPOOF C: "
-A INPUT -i eth0 -s 224.0.0.0/4 -j LOG --log-prefix "IP DROP MULTICAST D: "
-A INPUT -i eth0 -s 240.0.0.0/5 -j LOG --log-prefix "IP DROP SPOOF E: "
-A INPUT -i eth0 -d 127.0.0.0/8 -j LOG --log-prefix "IP DROP LOOPBACK: "

Similarly, you might wish to log packets containing some IPv6 reserved addresses if they are not expected on your network:

-A INPUT -i eth0 -s ::1 -j LOG --log-prefix "IPv6 DROP LOOPBACK: "
-A INPUT -s 2002:E000::/20 -j LOG --log-prefix "IPv6 6to4 TRAFFIC: "
-A INPUT -s 2002:7F00::/24 -j LOG --log-prefix "IPv6 6to4 TRAFFIC: "
-A INPUT -s 2002:0000::/24 -j LOG --log-prefix "IPv6 6to4 TRAFFIC: "
-A INPUT -s 2002:FF00::/24 -j LOG --log-prefix "IPv6 6to4 TRAFFIC: "
-A INPUT -s 2002:0A00::/24 -j LOG --log-prefix "IPv6 6to4 TRAFFIC: "
-A INPUT -s 2002:AC10::/28 -j LOG --log-prefix "IPv6 6to4 TRAFFIC: "
-A INPUT -s 2002:C0A8::/32 -j LOG --log-prefix "IPv6 6to4 TRAFFIC: "

If you are not expecting to see site-local multicast or auto-tunneled traffic, you can log those:

-A INPUT -s FF05::/16 -j LOG --log-prefix "IPv6 SITE-LOCAL MULTICAST: "
-A INPUT -s ::0.0.0.0/96 -j LOG --log-prefix "IPv4 COMPATIBLE IPv6 ADDR: "

If you wish to block multicasts to all link-local nodes (e.g. if you are not using router autoconfiguration and do not plan to have any services that multicast to the entire local network), you can block the link-local all-nodes multicast address (before accepting incoming ICMPv6):

-A INPUT -d FF02::1 -j LOG --log-prefix "Link-local All-Nodes Multicast: "

However, if you're going to allow IPv4 compatible IPv6 addresses (of the form ::0.0.0.0/96), you should then consider logging the non-routable IPv4-compatible addresses:

-A INPUT -s ::0.0.0.0/104 -j LOG --log-prefix "IP NON-ROUTABLE ADDR: "
-A INPUT -s ::127.0.0.0/104 -j LOG --log-prefix "IP DROP LOOPBACK: "
-A INPUT -s ::224.0.0.0.0/100 -j LOG --log-prefix "IP DROP MULTICAST D: "
-A INPUT -s ::255.0.0.0/104 -j LOG --log-prefix "IP BROADCAST: "

If you are not expecting to see any IPv4 (or IPv4-compatible) traffic on your network, consider logging it before it gets dropped:

-A INPUT -s ::FFFF:0.0.0.0/96 -j LOG --log-prefix "IPv4 MAPPED IPv6 ADDR: "
-A INPUT -s 2002::/16 -j LOG --log-prefix "IPv6 6to4 ADDR: "

The following rule will log all traffic originating from a site-local address, which is deprecated address space:

-A INPUT -s FEC0::/10 -j LOG --log-prefix "SITE-LOCAL ADDRESS TRAFFIC: "

3.5.5.3.4. Log and Drop All Other Packets

To log before dropping all packets that are not explicitly accepted by previous rules, change the final lines from

-A INPUT -j REJECT --reject-with icmp-host-prohibited
COMMIT

to

-A INPUT -j LOG
-A INPUT -j DROP
COMMIT

The rule to log all dropped packets must be used with care. Chatty but otherwise non-malicious network protocols (e.g. NetBIOS) may result in voluminous logs; insertion of earlier rules to explicitly drop their packets without logging may be appropriate.

3.5.5.3.4.a. Log and Drop All Other Packets

Log and drop packets that were not explicitly drop in the INPUT built-in chain.

3.5.5.4. Further Strengthening

Further strengthening, particularly as a result of customization to a particular environment, is possible for the iptables rules. Consider the following options, though their practicality depends on the network environment and usage scenario:

  • Restrict outgoing traffic. As shown above, the OUTPUT chain's default policy can be changed to DROP, and rules can be written to specifically allow only certain types of outbound traffic. Such a policy could prevent casual usage of insecure protocols such as ftp and telnet, or even disrupt spyware. However, it would still not prevent a sophisticated user or program from using a proxy to circumvent the intended effects, and many client programs even try to automatically tunnel through port 80 to avoid such restrictions.

  • SYN flood protection. SYN flood protection can be provided by iptables, but might run into limiting issues for servers. For example, the iplimit match can be used to limit simultaneous connections from a given host or class. Similarly, the recent match allows the firewall to deny additional connections from any host within a given period of time (e.g. more than 3 –state NEW connections on port 22 within a minute to prevent dictionary login attacks).

    A more precise option for DoS protection is using TCP SYN cookies.

3.5.5.5. Further Resources

More complex, restrictive, and powerful rulesets can be created, but this requires careful customization that relies on knowledge of the particular environment. The following resources provide more detailed information:

  • The iptables(8) man page

  • The Netfilter Project's documentation at http://www.netfilter.org

  • The Red Hat Enterprise Linux 6 Security Guide

3.5.6. Transport Layer Security Support

The Transport Layer Security (TLS) protocol provides encrypted and authenticated network communications, and many network services include support for it. Using TLS is recommended, especially to avoid any plaintext transmission of sensitive data, even over a local network. The three primary TLS implementations included with the system are GnuTLS, NSS and OpenSSL. Older versions of TLS were called Secure Sockets Layer (SSL).

TLS uses public key cryptography to provide authentication and encryption. Public key cryptography involves two keys, one called the public key and the other called the private key. These keys are mathematically related such that data encrypted with one key can only be decrypted by the other, and vice versa. As their names suggest, public keys can be distributed to anyone while a private key must remain known only to its owner.

TLS uses certificates, which are files that hold cryptographic data: a public key, and a signature of that public key. In TLS authentication, a server presents a client with its certificate as a means of demonstrating that it is who it claims it is. If everything goes correctly, the client can verify the server's certificate by determining that the signature inside the certificate could only have been generated by a third party whom the client trusts. This third party is called a Certificate Authority (CA). Each client system should also have certificates from trusted CAs, and the client uses these CA certificates to verify the authenticity of the server's certificate. After authenticating a server using its certificate and a CA certificate, TLS provides encryption by using the server certificate to securely negotiate a shared secret key.

If your server must communicate using TLS with systems that might not be able to securely accept a new CA certificate prior to any TLS communication, then paying an established CA (whose certificates your clients already have) to sign your server certificates is recommended. The steps for doing this vary by vendor. Once the signed certificates have been obtained, configuration of the services is the same whether they were purchased from a vendor or signed by your own CA.

For setting up an internal network and encrypting local traffic, creating your own CA to sign X.509 certificates can be appropriate. The major steps in this process are:

  1. Create a CA to sign certificates

  2. Create X.509 certificates for servers using that CA

  3. Enable client support by distributing the CA's certificate

3.5.6.1. Create a CA to Sign Certificates

The following instructions apply to OpenSSL. The security of certificates depends on the security of the CA that signed them, so performing these steps on a secure machine is critical. The system used as a CA should be physically secure and not connected to any network. It should receive any certificate signing requests (CSRs) via removable media and output certificates onto removable media.

The script /etc/pki/tls/misc/CA is included to assist in the process of setting up a CA. This script uses many settings in /etc/pki/tls/openssl.cnf. The settings in this file can be changed to suit your needs and allow easier selection of default settings, particularly in the [req distinguished name] section.

To create the CA:

# cd /etc/pki/tls/misc
# ./CA -newca

  • When prompted, press enter to create a new CA key with the default name cakey.pem.

  • When prompted, enter a password that will protect the private key, then enter the same password again to verify it.

  • At the prompts, fill out as much of the CA information as is relevant for your site. You must specify a common name, or generation of the CA certificate will fail.

  • Next, you will be prompted for the password, so that the script can re-open the private key in order to write the certificate.



This step performs the following actions:

  • creates the directory /etc/pki/CA (by default), which contains files necessary for the operation of a certificate authority. These are:

  • creates a public-private key pair for the CA in the file /etc/pki/CA/private/cakey.pem. The private key must be kept private in order to ensure the security of the certificates the CA will later sign.

  • signs the public key (using the corresponding private key, in a process called self-signing) to create the CA certificate, which is then stored in /etc/pki/CA/cacert.pem.



When the CA later signs a server certificate using its private key, it means that it is vouching for the authenticity of that server. A client can then use the CA's certificate (which contains its public key) to verify the authenticity of the server certificate. To accomplish this, it is necessary to distribute the CA certificate to any clients.

3.5.6.2. Create X.509 Certificates for Servers

Creating an X.509 certificate for a server involves the following steps:

  1. A public-private key pair for the server must be generated.

  2. A certificate signing request (CSR) must be created from the key pair.

  3. The CSR must be signed by a certificate authority (CA) to create the server certificate.

  4. The server certificate and keys must be installed on the server.

3.5.6.3. Enable Client Support

The system ships with certificates from well-known commercial CAs. If your server certificates were signed by one of these established CAs, then this step is not necessary since the clients should include the CA certificate already.

If your servers use certificates signed by your own CA, some user applications will warn that the server's certificate cannot be verified because the CA is not recognized. Other applications may simply fail to accept the certificate and refuse to operate, or continue operating without ever having properly verified the server certificate.

To avoid this warning, and properly authenticate the servers, your CA certificate must be exported to every application on every client system that will be connecting to an TLS-enabled server.

3.5.6.3.1. Adding a Trusted CA for Firefox

Firefox needs to have a certificate from the CA that signed the web server's certificate, so that it can authenticate the web server.

To import a new CA certificate into Firefox 3.6:

  1. Launch Firefox and choose Preferences from the Edit menu.

  2. Click the Advanced button.

  3. Select the Encryption pane.

  4. Click the View Certificates button.

  5. Click the Authorities tab.

  6. Click the Import button at the bottom of the screen.

  7. Navigate to the CA certificate and import it.

3.5.6.3.2. Adding a Trusted CA for Thunderbird

Thunderbird needs to have a certificate from the CA that signed the mail server's certificates, so that it can authenticate the mail server(s).

To import a new CA certificate into Thunderbird 3:

  1. Launch Thunderbird and choose Preferences from the Edit menu.

  2. Click the Advanced button.

  3. Select the Certificates tab

  4. Click the View Certificates button.

  5. Select the Authorities tab.

  6. Click the Import button at the bottom of the screen.

  7. Navigate to the CA certificate and import it. Determine whether the CA should be used to identify web sites, e-mail users, and software developers and trust it for each accordingly.

3.5.6.3.3. Adding a Trusted CA for Evolution

The Evolution e-mail client needs to have a certificate from the CA that signed the mail server's certificates, so that it can authenticate the mail server(s).

To import a new CA certificate into Evolution:

  1. Launch Evolution and choose Preferences from the Edit menu.

  2. Select Certificates from the icon list on the left.

  3. Select the Authorities tab.

  4. Click the Import button.

  5. Navigate to the CA certificate and import it.

3.5.6.4. Further Resources

  • The OpenSSL Project home page at http://www.openssl.org

  • The openssl(1) man page

3.5.7. Uncommon Network Protocols

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.

3.5.7.1. Disable Support for DCCP

To prevent the DCCP kernel module from being loaded, create /etc/modprobe.d/dccp.conf with the following content:

install dccp /bin/true

The Datagram Congestion Control Protocol (DCCP) is a relatively new transport layer protocol, designed to support streaming media and telephony.

3.5.7.1.a. Disable Support for DCCP

Support for DCCP should be disabled.

Security identifiers

  • CCE-14268-7

3.5.7.2. Disable Support for SCTP

To prevent the SCTP kernel module from being loaded, create /etc/modprobe.d/sctp.conf with the following content:

install sctp /bin/true

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.

3.5.7.2.a. Disable Support for SCTP

Support for SCTP should be disabled.

Security identifiers

  • CCE-14132-5

3.5.7.3. Disable Support for RDS

To prevent the RDS kernel module from being loaded, create /etc/modprobe.d/rds.conf with the following content:

install rds /bin/true

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.

3.5.7.3.a. Disable Support for RDS

Support for RDS should be disabled.

Security identifiers

  • CCE-14027-7

3.6. Logging and Auditing

Successful local or network attacks on systems do not necessarily leave clear evidence of what happened. It is necessary to build a configuration in advance that collects this evidence, both in order to determine that something anomalous has occurred, and in order to respond appropriately. In addition, a well-configured logging and audit infrastructure will show evidence of any misconfiguration which might leave the system vulnerable to attack.

Logging and auditing take different approaches to collecting data. A logging infrastructure provides a framework for individual programs running on the system to report whatever events are considered interesting: the sshd program may report each successful or failed login attempt, while the sendmail program may report each time it sends an e-mail on behalf of a local or remote user. An auditing infrastructure, on the other hand, reports each instance of certain low-level events, such as entry to the setuid system call, regardless of which program caused the event to occur.

Auditing has the advantage of being more comprehensive, but the disadvantage of reporting a large amount of information, most of which is uninteresting. Logging (particularly using a standard framework like syslog) has the advantage of being compatible with a wide variety of client applications, and of reporting only information considered important by each application, but the disadvantage that the information reported is not consistent between applications.

A robust infrastructure will perform both logging and auditing, and will use configurable automated methods of summarizing the reported data, so that system administrators can remove or compress reports of events known to be uninteresting in favor of alert monitoring for events known to be interesting.

This section discusses how to configure logging, log monitoring, and auditing, using tools included with RHEL6. It is recommended that rsyslog be used for logging, with logwatch providing summarization, and that auditd be used for auditing, with aureport providing summarization.

3.6.1. Configure Rsyslog

Rsyslog is an enhanced, multi-threaded syslog daemon. This section discusses how to configure rsyslog for best effect, and how to use tools provided with the system to maintain and monitor your logs.

3.6.1.a. Rsyslog service is enabled

The rsyslog service should be enabled.

Security identifiers

  • CCE-3679-8

3.6.1.2. Ensure All Important Messages are Captured


The default RHEL6 rsyslog configuration stores the facilities authpriv, cron, and mail in named logs. This guide describes the implementation of the following configuration, but any configuration which stores the important facilities and is usable by the administrators will suffice:

  • Store each of the facilities kern, daemon, and syslog in its own log, so that it will be easy to access information about messages from those facilities.

  • Restrict the information stored in /var/log/messages to only the facilities auth and user, and store all messages from those facilities. Messages can easily become cluttered otherwise.

  • Store information about all facilities which should not be in use at this site in a file called /var/log/unused.log. If any messages are logged to this file at some future point, this may be an indication that an unknown service is running, and should be investigated. In addition, if news and uucp are not in use at this site, remove the directive from the default syslog.conf which stores those facilities.


Making use of the local facilities is also recommended. Specific configuration is beyond the scope of this guide, but applications such as SSH can easily be configured to log to a local facility which is not being used for anything else. If this is done, reconfigure /etc/syslog.conf to store this facility in an appropriate named log or in /var/log/messages, rather than in /var/log/unused.log.

3.6.1.3. Confirm Existence and Permissions of System Log Files

For each log file LOGFILE referenced in /etc/rsyslog.conf, run the commands:

# touch LOGFILE
# chown root:root LOGFILE
# chmod 0600 LOGFILE

Some logs may contain sensitive information, so it is better to restrict permissions so that only administrative users can read or write logfiles.

3.6.1.3.a. User ownership of System Log Files

All syslog log files should be owned by user 0.

Security identifiers

  • CCE-4366-1

3.6.1.3.b. Group ownership of System Log Files

All syslog log files should be group owned group 0.

Security identifiers

  • CCE-3701-0

3.6.1.3.c. Permissions on System Log Files

File permissions for all syslog log files should be set correctly.

Security identifiers

  • CCE-4233-3

3.6.1.4. Syslog logs should be sent to a remote loghost


If system logs are to be useful in detecting malicious activities, it is necessary to send logs to a remote server. An intruder who has compromised the root account on a machine may delete the log entries which indicate that the system was attacked before they are seen by an administrator.

3.6.1.4.a. Send Logs to a Remote Loghost

Syslog logs should be sent to a remote loghost

Security identifiers

  • CCE-4260-6

3.6.1.5. Rsyslog shouldn't be run in a compatibility mode

Rsyslog can be run in a compatibility mode which simulates the behavior of its older versions. The version to be compatible with is specified with a command line option. It is advisable to run the daemon in a mode that matches its current version. Using an older mode may alter your configuration in an unexpected way. The mode can be configured by changing the value of the SYSLOGD_OPTIONS variable in /etc/sysconfig/rsyslog.

3.6.1.5.a. Rsyslog shouldn't be run in a compatibility mode

An appropriate compatibility mode, that matches the daemons current version should be specified using the SYSLOGD_OPTION variable in /etc/sysconfig/rsyslog.

3.6.1.6. Ensure All Logs are Rotated by logrotate

Edit the file /etc/logrotate.d/syslog. Find the first line, which should look like this:

/var/log/messages /var/log/secure /var/log/maillog /var/log/spooler /var/log/boot.log /var/log/cron {

Edit this line so that it contains a one-space-separated listing of each log file referenced in /etc/rsyslog.conf.
All logs in use on a system must be rotated regularly, or the log files will consume disk space over time, eventually interfering with system operation. The file /etc/logrotate.d/syslog is the configuration file used by the logrotate program to maintain all log files written by syslog. By default, it rotates logs weekly and stores four archival copies of each log. These settings can be modified by editing /etc/logrotate.conf, but the defaults are sufficient for purposes of this guide.

Note that logrotate is run nightly by the cron job /etc/cron.daily/logrotate. If particularly active logs need to be rotated more often than once a day, some other mechanism must be used.

3.6.1.6.a. All Logs are Rotated by logrotate

The logrotate (syslog rotater) service should be enabled.

Security identifiers

  • CCE-4182-2

3.6.1.7. Monitor Suspicious Log Messages using Logwatch

The system includes an extensible program called Logwatch for reporting on unusual items in syslog. Logwatch is valuable because it provides a parser for the syslog entry format and a number of signatures for types of lines which are considered to be mundane or noteworthy. Logwatch has a number of downsides: the signatures can be inaccurate and are not always categorized consistently, and you must be able to program in Perl in order to customize the signature database. However, it is recommended that all Linux sites which do not have time to deploy a third-party log monitoring application run Logwatch in its default configuration. This provides some useful information about system activity in exchange for very little administrator effort.

This guide recommends that Logwatch be run only on the central logserver, if your site has one, in order to focus administrator attention by sending all daily logs in a single e-mail.

3.6.1.7.1. Configure Logwatch on the Central Log Server

Is this machine the central log server? If so, edit the file /etc/logwatch/conf/logwatch.conf. Add or correct the following lines:

HostLimit = no
SplitHosts = yes
MultiEmail = no
Service = -zz-disk_space

On a central logserver, you want Logwatch to summarize all syslog entries, including those which did not originate on the logserver itself. The HostLimit setting tells Logwatch to report on all hosts, not just the one on which it is running.

If SplitHosts is set, Logwatch will separate entries by hostname. This makes the report longer but significantly more usable. If it is not set, then Logwatch will not report which host generated a given log entry, and that information is almost always necessary. If MultiEmail is set, then each host's information will be sent in a separate e-mail message. This is a matter of preference.

The Service directive -zz-disk space tells Logwatch not to run the zz-disk space report, which reports on free disk space. Since all log monitoring is being done on the central logserver, the disk space listing will always be that of the logserver, regardless of which host is being monitored. This is confusing, so disable that service. Note that this does mean that Logwatch will not monitor disk usage information. Many workarounds are possible, such as running df on each host daily via cron and sending the output to syslog so that it will be reported to the logserver.

3.6.1.7.2. Remove Logwatch on Clients if a Logserver Exists

Does your site have a central logserver which has been configured to report on logs received from all systems? If so:

# yum remove logwatch

If no logserver exists, it will be necessary for each machine to run Logwatch individually. Using a central logserver provides the security and reliability benefits discussed earlier, and also makes monitoring logs easier and less time-intensive for administrators.

3.6.2. System Accounting with auditd

The audit service is the current Linux recommendation for kernel-level auditing. By default, the service records 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. The audit service, in its default configuration, is strongly recommended for all sites, regardless of whether they are running SELinux.

DoD or federal networks often have substantial auditing requirements and auditd can be configured to meet these requirements.

Typical DoD requirements include:

  • Ensure Auditing is Configured to Collect Certain System Events

    • Information on the Use of Print Command (unsuccessful and successful)

    • Startup and Shutdown Events (unsuccessful and successful)

  • Ensure the auditing software can record the following for each audit event:

    • Date and time of the event

    • Userid that initiated the event

    • Type of event

    • Success or failure of the event

    • For I&A events, the origin of the request (e.g., terminal ID)

    • For events that introduce an object into a user’s address space, and for object deletion events, the name of the object, and in MLS systems, the objects security level.

  • Ensure files are backed up no less than weekly onto a different system than the system being audited or backup media.

  • Ensure old logs are closed out and new audit logs are started daily

  • Ensure the configuration is immutable. With the -e 2 setting a reboot will be required to change any audit rules.

  • Ensure that the audit data files have permissions of 640, or more restrictive.

3.6.2.1. Enable the auditd Service

Ensure that the auditd service is enabled (this is the default):

# chkconfig auditd on

By default, auditd logs only SELinux denials, which are helpful for debugging SELinux and discovering intrusion attempts, and certain types of security events, such as modifications to user accounts (useradd, passwd, etc), login events, and calls to sudo.

Data is stored in /var/log/audit/audit.log. By default, auditd rotates 4 logs by size (5MB), retaining a maximum of 20MB of data in total, and refuses to write entries when the disk is too full. This minimizes the risk of audit data filling its partition and impacting other services. However, it is possible to lose audit data if the system is busy.

3.6.2.1.a. Auditd service is enabled

The auditd service should be enabled.

Security identifiers

  • CCE-4292-9

3.6.2.2. Configure auditd Data Retention

  • Determine STOREMB , the amount of audit data (in megabytes) which should be retained in each log file. Edit the file /etc/audit/auditd.conf. Add or modify the following line:

    max_log_file = STOREMB

  • Use a dedicated partition (or logical volume) for log files. It is straightforward to create such a partition or logical volume during system installation time. The partition should be larger than the maximum space which auditd will ever use, which is the maximum size of each log file (max log file) multiplied by the number of log files (num logs). Ensure the partition is mounted on /var/log/audit.

  • If your site requires that the machine be disabled when auditing cannot be performed, configure auditd to halt the system when disk space for auditing runs low. Edit /etc/audit/auditd.conf, and add or correct the following lines:

    space_left_action = email
    action_mail_acct = root
    admin_space_left_action = halt

The default action to take when the logs reach their maximum size is to rotate the log files, discarding the oldest one. If it is more important to retain all possible auditing information, even if that opens the possibility of running out of space and taking the action defined by admin space left action, add or correct the line:

max_log_file_action = keep_logs

By default, auditd retains 4 log files of size 5Mb apiece. For a busy system or a system which is thoroughly auditing system activity, this is likely to be insufficient.

The log file size needed will depend heavily on what types of events are being audited. First configure auditing to log all the events of interest. Then monitor the log size manually for a while to determine what file size will allow you to keep the required data for the correct time period.

Using a dedicated partition for /var/log/audit prevents the auditd logs from disrupting system functionality if they fill the partition, and, more importantly, prevents other activity in /var from filling the partition and stopping the audit trail. (The audit logs are size-limited and therefore unlikely to grow without bound unless configured to do so.) Some machines may have requirements that no actions occur which cannot be audited. If this is the case, then auditd can be configured to halt the machine if it runs out of space.

Note: Since older logs are rotated, configuring auditd this way does not prevent older logs from being rotated away before they can be viewed.

If your system is configured to halt when logging cannot be performed, make sure this can never happen under normal circumstances! Ensure that /var/log/audit is on its own partition, and that this partition is larger than the maximum amount of data auditd will retain normally.

3.6.2.3. Enable Auditing for Processes Which Start Prior to the Audit Daemon

To ensure that all processes can be audited, even those which start prior to the audit daemon, add the argument audit=1 to the kernel line in /boot/grub/grub.conf, in the manner below:

kernel /vmlinuz-version ro vga=ext root=/dev/VolGroup00/LogVol00 rhgb quiet audit=1

Each process on the system carries an ”auditable” flag which indicates whether its activities can be audited. Although auditd takes care of enabling this for all processes which launch after it does, adding the kernel argument ensures that it is set for every process during boot.

3.6.2.3.a. Enable Auditing for Processes Which Start Prior to the Audit Daemon

To ensure that all processes can be audited, even those which start prior to the audit daemon, add the argument audit=1 to the kernel line in /boot/grub/grub.conf

Security identifiers

  • CCE-15026-8

3.6.2.4. Configure auditd Rules for Comprehensive Auditing

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 may be a good source of further information.

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 are controlled in 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 as such. See documentation in /usr/share/doc/audit-version and in the related man pages for more details.

Recommended audit rules are provided in /usr/share/doc/audit-version/stig.rules. In order to activate those rules:

# cp /usr/share/doc/audit-version/stig.rules /etc/audit/audit.rules

and then edit /etc/audit/audit.rules and 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, activate the new rules:

# service auditd restart

3.6.2.4.1. Records Events that Modify Date and Time Information

Add the following to /etc/audit/audit.rules, setting ARCH to either b32 or b64 as appropriate for your system:

-a always,exit -F arch=ARCH -S adjtimex -S settimeofday -S stime -k time-change
-a always,exit -F arch=ARCH -S clock_settime -k time-change
-w /etc/localtime -p wa -k time-change

3.6.2.4.1.a. Records Events that Modify Date and Time Information

Audit rules about time

Security identifiers

  • CCE-14051-7

3.6.2.4.2. Record Events that Modify User/Group Information

Add the following to /etc/audit/audit.rules, in order to capture events that modify account changes:

-w /etc/group -p wa -k identity
-w /etc/passwd -p wa -k identity
-w /etc/gshadow -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/security/opasswd -p wa -k identity

3.6.2.4.2.a. Record Events that Modify User/Group Information

Audit rules about User/Group Information

Security identifiers

  • CCE-14829-6

3.6.2.4.3. Record Events that Modify the System’s Network Environment

Add the following to /etc/audit/audit.rules, setting ARCH to either b32 or b64 as appropriate for your system:

-a exit,always -F arch=ARCH -S sethostname -S setdomainname -k system-locale
-w /etc/issue -p wa -k system-locale
-w /etc/issue.net -p wa -k system-locale
-w /etc/hosts -p wa -k system-locale
-w /etc/sysconfig/network -p wa -k system-locale

3.6.2.4.3.a. Record Events that Modify the System’s Network Environment

Audit rules about the System’s Network Environment

Security identifiers

  • CCE-14816-3

3.6.2.4.4. Record Events that Modify the System’s Mandatory Access Controls

Add the following to /etc/audit/audit.rules:

-w /etc/selinux/ -p wa -k MAC-policy

3.6.2.4.4.a. Record Events that Modify the System’s Mandatory Access Controls

Audit rules about the System’s Mandatory Access Controls

Security identifiers

  • CCE-14821-3

3.6.2.4.5. Ensure auditd Collects Logon and Logout Events

At a minimum the audit system should collect login info for all users and root. Add the following to /etc/audit/audit.rules:

-w /var/log/tallylog -p wa -k logins
-w /var/log/faillock/ -p wa -k logins
-w /var/log/lastlog -p wa -k logins

3.6.2.4.5.a. Auditd Collects Logon and Logout Events

Audit rules about the Logon and Logout Events

Security identifiers

  • CCE-14904-7

3.6.2.4.6. Ensure auditd Collects Process and Session Initiation Information

At a minimum the audit system should collect process information for all users and root. Add the following to /etc/audit/audit.rules:

-w /var/run/utmp -p wa -k session
-w /var/log/btmp -p wa -k session
-w /var/log/wtmp -p wa -k session

3.6.2.4.6.a. Ensure auditd Collects Process and Session Initiation Information

Audit rules about the Process and Session Initiation Information

Security identifiers

  • CCE-14679-5

3.6.2.4.7. Ensure auditd Collects Discretionary Access Control Permission Modification Events

At a minimum the audit system should collect file permission changes for all users and root. Add the following to /etc/audit/audit.rules, setting ARCH to either b32 or b64 as appropriate for your system:

-a always,exit -F arch=ARCH -S chmod -S fchmod -S fchmodat -F auid>=500 -F auid!=4294967295 -k perm_mod
-a always,exit -F arch=ARCH -S chown -S fchown -S fchownat -S lchown -F auid>=500 -F auid!=4294967295 -k perm_mod
-a always,exit -F arch=ARCH -S setxattr -S lsetxattr -S fsetxattr -S removexattr -S lremovexattr -S fremovexattr -F auid>=500 -F auid!=4294967295 -k perm_mod

3.6.2.4.7.a. Ensure auditd Collects Discretionary Access Control Permission Modification Events

Audit rules about the Discretionary Access Control Permission Modification Events

Security identifiers

  • CCE-14058-2

3.6.2.4.8. Ensure auditd Collects Unauthorized Access Attempts to Files (unsuccessful)

At a minimum the audit system should collect unauthorized file accesses for all users and root. Add the following to /etc/audit/audit.rules, setting ARCH to either b32 or b64 as appropriate for your system:

-a always,exit -F arch=ARCH -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EACCES -F auid>=500 -F auid!=4294967295 -k access
-a always,exit -F arch=ARCH -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EPERM -F auid>=500 -F auid!=4294967295 -k access

3.6.2.4.8.a. Ensure auditd Collects Unauthorized Access Attempts to Files (unsuccessful)

Audit rules about the Unauthorized Access Attempts to Files (unsuccessful)

Security identifiers

  • CCE-14917-9

3.6.2.4.9. Ensure auditd Collects Information on the Use of Privileged Commands

At a minimum the audit system should collect the execution of privileged commands for all users and root. Find all set-uid programs by running find /bin -type f -perm -04000 2>/dev/null and for each such program, add a rule similar to the following to /etc/audit/audit.rules, replacing /bin/ping by path to the program in question:

-a always,exit -F path=/bin/ping -F perm=x -F auid>=500 -F auid!=4294967295 -k privileged

3.6.2.4.9.a. Ensure auditd Collects Information on the Use of Privileged Commands

Audit rules about the Information on the Use of Privileged Commands

Security identifiers

  • CCE-14296-8

3.6.2.4.10. Ensure auditd Collects Information on Exporting to Media (successful)

At a minimum the audit system should collect media exportation events for all users and root. Add the following to /etc/audit/audit.rules, setting ARCH to either b32 or b64 as appropriate for your system:

-a always,exit -F arch=ARCH -S mount -F auid>=500 -F auid!=4294967295 -k export

3.6.2.4.10.a. Ensure auditd Collects Information on Exporting to Media (successful)

Audit rules about the Information on Exporting to Media (successful)

Security identifiers

  • CCE-14569-8

3.6.2.4.11. Ensure auditd Collects Files Deletion Events by User (successful and unsuccessful)

At a minimum the audit system should collect file deletion events for all users and root. Add the following to /etc/audit/audit.rules, setting ARCH to either b32 or b64 as appropriate for your system:

-a always,exit -F arch=ARCH -S unlink -S unlinkat -S rename -S renameat -F auid>=500 -F auid!=4294967295 -k delete

3.6.2.4.11.a. Ensure auditd Collects Files Deletion Events by User (successful and unsuccessful)

Audit rules about the Files Deletion Events by User (successful and unsuccessful)

Security identifiers

  • CCE-14820-5

3.6.2.4.12. Ensure auditd Collects System Administrator Actions

At a minimum the audit system should collect administrator actions for all users and root. Append the following line to /etc/pam.d/system-auth and /etc/pam.d/password-auth:
session required pam_tty_audit.so disable=* enable=root
and the following line to /etc/pam.d/sudo and /etc/pam.d/sudo-i:
session required pam_tty_audit.so open_only enable=root
Also add the following to /etc/audit/audit.rules:

-w /etc/sudoers -p wa -k actions

3.6.2.4.12.a. Ensure auditd Collects System Administrator Actions

Audit rules about the System Administrator Actions

Security identifiers

  • CCE-14824-7

3.6.2.4.13. Ensure auditd Collects Information on Kernel Module Loading and Unloading

Add the following to /etc/audit/audit.rules in order to capture kernel module loading and unloading events:

-w /sbin/insmod -p x -k modules
-w /sbin/rmmod -p x -k modules
-w /sbin/modprobe -p x -k modules
-a always,exit -F arch=ARCH -S init_module -S delete_module -k modules

3.6.2.4.13.a. Ensure auditd Collects Information on Kernel Module Loading and Unloading

Audit rules about the Information on Kernel Module Loading and Unloading

Security identifiers

  • CCE-14688-6

3.6.2.4.14. Make the auditd Configuration Immutable

Add the following to /etc/audit/audit.rules in order to make the configuration immutable:

-e 2

With this setting, a reboot will be required to change any audit rules.

3.6.2.4.14.a. Make the auditd Configuration Immutable

Force a reboot to change audit rules

Security identifiers

  • CCE-14692-8