TLS/SSL

Deploy OpenLDAP with encrypted connections using StartTLS (port 389) and LDAPS (port 636). Self-signed certificates are included for testing.

Project Files

openldap-tls
Explorer
docker-compose.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
services:
  openldap:
    image: ${LDAP_IMAGE:-openldap:local}
    container_name: openldap-tls
    hostname: openldap-tls
    environment:
      - LDAP_DOMAIN=example.com
      - LDAP_ADMIN_PASSWORD=AdminPass123!
      - LDAP_ORGANIZATION=TLS Test Organization
      - ENABLE_MONITORING=true
      
      # TLS configuration
      - LDAP_TLS_CERT=/certs/ldap.crt
      - LDAP_TLS_KEY=/certs/ldap.key
    ports:
      - "389:389"
      - "636:636"
    volumes:
      - ldap-data:/var/lib/ldap
      - ldap-config:/etc/openldap/slapd.d
      - ./logs:/logs
      - ./certs:/certs:ro
    
    # Security settings
    security_opt:
      - no-new-privileges:true
    cap_drop:
      - ALL
    cap_add:
      - DAC_READ_SEARCH
      - DAC_OVERRIDE
      - NET_BIND_SERVICE
      - SETUID
      - SETGID
      - CHOWN
    stop_grace_period: 30s
    
    restart: unless-stopped
    
    # Resource limits
    deploy:
      resources:
        limits:
          memory: 512M
          cpus: '1.0'
        reservations:
          memory: 128M
    
    # Log rotation
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"

volumes:
  ldap-data:
  ldap-config:
YAMLUTF-8
Ln 593 files

Set image

export LDAP_IMAGE=ghcr.io/vibhuvioio/openldap:latest

Start

docker compose up -d

StartTLS upgrades a plaintext connection on port 389 to TLS:

LDAPTLS_REQCERT=never ldapsearch -x -H ldap://localhost:389 -ZZ \
  -D "cn=Manager,dc=example,dc=com" \
  -w "AdminPass123!" \
  -b "dc=example,dc=com" -s base
  • -ZZ — Require TLS (fail if not available)
  • -Z — Use TLS if available (don't fail otherwise)

Test LDAPS (Direct SSL)

LDAPS uses a dedicated TLS connection on port 636:

LDAPTLS_REQCERT=never ldapsearch -x -H ldaps://localhost:636 \
  -D "cn=Manager,dc=example,dc=com" \
  -w "AdminPass123!" \
  -b "dc=example,dc=com" -s base
LDAPTLS_REQCERT=never is for self-signed certs only. In production, use LDAPTLS_CACERT=./certs/ca.crt instead.

Environment Variables

VariableValueDescription
LDAP_TLS_CERT/certs/ldap.crtPath to server certificate
LDAP_TLS_KEY/certs/ldap.keyPath to private key
LDAP_TLS_CAOptional CA certificate
LDAP_TLS_VERIFY_CLIENTneverClient cert verification mode
Client verification modes:

ValueDescription
neverNo client cert required (default)
allowRequest but don't require
tryVerify if provided
demandRequire valid client certificate

Generate Your Own Certificates

Replace the test certificates with your own:

# Self-signed (testing)
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout certs/ldap.key \
  -out certs/ldap.crt \
  -subj "/C=US/ST=State/L=City/O=Organization/CN=openldap.example.com"

# For production, use certificates from your CA:
# - Let's Encrypt
# - Internal PKI
# - cert-manager (Kubernetes)

Production Configuration

Mount your own certificates as read-only volumes:

environment:
  - LDAP_TLS_CERT=/certs/server.crt
  - LDAP_TLS_KEY=/certs/server.key
  - LDAP_TLS_CA=/certs/ca.crt
volumes:
  - /path/to/your/certs:/certs:ro

Connection Details

SettingValue
Hostlocalhost
LDAP Port389 (StartTLS)
LDAPS Port636 (Direct SSL)
Bind DNcn=Manager,dc=example,dc=com
Base DNdc=example,dc=com
PasswordAdminPass123!

Troubleshooting

"Can't contact LDAP server" — Check if slapd started correctly:
docker logs openldap-tls | grep -i tls
"Certificate verification failed" — For self-signed certs:
LDAPTLS_REQCERT=never ldapsearch ...
# or trust the specific cert:
LDAPTLS_CACERT=./certs/ldap.crt ldapsearch ...
Certificates not loading — Verify file permissions:
docker exec openldap-tls ls -la /certs/

Cleanup

docker compose down -v