Skip to main content
Uncategorized

Implementing a Password Policy in an LDAP Directory

By July 15, 2021No Comments

Implementing a Password Policy in an LDAP Directory

Introduction

A password policy is a list of rules that control how passwords within LDAP are administered. With a password policy in place, it improves security across the LDAP directory and decreases the likelihood of an account in the environment getting compromised. With rules in place, it will ensure that users will periodically update their password and also ensure that their password meets a specific criteria.

In this guide, we will set up a password policy in an existing OpenLDAP multi-master cluster on CentOS 7 servers running in Google Cloud.

Implementing the Password Policy

Start off the policy implementation by first loading the ppolicy module into the current LDAP directory.

~]# ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/ppolicy.ldif

Next, we need to create an organizational unit that will contain the password policy which is done with the following LDIF. In our example, the Policies organizational unit is being placed in the following section of the directory tree: "ou=Policies,dc=jacob-sandbox,dc=local".

~]# vi oupolicy.ldif     dn: ou=Policies,dc=jacob-sandbox,dc=local     objectClass: top     objectClass: organizationalUnit     ou: Policies     description: Password policy  ~]# ldapadd -x -W -D "cn=ldapadm,dc=jacob-sandbox,dc=local" -f oupolicy.ldif

Now we need to load the password policy module into the directory and then push the changes.

~]# vi ppmodule.ldif     dn: cn=module{0},cn=config     changetype: modify     add: olcModuleLoad     olcModuleLoad: ppolicy  ~]# ldapadd -Y EXTERNAL -H ldapi:/// -f ppmodule.ldif  ~]# vi ppolicyoverlay.ldif     dn: olcOverlay={0}ppolicy,olcDatabase={2}hdb,cn=config     objectClass: olcOverlayConfig     objectClass: olcPPolicyConfig     olcOverlay: {0}ppolicy     olcPPolicyDefault: cn=PPolicy,ou=Policies,dc=jacob-sandbox,dc=local  ~]# ldapadd -Y EXTERNAL -H ldapi:/// -f ppolicyoverlay.ldif

The last step is to set the rules that our password policy should enforce. The default policy object that we are creating defines the following policies:

  • pwdAllowUserChange: allow users to change their password
  • pwdCheckQuality: checks syntax of the password
  • pwdExpireWarning: lets the user know their password will expire in 10 minutes when they bind to LDAP
  • pwdGraceAuthNLimit: the server will allow five additional "grace" logins
  • pwdInHistory: server will maintain a history of the last five passwords that were used
  • pwdLockout: server will lock the account after the maximum number of failed bind attempts
  • pwdLockoutDuration: an account will remained locked until an administrator unlocks it
  • pwdMaxAge: passwords will not expire
  • pwdMinAge: passwords can be changed as often as desired
  • pwdMinLength: passwords must be at least 5 characters in length
  • pwdMustChange: password does not need to be changed at first bind
  • pwdMaxFailure: server will only allow five failed binds in a row

The policy is shown below in LDIF format and can be pushed to the directory via the ldapadd command with the administrator account.

~]# vi passwordpolicy.ldif     dn: cn=PPolicy,ou=Policies,dc=jacob-sandbox,dc=local     cn: PPolicy     objectClass: pwdPolicy     objectClass: device     objectClass: top     pwdAllowUserChange: TRUE     pwdAttribute: userPassword     pwdCheckQuality: 2     pwdExpireWarning: 600     pwdFailureCountInterval: 30     pwdGraceAuthNLimit: 5     pwdInHistory: 5     pwdLockout: TRUE     pwdLockoutDuration: 0     pwdMaxAge: 0     pwdMaxFailure: 5     pwdMinAge: 0     pwdMinLength: 5     pwdMustChange: FALSE     pwdSafeModify: FALSE  ~]# ldapadd -x -W -D "cn=ldapadm,dc=jacob-sandbox,dc=local" \             -f passwordpolicy.ldif

Testing the Password Policy

Changing a User’s Password

The first use case will show a user trying to change their password on a client using the LDAP directory as its authentication. If a user tries to set their password with a password that violates the policy, they will receive a Constraint Violation Error.

# Trying to set the users account with a password # of 4 characters gives a constraint violation error ldapclient01 ~]$ passwd Changing password for user testuser. (current) LDAP Password: ********** New password: q1w1 Retype new password: q1w1 password change failed: Constraint violation passwd: Authentication token manipulation error  # Trying to set the users account with a valid password ldapclient01 ~]$ passwd Changing password for user testuser. (current) LDAP Password: ********** New password: password123 Retype new password: password123 passwd: all authentication tokens updated successfully.

Locking Out/Unlocking a User

A password policy also allows administrators to lock out users of the directory and clients that utilize LDAP as its authentication. Locking out a user can be done by setting the pwdAccountLockedTime key-value pair and setting it to a date far in the future. The first LDIF shown below sets the key-value pair to lock out the test user. To unlock the user, the second LDIF shown below can be used which deletes the key-value pair from the user’s attributes.

~]# vi lockoutuser.ldif     dn: cn=testuser,ou=People,dc=jacob-sandbox,dc=local     changetype: modify     replace: pwdAccountLockedTime     pwdAccountLockedTime: 22000101000000Z  ~]# ldapadd -x -W -D "cn=ldapadm,dc=jacob-sandbox,dc=local" -f lockoutuser.ldif  ~]# vi unlockuser.ldif     dn: cn=testuser,ou=People,dc=jacob-sandbox,dc=local     changetype: modify     delete: pwdAccountLockedTime  ~]# ldapadd -x -W -D "cn=ldapadm,dc=jacob-sandbox,dc=local" -f unlockuser.ldif

Conclusion

To quickly recap, we added the password policy module to our LDAP directory to help increase the security of it. Users now must follow a specific set of guidelines when setting their password which will help prevent accounts from being compromised. There are many more attributes that can be added to increase security and I recommend anyone looking to implement this to have a look at all the available attributes and extend the policy that we built here.