Pages

Friday, January 6, 2012

Fun with pam

With this article I want you to show how to use several more or less useful pam modules. This is not an explanation to pam in general. This article is also based on the the prior released LDAP articles for Slackware and Solaris. I didn't test all modules under Solaris or else but with some brain you should be able use them under any Unix too.
The following modules are currently described here:

pam_nologin: Deny user log in
pam_securetty: Deny root log in
pam_tally2.so: Deny log in after X failed log in attempts
pam_cracklib: Strengthen passwords

Mostly I used some default settings and didn't explained all options for a certain module. It is always worth to take look at the man page for the particular pam module. In most case you can use the pam module name as man page, eg:

# man pam_cracklib
...

When I find a new useful pam module then I will add it here.

pam_nologin: Deny user login

If you need to do some maintenance work as root and you don't want any user on the specific system than you might use pam_nologin. The module checks if the text file /etc/nologin exist. If it exist and when a user tries to log in then the content will be shown to the user. root may still log in.
To use the pam_nologin module add it to your auth rule:

# vi /etc/pam.d/common-auth
auth            required        pam_nologin.so
auth            sufficient      pam_unix.so
auth            sufficient      pam_ldap.so use_first_pass
auth            required        pam_deny.so

Then create the /etc/nologin file with your message for the users:

echo "Closed due maintenance" > /etc/nologin

Then try to log in as a user via ssh:

# ssh sneill@localhost
Closed due maintenance

Or local with login:

# login
slack01 login: sneill
Closed due maintenance

pam_securetty: Deny root login

To deny root log in from special tty you can use pam_securetty. With a appropriate configuration root may login on your local machine by log in, but not by telnet, ssh etc. To use pam_securetty add it to your auth pam rules first:

# vi common-auth
auth            required        pam_securetty.so
auth            sufficient      pam_unix.so
auth            sufficient      pam_ldap.so use_first_pass
auth            required        pam_deny.so

Next add the tty that you want to enable root log in to /etc/securetty:

# vi /etc/securetty
console
tty1
tty2
tty3
tty4
tty5
tty6

With this configuration of /etc/securetty root may log in locally but not via ssh etc. You are still able to log in as a user via ssh and use the su command to gain root access.

pam_tally2.so: Deny login after X failed login attempts

The pam_tally2 module is used to deny login for a user if the user tries to login with a wrong password. pam_tally2 generates a log under /var/log/tallylog. If the user has locked his account then the account must be reset by root manually.
To use pam_tally2 add it to your auth pam rule first:

# vi /etc/pam.d/common-auth
auth            sufficient      pam_unix.so
auth            sufficient      pam_ldap.so use_first_pass
auth            required        pam_tally2.so deny=3 even_deny_root unlock_time=1200
auth            required        pam_deny.so

The options are:
deny=3: 3 tries left
even_deny_root: even root may not log in
unlock_time=1200: after 2min. account may log in again (1200ms/10/60s = 2min.)
Next try to log in as a user and type any wrong passwords:

# ssh sneill@dc01
Password: wrong_password
...
Received disconnect from 192.168.56.4: 2: Too many authentication failures for sneill

The logfile has a binary format so it can not be read by cat, less... instead use the pam_tally2 command:

# pam_tally2
Login           Failures Latest failure     From
sneill              5    01/04/12 17:04:40  nb023.example.com

To reset the user and allow him to log in again use the --reset option:

# pam_tally2 --reset -u sneill
Login           Failures Latest failure     From
sneill              7    01/04/12 20:23:23  nb023.example.com

Be warned, using pam_tally2 might have some ugly effects if configured wrong. Today I tried to log in as root via ssh on a small public server and got the following:

ssh root@ps01
Account locked due to 23 failed logins

Even log in as a simple user and su to root didn't work anymore.

pam_cracklib: Strengthen passwords

pam_cracklib is very usefull if you want to force users to use much more secure passwords. With pam_cracklib you can force users to use passwords with upper cases, lower cases, digits, not to use passwords based on dictionary etc. Before you can use pam_cracklib you have to compile it. I am using Slackware again so I have to install cracklib first. Down a copy of the source from http://sourceforge.net/projects/cracklib/files/cracklib/2.8.18/cracklib-2.8.18.tar.gz/download and move it to /usr/src:

# mv cracklib-2.8.18.tar.gz /usr/src
# cd /usr/src

Then extract the source package and change into the new directory:

# gunzip -dc cracklib-2.8.18.tar.gz | tar xf -
# cd cracklib-2.8.18

Then run the configure script, compile the lib and install it:

# ./configure --prefix=/usr --libdir=/usr/lib
...
# make
...
make install
...

Check that the pam_cracklib module was installed successfully:

# ls -la /lib/security/pam_cracklib.so
-rwxr-xr-x 1 root root 34483 Jan  4 22:38 /lib/security/pam_cracklib.so*

Next you need a wordlist to create your own dictionary, eg. download one from:

# wget ftp://coast.cs.purdue.edu/pub/tools/unix/libs/cracklib/cracklib.2.7.tar.gz
...

Decompress it:

# gunzip  cracklib.2.7.tar.gz

And create the dictionary:

# cracklib-packer < cracklib-words
1648379 1648379

Check that it is available:

# ls -lah /usr/share/cracklib/pw_dict.*
-rw-r--r-- 1 root root 1.0K Jan  4 23:53 /usr/share/cracklib/pw_dict.hwm
-rw-r--r-- 1 root root 7.1M Jan  4 23:53 /usr/share/cracklib/pw_dict.pwd
-rw-r--r-- 1 root root 403K Jan  4 23:53 /usr/share/cracklib/pw_dict.pwi

Finally you are ready to use pam_cracklib. First add the module to the pam password rule:

# vi /etc/pam.d/common-password
password        required        pam_cracklib.so retry=3 minlen=6 difok=3
password        sufficient      pam_unix.so
password        sufficient      pam_ldap.so use_first_pass
password        required        pam_deny.so

Then try to change any user password and use a password from the dictionary:

$ passwd
Enter login(LDAP) password:
New password: laetissima
BAD PASSWORD: it is based on a dictionary word
New password:
Retype new password:
LDAP password information changed for sneill
passwd: password updated successfully