Jephe Wu - http://linuxtechres.blogspot.com
Objective: Enable password age and complexity for production Linux servers for auditing
Environment: CentOS 5
Steps:
1. modify /etc/login.defs
PASS_MAX_DAYS 60
PASS_MIN_DAYS 7 (days between password change)
PASS_MIN_LEN 8
PASS_WARN_AGE 28
2. make sure the following appears in /etc/default/useradd
INACTIVE=-1
EXPIRE=
note: this will disable password inactivity settings, INACTIVATE sets the number of days of inactivity after a password has expired before the account is locked. Normally, we don't set it by useradd or chage.
3. change the existing user password ages
chage -m 7 -M 60 -W 28 jephe
chage -m 7 -M 60 -W 28 user1
note: some other useful commands:
chage -l jephe
chage -d 0 jephe (to immediately make the password expire so that the user has to change password upon login next time,
chage -d -1 jephe (to make password not expired)
If you encounters the following issues after password expiry, you might need to change ssh configuration
UsePrivilegeSeparation from yes to no, seems openssh 3.8 and above has already fixed
this issue
$ ssh jephe@servername
jephe@servername's password:
You are required to change your password immediately (password aged)
Your password has expired, the session cannot proceed.
Connection to localhost closed.
passwd -l jephe (lock user)
passwd -u jephe (unlock user)
usermod -L jephe
usermod -U jephe
note: How do I force users to change their passwords upon the first login?
1.) Firstly, lock the account to prevent the user from using the login until the change has been made:
# usermod -L jephe
# chage -d 0 jephe (make password expiry immediately)
# usermod -U jephe (unlock user account)
or
According to Redhat knowledge base, you can directly push a encrypted password string to /etc/shadow.
run command 'python', the salt can be a combination of exactly 2 upper or lower case alphabetic characters, digits, the dot (.) character, or the slash (/) character such as cd or 34
import crypt; print crypt.crypt("password","salt")
The output is the encrypted password similar to
15CsBd8FAc9DN
- ctrl -d to exit python
usermod -p "
15CsBd8FAc9DN" jephe
or you might set a empty password:
usermod -p "" jephe
4. enable password complexity
make sure /etc/security/opasswd exists, otherwise, create it:
touch /etc/security/opasswd
chown root:root /etc/security/opasswd
chmod 600 /etc/security/opasswd
note: opasswd maintains a list of old passwords for every user prohibiting the reuse of old passwords. The list is located in the /etc/security/opasswd file. This is not a plain text file, but should be protected the same as the /etc/shadow file. This is normally referred to as password history.
vi /etc/pam.d/system-auth to make it looks like this:
password requisite pam_cracklib.so try_first_pass retry=3 minlen=8 lcredit=-1 ucredit=-1 dcredit=-1 ocredit=-1 difok=3
password sufficient pam_unix.so md5 shadow nullok try_first_pass use_authtok remember=6
note: minimum 8 characters, 1 lowercase, 1 upper case, 1 number, 1 special character, the new password must have 3 characters which are different with the previous one, remember the last 6 passwords which cannot be used for new password.
According to my test, you have to use lcredit=-1 ucredit=-1 dcredit=-1 ocredit=-1, not lcredit=1 ucredit=1 dcredit=1 ocredit=1, otherwise, it doesn't actually enforce that which mentioned above.
5. References
a. Securing and Hardening Red Hat Linux Production Systems- http://www.puschitz.com/SecuringLinux.shtml
b. Linux Password Policy - http://www.brandonhutchinson.com/wiki/Linux_Password_Policy
c. redhat acknowledge base - doc7382