You only need one bad password to compromise a server. As a result, that one password subverts all the security we diligently built. Linux thrives on allowing Admins to do whatever they want, but unfortunately, that also means allowing Admins to set weak passwords. Great power, great responsibility… However, this also means we have the power to enforce strong passwords! We can prevent weak password use, and prevent storing passwords in a weak hashing algorithm. Let’s explore how we can better harden Linux security through stronger passwords and hashing requirements.
The following applies to Debian based systems only.
Enforce Password Complexity
Pluggable Authentication Modules(PAM) is the Linux system responsible for user authentication. Adding the “libpwquality” PAM module allows us to check password strength, and prevent weak ones. Use the following command to install the module.
apt install libpam-pwquality
Now we need to set the password complexity requirements. The “/etc/pam.d/common-password” file holds the configurations we need to edit. Open the file with your preferred text editor and change the config as described below.
# Below is the OLD config, comment out the line.
#password requisite pam_pwquality.so retry=3
# Add this NEW config below the line we just commented out.
password requisite pam_pwquality.so retry=3 minlen=13 maxrepeat=3 ucredit=-1 lcredit=-1 ocredit=-1 dcredit=-1 difok=5 reject_username enforce_for_root
Lets review the options in our policy
- retry=3: This option will prompt the user 3 times before exiting and returning an error.
- minlen=13: This specifies that the password cannot be less than 13 characters.
- maxrepeat=3: Maximum of 3 repeated sequential characters in the password.
- ucredit=-1: This option requires at least one uppercase character in the password.
- lcredit=-1: This option requires at least one lowercase character in the password.
- dcredit=-1: This option requires the password to have at least one numeric character.
- ocredit=-1: This option requires at least one special character in the password.
- difok=5: Minimum of 5 characters must be different from the previous password.
- reject_username: Rejects a password if it consists of the username; forward or in reverse.
- enforce_for_root: Enforce policy, even to the root user.
Enforce Strong System Password Storage
Computers store passwords in a one-way hashing algorithm. This turns a clear-text password like “5up3rG00dPVV” to “2e545bdb53dd16c3994e7c532734c7f0”. There is no way to turn the hash output, gibberish, back into the original password. However, we can make guesses at what the password is and check if the outputting gibberish matches the gibberish stored on the computer. This is the over-simplified concept of password cracking.
We can make password cracking extremely difficult by changing the default one-way hashing algorithm settings. The default hashing algorithm is SHA512 in Ubuntu. SHA512 is a cryptographic hash algorithm and designed to be fast. However, to make our passwords hard to crack offline we want a computationally expensive hashing process. That will result in password guesses being very slow. We can increase the hashing strength by increasing the number of hashing rounds. The default in Ubuntu is 5000 hashing rounds. This means one password runs through the hashing algorithm 5000 times. If we increase this number to 100,000 the passwords will be 20X harder to crack offline.
Linux system password storage settings are held in “/etc/pam.d/common-password”. Open “/etc/pam.d/common-password” in your preferred text editor to make the below changes.
# Find the below line
#password [success=1 default=ignore] pam_unix.so obscure use_authtok try_first_pass sha512
# Change the line to match the below.
password [success=1 default=ignore] pam_unix.so obscure use_authtok try_first_pass sha512 rounds=100000
Making this change will ensure even if an Attacker gets a copy of our “/etc/shadow” file they will not be able to break our password.
Lets review the results!