LemonLDAP::NG 2.23.4 on AWS User Guide
Overview
This guide covers launching and using the LemonLDAP::NG 2.23.4 on Ubuntu 24.04 AMI from cloudimg on Amazon EC2. It is one version of the cloudimg identity, secrets and PKI listing on AWS Marketplace.
LemonLDAP::NG is an open source web single sign-on (WebSSO) and access management system from the OW2 consortium. Its portal signs users in once and then acts as an OpenID Connect provider, a SAML 2.0 identity provider and (optionally) a CAS server for your applications; its handler protects web applications behind a reverse proxy; its Manager is the web console for the whole configuration. In this image the portal authenticates users against a local OpenLDAP directory.
The cloudimg image is a hardened, ready-to-use appliance:
- The current upstream release. LemonLDAP::NG 2.23.4, installed unmodified from the project's own signed package repository (the signing key is pinned at build time). It includes the fixes for CVE-2026-95811 (an access-rule bypass with an encoded URL) and CVE-2026-92288/92289 (OpenID Connect public clients).
- No demo accounts. A stock LemonLDAP::NG install signs in
dwho,rtylerandmsmithwith the password equal to the user name, anddwhocan open the Manager. This image replaces that demo backend on first boot: the portal checks passwords against its own OpenLDAP directory, and the demo accounts are refused. - The Manager is for administrators only. Every Manager request must come from a member of the directory group
cn=llng-admins(initially only the per-instance administratorllngadmin). The rule does not depend on the URL, so encoded, mixed-case or path-parameter variants cannot reach the Manager anonymously; it is re-applied before every start, so a package upgrade cannot quietly loosen it. - HTTPS from the first boot. nginx is the only public listener (ports 80 and 443) and serves a certificate generated on your instance (an end-entity certificate, not a certificate authority); port 80 redirects to HTTPS. LemonLDAP::NG's FastCGI server listens on a local socket only, OpenLDAP on
127.0.0.1and its local socket only. - Every secret is yours. First boot generates the administrator password, the directory passwords, the session cipher key, the OpenID Connect and SAML signing keys and the TLS key. Nothing secret is baked into the image.
- Metadata access blocked. LemonLDAP::NG can fetch URLs (metadata, discovery documents). Every service is blocked from the instance metadata service, and the AMI requires IMDSv2.
- Fully patched Ubuntu 24.04 LTS at build time, with unattended security upgrades switched on.
What is on the image: LemonLDAP::NG 2.23.4 (portal, Manager, handler, FastCGI server, documentation), OpenLDAP 2.6 (slapd, ldap-utils), nginx, Perl 5.38 with LemonLDAP::NG's modules, CryptX 0.091 and Crypt::JWT 0.038, Ubuntu 24.04 LTS, cloud-init and the AWS Systems Manager agent.
Default user: ubuntu · Architecture: x86_64 · Recommended instance type: m5.large
Prerequisites
- An AWS account subscribed to the listing, an EC2 key pair and a VPC subnet.
- A security group that allows TCP 22 (SSH) from your own networks only, and TCP 443 (the portal) and TCP 80 (redirects to HTTPS) from the people and applications that sign in. Do not open 389 or 636: nothing listens on them from the network.
- For production, a DNS name you control (for example
sso.example.com) and a certificate from a certificate authority for it, so that browsers and applications trust the portal without a warning.
Step 1: Launch the instance
In the AWS Marketplace listing choose Continue to Subscribe, then Continue to Configuration, pick LemonLDAP::NG 2.23.4 on Ubuntu 24.04 as the software version and your Region, then Launch through EC2. Choose m5.large, your key pair, and a security group as above.
With the AWS CLI (replace the values in angle brackets):
aws ec2 run-instances --image-id <ami-id-from-the-listing> --instance-type m5.large \
--key-name <your-key-pair> --security-group-ids <your-security-group> --subnet-id <your-subnet> \
--metadata-options HttpTokens=required,HttpEndpoint=enabled \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=lemonldap-ng}]'
First boot takes about fifteen seconds after cloud-init has run. It names the portal after the instance's public DNS name (or its public or private address). To use your own name from the start, put it in /etc/cloudimg/lemonldap-ng-host.preset with user data (for example a cloud-init write_files entry); you can also change it later (Step 11). The directory base DN is dc=example,dc=com unless you put another one (dc=...,dc=...) in /etc/cloudimg/lemonldap-ng-basedn.preset before the first boot.
Step 2: Connect to your instance
| Operating system | SSH user |
|---|---|
| Ubuntu 24.04 | ubuntu |
ssh -i <your-key.pem> ubuntu@<public-ip>
Step 3: Check the services
systemctl is-active lemonldap-ng-firstboot slapd lemonldap-ng-fastcgi-server nginx
active
active
active
active
Only SSH, HTTP and HTTPS are public. OpenLDAP listens on the loopback address, and LemonLDAP::NG's FastCGI server on a local socket that only www-data can reach:
sudo ss -tln | awk '{print $4}' | grep -E ':(22|80|389|443|636)$' | sort -u
sudo ls -ld /run/llng-fastcgi-server
0.0.0.0:22
0.0.0.0:443
0.0.0.0:80
127.0.0.1:389
[::]:22
[::]:443
[::]:80
drwxr-x--- 2 www-data www-data 80 Oct 31 17:32 /run/llng-fastcgi-server
Step 4: Your addresses and credentials
Everything first boot generated is in a root-only file (mode 0600). Show it without the password lines first:
sudo grep -v PASSWORD /root/lemonldap-ng-credentials.txt
# LemonLDAP::NG 2.23.4 - written on first boot by lemonldap-ng-firstboot.service. Unique to this instance.
PORTAL_URL=https://ec2-44-202-253-56.compute-1.amazonaws.com/
MANAGER_URL=https://ec2-44-202-253-56.compute-1.amazonaws.com/manager/
LLNG_ADMIN_USERNAME=llngadmin
OIDC_ISSUER=https://ec2-44-202-253-56.compute-1.amazonaws.com
SAML_METADATA_URL=https://ec2-44-202-253-56.compute-1.amazonaws.com/saml/metadata
LDAP_URL=ldap://127.0.0.1:389
LDAP_BASE_DN=dc=example,dc=com
LDAP_PEOPLE_DN=ou=people,dc=example,dc=com
LDAP_ADMIN_DN=cn=admin,dc=example,dc=com
LDAP_CONFIG_DN=cn=admin,cn=config
LDAP_LLNG_BIND_DN=cn=llng,ou=services,dc=example,dc=com
TLS_SHA256=9D:1C:14:F9:33:52:10:16:5B:37:EC:84:59:38:39:C7:2F:78:4E:54:E9:1F:7D:22:74:CB:EE:11:3A:A6:91:1E
TLS_SPKI_SHA256=8zK1rsq9/E8/RmRkSF4WU7jWvWFu6+ncCMyggJz4MhM=
#
# Sign in at PORTAL_URL as LLNG_ADMIN_USERNAME; the Manager (MANAGER_URL) admits members of cn=llng-admins only.
# Add a directory user: sudo lemonldap-ng-add-user alice (add --admin for Manager access)
# Register an OIDC client: sudo lemonldap-ng-add-oidc-rp my-app https://my-app.example.com/callback
# Directory tools as the directory administrator: sudo cloudimg-ldap ldapsearch -b dc=example,dc=com uid
# The LemonLDAP::NG cipher key and the OIDC/SAML signing keys are unique to this instance and live in its configuration
# (/var/lib/lemonldap-ng/conf, www-data only). OpenLDAP listens on 127.0.0.1 only.
# The HTTPS certificate is self-signed and unique to this instance: compare its SHA-256 fingerprint (TLS_SHA256), or
# replace it with a CA-issued certificate for your own name. Your own name: sudo lemonldap-ng-set-host sso.example.com
# User guide: https://www.cloudimg.co.uk/guides/lemonldap-ng-2-23-4-on-ubuntu-24-04-aws/
The file also holds LLNG_ADMIN_PASSWORD (the portal administrator), LDAP_ADMIN_PASSWORD, LDAP_CONFIG_PASSWORD and LDAP_LLNG_BIND_PASSWORD; read the one you need when you need it, for example sudo grep '^LLNG_ADMIN_PASSWORD=' /root/lemonldap-ng-credentials.txt. The session cipher key and the OpenID Connect and SAML signing keys are in LemonLDAP::NG's configuration (/var/lib/lemonldap-ng/conf, readable only by root and www-data).
The certificate is self-signed and unique to your instance. Do not add it to a trust store: compare its fingerprint (TLS_SHA256) with the one your browser shows, or replace it with a CA-issued certificate (Step 11).
Step 5: Run the self-test
sudo lemonldap-ng-selftest
It signs in to the portal as the administrator over HTTPS, checks that a wrong password and the upstream demo accounts are refused, opens the Manager as the administrator and checks that an anonymous request is sent to the sign-in page, registers a temporary OpenID Connect client, runs an authorization-code sign-in with it, verifies the ID token's signature against the portal's published keys (a tampered token fails), checks the SAML metadata, and deletes the temporary client again.
portal 200; llngadmin signs in; wrong password + dwho/rtyler/msmith refused; Manager 200 (admin) / 302 (anonymous)
JWT_VERIFY OK kid=432dca08 iss=https://ec2-44-202-253-56.compute-1.amazonaws.com sub=llngadmin; tampered token refused; SAML metadata entityID + certificate
LEMONLDAP_NG_SELFTEST_OK
Step 6: Sign in to the portal
Open PORTAL_URL (https://<your-name>/) in a browser, accept the certificate after comparing its fingerprint, and sign in as llngadmin with LLNG_ADMIN_PASSWORD.

A wrong user name or password is refused with a message. LemonLDAP::NG's brute-force protection is on: after three failed attempts an account is locked for 30 seconds, then for longer each time.

After signing in you see the application menu: the WebSSO Manager and a sample page protected by the LemonLDAP::NG handler.

Step 7: The Manager
Choose WebSSO Manager (or open MANAGER_URL). The Manager edits the whole configuration: authentication backends, virtual hosts and their access rules, OpenID Connect relying parties, SAML service providers, sessions and second factors. Each save creates a new numbered configuration that you can compare with or roll back to.

The Sessions tab lists active single sign-on sessions, which you can inspect and end.

Who may open the Manager is one rule, kept in /etc/cloudimg/lemonldap-ng-manager-protection and written into /etc/lemonldap-ng/lemonldap-ng.ini before every start of the LemonLDAP::NG FastCGI server:
sudo cat /etc/cloudimg/lemonldap-ng-manager-protection
sudo awk '/^\[manager\]/{m=1;next} /^\[/{m=0} m && /^(protection|staticPrefix)/' /etc/lemonldap-ng/lemonldap-ng.ini
inGroup("llng-admins")
protection = inGroup("llng-admins")
staticPrefix = /manager-static
To let another person administer LemonLDAP::NG, add them with --admin (Step 8). To change the rule itself (any LemonLDAP::NG rule expression on session attributes), edit that file and run sudo systemctl restart lemonldap-ng-fastcgi-server.
Anonymous requests never reach the Manager, whatever the URL looks like; they are sent to the sign-in page (302) or refused outright (400):
H=$(head -1 /etc/cloudimg/lemonldap-ng-host)
for p in /manager/ /manager/confs/latest /MANAGER/ '/manager;x=1/' '//manager/' '/%6Danager/' '/x/../manager/'; do
printf '%-22s %s\n' "$p" "$(curl -s -o /dev/null -w '%{http_code}' --path-as-is --cacert /etc/cloudimg/tls/lemonldap-ng.crt --resolve "$H:443:127.0.0.1" "https://$H$p")"
done | tee /run/manager-probe.txt; ! grep -q ' 200$' /run/manager-probe.txt; R=$?; rm -f /run/manager-probe.txt; [ "$R" -eq 0 ]
/manager/ 302
/manager/confs/latest 302
/MANAGER/ 302
/manager;x=1/ 400
//manager/ 400
/%6Danager/ 302
/x/../manager/ 302
Step 8: Add a directory user and sign in with it
sudo lemonldap-ng-add-user jane --name "Jane Example" --mail jane@example.com
sudo ls -l /root/lemonldap-ng-user-jane.password
user jane added; password in /root/lemonldap-ng-user-jane.password (root only)
-rw------- 1 root root 24 Oct 31 17:33 /root/lemonldap-ng-user-jane.password
The password is generated on the instance, stored in the directory as an Argon2 hash, and written only to that root-only file. Give it to the user over a secure channel; they can change it in the portal (Password). Add --admin to make a user a Manager administrator (member of cn=llng-admins).
Jane can sign in to the portal and open the protected sample page, but the Manager refuses her (403):
H=$(head -1 /etc/cloudimg/lemonldap-ng-host)
A="$(sudo python3 -I /usr/local/lib/cloudimg/lemonldap-ng/probe.py get "$H" jane /root/lemonldap-ng-user-jane.password /protected/)"
M="$(sudo python3 -I /usr/local/lib/cloudimg/lemonldap-ng/probe.py manager "$H" jane /root/lemonldap-ng-user-jane.password /manager/)"
echo "$A"; echo "$M"; [[ "$A" == "GET 200 "* && "$M" == "MANAGER 403 "* ]]
GET 200 593 login=ok
MANAGER 403 402 login=ok

The directory itself is managed with the standard OpenLDAP tools, bound as the directory administrator with the password from the credentials file (never on the command line):
sudo cloudimg-ldap ldapsearch -LLL -b ou=people,dc=example,dc=com uid cn mail
dn: ou=people,dc=example,dc=com
dn: uid=jane,ou=people,dc=example,dc=com
uid: jane
cn: Jane Example
mail: jane@example.com
dn: uid=llngadmin,ou=people,dc=example,dc=com
uid: llngadmin
cn: LemonLDAP::NG administrator
Step 9: Register an OpenID Connect client and get a token
Register a relying party (a confidential client using the authorization-code flow with RS256-signed ID tokens). The client secret is generated on the instance and written only to a root-only file:
sudo lemonldap-ng-add-oidc-rp my-app https://app.example.com/callback
OIDC client my-app registered; its secret is in /root/lemonldap-ng-oidc-my-app.secret (root only)
Point your application at the issuer's discovery document:
H=$(head -1 /etc/cloudimg/lemonldap-ng-host)
curl -s --cacert /etc/cloudimg/tls/lemonldap-ng.crt --resolve "$H:443:127.0.0.1" "https://$H/.well-known/openid-configuration" \
| jq '{issuer, authorization_endpoint, token_endpoint, jwks_uri}'
{
"issuer": "https://ec2-44-202-253-56.compute-1.amazonaws.com",
"authorization_endpoint": "https://ec2-44-202-253-56.compute-1.amazonaws.com/oauth2/authorize",
"token_endpoint": "https://ec2-44-202-253-56.compute-1.amazonaws.com/oauth2/token",
"jwks_uri": "https://ec2-44-202-253-56.compute-1.amazonaws.com/oauth2/jwks"
}
To see a sign-in end to end on the instance itself, the image's probe signs Jane in, approves the consent screen, exchanges the code for tokens, and saves the ID token and the published keys; the ID token's signature is then checked against the keys. (Each LemonLDAP::NG worker picks up a new configuration within a few seconds, hence the short pause after registering a client.)
sleep 5
H=$(head -1 /etc/cloudimg/lemonldap-ng-host); D=$(sudo mktemp -d /run/oidc-demo.XXXXXX)
sudo python3 -I /usr/local/lib/cloudimg/lemonldap-ng/probe.py oidc "$H" jane /root/lemonldap-ng-user-jane.password \
my-app /root/lemonldap-ng-oidc-my-app.secret https://app.example.com/callback "$D" \
&& sudo python3 -I /usr/local/lib/cloudimg/lemonldap-ng/jwt-verify.py "$D/id_token" "$D/jwks.json" "https://$H"; OK=$?
sudo rm -rf "$D"; [ "$OK" -eq 0 ]
OIDC_TOKEN_OK sub=jane aud=my-app
JWT_VERIFY OK kid=432dca08 iss=https://ec2-44-202-253-56.compute-1.amazonaws.com sub=jane
Every instance has its own signing key, so tokens from one instance never verify against another's keys. Remove a client with sudo lemonldap-ng-add-oidc-rp --delete my-app, or manage clients in the Manager under OpenID Connect Relying Parties.
Step 10: SAML 2.0
The portal is also a SAML 2.0 identity provider. Give your service providers its metadata, which carries this instance's own signing certificate:
H=$(head -1 /etc/cloudimg/lemonldap-ng-host)
curl -s --cacert /etc/cloudimg/tls/lemonldap-ng.crt --resolve "$H:443:127.0.0.1" "https://$H/saml/metadata" \
| grep -o 'entityID="[^"]*"\|<ds:X509Certificate>' | sort | uniq -c
6 <ds:X509Certificate>
1 entityID="https://ec2-44-202-253-56.compute-1.amazonaws.com/saml/metadata"
Register service providers in the Manager under SAML Service Providers. The CAS issuer is off; switch it on in the Manager (General Parameters → Issuer modules → CAS) only together with an explicit list of CAS applications.
Step 11: Use your own name and certificate
Point a DNS name at the instance, then (replace sso.example.com):
sudo lemonldap-ng-set-host sso.example.com
This renders nginx for the name (other names are refused), issues a new per-instance certificate for it, and updates the portal URL, the OpenID Connect issuer and the SAML entity ID in LemonLDAP::NG's configuration (a new configuration version; everything else you configured is kept). Relying parties and service providers registered against the old issuer must be updated. --cookie-domain example.com shares the single sign-on cookie with other hosts in that domain (the default is a host-only cookie).
To use a certificate from a certificate authority, replace /etc/cloudimg/tls/lemonldap-ng.crt and /etc/cloudimg/tls/lemonldap-ng.key (root-only key) with yours and run sudo systemctl reload nginx.
Step 12: Restrict the Manager to your own networks
nginx has an optional source-address list for /manager in addition to LemonLDAP::NG's own rule:
sudo cat /etc/nginx/cloudimg/lemonldap-ng-manager-access.conf
# cloudimg LemonLDAP::NG: optional source-address list for /manager (in addition to LemonLDAP::NG's own rule,
# inGroup("llng-admins"), which applies to every manager request). Example:
# allow 203.0.113.0/24;
# deny all;
Add allow <your-network>; lines followed by deny all;, then sudo nginx -t && sudo systemctl reload nginx.
Step 13: Check the security posture
The directory refuses anonymous access:
ldapsearch -x -H ldap://127.0.0.1 -b dc=example,dc=com -s base dn 2>&1 | tail -1 || true
additional info: anonymous bind disallowed
The instance itself can reach the metadata service, but none of the LemonLDAP::NG, nginx or OpenLDAP services can. The Manager's server-side URL loader (used to import SAML metadata or discovery documents) fails for the metadata address while it works for other addresses:
curl -s -m 5 -o /dev/null -w 'host root shell, IMDS token request: %{http_code}\n' -X PUT -H 'X-aws-ec2-metadata-token-ttl-seconds: 60' http://169.254.169.254/latest/api/token
for u in lemonldap-ng-fastcgi-server nginx slapd; do printf '%-28s %s\n' $u "$(systemctl show -p IPAddressDeny --value $u)"; done
H=$(head -1 /etc/cloudimg/lemonldap-ng-host); F=$(sudo mktemp /run/adm.XXXXXX)
sudo sh -c "sed -n 's/^LLNG_ADMIN_PASSWORD=//p' /root/lemonldap-ng-credentials.txt | tr -d '\n' > $F"
P="$(sudo python3 -I /usr/local/lib/cloudimg/lemonldap-ng/probe.py prx "$H" llngadmin "$F" http://169.254.169.254/latest/meta-data/)"
sudo shred -u "$F"; echo "$P"; [[ "$P" == "PRX 400 login=ok"*"timed out"* ]]
host root shell, IMDS token request: 200
lemonldap-ng-fastcgi-server ::ffff:169.254.169.254/128 168.63.129.16/32 169.254.169.254/32 fd00:ec2::254/128
nginx ::ffff:169.254.169.254/128 168.63.129.16/32 169.254.169.254/32 fd00:ec2::254/128
slapd ::ffff:169.254.169.254/128 168.63.129.16/32 169.254.169.254/32 fd00:ec2::254/128
PRX 400 login=ok Received unexpected HTTP status code 500 (Can't connect to 169.254.169.254:80 (Connection timed out)) when trying to load content from http://169.254.169.254/la
Step 14: Your data and backups
- LemonLDAP::NG's configuration is in
/var/lib/lemonldap-ng/conf(one JSON file per configuration version; they contain the signing keys and the cipher key, so protect the backups).sudo -u www-data /usr/share/lemonldap-ng/bin/lemonldap-ng-cli save > conf.jsonexports the current one. - The directory is in
/var/lib/ldap; export it withsudo slapcat -n 1 > directory.ldif. - Keep
/root/lemonldap-ng-credentials.txtwith the backups. Sessions in/var/lib/lemonldap-ng/sessionsare short-lived and need no backup.
Step 15: Licences and source
LemonLDAP::NG is licensed under the GNU General Public License, version 2 or later; the image runs the unmodified packages from the project's repository:
cat /usr/share/doc/cloudimg-lemonldap-ng/SOURCE.txt
dpkg-query -W -f='${Package} ${Version}\n' liblemonldap-ng-portal-perl lemonldap-ng-fastcgi-server slapd nginx
perl -MCryptX -MCrypt::JWT -e 'print "CryptX $CryptX::VERSION, Crypt::JWT $Crypt::JWT::VERSION\n"'
LemonLDAP::NG 2.23.4-1 (GPL-2.0-or-later) - https://lemonldap-ng.org/ ; source https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/tree/v2.23.4
Installed unmodified from upstream's signed apt repository https://lemonldap-ng.org/deb (suite 2.0, component main),
signing key 986D22DD43D558F8144B14DA376D233B5AEB361B. Licence texts: /usr/share/doc/liblemonldap-ng-*-perl/copyright.
Bundled artwork keeps upstream's licences (see those copyright files). Two artwork sets are not under an OSI licence but are
freely redistributable as upstream ships them: static/common/2F/okta-*.png (unDraw licence) and the WebAuthn logo
(webauthn.png, used to show built-in WebAuthn support). The Manager's AngularJS 1.7.9 is end-of-life upstream; see the guide.
CryptX 0.091 and Crypt::JWT 0.038 (perl_5: Artistic-1.0-Perl OR GPL-1.0-or-later) - https://metacpan.org/release/MIK/
built from https://cpan.metacpan.org/authors/id/M/MI/MIK/CryptX-0.091.tar.gz (sha256 3a82d5cf786985e5de5339d1236ce4b27306db5e6b1ed5fa15038ded6d44859a) and https://cpan.metacpan.org/authors/id/M/MI/MIK/Crypt-JWT-0.038.tar.gz (sha256 160e64e26cfce81556b9f376dab4535ff0a17b80f44d1ffe3f41977a785c51c3) into /usr/local, instead of
Ubuntu's libcryptx-perl 0.080 (CVE-2025-40914 fixed only in Ubuntu Pro ESM; CVE-2026-41564, CVE-2026-41565, CVE-2026-13758
unfixed in Ubuntu) and libcrypt-jwt-perl, which are not installed. The installed modules are byte-identical to the
tarballs (cpan-modules.sha256); their POD carries upstream's documentation EXAMPLE keys (e.g. Crypt::PK::RSA), listed by
exact path + sha256 in cpan-pem-labels.sha256. No man pages are installed.
Everything else is unmodified Ubuntu 24.04 packages (nginx, OpenLDAP slapd, Perl and LemonLDAP::NG's Perl dependencies).
lemonldap-ng-fastcgi-server 2.23.4-1
liblemonldap-ng-portal-perl 2.23.4-1
nginx 1.24.0-2ubuntu7.19
slapd 2.6.10+dfsg-0ubuntu0.24.04.1
CryptX 0.091, Crypt::JWT 0.038
OpenLDAP is distributed under The OpenLDAP Public License 2.8 (/usr/share/doc/slapd/copyright); nginx, Perl and the Perl modules are Ubuntu packages under their own licences (/usr/share/doc/<package>/copyright). CryptX and Crypt::JWT are under the Perl licence (Artistic License or GPL).
Step 16: Security notes
- Advisories. No published LemonLDAP::NG advisory affects 2.23.4. Ubuntu's CryptX 0.080 has four advisories (CVE-2025-40914, fixed only in Ubuntu Pro; CVE-2026-41564, CVE-2026-41565 and CVE-2026-13758, not fixed in Ubuntu); the image therefore runs CryptX 0.091 and Crypt::JWT 0.038 from CPAN instead, and Ubuntu's copies are not installed.
- Perl modules from Ubuntu universe. LemonLDAP::NG needs Perl modules that Ubuntu 24.04 ships only in its community-maintained universe section (for example Plack, Apache::Session, FCGI::ProcManager, Lasso for SAML). The image was checked for fixes available only through Ubuntu Pro (none). Open, unfixed advisories in these modules were checked against how LemonLDAP::NG uses them and are not reachable here: Plack CVE-2026-110332..110336 and CVE-2026-7381 (upload names, URL maps, recursion, error documents, X-Sendfile and the built-in HTTP server are not used; nginx normalises paths and the Manager rule is path-independent), Apache::Session CVE-2025-40931 and CVE-2026-5081 (the MD5 and mod_unique_id session-id generators are not used; LemonLDAP::NG uses its own SHA-256 generator) and CVE-2013-10075 (an expired or unknown session id never becomes a valid session), Crypt::OpenSSL::X509 CVE-2026-58101/58102 (certificate extension helpers are not called).
- The Manager's browser libraries. The Manager's single-page interface uses AngularJS 1.7.9, which is end-of-life upstream and has published advisories with no fixed release. They concern features this Manager does not use (resource-URL allow lists,
ng-srcset) or affect only the administrator's own browser (regular-expression slowness), and the Manager is reachable only byllng-adminsmembers (Steps 7 and 12). The bundled documentation pages use Bootstrap 3.4.1. - Bundled artwork. Two upstream images are under licences that are free to use but not open source: the unDraw illustrations for the Okta second-factor modules and the WebAuthn logo. They are shipped unmodified as the project distributes them.
- Hardening in place. Brute-force protection, CSRF tokens on the sign-in form, secure HttpOnly SameSite cookies, a per-client request limit in nginx, dynamic OpenID Connect client registration and the implicit and hybrid flows off, the CAS issuer off.
Support
cloudimg provides support for this image by e-mail at support@cloudimg.co.uk. LemonLDAP::NG is documented at https://lemonldap-ng.org/documentation/latest/ (and on the instance at /doc/), OpenLDAP at https://www.openldap.org/doc/. LemonLDAP::NG is an OW2 project and OpenLDAP is a registered trademark of the OpenLDAP Foundation; cloudimg is not affiliated with or endorsed by OW2, the LemonLDAP::NG project or the OpenLDAP Foundation.