Security Azure

LDAP Account Manager on Ubuntu 24.04 on Azure User Guide

| Product: LDAP Account Manager on Ubuntu 24.04 LTS on Azure

Overview

LDAP Account Manager (LAM) is the long established open source web front end for administering an LDAP directory. Instead of editing raw LDIF or reaching for command line tools, administrators browse and manage users, groups, hosts and other account types through a clean browser interface, with reusable account profiles, a tree view, PDF export and password self service. The cloudimg image is a self contained directory appliance: OpenLDAP (slapd) runs on the instance as the directory backend and LAM 9.6 is served by the Apache web server with PHP 8.3 in front of it, all on a hardened, fully patched Ubuntu 24.04 LTS base. The directory is pre organised with ou=People and ou=Groups containers and two sample accounts, so the management interface is populated the moment the instance boots. The directory service is bound to the loopback interface only, and a unique set of secrets is generated on the first boot of every VM. Backed by 24/7 cloudimg support.

What is included:

  • LDAP Account Manager 9.6 (community edition, GPL-3.0) served by Apache and PHP 8.3, managed by systemd
  • A bundled OpenLDAP (slapd) directory backend, provisioned with base DN dc=cloudimg,dc=local
  • A ready made directory layout: ou=People, ou=Groups and two sample accounts in a sample group
  • Three per VM secrets generated on first boot and recorded in a root only file: the directory manager login password, the LAM master configuration password and the LAM server profile password
  • No shipped default login: no known or blank credential authenticates; every secret is rotated to a discarded random at build time and regenerated uniquely on first boot
  • OpenLDAP bound to the loopback interface 127.0.0.1:389 only, never exposed to the network
  • slapd.service and apache2.service as enabled systemd units
  • An unauthenticated /healthz endpoint for Azure Load Balancer health probes
  • 24/7 cloudimg support

Prerequisites

An active Azure subscription, an SSH key pair, and a VNet plus subnet in the target region. Standard_B2s (2 vCPU / 4 GiB RAM) is a sensible starting point; step up to Standard_D2s_v3 for larger directories or more concurrent administrators. NSG inbound: allow 22/tcp from your management network and 80/tcp for the LAM web interface (add 443/tcp if you terminate TLS on the VM). The directory service is never exposed: slapd listens on 127.0.0.1 only, so port 389 stays off the network.

Step 1 - Deploy from the Azure Marketplace

Sign in to the Azure Portal, choose Create a resource, search the Marketplace for LDAP Account Manager by cloudimg, and select Create. On Basics pick your subscription, resource group, region and size; under Administrator account choose SSH public key and paste your key; under Inbound port rules allow SSH (22) and HTTP (80). Then Review + create then Create.

Step 2 - Deploy from the Azure CLI

az vm create \
  --resource-group <your-rg> \
  --name lam \
  --image <marketplace-image-urn> \
  --size Standard_B2s \
  --admin-username azureuser \
  --generate-ssh-keys \
  --public-ip-sku Standard

Then open port 80:

az vm open-port --resource-group <your-rg> --name lam --port 80

Step 3 - Confirm the services are running

SSH in as azureuser and confirm the directory backend and the web interface are both active. Note that slapd listens only on 127.0.0.1:389 while Apache serves LAM on port 80.

systemctl is-active slapd apache2
ss -tlnp | grep -E ':389 |:80 ' | sed 's/  */ /g'

The slapd and apache2 services reported active, with Apache listening on port 80 and slapd bound to loopback 127.0.0.1:389

Step 4 - Retrieve the per VM credentials

Every VM generates its own secrets on first boot and writes them, along with the login DN and the application URL, to a root only credentials file. Read it with sudo:

sudo cat /root/ldap-account-manager-credentials.txt

The per VM LDAP Account Manager credentials file, showing the login DN, the generated directory manager password, the base DN and the LAM master and profile passwords

You sign in to LAM by choosing the cn=admin,dc=cloudimg,dc=local entry and entering lam.login.pass from this file. That value is the OpenLDAP directory manager password; LAM authenticates your login by binding to the directory with it. The lam.master.pass and lam.profile.pass values guard LAM's own configuration editors and are not needed for day to day account management.

Step 5 - Sign in

Browse to http://<vm-public-ip>/. You land on the LAM sign in page, which offers the directory manager DN in a dropdown and a password field.

The LDAP Account Manager sign in page showing the user DN dropdown, the password field, the language selector and the Login button

After signing in you land on the account list. The Users tab lists the accounts under ou=People, pre populated with the two sample accounts so you can see the layout straight away.

The LDAP Account Manager user account list after signing in, showing the two sample users under ou=People with their user names and common names

Step 6 - Manage users and groups

Click a user to open the account editor, where each tab (Personal, Unix, and others depending on the active modules) exposes the attributes for that account. Use New user to create accounts, New group under the Groups tab to manage ou=Groups, and the account profiles to stamp out consistent new accounts. Every change is written straight into the directory.

The LDAP Account Manager account editor for a sample user, showing the Personal and Unix attribute tabs and the account fields

The Groups tab lists the groups under ou=Groups, pre populated with the sample demoteam group. LAM keeps group membership in step with your users, and the Tools menu also offers a raw tree view for inspecting objects and attributes that the typed editors do not surface.

The LDAP Account Manager group account list showing the sample demoteam group under ou=Groups with its GID number and members

Step 7 - No known or default credentials

Nothing in this image ships with a known or blank password. The directory manager (cn=admin) password, the LAM master configuration password and the LAM server profile password are each rotated to a discarded random value at build time and regenerated with a unique random secret on the first boot of every VM. You can prove the directory manager credential end to end on the box: the per VM password binds, a wrong password is rejected, and the bundled round trip check confirms both in one step.

DN="$(sudo grep '^lam.login.dn=' /root/ldap-account-manager-credentials.txt | cut -d= -f2-)"
PW="$(sudo grep '^lam.login.pass=' /root/ldap-account-manager-credentials.txt | cut -d= -f2-)"
sudo ldapwhoami -x -H ldap://127.0.0.1 -D "$DN" -w "$PW"
sudo ldapwhoami -x -H ldap://127.0.0.1 -D "cn=admin,dc=cloudimg,dc=local" -w 'definitely-the-wrong-password' || echo "wrong password correctly rejected"
sudo bash /usr/local/sbin/lam-cred-roundtrip.sh

The ldapwhoami bind succeeding with the per VM directory manager password, a wrong password being rejected, and the round trip check confirming the credential authenticates

Step 8 - Verify the directory and where your data lives

Confirm the loopback binding and inspect the seeded directory. The whole directory (OpenLDAP mdb backend) lives on the single OS disk under /var/lib/ldap, LAM's configuration under /etc/ldap-account-manager and /var/lib/ldap-account-manager, and the directory is never reachable off the instance:

curl -sI http://127.0.0.1/healthz | head -1
sudo ldapsearch -x -H ldap://127.0.0.1 -D "cn=admin,dc=cloudimg,dc=local" -w "$(sudo grep '^lam.login.pass=' /root/ldap-account-manager-credentials.txt | cut -d= -f2-)" -b "dc=cloudimg,dc=local" -LLL dn
ss -tlnp | grep ':389 ' | sed 's/  */ /g'

The healthz endpoint returning 200, the ldapsearch listing the People and Groups organisational units and the sample accounts, and slapd bound to loopback 127.0.0.1:389 only

Adding your own domain and TLS

LAM serves plain HTTP on port 80. For production, point a DNS record at your VM and obtain a certificate with Let's Encrypt:

sudo apt-get install -y certbot python3-certbot-apache
sudo certbot --apache -d <your-domain>

LAM derives its base URL from the request Host header, so once you reach the VM on your domain over HTTPS the pages render correctly with no further change.

Backing up

Your directory data is the OpenLDAP database plus its configuration. Export both to LDIF with slapcat, and archive LAM's configuration:

sudo slapcat -n 0 -l /tmp/lam-config-backup.ldif
sudo slapcat -n 1 -l /tmp/lam-directory-backup.ldif

Copy both files off the VM on your usual schedule, together with /etc/ldap-account-manager and /var/lib/ldap-account-manager/config. To restore onto a fresh instance, stop slapd, reload the LDIF with slapadd, and restore the LAM configuration directories.

Security notes

  • LAM serves plain HTTP on port 80 out of the box. For anything beyond a trusted network, add your own domain and TLS as above, or front the VM with Azure Application Gateway.
  • OpenLDAP listens on 127.0.0.1 only and is never reachable from the network. LAM talks to it locally; administer the directory through LAM or over SSH.
  • Every secret is unique per VM and no known or blank credential authenticates. Keep /root/ldap-account-manager-credentials.txt protected. To rotate the directory manager password from the box, generate a new hash and apply it to the directory configuration:
NEWHASH="$(slappasswd -h '{SSHA}' -s '<new-password>')"
sudo ldapmodify -Y EXTERNAL -H ldapi:/// <<EOF
dn: olcDatabase={1}mdb,cn=config
changetype: modify
replace: olcRootPW
olcRootPW: $NEWHASH
EOF
  • The two sample accounts (jsmith, agarcia) and the demoteam group exist only to populate the interface and carry discarded random passwords. Delete them from LAM once you have added your own accounts.
  • Apply operating system updates regularly with sudo apt update && sudo apt upgrade; unattended security updates are enabled by default.