Fun With PAM: Working with pam_cracklib and pam_tally2

Liberty-bell_13850_smPlugable Authentication Modules, or PAM, is the standard mechanism that most Unix and Linux Operatng Systems use for user credential authentication. By design, PAM is broken out into a number of files, each with a specific purpose. Before you can get started with PAM you need to understand a bit about how PAM configuration files are formatted.  So lets get into that first before we try to bite off anything more.


PAM Config File Standards:

PAM config files follow a standard format as shown below.

Rule Types        Control        Module [module arguments]


There are 4 Rule Types

  • auth – used to authenticate users/passwords
  • account – set properties for a user's account
  • password – controls password changes
  • session – sets and controls environmental variables

And there are 5 Control Types

  • required – a module that a user is required to pass
  • sufficient – a user is not required to pass a sufficient module
  • optional – these modules do not have to be passed sucessfully
  • include – these rules reference other PAM config files
  • requisite – similar to required, but if failed, no further rules are checked


Configuring pam_cracklib:

Pam_cracklib is used to define password complexity. It has several module arguments that can be used to define password complexity and lenght. Its most common arguments are show below

  • ucredit – when used in the following format (ucredit=-n) requires the defined number of uppercase characters in a password
  • dcredit – when used in the following format (dcredit=-n) requires the defined number of digits in a password
  • ocredit – when used in the following format (ocredit=-n) requires the defined number of other (think symbols) type charaters in a password
  • lcredit – when used in the following format (lcredit=-n) requires the defined number of lower case letters  in a password
  • minclass – defines the minimum number of different character classes that must be present in a password.
  • minlen – defines the minimum required lenght of a password.

Here's a usage example of the cracklib module from a /etc/pam.d/system-auth file. In this example try_first_pass tells pam to try to use any cached credentials, while retry allows a user to try their password 3 times before the fail this module.

password    requisite minlen=8 ocredit=-1 ucredit=-1 try_first_pass retry=3


Configuring pam_tally2:

Pam_tally2 can be used to lock users after a defined number of failed login attempts. The example below, taken from the system-auth file will lock a user after 3 failed login attempts, will automatically unlock the user after 300 seconds, and will do so quietly, without any notification to the user.

auth        required deny=3 unlock_time=300 quiet

The command pam_tally2 can be used to list users with failed logins and can also be used to reset a user's failed login count. See reset example below

pam_tally2 –reset –u testuser

Note that pam_tally2 deprecates the faillock module.


Supplementary PAM Configuration Options:

Want to limit a user to a particular number of concurrent ssh sessions? You can set this up in /etc/security/limits.conf if you are calling the in your pam configs. Limits.conf provides the example below. Just copy the format and you are off to the races. Remember to remove the #.

#@student        -       maxlogins       4



Related articles

How to enforce password complexity on Linux
Secure Linux Servers
You are not allowed to access to (crontab) because of pam configuration.

Quick and Dirty: Finding Duplicate UIDS and Usernames in Linux

6a00d83451b31569e20167611e4ac0970b-800wiOk this one is going to be quick and dirty. I have been sitting in Starbucks for about 3 hours now in what at this point is the hardest and most uncomfortable chair in the world. At this point its almost torture.

Anyway, enough about my bottom. Ever had the need to search your /etc/password file for users with duplicate UIDS or duplicate usernames? Want to make sure that no other user, other than root, has a uid of 0? Well then today is your lucky day.

For this test I have added a couple of test users so that we have some results.

The command below is searching for any two users with the same UID, and will return a UID number of any UID that it finds twice.

[root@localhost ~]# getent passwd | cut -d: -f3 | sort -n | uniq -d

As you can see from the example above, the command found two users with the UID of 0. As we all know this is not good. Time to see who as been up to some funny business. Guess what, its was me. I added a user called testuser and manually changes his UID to 0.

Interesting item of note, you cannot just remove this user, as the system thinks that you are trying to remove the root user. First I need to edit /etc/passwd and manually change the user’s uid.

[root@localhost ~]# userdel testuser
userdel: user testuser is currently used by process 1
[root@localhost ~]# vi /etc/passwd
[root@localhost ~]# userdel testuser

Now lets search for any users with duplicated user names

[root@localhost ~]# getent passwd | cut -d: -f1 | sort -n | uniq -d

Sure enough, we find that there are duplicate users with the username testuser1. A quick grep confirms this

[root@localhost ~]# grep testuser1 /etc/passwd

And again, you just cannot delete these users, you must clean them up manually.

[root@localhost ~]# userdel testuser1
Multiple entries named ‘testuser1’ in /etc/passwd. Please fix this with pwck or grpck.
userdel: cannot remove entry ‘testuser1’ from /etc/passwd

Introduction to AIDE – Advanced Intrusion Detection Environment

Wally_Gator_PhotoEver heard of AIDE, neither had I. Apparently its a simple intrusion detection application that can be used to monitor file changes.  It can be confired to monitor permission, ownership, timestamp, or content changes.

Lets install it. Its in the stock Redhat repos, so its a piece of cake to install via yum.


[root@localhost ~]# yum -y install aide

Once installed, you can tweak the config file (/etc/aide.conf) to your liking. The stock config is pretty robust, so I am going to trim it down a bit and just monitor /etc for permission changes, and /bin for what are defined as normal changes. Normal looks at file hashes to see if the files have been modified.

/bin    NORMAL
/etc    PERMS

Now lets start aide

[root@localhost ~]# aide –init

AIDE, version 0.15.1

### AIDE database at /var/lib/aide/ initialized.


Now this part is silly, we need to rename the database created above to the name that aide is configured to use.

[root@localhost ~]# cp /var/lib/aide/ /var/lib/aide/aide.db.gz


Now lets check for changes.

[root@localhost ~]# aide –check

AIDE, version 0.15.1

### All files match AIDE database. Looks okay!

Hey no changes. Now lets monkey with something and see if aide catches it. In this example we are creating a new file in /etc. As seen below aide catches the new file and reports on it.


[root@localhost ~]# touch /etc/aide.test.change
[root@localhost ~]# aide –check
AIDE 0.15.1 found differences between database and filesystem!!
Start timestamp: 2014-07-15 19:51:14

  Total number of files:        5054
  Added files:                  1
  Removed files:                0
  Changed files:                0

Added files:

added: /etc/aide.test.change


So now lets re-initialize the database, which is pretty much a snapshot.

[root@localhost ~]# aide –init

AIDE, version 0.15.1

### AIDE database at /var/lib/aide/ initialized.


Don't forget to overwrite the old database.

[root@localhost ~]# cp /var/lib/aide/ /var/lib/aide/aide.db.gz
cp: overwrite ‘/var/lib/aide/aide.db.gz’? yes

Now lets change the permissions on our test file and see if aide catches the change.  I'll spare you the suspense and let you know that aide did its job. See below.


[root@localhost ~]# chmod 777 /etc/aide.test.change
[root@localhost ~]# aide –check                    
AIDE 0.15.1 found differences between database and filesystem!!
Start timestamp: 2014-07-15 19:54:09

  Total number of files:        5054
  Added files:                  0
  Removed files:                0
  Changed files:                2

Changed files:

changed: /etc/aide.test.change
changed: /root/.mozilla/firefox/8u03e3hs.default/sessionstore.js

Detailed information about changes:

File: /etc/aide.test.change
 Perm     : -rw-r–r–                       , -rwxrwxrwx
 ACL      : old = A:
                  D: <NONE>
            new = A:
                  D: <NONE>

Now aide on its own is just a simple tool, but run via cron with a bit of tuning and a bit more logic behind it and I can see it being a very useful tool. Looking forward to playing with it more.

Related articles

How To Install Aide on a DigitalOcean VPS
RHEL6 – How to Setup an Anonymous Download Only FTP Server

Working With Extended Filesystem Attributes in Linux

GarfatIn my previous post I went over standard filesystem attibutes in Linux, and how to set and view those attibutes with lsattr and chattr. You can view that post here if you are interested.

In this post we are going to go over extended filesystem attibutes. Now there is not much to this as you are probably not going to ever have to use these settings. That being said, its not a bad thing to be aware of.

Attribute names are strings that can be set and configured at will using the setfatr command. They can be viewed with the getfattr command. There are 4 namespaces of attibutes, security, system, trusted, and user.

When using getfattr ( which I pronounce as getfatter) the -d option dumps only user namespace attibutes. The rest of the namespace attributes can be viewed by using the -m option along with the namespace name. In the example below you can see that there are no user namespace attibutes set on my anaconda-ks.cfg file, however there are attibutes set in the security namespace.

[root@localhost ~]# getfattr -d anaconda-ks.cfg
[root@localhost ~]# getfattr -d -m security anaconda-ks.cfg
# file: anaconda-ks.cfg


Using setfattr you can define and set custom attributes. See the useless example below.

[root@localhost ~]# setfattr -n user.example -v example anaconda-ks.cfg
[root@localhost ~]# getfattr -d anaconda-ks.cfg
# file: anaconda-ks.cfg

However this could be cool if you got an md5 sum on a file and dumped it into a file attibute. You could, in theory, use this process to see if someone has messed with one of your config files.


[root@localhost ~]# md5sum anaconda-ks.cfg
fda1aa550d3cf82423d1b1ad1ae53a13  anaconda-ks.cfg
[root@localhost ~]# setfattr -n user.md5sum -v fda1aa550d3cf82423d1b1ad1ae53a13 anaconda-ks.cfg
[root@localhost ~]# getfattr -d anaconda-ks.cfg
# file: anaconda-ks.cfg


Related articles

Why Extended Attributes are Coming to HDFS
Advanced Filesystem Attributes in Linux
How to create a file that root user also can't delete?

Securing Individual Files in Linux with Filesystem Attributes.

Permissions-Reset-IconFilesystem attibutes can be used to enhance standard file security on ext4 and XFS filesystems by blocking users from being able to delete or override a file. 

In order to get started you first must see if your filesystem supports the user_xattr mount option. To do this you can use the tune2fs command. Use the '-l' option to list options.

# tune2fs -l /dev/xvda1


As shown in the section below, the filesystem that I am working with on my virtual machine supports ext_attr and has been mounted with the user_xattr option (as well as the acl option)

Filesystem features:      has_journal ext_attr resize_inode dir_index filetype needs_recovery extent flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
Filesystem flags:         signed_directory_hash
Default mount options:    user_xattr acl


Alternatively, you can bypass mounting a filesystem with the user_xattr option by simply making user_xattr a default mounting option for the filesystem. You accompish this formidable task with the tune2fs command. For example.

[root@localhost ~]# tune2fs -o user_xattr /dev/sda1
tune2fs 1.42.8 (20-Jun-2013)


Now lets start messing around with a couple of the more common options. I have listed them below.

a Append Only – sets the file to append only
i Immutable – prevents deletion
d Do not back up with the dump command


To set the options show above you use the chattr command, and to view these options you use the lsattr command. Lets try it out. In this exmaple I am setting the immutable flag to that the file cannot be removed, renamed, or overwritten.

[root@localhost ~]# touch testfile
[root@localhost ~]# lsattr testfile
—————- testfile
[root@localhost ~]# chattr +i testfile
[root@localhost ~]# lsattr testfile
—-i———– testfile


Ok now lets remove the 'i' option..

[root@localhost ~]# chattr -i testfile
[root@localhost ~]# lsattr testfile
—————- testfile


See this is pretty simple stuff, however since these options are rarely set, not to many people know about them.





Yum: Under the Covers with GPG Keys

Skeleton_key_1_keychain_sculpture_photo_cut_outs-r558fef9b275d4609b522ac07970a6af6_x7sa6_8byvr_324Hey look at this spooky key. Don't be frightened little one. Nothing scary is going to happen to you here. This is a safe place. As a matter of fact, if you stick around you might just learn a thing or two. A thing or two about GPG!

First off do any of us really know what GPG stands for? Well yes we do! It stands for GNU Privacy Guard. RPM Package creators use GPG to apply a digital signature to their packages. If a package was tampered with, then its GPG signature will no longer match what was placed in the original package.

First off to check what keys you have installed on your Linux server you can run the following rpm command as show in the example below.

[root@ip-172-31-22-45 ~]# rpm -qa gpg-pubkey


Neet I have three keys installed. But lets say want to install another one. Well I can do so with the command below. In this example I have navigated to /etc/pki/rpm-gpg and am going to install the redhat beta key on my server.

[root@ip-172-31-22-45 rpm-gpg]# rpm –import RPM-GPG-KEY-redhat-beta

Hey that was fun. Now lets get our hands a bit dirtier.

Want to get more information on a specific key. Then this command is your huckleberry. Here you can see that this is the pubkey for the EPEL repo.

[root@ip-172-31-22-45 rpm-gpg]# rpm -qi gpg-pubkey-0608b895-4bd22942
Name        : gpg-pubkey                   Relocations: (not relocatable)
Version     : 0608b895                          Vendor: (none)
Release     : 4bd22942                      Build Date: Sat 14 Jun 2014 09:13:58 AM EDT
Install Date: Sat 14 Jun 2014 09:13:58 AM EDT      Build Host: localhost
Group       : Public Keys                   Source RPM: (none)
Size        : 0                                License: pubkey
Signature   : (none)
Summary     : gpg(EPEL (6) <>)
Description :


To verify signature of a downloaded package, use the rpm command as shown below. In this example I have highlighted the key that was used to sign this package.

# rpm -vK nautilus-dropbox-1.6.0-1.fedora.i386.rpm
    Header V3 RSA/SHA1 Signature, key ID 5044912e: OK
    Header SHA1 digest: OK (a4d51906633f92913db075ba33946f50999c245e)
    V3 RSA/SHA1 Signature, key ID 5044912e: OK
    MD5 digest: OK (1b8ff7abc18f68bf274e24fc57fd3a87)


Using the bolded information in the example above, I can then use this information to track down the exact key that was used to sign the package.

[root@localhost Downloads]# rpm -qa | grep 5044912e


Is this awesome, well not really, but you never know when you might need to use this information. Like on a test. Wink Wink.

Related articles

Using Yum Update to Apply Security Patches Only
How to Enable EPEL Repository on CentOs for Yum
Signing rpm packages with GPG

RPM Package Inspection for Fun and Profit

6a00d8341c562c53ef01538f8abd65970b-800wi"Whats in the box" — David Mills

Lets face it, one of your users needs to have a package installed on a system, you tend to do it for them. That is, as long as the package looks safe. Sure, your not going to install an rpm that is clearly dangerous, but as long as the package name looks reasonable and you trust the user, you might actually just go ahead an install it for them without thinking much about it. Hell, I know that I have done the exact same thing from time to time. And I have done it with an unsigned package.

"Sure you need this Oracle thing installed on this database server?"

 "You got it directly from Oracle right?"

But honestly, this is a very bad practice as you have no idea what the RPM is installing, and what its pre and post scripts might be doing to your system. Using the command below, you can inspect a packages post and pre install scripts to see if they are doing anything funny. In this instance I am taking a look at the dropbox package for my little Eeepc.

[root@localhost ~]# rpm -qp –scripts /root/Downloads/nautilus-dropbox-1.6.0-1.fedora.i386.rpm

If you have already installed a package and want to see what its pre and post install scripts did. You can run the command above using the installed package name. Note that you will drop the "P" from the command. See my sendmail example below.

[root@localhost ~]#rpm -q –scripts sendmail-8.14.8-2.fc20.i686


In addition to checking the pre and post scripts, you also want to check to see if the rpm has any triggers. What are triggers you ask? Well they are extensions to the normal install scripts, and they may often call for the installation of another package or the execution of a command. Just look at all the triggers that fire when you install sendmail.

[root@localhost ~]# rpm -q –triggers sendmail-8.14.8-2.fc20.i686
triggerun scriptlet (using /bin/sh) — sendmail < 8.14.5-3
/usr/bin/systemd-sysv-convert –save sendmail >/dev/null 2>&1 ||:
/bin/systemctl enable sendmail.service >/dev/null 2>&1
/bin/systemctl enable sm-client.service >/dev/null 2>&1
/sbin/chkconfig –del sendmail >/dev/null 2>&1 || :
/bin/systemctl try-restart sendmail.service >/dev/null 2>&1 || :
/bin/systemctl try-restart sm-client.service >/dev/null 2>&1 || :
# workaround for systemd rhbz#738022
/bin/systemctl is-active sendmail.service >/dev/null 2>&1 && \
        ! /bin/systemctl is-active sm-client.service >/dev/null 2>&1 && \
        /bin/systemctl start sm-client.service >/dev/null 2>&1 || :

Obviously you also want to check to see what files are actually part of a package. This can be accomplished with the query and list arguments seen below. Add the "P" argument if the rpm is not already installed. In this case I have already installed sendmail, so I exclude the "P" from the command.


[root@localhost ~]# rpm -ql sendmail-8.14.8-2.fc20.i686


So whats the moral of the story here. Well its really not that hard to take a minute and look under the covers and make sure that the packages that you are installing are not harming your systems. Is definetly worth 5 minutes of your time. Might just save your behind.


Related articles

RHEL6 – Simple Postfix Configuration
RHEL6 – Common Postfix Server Roles
Configure sendmail as a client for SMTPs
Sendmail Server