DEV Community

Cover image for Time-based one-time passwords (TOTP) with OpenLDAP
Ashkan
Ashkan

Posted on

1

Time-based one-time passwords (TOTP) with OpenLDAP

Two-factor authentication (2FA) is a method of enhancing the security of online accounts by requiring two types of credentials: something you know, such as a password, and something you have, such as a device. One common way of implementing the second factor is using time-based one-time passwords (TOTP), which are unique numeric codes that are generated based on the current time and a shared secret key. TOTP codes are usually displayed by an authentication app on your smartphone or tablet, and they expire after a short period of time. TOTP is an open standard that is defined in RFC 6238 and supported by many applications and services.

In this article, we will install and configure OpenLDAP on Ubuntu 22.04 and implement TOTP. To implement OTP we need OpenLDAP 2.5 or higher.

NOTICE: This guide is for educational purposes only and is NOT meant to be used in production environments.

Install and configure OpenLDAP

Run the following command:

sudo apt install slapd ldap-utils
Enter fullscreen mode Exit fullscreen mode

Enter a new password:

Admin password prompt

To reconfigure the default configuration, run:

sudo dpkg-reconfigure slapd
Enter fullscreen mode Exit fullscreen mode

You will be asked to omit OpenLDAP configuration, select No.

Initial configuration

Enter your domain name:

Domain name

Enter your organization name:

Organization name

Provide the administration password and then confirm it:

Admin password

For this guide, when you get prompted to remove the database when slapd is purged, select Yes:

Purge database

And finally select Yes:

Move old database

Open ldap.conf with a text editor:

sudo vim /etc/ldap/ldap.conf
Enter fullscreen mode Exit fullscreen mode

Find and uncomment the following lines:

#BASE   dc=example,dc=com
#URI    ldap://ldap.example.com ldap://ldap-provider.example.com:666
Enter fullscreen mode Exit fullscreen mode

Edit these entries, replace BASE with your domain name, and URI with the URI to your ldap server:

BASE    dc=mydomain,dc=com
URI     ldap://ldap.mydomain.com
Enter fullscreen mode Exit fullscreen mode

Save the changes and exit the editor. You might need to edit the hosts file and provide the FQDN to your LDAP server and its IP address:

sudo vim /etc/hosts
Enter fullscreen mode Exit fullscreen mode
192.168.1.1 ldap.mydomain.com
Enter fullscreen mode Exit fullscreen mode

Creating user accounts

Create a file:

vim users-ou.ldif
Enter fullscreen mode Exit fullscreen mode

Enter the following contents:

dn: ou=people,dc=mydomain,dc=com
objectClass: organizationalUnit
objectClass: top
ou: people

dn: ou=groups,dc=mydomain,dc=com
objectClass: organizationalUnit
objectClass: top
ou: groups
Enter fullscreen mode Exit fullscreen mode

Save and close the file. Now run the following command:

ldapadd -x -D cn=admin,dc=mydomain,dc=com -W -f users-ou.ldif
Enter fullscreen mode Exit fullscreen mode

And enter your administration password. You should see an output like this:

Addin OU

You can use the following command to verify:

ldapsearch -Q -LLL -Y EXTERNAL -H ldapi://
Enter fullscreen mode Exit fullscreen mode

That should print something like this:

ldapsearch ou

Now create a password using the slappasswd command. Run the command and enter a password, then confirm it. You should get something like this:

slappasswd

Copy the hash. Now create another file:

vim user.ldif
Enter fullscreen mode Exit fullscreen mode

Enter the following contents:

dn: uid=johndoe,ou=people,dc=mydomain,dc=com
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
objectClass: posixAccount
objectClass: shadowAccount
objectClass: top
homeDirectory: /home/john
givenName: John
sn: Doe
cn: John Doe
uid: johndoe
displayName: John Doe
uidNumber: 8000
gidNumber: 8000
userPassword: {SSHA}eLp4NBSK1SV3VOFY3iUxI8P73vmOW/Lh
Enter fullscreen mode Exit fullscreen mode

Replace {SSHA}eLp4NBSK1SV3VOFY3iUxI8P73vmOW/Lh with hash you copied earlier. Run the following command to create a user account:

ldapadd -x -D cn=admin,dc=mydomain,dc=com -W -f user.ldif
Enter fullscreen mode Exit fullscreen mode

Create another file:

vim group.ldif
Enter fullscreen mode Exit fullscreen mode

Enter the contents below:

dn: cn=appusers,ou=groups,dc=mydomain,dc=com
objectClass: posixGroup
objectClass: top
cn: appusers
gidNumber: 10000
memberUid: uid=johndoe,ou=people,dc=mydomain,dc=com
Enter fullscreen mode Exit fullscreen mode

Apply the changes to create a group:

ldapadd -x -D cn=admin,dc=mydomain,dc=com -W -f group.ldif
Enter fullscreen mode Exit fullscreen mode

You can use ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:// to verify the changes or use graphical tools such as the Apache Directory Studio to verify changes and manage your LDAP server.

Apache Directory Studio

Configure TOTP

First otp module must be loaded. Create a file:

vim otpload.ldif
Enter fullscreen mode Exit fullscreen mode

Enter the following contents:

dn: cn=module{0},cn=config
changetype: modify
add: olcModuleLoad
olcModuleLoad: otp.la
Enter fullscreen mode Exit fullscreen mode

Apply the changes:

sudo ldapmodify -Y EXTERNAL -H ldapi:// -D cn=config -W -f otpload.ldif
Enter fullscreen mode Exit fullscreen mode

The output should be like this:

otp load

Now the otp overlay must be added to databases. Create another file:

vim overlay.ldif
Enter fullscreen mode Exit fullscreen mode

Enter the following contents:

dn: olcOverlay=otp,olcDatabase={1}mdb,cn=config
objectClass: olcOverlayConfig
Enter fullscreen mode Exit fullscreen mode

Run the following command:

sudo ldapadd -Y EXTERNAL -H ldapi:// -D cn=config -W  -f overlay.ldif
Enter fullscreen mode Exit fullscreen mode

To set the otp parameters, create a file:

vim totp.ldif
Enter fullscreen mode Exit fullscreen mode

And enter the following contents:

dn: ou=people,dc=mydomain,dc=com
changetype: modify
add: objectClass
objectClass: oathTOTPParams
-
add: oathOTPLength
oathOTPLength: 6
-
add: oathHMACAlgorithm
oathHMACAlgorithm: 1.2.840.113549.2.7
-
add: oathTOTPTimeStepPeriod
oathTOTPTimeStepPeriod: 30
-
add: oathTOTPTimeStepWindow
oathTOTPTimeStepWindow: 3
Enter fullscreen mode Exit fullscreen mode

Run the command below to apply the configuration:

ldapmodify -x -D cn=admin,dc=mydomain,dc=com -W -f totp.ldif
Enter fullscreen mode Exit fullscreen mode

To be able to use TOTP, users need a key. This key is shared between the server and the user. The following command can be used to generate the key:

openssl rand 80 > key
Enter fullscreen mode Exit fullscreen mode

To use the key, create a file:

vim token.ldif
Enter fullscreen mode Exit fullscreen mode

Enter the contents like below:

dn: uid=johndoe,ou=people,dc=mydomain,dc=com
changetype: modify
add: objectClass
objectClass: oathTOTPToken
-
add: oathTOTPParams
oathTOTPParams: ou=people,dc=mydomain,dc=com
-
add: oathSecret
oathSecret:< file:key
-
add: objectClass
objectClass: oathTOTPUser
-
add: oathTOTPToken
oathTOTPToken: uid=johndoe,ou=people,dc=mydomain,dc=com
Enter fullscreen mode Exit fullscreen mode

The following command applies the changes:

ldapmodify -x -D cn=admin,dc=mydomain,dc=com -W -f token.ldif
Enter fullscreen mode Exit fullscreen mode

You can use qrencode to generate the QR code. First install it with the following command:

sudo apt install qrencode
Enter fullscreen mode Exit fullscreen mode

Use the commands below to generate the QR code:

base32 key > bkey
echo -n "otpauth://totp/myorg:johhdoe@mydomain.com?secret=$(<bkey)&issuer=myorg&period=30&digits=6&algorithm=SHA1" | qrencode -t ansiutf8
Enter fullscreen mode Exit fullscreen mode

QR

Now you can scan the QR code with an authenticator app such as the Google Authenticator.

How to authenticate?

Whenever you get asked to provide your password, enter your password followed by the code you get from the authenticator app. For example if your password is abcdef and the code that you get from the app is 123456, enter abcdef123456 as your password.

References and Further Reading

Do your career a big favor. Join DEV. (The website you're on right now)

It takes one minute, it's free, and is worth it for your career.

Get started

Community matters

Top comments (1)

Collapse
 
flowers profile image
Dave Flowers

This post misses a key aspect of security - you need to set the access permissions on your ldap server to keep the secret key secret, just as with the user password. And it might be worth discussing what acl changes you would need to make to allow the user to perform the step of adding totp to their account, rather than the ldap admin.

Also, there's no reason to use 80 random bytes - hmac-sha1 only really needs 20.

That said, this looks like a decent article otherwise, and much appreciated.

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

Dive into an ocean of knowledge with this thought-provoking post, revered deeply within the supportive DEV Community. Developers of all levels are welcome to join and enhance our collective intelligence.

Saying a simple "thank you" can brighten someone's day. Share your gratitude in the comments below!

On DEV, sharing ideas eases our path and fortifies our community connections. Found this helpful? Sending a quick thanks to the author can be profoundly valued.

Okay