Password Policies and Detecting Attack in Linux

CompTIABeginner
Practice Now

Introduction

In this lab, you will learn essential techniques to enhance the security of a Linux system by implementing and enforcing robust password policies. You will configure system-wide rules to enforce password complexity, requiring a minimum length and a mix of different character types, such as uppercase letters, lowercase letters, and digits. You will also set up password aging policies to ensure credentials are changed regularly, reducing the risk associated with compromised passwords by modifying core system configuration files.

Beyond establishing the policy, you will ensure these strong password requirements are applied to new user accounts. The lab then shifts from proactive security measures to reactive detection, teaching you how to monitor system authentication logs. By analyzing these logs, you will be able to identify suspicious activities, such as repeated failed login attempts, which can be an indicator of a brute-force attack or other unauthorized access attempts.

Configure Local Linux Password Policy for Complexity and Age

In this step, you will learn how to strengthen the security of a Linux system by configuring a robust password policy. A strong password policy is a fundamental security control that enforces two critical aspects: complexity and age. Complexity rules ensure that passwords are not easily guessable by requiring a mix of character types, while aging rules force users to change their passwords periodically, reducing the risk of compromised credentials. You will use standard Linux utilities to modify system-wide configuration files and apply these policies.

First, let's explore password complexity. On modern Debian-based systems like Ubuntu, password quality is managed by the pam_pwquality module. Its configuration is stored in the /etc/security/pwquality.conf file.

Let's begin by examining the default settings. Use the cat command to view the contents of the configuration file. We'll use grep to filter out commented lines and empty lines to make the output cleaner.

grep -vE '^#|^$' /etc/security/pwquality.conf

You might see some default settings or the file might be empty of active configurations. Now, we will enforce a stronger policy. We need to edit this file with administrator privileges, so we'll use sudo with the nano editor.

sudo nano /etc/security/pwquality.conf

Add the following lines to the file to enforce our new policy. These settings require a password to be at least 10 characters long, and contain at least one digit, one uppercase letter, and one lowercase letter.

minlen = 10
dcredit = -1
ucredit = -1
lcredit = -1

Let's break down these options:

  • minlen = 10: Sets the minimum acceptable length for the password to 10 characters.
  • dcredit = -1: Requires at least one digit. The negative number means "at least one".
  • ucredit = -1: Requires at least one uppercase character.
  • lcredit = -1: Requires at least one lowercase character.

After adding these lines, save the file and exit nano by pressing Ctrl+X, then Y, and Enter.

Now, let's move on to configuring password aging. These settings define the maximum and minimum lifetime of a password. The default values for new user accounts are stored in /etc/login.defs.

Use grep to find the relevant settings in this file.

grep -E 'PASS_MAX_DAYS|PASS_MIN_DAYS|PASS_WARN_AGE' /etc/login.defs

You will see the default values, which are often set to a very high number for PASS_MAX_DAYS, effectively disabling expiration.

##       PASS_MAX_DAYS   Maximum number of days a password may be used.
PASS_MAX_DAYS   99999
##       PASS_MIN_DAYS   Minimum number of days allowed between password changes.
PASS_MIN_DAYS   0
##       PASS_WARN_AGE   Number of days warning is given before a password expires.
PASS_WARN_AGE   7

Let's enforce a 9000-day expiration policy. Open the file with sudo nano.

sudo nano /etc/login.defs

Find the PASS_MAX_DAYS line and change its value from 99999 to 9000. You can also set PASS_MIN_DAYS to 7 to prevent users from changing their password too frequently.

##       PASS_MAX_DAYS   Maximum number of days a password may be used.
PASS_MAX_DAYS   9000
##       PASS_MIN_DAYS   Minimum number of days allowed between password changes.
PASS_MIN_DAYS   7
##       PASS_WARN_AGE   Number of days warning is given before a password expires.
PASS_WARN_AGE   14

Save the file and exit nano. These settings in /etc/login.defs apply to users created after this change. To apply the policy to an existing user, like our labex user, we use the chage command.

First, check the current aging information for the labex user.

sudo chage -l labex

The output will show that the password never expires.

Last password change                                    : Jul 22, 2023
Password expires                                        : never
Password inactive                                       : never
Account expires                                         : never
Minimum number of days between password change          : 0
Maximum number of days between password change          : 99999
Number of days of warning before password expires       : 7

Now, use chage with the -M flag to set the maximum number of days to 9000 for the labex user.

sudo chage -M 9000 labex

Verify the change by checking the user's aging information again.

sudo chage -l labex

You will now see that the Password expires date has been updated, and the maximum number of days is set to 9000, successfully applying the aging policy.

Last password change                                    : Jul 22, 2023
Password expires                                        : Jan 01, 2048
Password inactive                                       : never
Account expires                                         : never
Minimum number of days between password change          : 0
Maximum number of days between password change          : 9000
Number of days of warning before password expires       : 7

You have now successfully configured both password complexity and aging policies on your Linux system.

Enforce Strong Passwords for New User Accounts

In this step, you will verify that the password complexity and aging policies you configured in the previous step are being enforced for new user accounts. The best way to test this is to create a new user and attempt to set a password that violates the rules. This will demonstrate how the pam_pwquality module and the system's default settings work together to secure new accounts from the moment they are created.

We will use the adduser command, which is a user-friendly, interactive script for creating users in Debian-based systems. Let's create a new user named testuser.

sudo adduser testuser

The system will immediately prompt you to set a password for the new user. This is where our policy will be tested.

First, let's try to set a simple, weak password that violates our policy. When prompted for the new password, type password and press Enter.

Adding user `testuser' ...
Adding new group `testuser' (1001) ...
Adding new user `testuser' (1001) with home directory `/home/testuser' ...
Copying files from `/etc/skel' ...
New password:

Because password violates our rules (it's too short and contains no uppercase letters or digits), the system will reject it. Let's see the reason it gives.

BAD PASSWORD: The password contains less than 1 digits

The system rejects it, pointing out the lack of digits. It violates multiple policies, but this is the first one it reports.

The system will prompt you again. Now, let's try a password that meets the length requirement but still violates the complexity rules. Type 12345 and press Enter.

BAD PASSWORD: The password contains less than 1 uppercase letters
New password:

Tips: If you accidentally create a user, you can use sudo deluser testuser to delete the user and try again.

The system rejects it again. This time, it's because the password lacks a digit. It also lacks an uppercase letter, so it does not meet our complexity requirements. Now, let's provide a password that meets all our criteria. When prompted, type StrongPass2025 and press Enter. You will be asked to retype it for confirmation.

New password:
Retype new password:
passwd: password updated successfully

Success! The system accepted the strong password. It will now ask for additional information about the user. You can simply press Enter for each prompt to accept the defaults.

Changing the user information for testuser
Enter the new value, or press ENTER for the default
        Full Name []:
        Room Number []:
        Work Phone []:
        Home Phone []:
        Other []:
Is the information correct? [Y/n] Y

The user testuser has now been created. You can verify that the user exists by using the id command.

id testuser

This will show the user's ID, group ID, and group memberships.

uid=1001(testuser) gid=1001(testuser) groups=1001(testuser)

Next, let's confirm that the password aging policy we set in /etc/login.defs was automatically applied to this new user. Use the chage command to view the aging information for testuser.

sudo chage -l testuser

The output will show that the Maximum number of days between password change is set to 9000, exactly as we configured.

Last password change                                    : Jul 22, 2023
Password expires                                        : Jan 01, 2048
Password inactive                                       : never
Account expires                                         : never
Minimum number of days between password change          : 7
Maximum number of days between password change          : 9000
Number of days of warning before password expires       : 14

Finally, to keep our system clean, let's remove the test user. The deluser command will remove the user account.

sudo deluser testuser

The system will confirm that the user has been removed.

Removing user `testuser' ...
Warning: group `testuser' has no more members.
Done.

You have successfully created a new user, tested the password policy enforcement, and verified that default aging rules were applied.

Monitor Authentication Logs for Failed Login Attempts

In this step, you will learn how to monitor system authentication logs to detect potential security threats, such as brute-force attacks. A key part of system administration is regularly reviewing logs for suspicious activity. Failed login attempts are a critical indicator of unauthorized access attempts. You will simulate a failed login and then use standard Linux commands to find and analyze the corresponding log entries.

On Debian-based systems like Ubuntu, authentication events (both successful and failed) are typically recorded in the /var/log/auth.log file. This file requires administrator privileges to read.

First, let's generate a failed login attempt. We can do this safely by using the su (substitute user) command to try to switch to our own user account, labex, but intentionally providing the wrong password.

su labex

The system will prompt you for a password. Type any incorrect password, like wrongpassword, and press Enter.

Password:
su: Authentication failure

Let's do it one more time to create a pattern of failures.

su labex

Again, enter an incorrect password. Now that we have generated some log data, let's examine the authentication log file. We'll use the tail command with sudo to view the last few lines of /var/log/auth.log, which is where the newest events are recorded.

sudo tail /var/log/auth.log

You will see several new lines related to your failed su attempts. The output will look similar to this, showing the timestamp, the process (su), and the failure message.

Jul 22 16:45:01 labex-vm su[12345]: pam_unix(su:auth): authentication failure; logname=labex uid=1000 euid=0 tty=/dev/pts/0 ruser=labex rhost=  user=labex
Jul 22 16:45:01 labex-vm su[12345]: FAILED SU (to labex) labex on /dev/pts/0
Jul 22 16:45:15 labex-vm su[12346]: pam_unix(su:auth): authentication failure; logname=labex uid=1000 euid=0 tty=/dev/pts/0 ruser=labex rhost=  user=labex
Jul 22 16:45:15 labex-vm su[12346]: FAILED SU (to labex) labex on /dev/pts/0

Manually searching through logs can be time-consuming. A more efficient method is to use grep to filter for specific keywords. Let's search for all lines containing "authentication failure".

sudo grep "authentication failure" /var/log/auth.log

This command will display only the lines that match the pattern, making it easy to spot the failed attempts you just created.

Now, let's create a simple shell script to automate this monitoring process. This script will check the log for failures and report a summary. In your ~/project directory, create a new file named log_monitor.sh using nano.

nano log_monitor.sh

Enter the following Bash script into the editor. This script uses grep with the -c flag to count the number of failed login attempts and then prints a status message.

#!/bin/bash

LOG_FILE="/var/log/auth.log"
FAILURE_COUNT=$(sudo grep -c "authentication failure" $LOG_FILE)

echo "--- Authentication Log Monitor ---"
if [ "$FAILURE_COUNT" -gt 0 ]; then
  echo "WARNING: Found $FAILURE_COUNT failed login attempts."
else
  echo "OK: No failed login attempts found."
fi
echo "--------------------------------"

Save the file and exit nano by pressing Ctrl+X, then Y, and Enter.

Next, make your new script executable using the chmod command.

chmod +x log_monitor.sh

Finally, run your monitoring script to see the result.

./log_monitor.sh

Since you generated failed logins, the script will detect them and display a warning message with the exact count.

--- Authentication Log Monitor ---
WARNING: Found 2 failed login attempts.
--------------------------------

You have now learned how to simulate, detect, and create a basic monitoring script for failed authentication attempts, a crucial skill for maintaining system security.

Summary

In this lab, you learned how to enhance Linux system security by configuring a robust local password policy. You modified the /etc/security/pwquality.conf file to enforce password complexity rules using the pam_pwquality module. This involved setting a minimum password length and requiring the inclusion of at least one digit, one uppercase letter, and one lowercase letter to protect against easily guessable credentials.

Furthermore, you explored how to ensure these strong password policies are applied when creating new user accounts. The lab also covered the critical skill of monitoring system authentication logs to detect and analyze security events, such as repeated failed login attempts, which can indicate a potential attack.