Chapter 4. Hardening Your System with Tools and Services

4.1. Desktop Security
4.1.1. Password Security
4.1.2. Account Locking
4.1.3. Session Locking
4.1.4. Enforcing Read-Only Mounting of Removable Media
4.2. Controlling Root Access
4.2.1. Disallowing Root Access
4.2.2. Allowing Root Access
4.2.3. Limiting Root Access
4.2.4. Enabling Automatic Logouts
4.2.5. Securing the Boot Loader
4.2.6. Protecting Hard and Symbolic Links
4.3. Securing Services
4.3.1. Risks To Services
4.3.2. Identifying and Configuring Services
4.3.3. Insecure Services
4.3.4. Securing rpcbind
4.3.5. Securing rpc.mountd
4.3.6. Securing NIS
4.3.7. Securing NFS
4.3.8. Securing the Apache HTTP Server
4.3.9. Securing FTP
4.3.10. Securing Postfix
4.3.11. Securing SSH
4.3.12. Securing PostgreSQL
4.3.13. Securing Docker
4.4. Securing Network Access
4.4.1. Securing Services With TCP Wrappers and xinetd
4.4.2. Verifying Which Ports Are Listening
4.4.3. Disabling Source Routing
4.4.4. Reverse Path Forwarding
4.5. Using Firewalls
4.5.1. Introduction to firewalld
4.5.2. Installing firewalld
4.5.3. Configuring firewalld
4.5.4. Using the iptables Service
4.5.5. Additional Resources
4.6. Securing DNS Traffic with DNSSEC
4.6.1. Introduction to DNSSEC
4.6.2. Understanding DNSSEC
4.6.3. Understanding Dnssec-trigger
4.6.4. VPN Supplied Domains and Name Servers
4.6.5. Recommended Naming Practices
4.6.6. Understanding Trust Anchors
4.6.7. Installing DNSSEC
4.6.8. Using Dnssec-trigger
4.6.9. Using dig With DNSSEC
4.6.10. Setting up Hotspot Detection Infrastructure for Dnssec-trigger
4.6.11. Configuring DNSSEC Validation for Connection Supplied Domains
4.6.12. Additional Resources
4.7. Securing Virtual Private Networks (VPNs)
4.7.1. IPsec VPN Using Libreswan
4.7.2. VPN Configurations Using Libreswan
4.7.3. Host-To-Host VPN Using Libreswan
4.7.4. Site-to-Site VPN Using Libreswan
4.7.5. Site-to-Site Single Tunnel VPN Using Libreswan
4.7.6. Subnet Extrusion Using Libreswan
4.7.7. Road Warrior Application Using Libreswan
4.7.8. Road Warrior Application Using Libreswan and XAUTH with X.509
4.7.9. Additional Resources
4.8. Using OpenSSL
4.8.1. Creating and Managing Encryption Keys
4.8.2. Generating Certificates
4.8.3. Verifying Certificates
4.8.4. Encrypting and Decrypting a File
4.8.5. Generating Message Digests
4.8.6. Generating Password Hashes
4.8.7. Generating Random Data
4.8.8. Benchmarking Your System
4.8.9. Configuring OpenSSL
4.9. Using stunnel
4.9.1. Installing stunnel
4.9.2. Configuring stunnel as a TLS Wrapper
4.9.3. Starting, Stopping, and Restarting stunnel
4.10. Encryption
4.10.1. Using LUKS Disk Encryption
4.10.2. Creating GPG Keys
4.10.3. Using openCryptoki for Public-Key Cryptography
4.10.4. Using Smart Cards to Supply Credentials to OpenSSH
4.10.5. Trusted and Encrypted Keys
4.10.6. Using the Random Number Generator
4.11. Hardening TLS Configuration
4.11.1. Choosing Algorithms to Enable
4.11.2. Using Implementations of TLS
4.11.3. Configuring Specific Applications
4.11.4. Additional Information
4.12. Using MACsec (IEEE 802.1AE)

4.1. Desktop Security

Red Hat Enterprise Linux 7 offers several ways for hardening the desktop against attacks and preventing unauthorized accesses. This section describes recommended practices for user passwords, session and account locking, and safe handling of removable media.

4.1.1. Password Security

Passwords are the primary method that Red Hat Enterprise Linux 7 uses to verify a user's identity. This is why password security is so important for protection of the user, the workstation, and the network.
For security purposes, the installation program configures the system to use Secure Hash Algorithm 512 (SHA512) and shadow passwords. It is highly recommended that you do not alter these settings.
If shadow passwords are deselected during installation, all passwords are stored as a one-way hash in the world-readable /etc/passwd file, which makes the system vulnerable to offline password cracking attacks. If an intruder can gain access to the machine as a regular user, he can copy the /etc/passwd file to his own machine and run any number of password cracking programs against it. If there is an insecure password in the file, it is only a matter of time before the password cracker discovers it.
Shadow passwords eliminate this type of attack by storing the password hashes in the file /etc/shadow, which is readable only by the root user.
This forces a potential attacker to attempt password cracking remotely by logging into a network service on the machine, such as SSH or FTP. This sort of brute-force attack is much slower and leaves an obvious trail as hundreds of failed login attempts are written to system files. Of course, if the cracker starts an attack in the middle of the night on a system with weak passwords, the cracker may have gained access before dawn and edited the log files to cover his tracks.
In addition to format and storage considerations is the issue of content. The single most important thing a user can do to protect his account against a password cracking attack is create a strong password.

Note

Red Hat recommends using a central authentication solution, such as Red Hat Identity Management (IdM). Using a central solution is preferred over using local passwords. For details, see:

4.1.1.1. Creating Strong Passwords

When creating a secure password, the user must remember that long passwords are stronger than short and complex ones. It is not a good idea to create a password of just eight characters, even if it contains digits, special characters and uppercase letters. Password cracking tools, such as John The Ripper, are optimized for breaking such passwords, which are also hard to remember by a person.
In information theory, entropy is the level of uncertainty associated with a random variable and is presented in bits. The higher the entropy value, the more secure the password is. According to NIST SP 800-63-1, passwords that are not present in a dictionary comprised of 50000 commonly selected passwords should have at least 10 bits of entropy. As such, a password that consists of four random words contains around 40 bits of entropy. A long password consisting of multiple words for added security is also called a passphrase, for example:
randomword1 randomword2 randomword3 randomword4
If the system enforces the use of uppercase letters, digits, or special characters, the passphrase that follows the above recommendation can be modified in a simple way, for example by changing the first character to uppercase and appending "1!". Note that such a modification does not increase the security of the passphrase significantly.
Another way to create a password yourself is using a password generator. The pwmake is a command-line tool for generating random passwords that consist of all four groups of characters – uppercase, lowercase, digits and special characters. The utility allows you to specify the number of entropy bits that are used to generate the password. The entropy is pulled from /dev/urandom. The minimum number of bits you can specify is 56, which is enough for passwords on systems and services where brute force attacks are rare. 64 bits is adequate for applications where the attacker does not have direct access to the password hash file. For situations when the attacker might obtain the direct access to the password hash or the password is used as an encryption key, 80 to 128 bits should be used. If you specify an invalid number of entropy bits, pwmake will use the default of bits. To create a password of 128 bits, enter the following command:
pwmake 128
While there are different approaches to creating a secure password, always avoid the following bad practices:
  • Using a single dictionary word, a word in a foreign language, an inverted word, or only numbers.
  • Using less than 10 characters for a password or passphrase.
  • Using a sequence of keys from the keyboard layout.
  • Writing down your passwords.
  • Using personal information in a password, such as birth dates, anniversaries, family member names, or pet names.
  • Using the same passphrase or password on multiple machines.
While creating secure passwords is imperative, managing them properly is also important, especially for system administrators within larger organizations. The following section details good practices for creating and managing user passwords within an organization.

4.1.1.2. Forcing Strong Passwords

If an organization has a large number of users, the system administrators have two basic options available to force the use of strong passwords. They can create passwords for the user, or they can let users create their own passwords while verifying the passwords are of adequate strength.
Creating the passwords for the users ensures that the passwords are good, but it becomes a daunting task as the organization grows. It also increases the risk of users writing their passwords down, thus exposing them.
For these reasons, most system administrators prefer to have the users create their own passwords, but actively verify that these passwords are strong enough. In some cases, administrators may force users to change their passwords periodically through password aging.
When users are asked to create or change passwords, they can use the passwd command-line utility, which is PAM-aware (Pluggable Authentication Modules) and checks to see if the password is too short or otherwise easy to crack. This checking is performed by the pam_pwquality.so PAM module.

Note

In Red Hat Enterprise Linux 7, the pam_pwquality PAM module replaced pam_cracklib, which was used in Red Hat Enterprise Linux 6 as a default module for password quality checking. It uses the same back end as pam_cracklib.
The pam_pwquality module is used to check a password's strength against a set of rules. Its procedure consists of two steps: first it checks if the provided password is found in a dictionary. If not, it continues with a number of additional checks. pam_pwquality is stacked alongside other PAM modules in the password component of the /etc/pam.d/passwd file, and the custom set of rules is specified in the /etc/security/pwquality.conf configuration file. For a complete list of these checks, see the pwquality.conf (8) manual page.

Example 4.1. Configuring password strength-checking in pwquality.conf

To enable using pam_quality, add the following line to the password stack in the /etc/pam.d/passwd file:
password    required    pam_pwquality.so retry=3
Options for the checks are specified one per line. For example, to require a password with a minimum length of 8 characters, including all four classes of characters, add the following lines to the /etc/security/pwquality.conf file:
minlen = 8 
minclass = 4
To set a password strength-check for character sequences and same consecutive characters, add the following lines to /etc/security/pwquality.conf:
maxsequence = 3
maxrepeat = 3
In this example, the password entered cannot contain more than 3 characters in a monotonic sequence, such as abcd, and more than 3 identical consecutive characters, such as 1111.

Note

As the root user is the one who enforces the rules for password creation, they can set any password for themselves or for a regular user, despite the warning messages.

4.1.1.3. Configuring Password Aging

Password aging is another technique used by system administrators to defend against bad passwords within an organization. Password aging means that after a specified period (usually 90 days), the user is prompted to create a new password. The theory behind this is that if a user is forced to change his password periodically, a cracked password is only useful to an intruder for a limited amount of time. The downside to password aging, however, is that users are more likely to write their passwords down.
To specify password aging under Red Hat Enterprise Linux 7, make use of the chage command.

Important

In Red Hat Enterprise Linux 7, shadow passwords are enabled by default. For more information, see the Red Hat Enterprise Linux 7 System Administrator's Guide.
The -M option of the chage command specifies the maximum number of days the password is valid. For example, to set a user's password to expire in 90 days, use the following command:
chage -M 90 username
In the above command, replace username with the name of the user. To disable password expiration, use the value of -1 after the -M option.
For more information on the options available with the chage command, see the table below.

Table 4.1. chage command line options

Option Description
-d days Specifies the number of days since January 1, 1970 the password was changed.
-E date Specifies the date on which the account is locked, in the format YYYY-MM-DD. Instead of the date, the number of days since January 1, 1970 can also be used.
-I days Specifies the number of inactive days after the password expiration before locking the account. If the value is 0, the account is not locked after the password expires.
-l Lists current account aging settings.
-m days Specify the minimum number of days after which the user must change passwords. If the value is 0, the password does not expire.
-M days Specify the maximum number of days for which the password is valid. When the number of days specified by this option plus the number of days specified with the -d option is less than the current day, the user must change passwords before using the account.
-W days Specifies the number of days before the password expiration date to warn the user.
You can also use the chage command in interactive mode to modify multiple password aging and account details. Use the following command to enter interactive mode:
chage <username>
The following is a sample interactive session using this command:
~]# chage juan
Changing the aging information for juan
Enter the new value, or press ENTER for the default
Minimum Password Age [0]: 10
Maximum Password Age [99999]: 90
Last Password Change (YYYY-MM-DD) [2006-08-18]:
Password Expiration Warning [7]:
Password Inactive [-1]:
Account Expiration Date (YYYY-MM-DD) [1969-12-31]:
You can configure a password to expire the first time a user logs in. This forces users to change passwords immediately.
  1. Set up an initial password. To assign a default password, enter the following command at a shell prompt as root:
    passwd username

    Warning

    The passwd utility has the option to set a null password. Using a null password, while convenient, is a highly insecure practice, as any third party can log in and access the system using the insecure user name. Avoid using null passwords wherever possible. If it is not possible, always make sure that the user is ready to log in before unlocking an account with a null password.
  2. Force immediate password expiration by running the following command as root:
    chage -d 0 username
    This command sets the value for the date the password was last changed to the epoch (January 1, 1970). This value forces immediate password expiration no matter what password aging policy, if any, is in place.
Upon the initial log in, the user is now prompted for a new password.

4.1.2. Account Locking

In Red Hat Enterprise Linux 7, the pam_faillock PAM module allows system administrators to lock out user accounts after a specified number of failed attempts. Limiting user login attempts serves mainly as a security measure that aims to prevent possible brute force attacks targeted to obtain a user's account password.
With the pam_faillock module, failed login attempts are stored in a separate file for each user in the /var/run/faillock directory.

Note

The order of lines in the failed attempt log files is important. Any change in this order can lock all user accounts, including the root user account when the even_deny_root option is used.
Follow these steps to configure account locking:
  1. To lock out any non-root user after three unsuccessful attempts and unlock that user after 10 minutes, add two lines to the auth section of the /etc/pam.d/system-auth and /etc/pam.d/password-auth files. After your edits, the entire auth section in both files should look like this:
    1 auth        required      pam_env.so
    2 auth        required      pam_faillock.so preauth silent audit deny=3 unlock_time=600
    3 auth        sufficient    pam_unix.so nullok try_first_pass
    4 auth        [default=die] pam_faillock.so authfail audit deny=3 unlock_time=600
    5 auth        requisite     pam_succeed_if.so uid >= 1000 quiet_success
    6 auth        required      pam_deny.so
    Lines number 2 and 4 have been added.
  2. Add the following line to the account section of both files specified in the previous step:
    account     required      pam_faillock.so
  3. To apply account locking for the root user as well, add the even_deny_root option to the pam_faillock entries in the /etc/pam.d/system-auth and /etc/pam.d/password-auth files:
    auth        required      pam_faillock.so preauth silent audit deny=3 even_deny_root unlock_time=600
    auth        sufficient    pam_unix.so nullok try_first_pass
    auth        [default=die] pam_faillock.so authfail audit deny=3 even_deny_root unlock_time=600
    
    account     required      pam_faillock.so
When user john attempts to log in for the fourth time after failing to log in three times previously, his account is locked upon the fourth attempt:
[yruseva@localhost ~]$ su - john
Account locked due to 3 failed logins
su: incorrect password
To prevent the system from locking users out even after multiple failed logins, add the following line just above the line where pam_faillock is called for the first time in both /etc/pam.d/system-auth and /etc/pam.d/password-auth. Also replace user1, user2, and user3 with the actual user names.
auth [success=1 default=ignore] pam_succeed_if.so user in user1:user2:user3
To view the number of failed attempts per user, run, as root, the following command:
[root@localhost ~]# faillock
john:
When                Type  Source                                           Valid
2013-03-05 11:44:14 TTY   pts/0                                                V
To unlock a user's account, run, as root, the following command:
faillock --user <username> --reset

Keeping Custom Settings with authconfig

When modifying authentication configuration using the authconfig utility, the system-auth and password-auth files are overwritten with the settings from the authconfig utility. This can be avoided by creating symbolic links in place of the configuration files, which authconfig recognizes and does not overwrite. In order to use custom settings in the configuration files and authconfig simultaneously, configure account locking using the following steps:
  1. Check whether the system-auth and password-auth files are already symbolic links pointing to system-auth-ac and password-auth-ac (this is the system default):
    ~]# ls -l /etc/pam.d/{password,system}-auth
    If the output is similar to the following, the symbolic links are in place, and you can skip to step number 3:
    lrwxrwxrwx. 1 root root 16 24. Feb 09.29 /etc/pam.d/password-auth -> password-auth-ac
    lrwxrwxrwx. 1 root root 28 24. Feb 09.29 /etc/pam.d/system-auth -> system-auth-ac
    If the system-auth and password-auth files are not symbolic links, continue with the next step.
  2. Rename the configuration files:
    ~]# mv /etc/pam.d/system-auth /etc/pam.d/system-auth-ac
    ~]# mv /etc/pam.d/password-auth /etc/pam.d/password-auth-ac
  3. Create configuration files with your custom settings:
    ~]# vi /etc/pam.d/system-auth-local
    The /etc/pam.d/system-auth-local file should contain the following lines:
    auth        required       pam_faillock.so preauth silent audit deny=3 unlock_time=600
    auth        include        system-auth-ac
    auth        [default=die]  pam_faillock.so authfail silent audit deny=3 unlock_time=600
    
    account     required       pam_faillock.so
    account     include        system-auth-ac
    
    password    include        system-auth-ac
    
    session     include        system-auth-ac
    ~]# vi /etc/pam.d/password-auth-local
    The /etc/pam.d/password-auth-local file should contain the following lines:
    auth        required       pam_faillock.so preauth silent audit deny=3 unlock_time=600
    auth        include        password-auth-ac
    auth        [default=die]  pam_faillock.so authfail silent audit deny=3 unlock_time=600
    
    account     required       pam_faillock.so
    account     include        password-auth-ac
    
    password    include        password-auth-ac
    
    session     include        password-auth-ac
  4. Create the following symbolic links:
    ~]# ln -sf /etc/pam.d/system-auth-local /etc/pam.d/system-auth
    ~]# ln -sf /etc/pam.d/password-auth-local /etc/pam.d/password-auth
For more information on various pam_faillock configuration options, see the pam_faillock(8) manual page.

4.1.3. Session Locking

Users may need to leave their workstation unattended for a number of reasons during everyday operation. This could present an opportunity for an attacker to physically access the machine, especially in environments with insufficient physical security measures (see Section 1.2.1, “Physical Controls”). Laptops are especially exposed since their mobility interferes with physical security. You can alleviate these risks by using session locking features which prevent access to the system until a correct password is entered.

Note

The main advantage of locking the screen instead of logging out is that a lock allows the user's processes (such as file transfers) to continue running. Logging out would stop these processes.

4.1.3.1. Locking Virtual Consoles Using vlock

Users may also need to lock a virtual console. This can be done using a utility called vlock. To install this utility, execute the following command as root:
~]# yum install vlock
After installation, any console session can be locked using the vlock command without any additional parameters. This locks the currently active virtual console session while still allowing access to the others. To prevent access to all virtual consoles on the workstation, execute the following:
vlock -a
In this case, vlock locks the currently active console and the -a option prevents switching to other virtual consoles.
See the vlock(1) man page for additional information.

Important

There are several known issues relevant to the version of vlock currently available for Red Hat Enterprise Linux 7:
  • The program does not currently allow unlocking consoles using the root password. Additional information can be found in BZ#895066.
  • Locking a console does not clear the screen and scrollback buffer, allowing anyone with physical access to the workstation to view previously issued commands and any output displayed in the console. See BZ#807369 for more information.

4.1.4. Enforcing Read-Only Mounting of Removable Media

To enforce read-only mounting of removable media (such as USB flash disks), the administrator can use a udev rule to detect removable media and configure them to be mounted read-only using the blockdev utility. This is sufficient for enforcing read-only mounting of physical media.

Using blockdev to Force Read-Only Mounting of Removable Media

To force all removable media to be mounted read-only, create a new udev configuration file named, for example, 80-readonly-removables.rules in the /etc/udev/rules.d/ directory with the following content:
SUBSYSTEM=="block",ATTRS{removable}=="1",RUN{program}="/sbin/blockdev --setro %N"
The above udev rule ensures that any newly connected removable block (storage) device is automatically configured as read-only using the blockdev utility.

Applying New udev Settings

For these settings to take effect, the new udev rules need to be applied. The udev service automatically detects changes to its configuration files, but new settings are not applied to already existing devices. Only newly connected devices are affected by the new settings. Therefore, you need to unmount and unplug all connected removable media to ensure that the new settings are applied to them when they are next plugged in.
To force udev to re-apply all rules to already existing devices, enter the following command as root:
~# udevadm trigger
Note that forcing udev to re-apply all rules using the above command does not affect any storage devices that are already mounted.
To force udev to reload all rules (in case the new rules are not automatically detected for some reason), use the following command:
~# udevadm control --reload