Authelia with LLDAP on Ubuntu 24.04 on Azure User Guide
Overview
This image is a complete, self contained single sign on stack on one VM. Authelia is the login portal: it presents the sign in page, applies access control policy and acts as a forward authentication provider for nginx, Traefik and Caddy. LLDAP is the directory behind it: a lightweight, self hosted LDAP server with a friendly web admin UI, and a far simpler alternative to running OpenLDAP or Active Directory.
The two are wired together for you. Authelia is configured with an LDAP authentication backend pointed at the local LLDAP instance and has no user database of its own, so every account lives in one place. Create a user in the LLDAP admin UI and that user can sign in to the Authelia portal immediately, and to every application you put behind it.
There is no default login. A unique admin password, both LLDAP secrets, all three Authelia secrets and the TLS private key 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:
- Authelia 4.39.20 as the single sign on portal, served over HTTPS on port 443
- LLDAP 0.6.3 as the directory, with a web admin UI on port 17170 and an LDAP endpoint on port 3890
- Authelia pre-configured to authenticate against LLDAP, with no separate user database to keep in sync
- A unique admin password that signs in to both the portal and the directory admin UI, generated on first boot
- Per VM Authelia session, reset password and storage encryption secrets, and per VM LLDAP JWT and key seed secrets
- A per VM self signed TLS certificate and private key, generated on first boot and never shared between VMs
- A shared 24 GiB Azure data disk at
/srv/ssoholding both datastores lldap.service,authelia.serviceandnginx.serviceas systemd units, 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 for both services.
NSG inbound rules: allow 22/tcp from your management network for SSH, 443/tcp for the sign in portal, and 80/tcp so plain HTTP requests are redirected to HTTPS. Allow 17170/tcp for the LLDAP admin UI and 3890/tcp for LDAP only from the networks that need them, normally your own VNet, since the LDAP endpoint is a plain connection.
You will also need a hostname, not just the VM's IP address. Authelia scopes its session cookie to a domain and marks it secure, so a browser will only keep you signed in when you reach the portal over HTTPS at a hostname under that domain. Step 6 shows a one line workstation change you can use to try it immediately, and Step 10 shows how to switch to your own domain for production.
Step 1 - Deploy from the Azure Marketplace
Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Authelia with 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) and HTTPS (443). After deployment, add inbound rules for HTTP 80, and for 17170 and 3890 restricted to your VNet. 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 authelia-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 authelia-lldap --port 443 --priority 1010
az vm open-port --resource-group <your-rg> --name authelia-lldap --port 80 --priority 1020
az vm open-port --resource-group <your-rg> --name authelia-lldap --port 17170 --priority 1030
az vm open-port --resource-group <your-rg> --name authelia-lldap --port 3890 --priority 1040
Step 3 - Connect to your VM
ssh azureuser@<vm-public-ip>
Step 4 - Confirm both services are running
The portal and the directory are separate systemd units. Both must be active, and the first boot unit must have completed.
systemctl is-active lldap.service authelia.service nginx.service
Confirm each service is listening where it should be. Authelia itself binds only to loopback: nginx is the single public front door, which is why port 9091 must never appear on 0.0.0.0.
sudo ss -tlnp | grep -E ':(80|443|3890|9091|17170) ' | awk '{print $1, $4}'
Confirm the shared data disk carrying both datastores is mounted.
findmnt -no SOURCE,TARGET,FSTYPE /srv/sso && df -h /srv/sso | tail -1
Step 5 - Retrieve your per VM admin login
The admin password is generated on this VM's first boot and written to a root only file. The same password signs in to both the Authelia portal and the LLDAP admin UI.
sudo cat /root/authelia-lldap-credentials.txt
Confirm the file is readable only by root, and that this VM generated its own TLS key rather than shipping one baked into the image.
sudo stat -c '%a %U:%G' /root/authelia-lldap-credentials.txt
sudo stat -c '%a %U:%G' /etc/nginx/ssl/authelia-selfsigned.key
Step 6 - Reach the portal
Authelia is domain based. It marks its session cookie secure and scopes it to the configured cookie domain, so browsing to https://<vm-public-ip>/ will render the sign in page but the browser will discard the session cookie and sign in will not stick. This is Authelia's design, not a limitation of the image.
The image ships with the placeholder domain auth.example.com. To try the portal straight away, point that name at your VM by adding one line to your workstation's hosts file (/etc/hosts on macOS and Linux, C:\Windows\System32\drivers\etc\hosts on Windows):
<vm-public-ip> auth.example.com
Then open https://auth.example.com/ and accept the certificate warning, which appears because the VM generated its own self signed certificate on first boot. Step 10 replaces both the placeholder domain and the self signed certificate for production use.
You can confirm the portal and the redirect are healthy from the VM itself before touching a browser:
curl -s -o /dev/null -w 'portal https: %{http_code}\n' --resolve auth.example.com:443:127.0.0.1 -k https://auth.example.com/
curl -s -o /dev/null -w 'http redirect: %{http_code}\n' -H 'Host: auth.example.com' http://127.0.0.1/
Step 7 - Sign in to the single sign on portal
Open https://auth.example.com/ and sign in as admin with the password from Step 5.

Once signed in the portal greets you by display name and shows an Authenticated status. The display name comes from the LLDAP directory entry, so this screen is itself confirmation that the portal and the directory are talking to each other.

Step 8 - Manage users and groups in the directory
Open the LLDAP admin UI at http://<vm-public-ip>:17170/ and sign in with the same admin credentials. The Users page is where every account in your SSO estate lives.

The Groups page shows LLDAP's three built in groups, lldap_admin, lldap_password_manager and lldap_strict_readonly, which you can use to delegate directory administration. Create your own groups alongside them to drive Authelia access control rules.

Step 9 - Create a user and prove single sign on works
Choose Create a user in the LLDAP admin UI, give it a user ID, a display name and an email address, then set a password from the user's detail page. Because Authelia has no user database of its own, that account can sign in to the portal immediately, with no restart and nothing to synchronise.
You can prove the whole path from the command line. This binds to LDAP as the new account, then signs the same account in through the Authelia portal.
ldapwhoami -x -H ldap://127.0.0.1:3890 \
-D "uid=<new-user>,ou=people,dc=example,dc=com" -w '<their-password>'
curl -s --resolve auth.example.com:443:127.0.0.1 -k \
-H 'Content-Type: application/json' \
-d '{"username":"<new-user>","password":"<their-password>","keepMeLoggedIn":false}' \
https://auth.example.com/api/firstfactor
A response containing "status":"OK" means Authelia authenticated that user against LLDAP.
To confirm the current directory contents at any time, bind as the admin and list the accounts:
PW=$(sudo grep -m1 '^AUTHELIA_LLDAP_ADMIN_PASSWORD=' /root/authelia-lldap-credentials.txt | cut -d= -f2-)
ldapsearch -x -LLL -H ldap://127.0.0.1:3890 \
-D 'cn=admin,ou=people,dc=example,dc=com' -w "$PW" \
-b 'ou=people,dc=example,dc=com' '(objectclass=person)' uid mail displayName
Step 10 - Switch to your own domain and a real certificate
For production, point a hostname you control at the VM and tell Authelia about it. Edit /etc/authelia/configuration.yml and set both session.cookies[].domain to your registered domain and session.cookies[].authelia_url to the HTTPS URL of the portal on that domain. The authelia_url value must use https://, since Authelia refuses to start otherwise.
sudo nano /etc/authelia/configuration.yml
# session:
# cookies:
# - name: 'authelia_session'
# domain: 'your-domain.com'
# authelia_url: 'https://auth.your-domain.com'
sudo systemctl restart authelia
Replace the self signed certificate with one issued by a certificate authority. Install your certificate and key at the paths nginx already reads, then reload:
sudo install -o root -g www-data -m 0644 fullchain.pem /etc/nginx/ssl/authelia-selfsigned.crt
sudo install -o root -g www-data -m 0640 privkey.pem /etc/nginx/ssl/authelia-selfsigned.key
sudo nginx -t && sudo systemctl reload nginx
If you would rather use Let's Encrypt, install certbot and point the nginx TLS directives at the issued certificate instead.
sudo apt-get update && sudo apt-get install -y certbot
sudo certbot certonly --standalone -d auth.your-domain.com
Step 11 - Protect an application with forward authentication
Authelia's purpose is to sit in front of your other applications. On any nginx that fronts an app, send each request to Authelia first and only proxy it on if Authelia approves. The essentials look like this:
location /authelia {
internal;
proxy_pass http://<sso-vm-ip>:443/api/authz/auth-request;
proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
}
location / {
auth_request /authelia;
auth_request_set $user $upstream_http_remote_user;
proxy_set_header Remote-User $user;
error_page 401 =302 https://auth.your-domain.com/?rd=$scheme://$http_host$request_uri;
proxy_pass http://<your-app>;
}
Add access control rules to /etc/authelia/configuration.yml to decide which LLDAP groups may reach which applications. Until you add rules, the shipped default_policy of one_factor means any account in the directory can sign in.
Maintenance
Both datastores live on the dedicated data disk, so a snapshot of that disk captures your whole directory and the portal's session state.
sudo ls -l /srv/sso/lldap /srv/sso/authelia
Check the health endpoint, which stays on plain HTTP so monitoring never needs the certificate:
curl -s -o /dev/null -w 'health: %{http_code}\n' http://127.0.0.1/health
Review the logs for either service:
sudo journalctl -u authelia.service -n 30 --no-pager
sudo journalctl -u lldap.service -n 30 --no-pager
Apply operating system updates on your normal patching schedule:
sudo apt-get update && sudo apt-get -y upgrade
Support
cloudimg provides 24/7 support for this image. Contact support@cloudimg.co.uk with your Azure subscription ID and the VM name. For questions about Authelia or LLDAP themselves, see the Authelia documentation and the LLDAP project.