OpenLDAP
Overview
OpenLDAP is the widely deployed open-source implementation of the Lightweight Directory Access Protocol (LDAP). Its standalone daemon, slapd, stores users, groups and organisational data in a hierarchical directory and answers standard LDAP queries. Your applications, operating systems and network services can then share one authoritative identity source instead of keeping a separate account store for each.
The SecureAnyCloud image installs OpenLDAP 2.6.10 from the Ubuntu 24.04 main repository and seeds a usable directory tree. It enables LDAP over TLS (LDAPS), stores the directory database on a dedicated Azure data disk, and generates a unique administrator password on first boot. It is backed by 24/7 SecureAnyCloud support.
What you get:
- OpenLDAP 2.6.10 (
slapdandldap-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, with 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.
Prerequisites
- An active Azure subscription, an SSH key pair, and a VNet with a subnet in the target region.
- Standard_B2s (2 vCPU, 4 GiB RAM) is a good starting point.
- Network security group inbound rules: allow
22/tcpfrom your management network. Open636/tcp(LDAPS),389/tcp(LDAP with StartTLS), or both, 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 SecureAnyCloud, and select Create.
On the Basics tab, 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). After deployment, add port 636 (and optionally 389) scoped to your VNet. Then choose Review + create, and then Create.
Step 2 - Deploy from the Azure CLI
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:openldap-ubuntu-24-04:default:latest
az vm create \
--resource-group <your-rg> \
--name openldap \
--image sac1647283583153:openldap-ubuntu-24-04:default:latest \
--size Standard_B2s \
--admin-username azureuser \
--ssh-key-values ~/.ssh/id_ed25519.pub \
--vnet-name <your-vnet> --subnet <your-subnet> \
--public-ip-sku StandardStep 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/ldapThe output shows OpenLDAP 2.6.10, the active state, 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 ext4Step 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.txtOPENLDAP_ADMIN_DN=cn=admin,dc=example,dc=com OPENLDAP_ADMIN_PASSWORD=<set-at-first-boot> openldap.base_dn=dc=example,dc=com openldap.ldap_uri=ldap://10.0.0.6:389 openldap.ldaps_uri=ldaps://10.0.0.6:636The 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:// and 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 supportedLDAPVersiondn: namingContexts: dc=example,dc=com supportedLDAPVersion: 3dc=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=*)' dndn: 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=comStep 8 - Authenticated search for user attributes
Filter for the seeded inetOrgPerson entries and return selected attributes. The result 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 uiddn: uid=demo,ou=people,dc=example,dc=com uid: demo cn: Demo User sn: User mail: demo@example.comStep 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. Because the certificate is self-signed, an LDAP client must either trust it or skip verification, so this test sets LDAPTLS_REQCERT=never:
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=comFor production, replace the self-signed certificate under /etc/ldap/certs/ with one issued by your own certificate authority (CA). 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, replacing the example password with your own:
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.ldifRemove the entry 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 command 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, which confirms that 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, such as Nextcloud, Grafana, Gitea and Jellyfin, can bind to this directory. Configure them with these settings:
- 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 that 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 optionally 389/tcp) on the VM's network security group only to the private networks that host those services. Keep the directory off the public internet.
Maintenance
- Persistence: the directory database (
data.mdb) lives on the dedicated data disk at/var/lib/ldap. The directory survives reboots, and you can resize the volume independently. - Admin password: the per-VM password is generated once at first boot. To rotate it later, replace
olcRootPWonolcDatabase={1}mdb,cn=configwithldapmodify -Y EXTERNAL -H ldapi:///, using a freshslappasswdhash. - Service control:
sudo systemctl restart slapdrestarts the directory, andjournalctl -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 theolcTLSCertificateFileandolcTLSCertificateKeyFilesettings. - Security patches: unattended-upgrades stays 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 against ports389and636.
Support
SecureAnyCloud provides 24/7 expert support for this image. Contact sales@secureanycloud.com.
OpenLDAP is a registered trademark of the OpenLDAP Foundation. This image is provided by SecureAnyCloud and is not affiliated with or endorsed by the OpenLDAP Foundation.
Deploy on Azure
Launch OpenLDAP on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.
View this image
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com
Overview
OpenLDAP is the widely deployed open-source implementation of the Lightweight Directory Access Protocol (LDAP). Its standalone daemon, slapd, stores users, groups and organisational data in a hierarchical directory and answers standard LDAP queries. Your applications, operating systems and network services can then share one authoritative identity source.
This image runs OpenLDAP 2.6. slapd runs as a systemd service that starts on boot, using the fast memory-mapped mdb backend. The directory database lives on a dedicated EBS volume mounted at /var/lib/ldap, separate from the operating system disk and independently resizable.
What you get:
- Plain LDAP on port 389 (with StartTLS) and LDAP over TLS (LDAPS) on port 636.
- A seeded base
dc=example,dc=com, the organisational unitsou=peopleandou=groups, and a demonstration useruid=demo, so an authenticated search returns real data the moment the instance is up. The directory administrator binds ascn=admin,dc=example,dc=com. - No usable administrator credential in the image. A one-shot first-boot service generates a unique administrator password of at least 24 characters on every instance and applies it to the slapd rootdn. It also regenerates the self-signed TLS certificate per instance and writes the result to
/root/openldap-credentials.txtwith mode 0600. No two instances launched from this image share a directory password or a TLS key.
Unlike a loopback-only appliance, slapd binds on all interfaces so downstream services can reach it. An LDAP endpoint reachable from the internet is a serious exposure. Restrict the 389 and 636 security group rules to your own VPC CIDR rather than 0.0.0.0/0, and prefer LDAPS on port 636 for any bind that carries credentials. Both are covered below. This guide also proves that the generated password authenticates.
Prerequisites
Before you deploy this image, you need:
- An Amazon Web Services account where you can launch EC2 instances.
- IAM permissions to launch instances, create security groups, and subscribe to AWS Marketplace products.
- An EC2 key pair in the target Region for SSH access to the instance.
- A VPC and subnet in the target Region, with a security group that allows inbound port 22 from your management network only, and ports 389 and 636 from the private CIDR of the services that will bind to the directory.
- An SSH client on your workstation. An LDAP browser is useful but not required.
Launching from the AWS Marketplace
- Open the product page in AWS Marketplace and choose Continue to Subscribe.
- Accept the terms, and then choose Continue to Configuration.
- Select the software version and the Region you want to deploy into, and then choose Continue to Launch.
- Choose Launch through EC2 for full control of networking and storage.
- Pick an instance type.
m5.largeis the recommended minimum. Scale up as your entry count and query concurrency grow. - Select your VPC, subnet and key pair.
- Attach a security group that allows inbound TCP 22 from your management network. Add TCP 389 and TCP 636 only from the private CIDR of the services that will bind to the directory, never from
0.0.0.0/0. - Launch the instance, and wait for it to reach the 2/2 checks passed state.
Launching with the AWS CLI
Substitute your own AMI ID, key pair, security group and subnet:
aws ec2 run-instances \
--image-id <ami-id> \
--instance-type m5.large \
--key-name <your-key-pair> \
--security-group-ids <your-sg-id> \
--subnet-id <your-subnet-id> \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=openldap}]'Connecting to your instance
Connect over SSH on port 22. On Ubuntu 24.04 LTS, the default login user is ubuntu.
ssh -i /path/to/your-key.pem ubuntu@<public-ip>Verifying the directory is running
Confirm the service is active and reporting the installed version:
systemctl is-active slapd.service slapd -VVV 2>&1 | head -1The output from a deployed instance looks like this:
active @(#) $OpenLDAP: slapd 2.6.10+dfsg-0ubuntu0.24.04.1 (Sep 23 2025) $Check the listening sockets. slapd binds LDAP on port 389 and LDAPS on port 636:
ss -tln | grep -E ':389 |:636 'LISTEN 0 2048 0.0.0.0:389 0.0.0.0:* LISTEN 0 2048 0.0.0.0:636 0.0.0.0:* LISTEN 0 2048 [::]:389 [::]:* LISTEN 0 2048 [::]:636 [::]:*Retrieving the administrator credentials
First boot writes the per-instance administrator password to a root-only file. View the file with:
sudo cat /root/openldap-credentials.txtThe file contains the generated password, the admin bind DN, the base DN, and the resolved LDAP and LDAPS URIs for this instance:
# OpenLDAP on Ubuntu 24.04 LTS (sac AWS Marketplace image)
# These credentials are unique to THIS VM, generated on first boot. Store them safely. OPENLDAP_ADMIN_DN=cn=admin,dc=example,dc=com OPENLDAP_ADMIN_PASSWORD=<generated-on-first-boot> openldap.base_dn=dc=example,dc=com openldap.ldap_uri=ldap://<this-instance-public-ip>:389 openldap.ldaps_uri=ldaps://<this-instance-public-ip>:636Load the password into a shell variable rather than printing it, so it never lands in your shell history or terminal scrollback. The rest of this guide uses $PW in its commands:
PW=$(grep '^OPENLDAP_ADMIN_PASSWORD=' /root/openldap-credentials.txt | cut -d= -f2-) if [ -n "$PW" ]; then echo "administrator password loaded (${#PW} characters)"; else echo "not yet generated"; fiadministrator password loaded (24 characters)Confirm the file is readable only by root:
stat -c '%a %U:%G' /root/openldap-credentials.txt600 root:rootQuerying the directory
Bind as the administrator and confirm your identity with ldapwhoami. The password comes from $PW, so it is never echoed:
PW=$(grep '^OPENLDAP_ADMIN_PASSWORD=' /root/openldap-credentials.txt | cut -d= -f2-) ldapwhoami -x -H ldap://127.0.0.1 -D 'cn=admin,dc=example,dc=com' -w "$PW"dn:cn=admin,dc=example,dc=comSearch the seeded directory. The search returns the base entry, both organisational units and the demonstration user:
PW=$(grep '^OPENLDAP_ADMIN_PASSWORD=' /root/openldap-credentials.txt | cut -d= -f2-) ldapsearch -x -LLL -H ldap://127.0.0.1 -D 'cn=admin,dc=example,dc=com' -w "$PW" -b 'dc=example,dc=com' '(objectclass=*)' dndn: 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=comConfirming the LDAPS listener works
Bind over TLS on port 636. The LDAPTLS_REQCERT=never setting accepts the per-instance self-signed certificate. For production, install your own CA-signed certificate as described later, and drop that setting:
PW=$(grep '^OPENLDAP_ADMIN_PASSWORD=' /root/openldap-credentials.txt | cut -d= -f2-) LDAPTLS_REQCERT=never ldapwhoami -x -H ldaps://127.0.0.1:636 -D 'cn=admin,dc=example,dc=com' -w "$PW"dn:cn=admin,dc=example,dc=comConfirming the administrator password is unique to your instance
The image ships no usable administrator credential, because the password is generated on first boot. This check proves that the generated password is accepted and that a wrong password is rejected with LDAP result 49, without printing either:
PW=$(grep '^OPENLDAP_ADMIN_PASSWORD=' /root/openldap-credentials.txt | cut -d= -f2-)
GOOD=$(ldapwhoami -x -H ldap://127.0.0.1 -D 'cn=admin,dc=example,dc=com' -w "$PW" 2>&1 || true)
BAD=$(ldapwhoami -x -H ldap://127.0.0.1 -D 'cn=admin,dc=example,dc=com' -w 'wrong-password' 2>&1 || true)
echo "$GOOD" | grep -qi 'dn:cn=admin' && echo "generated password: ACCEPTED" || echo "generated password: REJECTED"
echo "$BAD" | grep -qi 'Invalid credentials\|(49)' && echo "wrong password: REJECTED (result 49)" || echo "wrong password: ACCEPTED"generated password: ACCEPTED wrong password: REJECTED (result 49)Checking the directory data volume
The mdb directory database lives on a dedicated EBS volume mounted at /var/lib/ldap, so it persists across restarts and is independently resizable:
findmnt -no SOURCE,TARGET,FSTYPE /var/lib/ldap ls -1 /var/lib/ldap/data.mdb/dev/nvme1n1 /var/lib/ldap ext4 /var/lib/ldap/data.mdbRestricting the LDAP ports to your network
slapd binds on all interfaces so downstream services can reach it, but you should never leave ports 389 and 636 open to the internet. Use two layers of control:
- Security group: this is the primary control. In the EC2 console, edit the instance's security group so the inbound rules for TCP 389 and TCP 636 allow only the private CIDR of the services that bind to the directory (for example
10.0.0.0/16), never0.0.0.0/0. Keep port 22 restricted to your management network. - LDAPS: for any bind that carries credentials, use
ldaps://<host>:636(or StartTLS on port 389), so the bind DN and password are encrypted in transit. A plaintextldap://bind over an untrusted network exposes the credentials.
Anonymous read of directory entries other than userPassword is permitted by default, which is standard LDAP behaviour. If you require authenticated reads, tighten the access controls (olcAccess) on the mdb database to match your policy.
Installing your own TLS certificate
The image ships a self-signed certificate that is regenerated per instance. For production, replace it with a certificate signed by your own CA.
Copy your certificate, key and CA chain into /etc/ldap/certs/. Set ownership to root:openldap with mode 0640 on the key. Then point the olcTLS* attributes on cn=config at the new files:
# Run as root. Adjust the paths to your own cert/key/CA files. install -o root -g openldap -m 0640 /path/to/your.key /etc/ldap/certs/ldap.key install -o root -g openldap -m 0644 /path/to/your.crt /etc/ldap/certs/ldap.crt ldapmodify -Y EXTERNAL -H ldapi:/// <<'LDIF' dn: cn=config changetype: modify replace: olcTLSCertificateFile olcTLSCertificateFile: /etc/ldap/certs/ldap.crt - replace: olcTLSCertificateKeyFile olcTLSCertificateKeyFile: /etc/ldap/certs/ldap.key LDIF systemctl restart slapdAdding your own directory data
Replace the demonstration entries with your own organisational structure. Write an LDIF file and add it as the administrator. These commands change the directory, so run them once. They are shown for reference and are not executed automatically:
# my-org.ldif dn: ou=engineering,dc=example,dc=com objectClass: organizationalUnit ou: engineering dn: uid=jsmith,ou=people,dc=example,dc=com objectClass: inetOrgPerson uid: jsmith cn: Jane Smith sn: Smith mail: jsmith@example.com# Run as root; $PW is your administrator password from the credentials file. ldapadd -x -H ldap://127.0.0.1 -D 'cn=admin,dc=example,dc=com' -w "$PW" -f my-org.ldifTo use your own domain, set the base DN when you plan your directory. Changing the suffix of a populated directory is a re-provisioning exercise that is best done on a fresh instance.
Changing the administrator password
To rotate the administrator password yourself, generate a new hash with slappasswd and replace olcRootPW. This is a one-off administrative change and is shown for reference:
# Run as root.
NEWHASH=$(slappasswd -s 'your-new-password') ldapmodify -Y EXTERNAL -H ldapi:/// <<LDIF dn: olcDatabase={1}mdb,cn=config changetype: modify replace: olcRootPW olcRootPW: ${NEWHASH} LDIFBackup and maintenance
- Back up the directory by taking an EBS snapshot of the volume mounted at
/var/lib/ldap. You can also export the DIT to LDIF withslapcat -b dc=example,dc=com -l backup.ldif. Run it as root while slapd is stopped for a consistent export, or online for a point-in-time export. - Back up the configuration with
slapcat -b cn=config -l config.ldifto capture yourolcAccessrules and TLS settings. - Apply operating system updates with
sudo apt update && sudo apt upgrade. Unattended-upgrades is enabled for security patches. - Resize the directory volume by growing the EBS volume in the console, and then running
sudo resize2fs /dev/nvme1n1on the instance.
Troubleshooting
ldap_bind: Invalid credentials (49): the password does not match. Re-read it withsudo cat /root/openldap-credentials.txt. On a brand-new instance, wait for first boot to complete. Until it does, the credentials file shows example text instead of the password.- A remote client cannot reach the directory: confirm that the security group opens port 389 or 636 from the client's CIDR, and that the client is inside the VPC or reaches it over a private path. Check the listeners with
ss -tln | grep -E ':389 |:636 '. - LDAPS certificate errors: the shipped certificate is self-signed. Either install your own CA-signed certificate (see above) or, for testing only, set
LDAPTLS_REQCERT=neveron the client. - Service will not start: inspect
journalctl -u slapd --no-pager | tail -40, and confirm that/var/lib/ldapis mounted withfindmnt /var/lib/ldap.
Support
Every SecureAnyCloud deployment is backed by our engineers, available around the clock by email and live chat. Support covers:
- Deployment and sizing guidance.
- Directory schema and DIT design, and LDIF import.
- Hardening the LDAP and LDAPS listeners, TLS certificate configuration and access control configuration.
- Replication setup, and backup and restore of the directory database.
- OpenLDAP upgrades and troubleshooting.
Critical issues receive a one-hour average response time. Contact sales@secureanycloud.com.
OpenLDAP is a registered trademark of the OpenLDAP Foundation. SecureAnyCloud is not affiliated with the OpenLDAP Foundation. All product and company names are trademarks or registered trademarks of their respective holders.
Deploy on AWS
Launch OpenLDAP on AWS with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com