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.

ansibleSecurity & Secrets

Verification

Live-tested

Really 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 · attribution

Paste 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.

README.md, GitLab, Gitea
[![IaC Bazaar: live-tested](https://www.iac-bazaar.com/api/artifacts/ansible-openldap/badge)](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:IaC Bazaar: live-tested

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

Live-tested

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.

View module
Live-tested

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.

View module
Live-tested

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.

View module
Live-tested

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.

View module
Live-tested

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.

View module
Live-tested

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.

View module