OpenLDAP on Ubuntu 24.04 on Azure User Guide
Overview
OpenLDAP is the widely deployed open source implementation of the Lightweight Directory Access Protocol. Its standalone daemon, slapd, stores users, groups and organisational data in a hierarchical directory and answers standard LDAP queries, so your applications, operating systems and network services can share one authoritative identity source instead of a separate account store for each. The cloudimg image installs OpenLDAP 2.6.10 from the Ubuntu 24.04 main repository, seeds a usable directory tree, enables LDAP over TLS (LDAPS), stores the directory database on a dedicated Azure data disk, and rotates a unique administrator password into the image on first boot. Backed by 24/7 cloudimg support.
What is included:
- OpenLDAP 2.6.10 (
slapd+ldap-utils) with the fast memory mappedmdbbackend - The directory database (
data.mdb) on a dedicated 20 GiB Azure data disk at/var/lib/ldap - A seeded base directory
dc=example,dc=comwithou=people,ou=groupsand a demoinetOrgPerson, so queries return data out of the box - A unique per-VM administrator password generated on first boot (no shared default credential)
- LDAP on
389(with StartTLS) and LDAPS on636, with a self-signed TLS certificate regenerated per VM on first boot - Anonymous writes refused by default; the administrator binds as
cn=admin,dc=example,dc=com - 24/7 cloudimg support
Prerequisites
An active Azure subscription, an SSH key pair, and a VNet + subnet in the target region. Standard_B2s (2 vCPU / 4 GiB RAM) is a good starting point. NSG inbound: allow 22/tcp from your management network, and open 636/tcp (LDAPS) and/or 389/tcp (LDAP with StartTLS) only to the private networks that host the services that bind to the directory. Never expose the plain LDAP port to the internet without transport encryption.
Step 1 - Deploy from the Azure Marketplace
Sign in to the Azure Portal, choose Create a resource, search the Marketplace for OpenLDAP 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 add 636 (and optionally 389) scoped to your VNet after deployment. Then Review + create -> Create.
Step 2 - Deploy from the Azure CLI
az vm create \
--resource-group <your-rg> \
--name openldap \
--image <marketplace-image-urn> \
--size Standard_B2s \
--admin-username azureuser \
--ssh-key-values ~/.ssh/id_ed25519.pub \
--vnet-name <your-vnet> --subnet <your-subnet> \
--public-ip-sku Standard
Step 3 - Connect to your VM
ssh azureuser@<vm-public-ip>
Step 4 - Confirm OpenLDAP is installed and running
slapd runs as the slapd.service systemd unit and listens for LDAP on 389 and LDAPS on 636. Check the version, the service state, the listeners and the dedicated data disk:
slapd -VV 2>&1 | head -1
systemctl is-active slapd
ss -tln | grep -E ':389 |:636 ' | awk '{print $1, $4}'
findmnt -no SOURCE,TARGET,FSTYPE /var/lib/ldap
You should see OpenLDAP 2.6.10, active, listeners on 389 and 636, and the directory database on the dedicated data disk:
@(#) $OpenLDAP: slapd 2.6.10+dfsg-0ubuntu0.24.04.1 (Sep 23 2025 16:26:39) $
active
LISTEN 0.0.0.0:389
LISTEN 0.0.0.0:636
/dev/sdc /var/lib/ldap ext4

Step 5 - Retrieve your per-VM admin password
Each VM generates its own unique directory administrator password on first boot and writes it to a root-only credentials file:
sudo cat /root/openldap-credentials.txt
OPENLDAP_ADMIN_DN=cn=admin,dc=example,dc=com
OPENLDAP_ADMIN_PASSWORD=************************
openldap.base_dn=dc=example,dc=com
openldap.ldap_uri=ldap://10.0.0.6:389
openldap.ldaps_uri=ldaps://10.0.0.6:636
The file contains OPENLDAP_ADMIN_PASSWORD, the bind DN cn=admin,dc=example,dc=com, the base DN dc=example,dc=com and the resolved ldap:// / ldaps:// URIs. Store the password in your secrets manager. In the commands below, <OPENLDAP_ADMIN_PASSWORD> stands for the value of OPENLDAP_ADMIN_PASSWORD.
Step 6 - Run an anonymous rootDSE query
OpenLDAP permits an anonymous read of the rootDSE so clients can discover the server's naming contexts and capabilities without credentials:
ldapsearch -x -LLL -H ldap://127.0.0.1 -s base -b '' namingContexts supportedLDAPVersion
dn:
namingContexts: dc=example,dc=com
supportedLDAPVersion: 3
dc=example,dc=com is the seeded base directory.
Step 7 - Search the seeded directory tree
Bind as the administrator and list the seeded directory tree under dc=example,dc=com:
ldapsearch -x -LLL -H ldap://127.0.0.1 \
-D 'cn=admin,dc=example,dc=com' -w '<OPENLDAP_ADMIN_PASSWORD>' \
-b 'dc=example,dc=com' '(objectclass=*)' dn
dn: dc=example,dc=com
dn: ou=people,dc=example,dc=com
dn: ou=groups,dc=example,dc=com
dn: uid=demo,ou=people,dc=example,dc=com

Step 8 - Authenticated search for user attributes
Filter for the seeded inetOrgPerson entries and return selected attributes - this proves the authenticated bind and the directory data:
ldapsearch -x -LLL -H ldap://127.0.0.1 \
-D 'cn=admin,dc=example,dc=com' -w '<OPENLDAP_ADMIN_PASSWORD>' \
-b 'dc=example,dc=com' '(objectclass=inetOrgPerson)' cn sn mail uid
dn: uid=demo,ou=people,dc=example,dc=com
uid: demo
cn: Demo User
sn: User
mail: demo@example.com

Step 9 - Bind securely over LDAPS (TLS)
The image enables LDAPS on port 636 with a self-signed certificate that is regenerated uniquely on each VM's first boot. Confirm an authenticated bind over TLS with ldapwhoami (the self-signed certificate means an LDAP client must trust or skip verification, hence LDAPTLS_REQCERT=never for this test):
LDAPTLS_REQCERT=never ldapwhoami -x -H ldaps://127.0.0.1:636 \
-D 'cn=admin,dc=example,dc=com' -w '<OPENLDAP_ADMIN_PASSWORD>'
dn:cn=admin,dc=example,dc=com
For production, replace the self-signed certificate under /etc/ldap/certs/ with one issued by your own CA and distribute the CA certificate to your LDAP clients so they can verify the connection.

Step 10 - Add your own entry
Add a new user with ldapadd. Create an LDIF file and import it (replace the placeholder password):
cat > /tmp/alice.ldif <<'LDIF'
dn: uid=alice,ou=people,dc=example,dc=com
objectClass: inetOrgPerson
cn: Alice Anderson
sn: Anderson
uid: alice
mail: alice@example.com
LDIF
ldapadd -x -H ldap://127.0.0.1 \
-D 'cn=admin,dc=example,dc=com' -w '<OPENLDAP_ADMIN_PASSWORD>' -f /tmp/alice.ldif
Remove it again with ldapdelete:
ldapdelete -x -H ldap://127.0.0.1 \
-D 'cn=admin,dc=example,dc=com' -w '<OPENLDAP_ADMIN_PASSWORD>' \
'uid=alice,ou=people,dc=example,dc=com'
Step 11 - Confirm authentication is enforced
A wrong administrator password is rejected with LDAP result code 49 (Invalid credentials), so the directory is never readable with a bad credential. The block below is expected to fail by design:
$ ldapsearch -x -H ldap://127.0.0.1 \
-D 'cn=admin,dc=example,dc=com' -w WRONG-PASSWORD \
-b 'dc=example,dc=com' '(objectclass=*)'
ldap_bind: Invalid credentials (49)
The bind fails immediately with result: 49, confirming authentication is enforced before any directory data is returned. Anonymous writes are refused for the same reason.
Step 12 - Point your services at the directory
Applications that support LDAP authentication (for example Nextcloud, Grafana, Gitea, Jellyfin and many others) can bind to this directory. Configure them with:
- Host / URI:
ldaps://<vm-private-ip>:636(preferred) orldap://<vm-private-ip>:389with StartTLS - Base DN:
dc=example,dc=com - Bind DN: a dedicated read-only service account you create under
ou=people,dc=example,dc=com(do not use the administrator for application binds) - User search base:
ou=people,dc=example,dc=com
Open 636/tcp (and/or 389/tcp) on the VM's NSG only to the private networks that host those services, and keep the directory off the public internet.
Maintenance
- Persistence: the directory database (
data.mdb) lives on the dedicated data disk at/var/lib/ldap, so the directory survives reboots and the volume is independently resizable. - Admin password: the per-VM password is generated once at first boot. Rotate it later by replacing
olcRootPWonolcDatabase={1}mdb,cn=configwith anldapmodify -Y EXTERNAL -H ldapi:///using a freshslappasswdhash. - Service control:
sudo systemctl restart slapdrestarts the directory;journalctl -u slapdshows the logs. - TLS: the shipped certificate is self-signed and unique to each VM. For production, install a CA-issued certificate under
/etc/ldap/certs/and update theolcTLSCertificateFile/olcTLSCertificateKeyFilesettings. - Security patches: unattended-upgrades remains enabled so the OS continues to receive security updates automatically.
- Compatibility:
slapdis a standard LDAP v3 server - existing LDAP clients, libraries and tooling work unchanged against389/636.
Support
cloudimg provides 24/7 expert support for this image. Contact support@cloudimg.co.uk.
OpenLDAP is a registered trademark of the OpenLDAP Foundation. This image is provided by cloudimg and is not affiliated with or endorsed by the OpenLDAP Foundation.