DaemonForums  

Go Back   DaemonForums > Miscellaneous > Guides

Guides All Guides and HOWTO's.

Reply
 
Thread Tools Display Modes
  #1   (View Single Post)  
Old 22nd June 2008
anomie's Avatar
anomie anomie is offline
Local
 
Join Date: Apr 2008
Location: Texas
Posts: 446
Thanked 69 Times in 46 Posts
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
  #2   (View Single Post)  
Old 23rd June 2008
cajunman4life cajunman4life is offline
Real Name: Aaron Graves
Package Pilot
 
Join Date: May 2008
Location: Coolidge, Arizona
Posts: 203
Thanked 16 Times in 14 Posts
Default

Good looking guide, anomie.

In terms of requiring password change for new/existing users, I can write up on this tomorrow as this is something I do every now and then. I've got the next few days off, so I've got a bit of time. Unfortunately I'm much too tired right now
__________________
I just saved a bunch of money on my car insurance by fleeing the scene of the accident!
Reply With Quote
  #3   (View Single Post)  
Old 23rd June 2008
cajunman4life cajunman4life is offline
Real Name: Aaron Graves
Package Pilot
 
Join Date: May 2008
Location: Coolidge, Arizona
Posts: 203
Thanked 16 Times in 14 Posts
Default

I can't speak to the ability to do this on CentOS or any other Linux for that matter, but as promised, I'm going to show you how to quickly and easily force a password change on your users of your FreeBSD system.

Let's say you just came across this guide, and you set up your password requirements. Great! But doing this won't require your users to change their passwords to be compliant. So how would you go about doing this?

The quick and easy way is to set the "change" date on the user's password. There are a few different ways to do this, and I'll touch on each way.

The first way is by using the chsh command. The syntax is:

Code:
# chsh <username>
This will bring up vi, or whatever root's editor is. Here's an example output from my system:

Code:
Changing user information for testuser.
Login: testuser
Password: (REMOVED)
Uid [#]: 10002
Gid [# or name]: 9999
Change [month day year]:
Expire [month day year]:
Class: default
Home directory: /home/testuser
Shell: /usr/local/bin/bash
Full Name: Test User
Office Location:
Office Phone:
Home Phone:
Other information:
Once in this editor, you can type the date in the "Change" field. Honestly I'm not sure of the different formats accepted in this field, but I generally use the numerical version of month (with leading "0" if necessary), same for day, and four digit year. Use ":wq" to save and leave vi, and the next time the user is logged in, he will be informed that his password has expired, and he will have to select a new password using the rules you set up above.

Now, the other option is to use FreeBSD's "pw" command. The syntax is:

Code:
# pw usermod -p 23-Jun-2008 <username>
From the manpage:

Code:
<excerpt>
     -e date       Set the account's expiration date.  Format of the date is
                   either a UNIX time in decimal, or a date in `dd-mmm-yy[yy]'
                   format, where dd is the day, mmm is the month, either in
                   numeric or alphabetic format ('Jan', 'Feb', etc) and year
                   is either a two or four digit year.  This option also
                   accepts a relative date in the form `+n[mhdwoy]' where `n'
                   is a decimal, octal (leading 0) or hexadecimal (leading 0x)
                   digit followed by the number of Minutes, Hours, Days,
                   Weeks, Months or Years from the current date at which the
                   expiration date is to be set.

     -p date       Set the account's password expiration date.  This field is
                   similar to the account expiration date option, except that
                   it applies to forced password changes.  This is set in the
                   same manner as the -e option.
</excerpt>
I included the "-e" because it's referenced by "-p". Basically by using "pw" you're doing the same thing. There's just more than one way to do it

Now, that is all well and good, but what if your users never log out? In the real world, this may actually never be possible (dropped network connections, etc), however I thought I'd throw in this little extra tidbit: Forcing a logout on one of your users.

It's quite simple really:

Code:
# pkill -KILL -u <username>
This will log out the user you enter in <username>. And the next time they log in, they'll be forced to change their password.

Comments/fixes/concerns/questions/etc are of course welcome
__________________
I just saved a bunch of money on my car insurance by fleeing the scene of the accident!
Reply With Quote
  #4   (View Single Post)  
Old 24th June 2008
hopla hopla is offline
New User
 
Join Date: May 2008
Posts: 8
Thanked 5 Times in 2 Posts
Default

I was going to post my way of forcing (new) users to change their password, but unfortunatly canjunman beat me to it. I will post it anyway, since I have a few nice extras

Also, while writing this, I have found the reason why I also had the pam_passwdqc line in /etc/pam.d/sshd and not just in /etc/pam.d/passwd (see the forum thread anomie referred to). More about that below!

Okay, so let's start with some basics:

* your basic forced password change:

Like canjunman said, this is easiest with pw(8).
Code:
pw usermod <user> -p 0-0-0
Notice that I use 0-0-0 as date here, an easy to remember 'date' that will always be in the past

* what if a user forgot his password and you want to email him a new one?

You can quickly set a new random password, that will expire at first login, with:
Code:
pw usermod <user> -p 0-0-0 -w random
Making it (relatively) safe to email it to him. If anyone retrieves the email later on, chances are, the password has already changed.


But how can you easily make all this apply to a new user? That's where /etc/adduser.conf comes into play! Let's set it up so adduser(8) creates a user with a random, expired password by default!

First run
Code:
adduser -C
At these questions, chose these defaults:

Use password-based authentication? yes
Use an empty password? no
Use a random password? yes

After all questions are answered you will be asked to confirm the default setup, review and say 'yes'. Your changes will be saved in /etc/adduser.conf

Next up, open /etc/adduser.conf - yes this has to be done manually - and add the line:
Code:
upwexpire=0-0-0
Now create a test user with adduser(8) and check it out! (you can remove the user afterwards with rmuser)

One thing you might notice is that, when logging in the first time via ssh you are indeed forced to change your password, but no quality check is performed on it! That's why you also need the pam_passwdqc line in /etc/pam.d/sshd! Put it in so the last lines look like this:

Code:
# password
#password       sufficient      pam_krb5.so             no_warn try_first_pass
password        requisite       pam_passwdqc.so         enforce=everyone min=disabled,8,8,8,8
password        required        pam_unix.so             no_warn try_first_pass
I dont know why putting it in /etc/pam.d/passwd alone is not enough. If anyone can explain, please do!

Voil*, that's it!
Reply With Quote
  #5   (View Single Post)  
Old 24th June 2008
cajunman4life cajunman4life is offline
Real Name: Aaron Graves
Package Pilot
 
Join Date: May 2008
Location: Coolidge, Arizona
Posts: 203
Thanked 16 Times in 14 Posts
Default

Thank you hopla, with your information above I verified that with a new ssh connection, and without adding passwdqc in sshd, the new rules are not enforced.

Serves me right for trying my setting by using "login" from an already connected session.
__________________
I just saved a bunch of money on my car insurance by fleeing the scene of the accident!
Reply With Quote
  #6   (View Single Post)  
Old 24th June 2008
cajunman4life cajunman4life is offline
Real Name: Aaron Graves
Package Pilot
 
Join Date: May 2008
Location: Coolidge, Arizona
Posts: 203
Thanked 16 Times in 14 Posts
Default

Also, the pam_passwdqc(8) man page might come in handy as well
__________________
I just saved a bunch of money on my car insurance by fleeing the scene of the accident!
Reply With Quote
  #7   (View Single Post)  
Old 6th November 2008
awyeah awyeah is offline
New User
 
Join Date: Nov 2008
Posts: 4
Thanked 0 Times in 0 Posts
Default

Another dilemma. This is on a 7.1-PRERELEASE.

I added the following line to my /etc/pam.d/sshd file:

Code:
password    requisite   pam_passwdqc.so min=disabled,8,8,8,8 max=40 passphrase=0 similar=permit enforce=users random=0
This is the exact same line as I have in my /etc/pam.d/passwd file.

I set a user's password to be expired, then logged in via ssh, and it asked me to change the password. It even displayed the information about the password restrictions. However, I was able to set the password to something simple and too short (like "aa") and it took it. However, if I try to use passwd to change the password, it won't take it. Again - the exact same line, literally copied and pasted.

Any ideas why it won't enforce the restrictions on an ssh login?
Reply With Quote
  #8   (View Single Post)  
Old 6th November 2008
awyeah awyeah is offline
New User
 
Join Date: Nov 2008
Posts: 4
Thanked 0 Times in 0 Posts
Default

You know what - I answered my own question.

If you set "enforce=users" it will not enforce it... it's treating it like it's root changing their password.

If you set "enforce=everyone" then it does enforce it.

Granted, enforcing it for root is good to, I guess it's most important to have a secure password for root.

Thanks!
Reply With Quote
  #9   (View Single Post)  
Old 7th November 2008
anemos's Avatar
anemos anemos is offline
Fdisk Soldier
 
Join Date: May 2008
Location: Ελλάδα
Posts: 53
Thanked 5 Times in 5 Posts
Default

Guys, congratulations for this guide. Although I haven’t followed it yet, it seems you have done a very mindful research. However, I do have some objections.

1.
Quote:
It's quite simple really:

Code:
# pkill -KILL -u <username>
You think that it is so simple to kill a user's session? How do you know what he/she does at that time? Even a gamer would kill you (literally) - imagine a real-life user.

2.
Quote:
The quick and easy way is to set the "change" date on the user's password. There are a few different ways to do this, and I'll touch on each way.

The first way is by using the chsh command. The syntax is:

Code:
# chsh <username>
This does the job for 5-10 users. What happens when there are more and you want to change their passwords, say, every 60 days, which incidentally is absolutely common?

3.
Quote:
You can quickly set a new random password, that will expire at first login, with:
Code:
pw usermod <user> -p 0-0-0 -w random
Making it (relatively) safe to email it to him. If anyone retrieves the email later on, chances are, the password has already changed.
It is not safe[r]. The risk when sending a password via email is while sending it.

4.
Quote:
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.
I understood that (at least I think so). But how can you explain it to the grandma working three doors next to you?



To conclude, I don't mean to start any flame on this subject (honestly),
though you all know that we can talk/write for hours for such a topic.

Technically speaking, this thread is very helpful.
But password policy enforcement, as this guide's title claims to be, is not as simple as that
and I, personally, would be more cautious when using such terms/words.

I would also appreciate if inside this guide was included an instruction such as:
How to make users understand why they should use a strong password instead of impose strict policies.

No intention to offend anyone

Last edited by anemos; 7th November 2008 at 09:13 PM.
Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Policy routing bsd and cisco clone Guides 1 17th August 2009 04:57 PM
IP Security Policy Management snap-in wesley OpenBSD Security 2 11th August 2009 04:34 AM
A PF packet tagging (policy filtering) question... Quaxo OpenBSD Security 2 30th March 2009 10:47 PM
Set password for Folder mfaridi FreeBSD Security 6 5th September 2008 10:49 PM


All times are GMT. The time now is 02:16 PM.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content copyright © 2007-2010, the authors
Daemon image copyright ©1988, Marshall Kirk McKusick