There will be three articles in total on how to create an LDAP back end and using that with Dovecot and Postfix. This article covers the setup of LDAP and adding email addresses and aliases to LDAP.

Purpose:
Configure Postfix and Dovecot to use OpenLDAP for alias resolution and mailbox delivery, allowing one real mailbox (testuser@example.com) to receive mail for many virtual addresses (e.g., admin, webmaster, postmaster).


Step 0: Verify hostname

hostname
hostname -f

Fix if needed.

Step 1: Update

# Update your system
apt update -y && apt install net-tools && apt upgrade -y && apt dist-upgrade -y

Reboot if a new kernel is installed.

Step 2: Install OpenLDAP server and utilities
apt install slapd ldap-utils -y

During installation, you’ll be prompted to set an admin password for LDAP. Choose a strong password and save it securely.

Step 2.1: Reconfigure OpenLDAP

# Reconfigure OpenLDAP to set up your domain
dpkg-reconfigure slapd

When prompted:

  • Omit OpenLDAP server configuration? No
  • DNS domain name: example.com
  • Organization name: Example Organization
  • Administrator password: Enter the password you chose earlier
  • Database backend: MDB
  • Remove the database when slapd is purged? No
  • Move old database? Yes

Check that the service is listening on port 389.

netstat -natl

Step 3: Create Basic LDAP Structure

Create a directory for our ldif files.

mkdir ldap && cd ldap

Create a file named base.ldif with this content:

# Create organizational units
dn: ou=people,dc=example,dc=com
objectClass: organizationalUnit
ou: people

dn: ou=groups,dc=example,dc=com
objectClass: organizationalUnit
ou: groups

# Create mail aliases OU
dn: ou=aliases,dc=example,dc=com
objectClass: organizationalUnit
ou: aliases

Add this structure to LDAP:

ldapadd -x -D "cn=admin,dc=example,dc=com" -W -f base.ldif

Step 4: Add Email Schema Extensions

LDAP needs extra schemas to handle email attributes. Create a file named mail-schema.ldif:

dn: cn=mail,cn=schema,cn=config
objectClass: olcSchemaConfig
cn: mail
olcAttributeTypes: ( 1.3.6.1.4.1.7165.2.1.63 NAME 'mailAddress'
  DESC 'Email Address'
  EQUALITY caseIgnoreIA5Match
  SUBSTR caseIgnoreIA5SubstringsMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
olcAttributeTypes: ( 1.3.6.1.4.1.7165.2.1.64 NAME 'mailAlias'
  DESC 'Email Alias'
  EQUALITY caseIgnoreIA5Match
  SUBSTR caseIgnoreIA5SubstringsMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
olcObjectClasses: ( 1.3.6.1.4.1.7165.2.2.10 NAME 'mailAccount'
  DESC 'Mail Account'
  SUP top AUXILIARY
  MUST mailAddress
  MAY mailAlias )

Add the schema:

ldapadd -Y EXTERNAL -H ldapi:/// -f mail-schema.ldif

Step 5: Create a User with Email Attributes

Create a file named user.ldif to add a user:

# Add user entry
dn: uid=testuser,ou=people,dc=example,dc=com
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: mailAccount
uid: testuser
sn: User
givenName: Test
cn: Test User
uidNumber: 10000
gidNumber: 10000
homeDirectory: /home/testuser
loginShell: /bin/bash
userPassword: {SSHA}GeneratedPasswordHash
mailAddress: testuser@example.com
mailAlias: admin@example.com
mailAlias: info@example.com

Generate a hashed password and add the user:

Generate password hash

PASSWORD_HASH=$(slappasswd -s "YourUserPassword")

Replace the hash in the LDIF file

sed -i "s|{SSHA}GeneratedPasswordHash|$PASSWORD_HASH|" user.ldif

Add user to LDAP

ldapadd -x -D "cn=admin,dc=example,dc=com" -W -f user.ldif

Step 6: Query Your LDAP Directory to verify it works

Search for all entries

ldapsearch -x -b "dc=example,dc=com" -H ldap://localhost

Search for a specific user

ldapsearch -x -b "dc=example,dc=com" "uid=testuser"

Search for email aliases

ldapsearch -x -b "ou=aliases,dc=example,dc=com" "objectClass=inetOrgPerson"

Step 7: PHPLDAPAdmin

Install phpLDAPadmin

apt install phpldapadmin -y

Configure phpLDAPadmin

vim /etc/phpldapadmin/config.php

Most of these lines will be set but double check.

$servers->setValue('server','host','localhost');
$servers->setValue('server','base',array('dc=example,dc=com'));
$servers->setValue('login','bind_id','cn=admin,dc=example,dc=com');

## Before creating users in LDAP, it is interesting to change the following line at
##  the file /etc/phpldapadmin/config.php with the uidNumber greater than the last user
##  with an account already created on the server, and maybe even give it an interval
##  range... Ex.: usually the first account created on the server has the uidNumber
##  1000.
## command to verify uidNumbers on Ubuntu:
## cat /etc/passwd

## then change it to 1200 or more:
## Original:
## $servers->setValue('auto_number','min',array('uidNumber'=>1000,'gidNumber'=>500));
## Changed:
$servers->setValue('auto_number','min',array('uidNumber'=>1200,'gidNumber'=>500));

If changes were made restart Apache

systemctl restart apache2.service

Web Interface

http://192.168.0.142/phpldapadmin

Login DN:

cn=admin,dc=example,dc=com

Login password:
Admin password is used.

Keep in mind this is not secure and needs TLS for production.

Step 8: Configure Mail Logging

Install rsyslog if not already installed

apt install rsyslog -y

Configure rsyslog to log mail messages

echo 'mail.*  -/var/log/mail.log' | sudo tee -a /etc/rsyslog.d/50-default.conf

Restart rsyslog

systemctl restart rsyslog

At this point a lab sysytem is ready to go.


Security Considerations – Lab system and the next was skipped but will be worked on in the future.

  1. Enable TLS/SSL:
sudo apt install gnutls-bin ssl-cert -y
sudo mkdir /etc/ldap/ssl
sudo certtool --generate-privkey > /etc/ldap/ssl/ldap_key.pem
sudo certtool --generate-self-signed --load-privkey /etc/ldap/ssl/ldap_key.pem --outfile /etc/ldap/ssl/ldap_cert.pem
  1. Restrict access to your LDAP server by configuring a firewall:
sudo apt install ufw -y
sudo ufw allow 22/tcp
sudo ufw allow 389/tcp
sudo ufw allow 636/tcp
sudo ufw enable

Troubleshooting

  • Check LDAP logs: sudo journalctl -u slapd
  • Check Postfix logs: sudo tail -f /var/log/mail.log or sudo journalctl -u postfix
  • Verify LDAP connectivity: ldapwhoami -x -D "cn=admin,dc=example,dc=com" -W -H ldap://localhost
  • Check mail queue: mailq
  • Clear mail queue if needed: sudo postsuper -d ALL
  • Restart services: sudo systemctl restart slapd postfix rsyslog

What does all of this mean?

Explaining LDAP acronyms

  • LDAP: Lightweight Directory Access Protocol
  • DN: Distinguished Name, the full path
  • RDN: Relative Distinguished Name
  • CN: Common Name
  • SN: S

Things to Know

Here’s a quick glossary of the most common LDAP-related acronyms you’ll see when working with Debian’s OpenLDAP (and LDAP in general), along with some extras you might encounter:


Protocol & File Formats

  • LDAPLightweight Directory Access Protocol.
    The network protocol used to query and modify directory services.
  • DITDirectory Information Tree.
    The hierarchical data structure (tree) of entries in an LDAP directory.
  • LDIFLDAP Data Interchange Format.
    A plain-text format for representing directory entries and update operations.

Naming & Distinguished Names

  • DNDistinguished Name.
    The full, unique “path” to an entry in the DIT.
  dn: cn=John Doe,ou=People,dc=example,dc=com
  • RDNRelative Distinguished Name.
    The left-most component of a DN (e.g. cn=John Doe).

Common Attribute Types

AcronymStands forTypical use
CNCommon NamePerson’s full name or a group’s name
SNSurnameFamily name (last name)
GNGiven NameFirst name
UIDUser IDLogin name or UNIX uid
OUOrganizational UnitDepartment or division (e.g. “Sales”, “IT”)
OOrganization NameCompany or organization (e.g. “Example Corp”)
DCDomain ComponentA DNS component; each becomes one level in your base DN
CCountry NameTwo-letter ISO country code (e.g. “US”, “GB”)
LLocality NameCity or locality (e.g. “Louisville”)
STState or Province NameFull state/province name (e.g. “Kentucky”)
postalAddressPostal AddressStreet address, often multi-line
telephoneNumberTelephoneContact number
mailE-mail AddressUser’s email (e.g. user@example.com)

Other Useful Acronyms

  • ACLAccess Control List.
    Rules governing who can read or modify which entries/attributes.
  • SASLSimple Authentication and Security Layer.
    A framework for adding authentication support to protocols like LDAP.
  • TLS/SSLTransport Layer Security / Secure Sockets Layer.
    Encryption layers you’ll often enable for secure LDAP (ldaps\:// or STARTTLS).
  • ACIAccess Control Instruction.
    In some directory servers (e.g. 389-ds), the syntax for ACL entries.
  • SyncreplSYNChronization REPLication.
    How OpenLDAP masters and replicas keep in sync.

Putting It All Together

A typical base DN for a company might be:

dn: dc=example,dc=com
objectClass: top
objectClass: dcObject
objectClass: organization
dc: example
o: Example Corporation

An employee entry under that might look like:

dn: uid=jdoe,ou=People,dc=example,dc=com
objectClass: inetOrgPerson
cn: John Doe
sn: Doe
givenName: John
uid: jdoe
mail: j.doe@example.com
telephoneNumber: +1 555 1234

Where to Look on Debian 12

  • /etc/ldap/ldap.conf – client-side defaults (e.g. BASE dc=example,dc=com).
  • /etc/ldap/slapd.d/ – the cn=config database of your slapd server.
  • slapcat / slapadd / ldapadd – tools to export or import LDIFs.

Change user alias via cli:

cat > modify_alias.ldif << EOF
dn: cn=webmaster,ou=aliases,dc=example,dc=com
changetype: modify
replace: mail
mail: testuser2@example.com
EOF
ldapmodify -x -D "cn=admin,dc=example,dc=com" -W -f modify_alias.ldif
ldapsearch -x -b "ou=aliases,dc=example,dc=com" "(cn=webmaster)"

Change multiple users:
LDIF file:

## Change multiple aliases at once
dn: cn=webmaster,ou=aliases,dc=example,dc=com
changetype: modify
replace: mail
mail: testuser2@example.com
-
replace: description
description: Updated mail alias for webmaster

dn: cn=admin,ou=aliases,dc=example,dc=com
changetype: modify
replace: mail
mail: testuser2@example.com

Important:
The dash (-) is used to separate multiple operations on the same entry.
You can also add or delete values instead of replacing them. For example, to add an additional mail attribute (though this isn’t typically done for aliases):

You can also add or delete values instead of replacing them. For example, to add an additional mail attribute (though this isn’t typically done for aliases):
LDIF file:

dn: cn=webmaster,ou=aliases,dc=example,dc=com
changetype: modify
add: mail
mail: another@example.com

Or to delete a specific value:
LDIF file:

dn: cn=webmaster,ou=aliases,dc=example,dc
changetype: modify
delete: mail
mail: testuser@example.com

Next Steps

Postfix and Dovecot setup will be next. The zip file below contains this article in text format for easier copy and paste.