Skip to content

How to setup LDAP Authentication

Alfred Syatsukwa edited this page Jan 9, 2026 · 4 revisions

How to setup LDAP Authentication

Introduction

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:

  1. Manual installation (using code or tarball)
  2. Docker-based installation

Prerequisites

  • An LDAP server (Active Directory, OpenLDAP, etc.)
  • LDAP server connection details (server, port, bind DN, etc.)
  • PHP LDAP extension installed and enabled

Verify PHP LDAP Extension

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 ldap

If 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.

Configuration Overview

Cypht has two separate LDAP configurations that serve different purposes:

  1. LDAP Authentication Configuration - For authenticating users to log into Cypht (uses LDAP_AUTH_* variables)
  2. 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.


Manual Installation (Code/Tarball)

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.

LDAP Authentication Configuration

This section configures how users authenticate to Cypht using LDAP credentials.

Required Environment Variables

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"

Parameter Descriptions

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 to false - For unencrypted connections (insecure, recommended only for testing). This will automatically use ldap:// in the query.
  • Set to true - To enable LDAP over SSL/TLS. You need to use this with LDAP_AUTH_PORT=636 if your server is configured to use the standard ports or change with the used custom port. This setup will automatically use ldaps:// 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

Active Directory Authentication

Note: Active Directory support for UPN and domain\user formats requires Cypht version with PR #1826 merged. See PR #1826 for details.

Supported Authentication Formats

Cypht supports multiple Active Directory authentication formats:

  1. User Principal Name (UPN): user@domain.com

    • Example: alfred@example.com
    • Use this format directly in the login form
    • Recommended format for Active Directory
  2. Down-Level Logon Name: domain\user

    • Example: example\alfred
    • Use this format directly in the login form
    • Traditional Windows domain format
  3. 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

Active Directory Configuration 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"

Active Directory Login Examples

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 with LDAP_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 with sAMAccountName does not work because Active Directory doesn't support that DN format.

Active Directory Notes

  • 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=com format. The CN=Users container is automatically searched within the base DN
  • Username-Only Authentication Limitation: Active Directory does not support username-only authentication reliably. The sAMAccountName attribute cannot be used in DN construction for binding. The cn attribute 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.

OpenLDAP Configuration Example

For OpenLDAP servers, use traditional DN-based authentication. OpenLDAP supports both uid and cn attributes:

Using uid (Username-based)

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.

Using cn (Common Name)

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.


LDAP Addressbook Configuration

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.

Required Environment Variables

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=true

Parameter Descriptions

LDAP_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.

Key Differences from Authentication Config

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

Docker Installation

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.

Complete Docker Compose Example

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/fonts

Active Directory Docker Example

For 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/fonts

Important Notes for Docker Configuration:

  1. 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.

  2. 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.


Important Note about LDAPS (LDAP over SSL/TLS)

When using LDAPS (LDAP over SSL/TLS), you need to ensure that the LDAP server's certificate is trusted by the client system.

Using a Trusted Certificate Authority

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

Using a Self-Signed Certificate (Common in Internal Networks)

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.


Troubleshooting

Authentication Fails

  1. Verify PHP LDAP Extension:

    php -m | grep ldap

    If not found, install: apt-get install php-ldap (Debian/Ubuntu) or yum install php-ldap (RHEL/CentOS)

  2. Test LDAP Connection:

    ldapsearch -x -H ldap://your-server:389 -b "dc=example,dc=com" -s base
  3. 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
  4. Check Base DN: Ensure LDAP_AUTH_BASE_DN matches your directory structure. The base DN must be correct for your LDAP server.

  5. Verify Username Format:

    • For Active Directory, use user@domain.com or domain\user format
    • For OpenLDAP, use just the username (e.g., alfred)
  6. 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

Active Directory Specific Issues

  • "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
  • 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

OpenLDAP Specific Issues

  • DN Construction: Verify that LDAP_AUTH_UID_ATTR matches your LDAP schema. Common values are uid or cn
  • Base DN: Ensure the base DN includes the correct organizational units if users are not at the root

TLS/SSL Certificate Issues

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.

Addressbook Issues

  • No Contacts Showing:

    • Verify LDAP_BASE_DN is correct
    • Check LDAP_SEARCH_TERM matches your LDAP object classes
    • Ensure LDAP_AUTH is set correctly (true if authentication required, false for anonymous)
  • Cannot Edit Contacts:

    • Verify LDAP_READ_WRITE=true
    • Check user has write permissions in LDAP directory
    • Ensure authenticated binding is configured if required

Related Resources


Final Notes

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.


Summary

  • 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 uid attribute
  • 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

>

Clone this wiki locally