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.
- 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
- 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
orsudo 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
- LDAP – Lightweight Directory Access Protocol.
The network protocol used to query and modify directory services. - DIT – Directory Information Tree.
The hierarchical data structure (tree) of entries in an LDAP directory. - LDIF – LDAP Data Interchange Format.
A plain-text format for representing directory entries and update operations.
Naming & Distinguished Names
- DN – Distinguished Name.
The full, unique “path” to an entry in the DIT.
dn: cn=John Doe,ou=People,dc=example,dc=com
- RDN – Relative Distinguished Name.
The left-most component of a DN (e.g.cn=John Doe
).
Common Attribute Types
Acronym | Stands for | Typical use |
---|---|---|
CN | Common Name | Person’s full name or a group’s name |
SN | Surname | Family name (last name) |
GN | Given Name | First name |
UID | User ID | Login name or UNIX uid |
OU | Organizational Unit | Department or division (e.g. “Sales”, “IT”) |
O | Organization Name | Company or organization (e.g. “Example Corp”) |
DC | Domain Component | A DNS component; each becomes one level in your base DN |
C | Country Name | Two-letter ISO country code (e.g. “US”, “GB”) |
L | Locality Name | City or locality (e.g. “Louisville”) |
ST | State or Province Name | Full state/province name (e.g. “Kentucky”) |
postalAddress | Postal Address | Street address, often multi-line |
telephoneNumber | Telephone | Contact number |
E-mail Address | User’s email (e.g. user@example.com) |
Other Useful Acronyms
- ACL – Access Control List.
Rules governing who can read or modify which entries/attributes. - SASL – Simple Authentication and Security Layer.
A framework for adding authentication support to protocols like LDAP. - TLS/SSL – Transport Layer Security / Secure Sockets Layer.
Encryption layers you’ll often enable for secure LDAP (ldaps\:// or STARTTLS). - ACI – Access Control Instruction.
In some directory servers (e.g. 389-ds), the syntax for ACL entries. - Syncrepl – SYNChronization 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.