04 - Authentication - OpenLDAP

Docker
Self-hosted software
OpenLDAP
Authentication
Centralize your user database for services authentication
Author

ProtossGP32

Published

February 3, 2023

Introduction

TODO

Add properly explained procedure to deploy SonarQube, both on internal network and accessible from outside with HTTPS partially enabled

OpenLDAP

An open-source LDAP server

phpLDAPadmin

An open-source LDAP administration service with a web interface

Self Service Password

An open-source web interface that allows LDAP users to change their own passwords.

The docker container needs a config file named config.inc.local.php that overwrites the default values defined in config.inc.php; this file is provided in the docker-compose.yml file as a volume.

There are a lot of parameters that can be configured, but for the sake of simplicity only LDAP server parameters and password policies are defined here:

config.inc.local.php
<?php
// A random keyphrase is required to initialize the service
$keyphrase = getenv('SSP_KEYPHRASE');
$debug = false;

// LDAP server config
$ldap_url = "ldap://openldap:1389";
$ldap_starttls = false;
$ldap_binddn = "cn=admin,dc=protossnet,dc=local";
$ldap_bindpw = getenv('LDAP_BIND_PASSWORD');

$ldap_base = "ou=users,dc=protossnet,dc=local";
$ldap_login_attribute = "uid";
$ldap_fullname_attribute = "displayName";
$ldap_filter = "(&(objectClass=inetOrgPerson)($ldap_login_attribute={login}))";

// Password policies that new passwords must comply
$pwd_min_length = 8;
$pwd_max_length = 16;
$pwd_min_lower = 1;
$pwd_min_upper = 1;
$pwd_min_digit = 1;
$pwd_min_special = 1;
$pwd_special_chars = "^@%!-_";
$pwd_no_reuse = true;
$pwd_diff_login = true;
$pwd_diff_last_min_chars = 0;
$pwd_no_special_at_ends = false;

// "manager" means that the user defined in ldap_binddn is the responsible of
// changing the user's passwords within LDAP (the rest of users don't have enough privileges)
$who_change_password = "manager";
$lang = "en";
$allowed_lang = array("en");
?>

Docker compose

Some sensitive data must be provided using two different methods:

  • The .env file that should exists in the same path as the docker-compose.yml must contain the LDAP admin password and a random string that will act as a keyphrase, both values required for Self Service Password:

    .env
    SSP_PASSPHRASE="yourRandomSecretString"
    LDAP_BIND_PASSWORD="the-password-of-the-LDAP-admin"
  • A secret file that also contains the LDAP admin password, this time required by the openLDAP service:

    secrets/ldap_admin_password.txt
    "the-password-of-the-LDAP-admin"

Finally, the docker-compose.yml file that creates all of the LDAP services is as follows:

docker-compose.yml
version: '2'
name: ldap-service
services:
  # LDAP server
  openldap:
    image: docker.io/bitnami/openldap:2.6
    container_name: openldap
    hostname: openldap
    ports:
      - '1389:1389'
      - '1636:1636'
    environment:
      # Default LDAP_ROOT: dc=example,dc=org
      - LDAP_ROOT=dc=protossnet,dc=local
      #- LDAP_ADMIN_USERNAME=admin
      - LDAP_ADMIN_PASSWORD_FILE=/run/secrets/ldap_admin_password
      #- LDAP_USERS=user01
      #- LDAP_PASSWORDS=password1
      - LDAP_ENABLE_TLS=no
    volumes:
      - 'openldap_data:/bitnami/openldap'
    networks:
      - network
    secrets:
      - ldap_admin_password

  # LDAP administrator via web interface
  phpldapadmin:
    image: osixia/phpldapadmin:latest
    container_name: phpldapadmin
    environment:
      # bitnami/openldap uses non-privileged port as default
      PHPLDAPADMIN_LDAP_HOSTS: "#PYTHON2BASH:[{'openldap': [{'server': [{ 'port': 1389 }]}]}]"
      PHPLDAPADMIN_HTTPS: "false"
      PHPLDAPADMIN_LDAP_CLIENT_TLS: "false"
    networks:
      - network
    ports:
      - "8080:80"
    depends_on:
      - openldap

  # Simple web service for password restart
  self-service-password:
    image: ltbproject/self-service-password:latest
    container_name: self-service-password
    environment:
      LDAP_BIND_PASSWORD: ${LDAP_BIND_PASSWORD}
      SSP_KEYPHRASE: ${SSP_KEYPHRASE}
    volumes:
      - '$PWD/conf/config.inc.local.php:/var/www/conf/config.inc.local.php'
    ports:
      - "8081:80"
    networks:
      - network
    depends_on:
      - openldap

networks:
  network:
    driver: bridge

volumes:
  openldap_data:
    driver: local

secrets:
  ldap_admin_password:
    file: secrets/ldap_admin_password.txt