OpenLDAP With No Anonymous Access And Hashes Only Their Owner Reads
OpenLDAP from EPEL as a directory that gives nothing away: no anonymous binds, passwords only over TLS, each hash readable by its owner alone and stored as yescrypt even when written in clear, and no local account reading through ldapi. The package lets anyone, anonymous included, read every hash. Original role, live-tested on Rocky Linux 10.
Verification
Live-testedReally deployed to a container sandbox, proven idempotent (a second run changes nothing), verified against the role’s assertions, then torn down.
Conformance
- Static validation (yamllint · ansible-lint)
Provenance
- SHA-256 checksum
- Signature (pending)
Functional
- Live-tested - applied, verified, destroyed
Last verified 2026-10-08 · podman 4.9.3 · ansible 2.21.4 · how we verify
Cite it in your README
badge · attributionPaste this beside the module in the repository that uses it. The badge is rendered from this artifact's verification record, so it reads live-tested because the record says so, and the link lands on this page.
[](https://www.iac-bazaar.com/catalog/ansible-openldap?utm_source=syndication&utm_medium=readme&utm_campaign=artifact)
Ansible role 1.0.0, live-tested on IaC Bazaar: [OpenLDAP With No Anonymous Access And Hashes Only Their Owner Reads](https://www.iac-bazaar.com/catalog/ansible-openldap?utm_source=syndication&utm_medium=readme&utm_campaign=artifact)
```yaml
# OpenLDAP With No Anonymous Access And Hashes Only Their Owner Reads: https://www.iac-bazaar.com/catalog/ansible-openldap (download from your IaC Bazaar account)
```Preview:
Documentation
openldap
OpenLDAP from EPEL as a directory server that gives nothing away: no anonymous binds and nothing below the suffix for a client that never binds, passwords only over TLS, each password hash readable by its owner alone and stored as yescrypt even when it was written in clear, the directory readable only by its own entries, local root as the only administrator, and the listener on loopback until you open it. Original role for EL 10, live-tested with podman on Rocky Linux 10.
No download, and no version to pin. EL 10 packages slapd in EPEL, so the
role installs it by name and takes what the distribution ships: a security
update arrives through dnf, not through a new release of this role. What the
role owns is the configuration and the proof that the service works.
The distribution's unit, our configuration. The role installs
openldap-servers from EPEL, gives the package's slapd.service a drop-in with
the URLs it should listen on (ldap://127.0.0.1:389/ and ldapi:/// by
default; no ldaps:///, StartTLS on 389 instead), and writes its settings into
cn=config through ldapi, where slapd checks each value as it is written. The
helper that does that changes only what differs, reads every value back, and
says what it changed. The live test reads the listening sockets and expects
loopback only, and nothing on 636.
The package's directory is open. Its unit listens on every address, on
389 and on 636; anonymous clients bind and read; and with no access rules on the
database anyone - anonymous included - reads every userPassword hash, while a
user cannot change their own password (measured). The role refuses anonymous
binds, requires TLS for a simple bind (a plain-text bind gets "Confidentiality
required"), lets each user read and change only their own hash, and answers a
search sent with no bind at all with nothing below the suffix (the root DSE,
which names the suffix and the supported mechanisms, stays readable).
A local account is an authenticated LDAP user. Through ldapi:///, any
account on the host binds as gidNumber=...+uidNumber=...,cn=peercred,...
without a password, so the usual by users read lets every local account read
the directory (measured). The role grants reading to the directory's own
entries (dn.subtree of the suffix) instead: a local account reads nothing,
root manages everything through ldapi, and there is no root password at all:
olcRootPW is removed if present - the live test starts from a running slapd
whose database has one, and a bind with it is refused afterwards.
Hashes that are not SHA-1, even for a password written in clear. The
package hashes with salted SHA-1 ({SSHA}) and ships neither argon2 nor the
SHA-2 module. The role sets {CRYPT} with a yescrypt salt format, the scheme EL
10 uses for /etc/shadow, and loads the password-policy overlay to hash a
password that arrives as a plain attribute: without it, a userPassword added
in clear is stored in clear. The live test reads back {CRYPT}$y$ for a
password added in clear and for one changed by its owner.
TLS 1.2 or later. The system policy already makes slapd refuse TLS 1.1
(measured, asked by a client that offers it); the role sets
olcTLSProtocolMin 3.3 so a host with a looser policy keeps that floor.
License
Commercial - IaC Bazaar EULA. (c) IaC Bazaar.
Usage code & full reference need an account
The complete copy-paste usage, the full input/output reference, and operational notes are free with an account - shown here and bundled in the download. Sign in and this section fills in.
- Variables
- Test
Related modules
ansible-lynis
Lynis from EPEL on a systemd timer, with the units the package keeps only in its docs, your skipped tests in custom.prf, and a minimum hardening index below which the audit unit fails, so a falling score shows as a failed unit. The live test runs the audit, reads the index and the tests that ran, and finds the timer enabled. Original role, live-tested on Rocky Linux 10.
ansible-suricata
Suricata from EPEL watching the default-route interface as the suricata user, ET Open fetched at install and refreshed daily, plus a canary rule that proves the sensor is alive. A root-run check left root-owned logs and a daemon recording nothing; the role prevents it. The live test raises the canary alert while a second lookup is logged, not alerted. Original role, live-tested on Rocky Linux 10.
ansible-aide
AIDE from AppStream on EL 10: a watched tree, a baseline database built once, and the oneshot unit and timer the package does not ship. The live test passes on an unchanged host, FAILS when a file appears inside a watched path and names it, ignores one inside an excluded path, and passes again once the change is gone. Original role, live-tested on Rocky Linux 10.
ansible-389-ds
389 Directory Server from AppStream. A fresh instance listens on every interface and lets anonymous clients read the tree; this role binds both listeners to loopback and limits anonymous clients to the rootDSE. The live test adds a user who binds, sees a wrong password and an anonymous search refused, and reads the LDAPS certificate. Original role, live-tested on Rocky Linux 10.
ansible-krb5-kdc
An MIT Kerberos KDC: the realm created once with a stash, kadmind behind an ACL, a default policy that locks an account after five wrong passwords, every listener on loopback. The KDC starts on a broken config without a word, so the live test proves each setting by behaviour: the ticket lifetime, the refusals, the lockout. Original role, live-tested on Rocky Linux 10.
ansible-authelia
Authelia from the upstream release (sha256-verified) as a hardened system service on loopback with file users and sqlite; its secrets are generated once on the host and reach the service as AUTHELIA_*_FILE variables. The live test hashes a password with Authelia's hasher, logs in, sees a wrong password refused and an anonymous visitor sent to the portal. Original role, live-tested on Rocky 10.