View Single Post
  #1   (View Single Post)  
Old 22nd June 2008
anomie's Avatar
anomie anomie is offline
Local
 
Join Date: Apr 2008
Location: Texas
Posts: 445
Default Enforce a better user password policy

Intro

This guide is written for sysadmins who wish to exert more influence over the passwords their users are able to choose. There is a FreeBSD (7.0, to be exact) section and a GNU/Linux (CentOS 4.6, to be exact) section. Other operating systems / versions that utilize PAM should be able to take advantage of the same – or very similar – approaches. Be sure to test on your OS / version to confirm it is behaving as you'd expect.

This short guide was inspired by some of the thoughtful commentary in the “Hardening FreeBSD” thread, starting from this post.

-----------------------------------------

A word on PAM

In a nutshell, PAM (pluggable authentication modules) is a series of libraries that provide an API to assist with authentication for services. The general idea is that PAM provides customizable authentication – which is exactly what this guide will take advantage of.

An in depth discussion of PAM is well beyond the scope of this guide. I'd recommend a visit to google, wikipedia, and/or the documentation on your system, as you prefer.

Note that FreeBSD uses OpenPAM by default, and CentOS uses Linux-PAM by default. The differences between the two are not important for the purposes of this guide.

-----------------------------------------

FreeBSD: easy tweaks to enforce better passwords

Here we'll take advantage of the powerful pam_passwdqc module.

Edit the /etc/pam.d/passwd file, and change this:
Code:
#password        requisite       pam_passwdqc.so         enforce=users
password        required        pam_unix.so             no_warn try_first_pass nullok
To this:
Code:
password        requisite       pam_passwdqc.so         enforce=users
password        required        pam_unix.so             no_warn try_first_pass nullok
(Hint: All we did was remove the #.)

That's it. Seriously.

Ok, if you want to actually customize pam_passwdqc's behavior there are a few more steps. From the manpages for pam_passwdqc(8):
Quote:
min=N0,N1,N2,N3,N4

(min=disabled,24,12,8,7) The minimum allowed password lengths for
different kinds of passwords/passphrases. The keyword disabled
can be used to disallow passwords of a given kind regardless of
their length. Each subsequent number is required to be no larger
than the preceding one.
...
...
By experimenting with this and a few other directives, we might wind up with rules that look more like this:
Code:
password        requisite       pam_passwdqc.so         min=disabled,disabled,disabled,12,10 similar=deny retry=3 enforce=users
password        required        pam_unix.so             no_warn try_first_pass nullok
What does this draconian ruleset actually mean? It means that users who change their password can only use 12-byte (or more) passwords with characters from three classes or 10-byte (or more) passwords with characters from four classes. It also means that a password too similar to the previous one will be rejected. Finally, it means the user will get three tries at coming up with a new password before passwd gives him the boot. (The last directive, which we kept from the original, means that root is not subjected to these rules.)

For much more information on the PAM file layouts and pam_passwdqc in particular, it's important to read the manpages:
CentOS: tweaks to enforce better passwords

Here we'll take advantage of the powerful, underrated, and rather poorly documented pam_cracklib module. (NB: pam_passwdqc is also available on CentOS, and could be used in a fashion similar to what we used for FreeBSD.)

Like some things in the Linux world, this isn't quite as neat and tidy as our FreeBSD solution. No offense intended; this is still very much workable, just a bit of a hack to preserve our settings.

Edit the /etc/pam.d/system-auth file (which /etc/pam.d/passwd recurses to), and change this line:
Code:
password    requisite     /lib/security/$ISA/pam_cracklib.so retry=3
To this:
Code:
password    requisite     /lib/security/$ISA/pam_cracklib.so minlen=12 lcredit=-2 ucredit=-1 dcredit=-1 ocredit=-2 retry=3
And what does this mean exactly? Think of it this way: We have a minimum password length to satisfy. But we're able to assign different character classes different “credits” in satisfying it.

The kernel.org entry on pam_cracklib describes it this way:
Quote:
dcredit=N

(N >= 0) This is the maximum credit for having digits in the new password. If you have less than or N digits, each digit will count +1 towards meeting the current minlen value. The default for dcredit is 1 which is the recommended value for minlen less than 10.
(N < 0) This is the minimum number of digits that must be met for a new password.

ucredit=N

(N >= 0) This is the maximum credit for having upper case letters in the new password. If you have less than or N upper case letters each letter will count +1 towards meeting the current minlen value. The default for ucredit is 1 which is the recommended value for minlen less than 10.
(N < 0) This is the minimum number of upper case letters that must be met for a new password.

lcredit=N

(N >= 0) This is the maximum credit for having lower case letters in the new password. If you have less than or N lower case letters, each letter will count +1 towards meeting the current minlen value. The default for lcredit is 1 which is the recommended value for minlen less than 10.
(N < 0) This is the minimum number of lower case letters that must be met for a new password.

ocredit=N

(N >= 0) This is the maximum credit for having other characters in the new password. If you have less than or N other characters, each character will count +1 towards meeting the current minlen value. The default for ocredit is 1 which is the recommended value for minlen less than 10.
(N < 0) This is the minimum number of other characters that must be met for a new password.
So in my example, users would be required to enter a password with a minimum length of 12. At least two lowercase letters, one uppercase letter, one digit, and two special characters would be needed.

Take the time to read through the pam_cracklib reference cited above. It actually performs a number of intelligent checks before it even reaches the minlength and credit rules, to ensure that users are not providing easily guessable passwords.

Now for the hack job. On CentOS, you may want to make your /etc/pam.d/system-auth file system immutable (or perhaps instead modify /etc/pam.d/passwd directly such that it does not recurse). Without doing so you run the risk of having your customization overwritten by programs that write to system-auth.

-----------------------------------------

Closing / call for feedback

This concludes our brief guide on enforcing better passwords using PAM. This is quite a broad and complex subject, so I'd like to encourage any corrections and related additions (e.g. how to require a password change for new or existing users!).
__________________
Kill your t.v.
Reply With Quote