-
Notifications
You must be signed in to change notification settings - Fork 202
How to setup LDAP Authentication
Cypht Webmail supports various authentication methods, including LDAP (Lightweight Directory Access Protocol), which allows integration with directory services like Active Directory, OpenLDAP, and other LDAP-compliant servers.
Integrating Lightweight Directory Access Protocol (LDAP) authentication is a critical feature for deploying Cypht in any organizational environment, especially within businesses, educational institutions, or any setting that requires centralized user management. Its importance extends far beyond a simple login method, offering strategic advantages in security, administration, and scalability.
This documentation covers two methods for setting up Cypht with LDAP authentication:
- Manual installation (using code or tarball)
- Docker-based installation
- An LDAP server (Active Directory, OpenLDAP, etc.)
- LDAP server connection details (server, port, bind DN, etc.)
- PHP LDAP extension installed and enabled
Before you proceed, you must verify that the LDAP extension is active in your PHP CLI and web server environments. Check via Command Line:
php -m | grep ldapIf the extension is not found, you need to install it:
-
Debian/Ubuntu:
apt-get install php-ldap -
RHEL/CentOS:
yum install php-ldap -
Fedora:
dnf install php-ldap
After installation, restart your web server.
Cypht has two separate LDAP configurations that serve different purposes:
-
LDAP Authentication Configuration - For authenticating users to log into Cypht (uses
LDAP_AUTH_*variables) -
LDAP Addressbook Configuration - For accessing LDAP directory contacts/addressbook (uses
LDAP_*variables)
These configurations are independent and can use the same or different LDAP servers. You can configure authentication without addressbook, or both together.
This section details the process of configuring LDAP authentication for a manual installation of Cypht. It is assumed that you have already successfully installed Cypht on your web server by following the official Cypht Installation Guide https://www.cypht.org/install/. This includes steps such as downloading the source code, setting appropriate file permissions, and configuring your web server (Apache, Nginx, etc.) to serve the application.
This section configures how users authenticate to Cypht using LDAP credentials.
You need to make these changes in your .env file:
# Enable LDAP authentication
AUTH_TYPE=LDAP
# LDAP Authentication Settings
LDAP_AUTH_SERVER=ldap.example.com
LDAP_AUTH_PORT=389
LDAP_AUTH_TLS=
LDAP_AUTH_BASE_DN="dc=example,dc=com"
LDAP_AUTH_UID_ATTR="uid"AUTH_TYPE: Master switch for authentication method. Must be set to LDAP (all caps) to enable LDAP authentication. Valid values:
-
DB- Authenticate against the database -
LDAP- Authenticate against an LDAP server -
IMAP- Authenticate using an IMAP server -
dynamic- Let the user choose from a list, or try to auto discover the mail services based on the email domain -
custom- Create your own auth class
LDAP_AUTH_SERVER: The hostname or IP address of the LDAP server to authenticate to. Replace ldap.example.com with the actual server address. Examples: ldap.example.com, 192.168.1.50, ad.company.local
LDAP_AUTH_PORT: The port the LDAP server is listening on. Standard ports:
-
389- Unencrypted LDAP or StartTLS -
636- LDAPS (LDAP over SSL/TLS)
LDAP_AUTH_TLS: Enable TLS/SSL connections. This is a major security setting:
- Leave empty (
LDAP_AUTH_TLS=) or set tofalse- For unencrypted connections (insecure, recommended only for testing). This will automatically useldap://in the query. - Set to
true- To enable LDAP over SSL/TLS. You need to use this withLDAP_AUTH_PORT=636if your server is configured to use the standard ports or change with the used custom port. This setup will automatically useldaps://in the query.
LDAP_AUTH_BASE_DN: The "base dn" of the LDAP server. This is your LDAP directory where the application will search for user accounts. Note: Cypht doesn't support a recursive search in your LDAP directory tree. This is a Distinguished Name (DN) that defines the scope of your search. You must change this to match your organization's structure.
Examples:
-
"dc=example,dc=com"- Search at the root of the domain -
"ou=Users,dc=example,dc=com"- Search in the "Users" organizational unit -
"ou=IT,ou=Departments,dc=example,dc=com"- Search in the OU "IT" which is a child OU of "Departments". Remember, the root on the right and the child on the left. If you have more than two levels, that's the rule. -
"cn=Users,dc=example,dc=com"- Users container (Active Directory)
LDAP_AUTH_UID_ATTR: Attribute to use as the unique identifier for users. This is arguably the most important parameter. It defines which LDAP attribute matches the "username" that the user types into the login form. What to set depends entirely on your LDAP server's schema.
Common values:
-
"uid"- OpenLDAP, Unix-based systems (username-based, e.g., "alfred") -
"cn"- Common Name (full name like "John Doe"). Supported by both OpenLDAP and Active Directory
Note: Active Directory support for UPN and domain\user formats requires Cypht version with PR #1826 merged. See PR #1826 for details.
Cypht supports multiple Active Directory authentication formats:
-
User Principal Name (UPN):
user@domain.com- Example:
alfred@example.com - Use this format directly in the login form
- Recommended format for Active Directory
- Example:
-
Down-Level Logon Name:
domain\user- Example:
example\alfred - Use this format directly in the login form
- Traditional Windows domain format
- Example:
-
Distinguished Name (DN):
CN=User Name,CN=Users,DC=domain,DC=com- Example:
CN=Alfred Syatsukwa,CN=Users,DC=example,DC=com - Full DN format, works with any LDAP server
- Example:
AUTH_TYPE=LDAP
# Active Directory Server
LDAP_AUTH_SERVER=ldap.example.com
LDAP_AUTH_PORT=389
LDAP_AUTH_TLS=false
# Base DN for your Active Directory domain
LDAP_AUTH_BASE_DN="DC=example,DC=com"
# For Active Directory, this setting is optional when using UPN or domain\user formats
# It's only used if users enter just the username without @ or \
# Note: Username-only authentication is NOT recommended for Active Directory
# If you must use it, set to "cn" but users must enter their FULL NAME (e.g., "Alfred Syatsukwa")
# not just username, because CN attribute contains the full name in Active Directory
LDAP_AUTH_UID_ATTR="cn"Users can log in using any of these formats:
-
UPN format:
alfred@example.com✅ (Recommended) -
Domain\Username:
example\alfred✅ (Recommended) -
Full DN:
CN=Alfred Syatsukwa,CN=Users,DC=example,DC=com✅ -
Username only:
⚠️ Not recommended for Active Directory. If you must use it withLDAP_AUTH_UID_ATTR="cn", users must enter their full name (e.g.,Alfred Syatsukwa), not just username, because the CN attribute contains the full name in Active Directory. Username-only withsAMAccountNamedoes not work because Active Directory doesn't support that DN format.
- Referral Handling: Cypht automatically disables LDAP referral following for authentication to ensure local authentication checks. Active Directory may return referrals for searches across domains or special partitions, but for authentication we should keep the check local to the connected server without following referrals to other DCs.
- No TLS Required: Active Directory supports unencrypted LDAP on port 389 (though TLS is recommended for production environments)
-
Base DN Format: Active Directory typically uses
DC=domain,DC=comformat. TheCN=Userscontainer is automatically searched within the base DN -
Username-Only Authentication Limitation: Active Directory does not support username-only authentication reliably. The
sAMAccountNameattribute cannot be used in DN construction for binding. Thecnattribute requires users to enter their full name, not just username. For Active Directory, always use UPN (user@domain.com) or domain\user (domain\user) formats.
For OpenLDAP servers, use traditional DN-based authentication. OpenLDAP supports both uid and cn attributes:
AUTH_TYPE=LDAP
LDAP_AUTH_SERVER=ldap.example.com
LDAP_AUTH_PORT=389
LDAP_AUTH_TLS=false
LDAP_AUTH_BASE_DN="dc=example,dc=com"
LDAP_AUTH_UID_ATTR="uid"Users log in with just their username (e.g., alfred), and Cypht constructs the DN as uid=alfred,dc=example,dc=com.
AUTH_TYPE=LDAP
LDAP_AUTH_SERVER=ldap.example.com
LDAP_AUTH_PORT=389
LDAP_AUTH_TLS=false
LDAP_AUTH_BASE_DN="dc=example,dc=com"
LDAP_AUTH_UID_ATTR="cn"Users log in with their full name (e.g., John Doe), and Cypht constructs the DN as CN=John Doe,dc=example,dc=com.
Note: Choose the attribute that matches your OpenLDAP schema. Most OpenLDAP installations use uid for username-based authentication, but cn is also commonly supported.
This section configures LDAP as a contact/addressbook source. This is separate from authentication and is optional. The addressbook allows users to search and access contacts from your LDAP directory.
Add these to your .env file (separate from authentication settings):
# LDAP Addressbook Settings (for contacts, separate from authentication)
LDAP_SERVER=ldap.example.com
LDAP_PORT=389
LDAP_ENABLE_TLS=false
LDAP_BASE_DN="dc=example,dc=com"
LDAP_SEARCH_TERM="objectclass=inetOrgPerson"
LDAP_AUTH=false
LDAP_UID_ATTR="uid"
LDAP_USER=""
LDAP_PASS=""
LDAP_OBJECT_CLASS="top,person,organizationalperson,inetorgperson"
LDAP_READ_WRITE=trueLDAP_SERVER: LDAP Server hostname or IP address for addressbook queries.
LDAP_PORT: Port to connect to for addressbook LDAP connection (typically 389 or 636).
LDAP_ENABLE_TLS: Flag to enable or disable TLS connections for addressbook. Set to true to enable, false to disable.
LDAP_BASE_DN: Base DN for searching contacts in the addressbook.
LDAP_SEARCH_TERM: LDAP filter for finding contact entries. Default: "objectclass=inetOrgPerson". This defines which entries will be shown in the addressbook.
LDAP_AUTH: Flag to enable user binding. Anonymous binding is used when set to false. If set to true, requires credentials in LDAP_USER and LDAP_PASS, or users can configure their own credentials in Settings.
LDAP_UID_ATTR: Attribute to use for user identification in the addressbook (typically "uid" or "cn").
LDAP_USER: Global username to bind with if LDAP_AUTH is set to true. If left blank, users will have a setting on the Settings -> Site page for this connection to enter their own.
LDAP_PASS: Global password to bind with if LDAP_AUTH is set to true. If left blank, users will have a setting on the Settings -> Site page for this connection to enter their own.
LDAP_OBJECT_CLASS: Object classes for the addressbook entries. Comma-separated list. Default: "top,person,organizationalperson,inetorgperson".
LDAP_READ_WRITE: Flag to allow editing of the addressbook contents. Set to true to allow editing, false for read-only.
| Feature | Authentication | Addressbook |
|---|---|---|
| Purpose | User login | Contact lookup |
| Prefix | LDAP_AUTH_* |
LDAP_* |
| Required | Yes (if using LDAP auth) | Optional |
| Can use same server | Yes | Yes |
| Configuration file | config/app.php |
config/ldap.php |
This section details the process of configuring LDAP authentication for a Docker-based installation of Cypht. It is assumed that you have already successfully deployed a Cypht container using the official image from Docker Hub or another repository. This includes having Docker and Docker Compose installed on your host system, and understanding how to manage containers and volumes.
Following the same core principles as the manual installation, we will be configuring the same essential LDAP parameters (such as server host, port, and base DN). However, in the Docker methodology, these settings will not be defined in a static .env file. Instead, they will be passed directly to the Cypht container as environment variables within the docker-compose.yaml file, leveraging the container's innate ability to dynamically generate its configuration upon startup.
Here is a complete docker-compose.yaml example file with LDAP authentication and addressbook configuration:
# Complete Docker Compose example for Cypht with LDAP authentication
services:
db:
image: mariadb:10
ports:
- "3306:3306"
volumes:
- ./data/mysql:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=root_password
- MYSQL_DATABASE=cypht
- MYSQL_USER=cypht
- MYSQL_PASSWORD=cypht_password
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-ucypht", "-pcypht_password"]
interval: 10s
timeout: 5s
retries: 5
cypht:
image: cypht/cypht:2.5.1
depends_on:
db:
condition: service_healthy
ports:
- "80:80"
environment:
# Database Configuration
- DB_CONNECTION_TYPE=host
- DB_DRIVER=mysql
- DB_HOST=db
- DB_NAME=cypht
- DB_USER=cypht
- DB_PASS=cypht_password
# Session and User Config
- SESSION_TYPE=db
- USER_CONFIG_TYPE=DB
# LDAP Authentication Configuration
- AUTH_TYPE=LDAP
- LDAP_AUTH_SERVER=ldap.example.com
- LDAP_AUTH_PORT=389
- LDAP_AUTH_TLS=
- LDAP_AUTH_BASE_DN=dc=example,dc=com
- LDAP_AUTH_UID_ATTR=uid
# LDAP Addressbook Configuration (optional)
- LDAP_SERVER=ldap.example.com
- LDAP_PORT=389
- LDAP_ENABLE_TLS=false
- LDAP_BASE_DN=dc=example,dc=com
- LDAP_SEARCH_TERM=objectclass=inetOrgPerson
- LDAP_AUTH=false
- LDAP_UID_ATTR=uid
- LDAP_USER=
- LDAP_PASS=
- LDAP_OBJECT_CLASS=top,person,organizationalperson,inetorgperson
- LDAP_READ_WRITE=true
volumes:
- ./data/log/nginx:/var/log/nginx
- ./data/log/php:/var/log/php
- ./data/log/supervisord:/var/log/supervisord
- ./data/fonts:/usr/local/share/cypht/site/fontsFor Active Directory, use this configuration:
services:
db:
image: mariadb:10
ports:
- "3306:3306"
volumes:
- ./data/mysql:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=root_password
- MYSQL_DATABASE=cypht
- MYSQL_USER=cypht
- MYSQL_PASSWORD=cypht_password
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-ucypht", "-pcypht_password"]
interval: 10s
timeout: 5s
retries: 5
cypht:
image: cypht/cypht:2.5.1
depends_on:
db:
condition: service_healthy
ports:
- "80:80"
environment:
# Database Configuration
- DB_CONNECTION_TYPE=host
- DB_DRIVER=mysql
- DB_HOST=db
- DB_NAME=cypht
- DB_USER=cypht
- DB_PASS=cypht_password
# Session and User Config
- SESSION_TYPE=db
- USER_CONFIG_TYPE=DB
# LDAP Authentication for Active Directory
- AUTH_TYPE=LDAP
- LDAP_AUTH_SERVER=ldap.example.com
- LDAP_AUTH_PORT=389
- LDAP_AUTH_TLS=
- LDAP_AUTH_BASE_DN=DC=example,DC=com
- LDAP_AUTH_UID_ATTR=cn
volumes:
- ./data/log/nginx:/var/log/nginx
- ./data/log/php:/var/log/php
- ./data/log/supervisord:/var/log/supervisord
- ./data/fonts:/usr/local/share/cypht/site/fontsImportant Notes for Docker Configuration:
-
No Quotes: Don't add quotes on the different values. This will not work:
# ❌ WRONG - LDAP_AUTH_SERVER="ldap.example.com" - LDAP_AUTH_TLS=true - LDAP_AUTH_BASE_DN="dc=example,dc=com"
Keep everything without any quotes like the examples given above.
-
Docker Image Compatibility: The official Cypht Docker images starting from version 2.5.0 include the PHP LDAP extension. For LDAP authentication, use cypht:2.5.0 or later (e.g., cypht:2.5.1). Earlier versions (2.4.2 and below) do not include the LDAP extension and will not support LDAP authentication.
When using LDAPS (LDAP over SSL/TLS), you need to ensure that the LDAP server's certificate is trusted by the client system.
If your LDAP server uses a certificate signed by a trusted Certificate Authority (CA), typically no additional configuration should be needed. But in case you have persistent issues, check the content of this file (/etc/ldap/ldap.conf) to make sure you have this line:
TLS_CACERT /etc/ssl/certs/ca-certificates.crt
This is very common for internal corporate or lab LDAP servers. The certificate is often signed by an internal company CA or is self-signed. The client does not inherently trust this certificate, so you must explicitly add it to the client's trust store (the process depends on your OS).
For test purposes, you can tell your client to ignore this verification by replacing the line:
TLS_CACERT /etc/ssl/certs/ca-certificates.crt
by this:
TLS_REQCERT allow
in your file config /etc/ldap/ldap.conf.
Note: Using TLS_REQCERT allow disables certificate verification and should only be used for testing. For production, properly install and trust the certificate.
-
Verify PHP LDAP Extension:
php -m | grep ldapIf not found, install:
apt-get install php-ldap(Debian/Ubuntu) oryum install php-ldap(RHEL/CentOS) -
Test LDAP Connection:
ldapsearch -x -H ldap://your-server:389 -b "dc=example,dc=com" -s base -
Test Authentication with ldapsearch:
# Test with UPN format (Active Directory) ldapsearch -x -H ldap://ldap.example.com:389 -D "user@example.com" -W -b "DC=example,DC=com" -s base "(objectclass=*)" dn # Test with domain\user format (Active Directory) ldapsearch -x -H ldap://ldap.example.com:389 -D "example\user" -W -b "DC=example,DC=com" -s base "(objectclass=*)" dn # Test with DN format ldapsearch -x -H ldap://ldap.example.com:389 -D "CN=User Name,CN=Users,DC=example,DC=com" -W -b "DC=example,DC=com" -s base "(objectclass=*)" dn
-
Check Base DN: Ensure
LDAP_AUTH_BASE_DNmatches your directory structure. The base DN must be correct for your LDAP server. -
Verify Username Format:
- For Active Directory, use
user@domain.comordomain\userformat - For OpenLDAP, use just the username (e.g.,
alfred)
- For Active Directory, use
-
Check Network Connectivity: Ensure the Cypht server can reach the LDAP server on the specified port:
telnet ldap.example.com 389 # or nc -zv ldap.example.com 389
-
"Invalid username or password":
- Try using UPN format (
user@domain.com) instead of just username - Try using domain\user format (
domain\user) - Verify the user account is not locked or disabled in Active Directory
- Check if the user has the correct password
- Try using UPN format (
-
Referral Errors: Should be automatically handled by Cypht (LDAP_OPT_REFERRALS=0 is set), but if you encounter issues, verify the setting is applied in the code
-
Certificate Issues: If using LDAPS, ensure certificates are trusted (see TLS section above)
-
Port Issues: Active Directory typically uses port 389 for unencrypted LDAP. Ensure the port is correct and not blocked by firewall
-
DN Construction: Verify that
LDAP_AUTH_UID_ATTRmatches your LDAP schema. Common values areuidorcn - Base DN: Ensure the base DN includes the correct organizational units if users are not at the root
For LDAPS connections, ensure the LDAP server's certificate is trusted:
Linux: Check /etc/ldap/ldap.conf:
TLS_CACERT /etc/ssl/certs/ca-certificates.crt
Self-Signed Certificates (testing only):
TLS_REQCERT allow
Docker: If using Docker, you may need to configure certificate trust inside the container or mount certificate files.
-
No Contacts Showing:
- Verify
LDAP_BASE_DNis correct - Check
LDAP_SEARCH_TERMmatches your LDAP object classes - Ensure
LDAP_AUTHis set correctly (true if authentication required, false for anonymous)
- Verify
-
Cannot Edit Contacts:
- Verify
LDAP_READ_WRITE=true - Check user has write permissions in LDAP directory
- Ensure authenticated binding is configured if required
- Verify
- PR #1826 - Active Directory UPN and domain\user support
- Issue #1791 - Active Directory authentication discussion
- Official Cypht Installation Guide
We hope this guide has been helpful in configuring LDAP authentication for your Cypht instance. Thank you for choosing Cypht as your webmail solution.
The Cypht project thrives on feedback and contributions from its community. If you encounter any errors or have suggestions for improving this documentation, please do not hesitate to open an issue on the official Cypht GitHub repository. Your input is invaluable in helping to improve the software for everyone.
-
Authentication uses
LDAP_AUTH_*variables and is required for LDAP login -
Addressbook uses
LDAP_*variables and is optional for contact lookup -
Active Directory supports UPN (
user@domain.com) and domain\user (domain\user) formats (requires PR #1826) -
OpenLDAP uses traditional DN construction with
uidattribute - Both configurations can use the same LDAP server or different ones
- Docker configuration requires PHP LDAP extension in the image (check version compatibility)
- TLS/SSL certificates must be properly configured for LDAPS connections