Security Azure

LLDAP on Ubuntu 24.04 on Azure User Guide

| Product: LLDAP on Ubuntu 24.04 LTS on Azure

Overview

LLDAP (Light LDAP) is a lightweight, self hosted authentication and directory server with a friendly web admin UI. It gives small self hosted deployments a single place to manage user accounts and groups, and exposes a standard LDAP interface so services like Nextcloud, Grafana, Gitea, Jellyfin, Portainer and many more can authenticate against one shared directory instead of each keeping its own logins. It is an opinionated, much simpler alternative to running OpenLDAP or Active Directory. The cloudimg image installs LLDAP 0.6.3 as a single self contained systemd service that serves the LDAP endpoint on port 3890 and the web admin UI on port 17170, backed by an embedded SQLite datastore on a dedicated Azure data disk. There is no default login: a unique admin password, JWT signing secret and key seed are generated on the first boot of every VM, so no two instances ever share a credential. Backed by 24/7 cloudimg support.

What is included:

  • LLDAP 0.6.3 managed by systemd, serving LDAP on port 3890 and the web admin UI on port 17170
  • A unique admin password plus JWT and key seed secrets generated on first boot, recorded in a root only file
  • An embedded SQLite datastore on a dedicated Azure data disk at /var/lib/lldap
  • A default base DN of dc=example,dc=com with the admin as cn=admin,ou=people,dc=example,dc=com
  • The built in lldap_admin, lldap_password_manager and lldap_strict_readonly groups for delegating access
  • lldap.service as a systemd unit, enabled and active
  • No baked or shared credential of any kind in the image
  • 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 comfortable starting point. NSG inbound rules: allow 22/tcp from your management network for SSH, 17170/tcp for the web admin UI, and 3890/tcp for LDAP so downstream services can bind. LLDAP serves the admin UI and LDAP over plain connections; for production, restrict 17170 and 3890 to your VNet or front them with TLS (see Maintenance).

Step 1 - Deploy from the Azure Marketplace

Sign in to the Azure Portal, choose Create a resource, search the Marketplace for LLDAP 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). After deployment, add inbound rules for the web admin UI on TCP 17170 and LDAP on TCP 3890. Review the dedicated data disk on the Disks tab, then Review + create -> Create.

Step 2 - Deploy from the Azure CLI

az vm create \
  --resource-group <your-rg> \
  --name lldap \
  --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

az vm open-port --resource-group <your-rg> --name lldap --port 17170 --priority 1010
az vm open-port --resource-group <your-rg> --name lldap --port 3890 --priority 1020

Step 3 - Connect to your VM

ssh azureuser@<vm-public-ip>

Step 4 - Confirm the service is running

systemctl is-active lldap.service

It reports active. LLDAP serves its LDAP endpoint on port 3890 and its web admin UI on port 17170, and all directory data lives on the dedicated Azure data disk mounted at /var/lib/lldap.

The lldap service reporting active, the web admin UI listening on port 17170 and the LDAP endpoint on port 3890, and the dedicated data disk mounted at /var/lib/lldap

Step 5 - Retrieve your admin login

The LLDAP admin username and password are generated uniquely on the first boot of your VM and written to a root only file:

sudo cat /root/lldap-credentials.txt

This file contains LLDAP_ADMIN_USERNAME, LLDAP_ADMIN_PASSWORD, the lldap.url to open in a browser, the lldap.ldap_url for downstream services, the base DN and the admin bind DN. Store the password somewhere safe.

The LLDAP version and the per VM credentials file with the generated admin username, the masked password, the web UI URL, the LDAP URL, the base DN and the admin bind DN

Step 6 - Confirm the web admin UI responds

curl -s -o /dev/null -w 'GET / -> HTTP %{http_code}\n' http://localhost:17170/

It returns HTTP 200, the LLDAP login page served by the web admin on port 17170.

Step 7 - Verify an LDAP bind from the command line

Prove that the per VM admin authenticates over LDAP and that a wrong password is rejected. Read the password from Step 5 first. Because the command embeds your unique password, run it interactively rather than from a script, substituting the value of LLDAP_ADMIN_PASSWORD for <LLDAP_ADMIN_PASSWORD>:

ldapsearch -x -LLL -H ldap://127.0.0.1:3890 -D 'cn=admin,ou=people,dc=example,dc=com' -w '<LLDAP_ADMIN_PASSWORD>' -b 'ou=people,dc=example,dc=com' '(objectclass=person)' cn uid mail

A correct password returns the admin entry (dn: uid=admin,ou=people,dc=example,dc=com). A wrong password is rejected with ldap_bind: Invalid credentials (49). Downstream services bind to the same LDAP endpoint using this bind DN, or a dedicated service account you create in the web UI.

An authenticated LDAP bind and search returning the admin entry with the per VM password, and a wrong password rejected with Invalid credentials result 49

Step 8 - Sign in to the web admin UI

Browse to http://<vm-public-ip>:17170/. LLDAP shows a sign in page; enter admin and the password from Step 5.

The LLDAP sign in page in the browser showing the username and password fields and the version and licence in the footer

Once signed in, the Users page lists every account with its user ID, email, display name and creation date, and lets you create or delete users.

The LLDAP users page listing accounts with user ID, email, display name, first and last name and creation date, and a create user button

Step 9 - Manage groups

Open Groups to review and manage groups. LLDAP ships with lldap_admin, lldap_password_manager and lldap_strict_readonly for delegating administrative and password reset rights, and you can add your own groups to map onto the roles your downstream services expect.

The LLDAP groups page showing the built in lldap_admin, lldap_password_manager and lldap_strict_readonly groups with a create group button

Step 10 - Edit a user and set a password

Click any user to open its detail page, where you can edit the display name, first and last name, email and avatar, change the user's password, and manage its group memberships.

The LLDAP user detail page for a user showing editable display name, first name, last name and avatar fields and a modify password button

Step 11 - Point a downstream service at the directory

Most self hosted apps accept LDAP settings directly. Use the VM's address, port 3890, the base DN dc=example,dc=com, and either the admin bind DN or a dedicated service account. For example, a typical service configuration looks like:

LDAP host:      <vm-public-ip>
LDAP port:      3890
Base DN:        dc=example,dc=com
Bind DN:        cn=admin,ou=people,dc=example,dc=com
User search:    ou=people,dc=example,dc=com   filter (uid={{username}})
Group search:   ou=groups,dc=example,dc=com

For anything beyond a lab, create a read only service account in the lldap_strict_readonly group and bind as that account rather than the admin.

Step 12 - Confirm state lives on the dedicated disk

LLDAP's SQLite datastore lives under /var/lib/lldap on the dedicated Azure data disk, so it survives OS changes and can be resized independently:

findmnt /var/lib/lldap

The mount is backed by a separate Azure data disk captured into the image and re-provisioned on every VM.

Maintenance

  • Admin login: the per VM credentials live in /root/lldap-credentials.txt. To change the admin password, sign in to the web UI, open the admin user and use Modify password.
  • Users and groups: manage everything under Users and Groups in the web admin UI, or script it through the LLDAP GraphQL API at /api/graphql.
  • Downstream services: point them at LDAP on port 3890 with base DN dc=example,dc=com; create a read only service account rather than binding as admin.
  • Storage: all directory data lives under /var/lib/lldap on the data disk; back up that volume to protect your users, groups and password hashes.
  • Service: the unit is lldap.service; after any change run sudo systemctl restart lldap.
  • TLS: the web UI and LDAP are served over plain connections; restrict ports 17170 and 3890 to your VNet, or front the web UI with TLS (for example a reverse proxy with your own domain) and enable LDAPS before production use.
  • Security patches: unattended-upgrades remains enabled so the OS continues to receive security updates automatically.

Support

cloudimg provides 24/7 expert support for this image. Contact support@cloudimg.co.uk.