authnd, ein LDAP-Server für Personen, die anderswo verwaltet werden
Die Personen eines Standorts stehen bereits in einer Datenbank, einer Datei oder einem
anderen Verzeichnis. Was sie authentifizieren will, spricht LDAP. authnd ist die Fassade
davor: Es führt Binds und Suchen über die Quellen von
go-authn/directory aus, sodass das, was eine
Datenbank enthält, von allem gelesen werden kann, das ein Verzeichnis zu fragen weiß. Reines Go,
CGO_ENABLED=0, ein Binary. Diese Seiten beschreiben v0.11.1, dessen Einträge den
Standardschemata folgen und das Schema bestehen, das es unter cn=Subschema bereitstellt,
mit go-authn/ldap v0.8.0 und go-authn/directory v0.14.0 darunter; was geprüft ist und
was nicht, steht auf der Seite Stand.
Upgrade von v0.10.x
publish_nt_hash = truebraucht nun einensamba-Block, sonst startet authnd nicht.- Eine Person ohne
uidNumber,gidNumberundhomeDirectoryist keinposixAccountmehr, und eine Gruppe ohnegidNumberkeineposixGroupmehr; ein Konsument, der nach diesen Klassen filtert, sieht daher weniger Einträge: siehe die Einträge. - Ein
users "ldap"-Block liest standardmäßig mehr aus dem Verzeichnis dahinter: siehe Personen.
authnd check mit dem neuen Binary sagt alle drei vor dem Neustart.
authnd --config /etc/authnd # serve
authnd check /etc/authnd # say what would be served, without listeningDie kleinste Konfiguration
listen = "127.0.0.1:3893" # the default
base_dn = "dc=example,dc=org" # required
reader "cn=reader,dc=example,dc=org" { password_file = "/etc/authnd/reader.pw" }
user "alice" { password_file = "/etc/authnd/passwords/alice.pw" }
group "staff" { members = ["alice"] }Personen werden als uid=<name>,ou=people,<base_dn> veröffentlicht, Gruppen als
cn=<name>,ou=groups,<base_dn>. Was jeder Eintrag ist, ergibt sich aus dem, was seine
Quelle geliefert hat: Eine Person ist ein account, oder ein inetOrgPerson, wenn es
ein sn gibt, und ein posixAccount nur mit uidNumber, gidNumber und
homeDirectory; jede Person ist ein uidObject. Eine Gruppe ist eine posixGroup
(mit memberUid), wenn sie eine gidNumber hat, andernfalls eine groupOfNames
(mit member-DNs), oder eine organizationalRole, wenn sie zudem leer ist.
sshPublicKey kommt hinzu, wenn die Person Schlüssel hat, und sambaNTPassword, wenn
publish_nt_hash es vorsieht
und eine SID angegeben werden kann. Jeder Eintrag besteht das unter
cn=Subschema bereitgestellte Schema, bevor er veröffentlicht wird: siehe
die Einträge und das Schema. Bis
v0.10.2 war jede Person ein posixAccount und jede Gruppe eine posixGroup,
was auch immer sie hatten.
--config (-c) nimmt eine Datei oder ein Verzeichnis und darf wiederholt werden; ein
Verzeichnis steht für jede .hcl-Datei darin, in Namensreihenfolge gelesen und zu einer
Konfiguration zusammengeführt. Eine Konfiguration ohne base_dn oder ohne eine einzige
Person startet nicht.
Wer sich binden und wer lesen darf
Ein LDAP-Server soll Personen nachweisen, also sind seine Ablehnungen das eigentliche Design. Dies sind Antworten des Release-Binarys v0.10.0 an den Client von OpenLDAP selbst:
$ ldapwhoami -x -H ldap://127.0.0.1:3893 -D uid=alice,ou=people,dc=example,dc=org -y alice.pwin
dn:uid=alice,ou=people,dc=example,dc=org
$ ldapwhoami -x -H ldap://127.0.0.1:3893 -D uid=alice,ou=people,dc=example,dc=org -y wrong.pwin
ldap_bind: Invalid credentials (49)
$ ldapwhoami -x -H ldap://127.0.0.1:3893 -D uid=alice,ou=people,dc=example,dc=org -w ''
ldap_bind: Server is unwilling to perform (53)
additional info: an unauthenticated bind proves nothing, and this server does not accept one
$ ldapsearch -x -LLL -H ldap://127.0.0.1:3893 -D uid=alice,ou=people,dc=example,dc=org -y alice.pwin -b dc=example,dc=org '(uid=alice)'
Insufficient access (50)
Additional information: only a reader may search| Anfrage | Antwort | warum |
|---|---|---|
| leerer Name, leeres Passwort (RFC 4513 §5.1.1, anonym) | Erfolg | sie sagt „ich bin niemand“, was stimmt, und ein Client sendet sie, bevor er irgendetwas herausgefunden hat |
| ein Name und ein leeres Passwort (§5.1.2, nicht authentifiziert) | unwillingToPerform | sie benennt jemanden und beweist nichts; §5.1.2 verlangt genau diesen Code. invalidCredentials würde einer Person sagen, ihr Passwort sei falsch |
| ein falsches Passwort oder ein Name, den hier niemand hat | invalidCredentials | beides wird nicht unterschieden |
eine Suche durch jemand anderen als einen reader | insufficientAccessRights | ein Bind beweist, wer Sie sind; alle lesen zu dürfen, ist eine eigene Erlaubnis |
add, delete, modifyDN | unwillingToPerform | dafür ist kein Handler angebunden; der eine Schreibvorgang ist das eigene Passwort einer Person |
Ein reader ist ein Dienstkonto mit einem Bind-DN und password oder password_file; ein
Reader ohne beides wird beim Start abgelehnt (ein Reader, der nichts beweist, ist eine anonyme
Suche mit zusätzlichen Schritten). Ohne jeden Reader darf nichts suchen, und check sagt das.
Das Root-DSE wird einem anonymen Client beantwortet, wie es die Erkennung braucht:
$ ldapsearch -x -LLL -H ldap://127.0.0.1:3893 -s base -b '' '+' '*'
dn:
objectClass: top
objectClass: OpenLDAProotDSE
supportedLDAPVersion: 3
namingContexts: dc=example,dc=org
supportedExtension: 1.3.6.1.4.1.4203.1.11.3
supportedExtension: 1.3.6.1.4.1.4203.1.11.1
supportedControl: 1.2.840.113556.1.4.319
supportedControl: 1.3.6.1.1.13.1
supportedControl: 1.3.6.1.1.13.2
supportedFeatures: 1.3.6.1.4.1.4203.1.5.1
supportedFeatures: 1.3.6.1.4.1.4203.1.5.3
subschemaSubentry: cn=Subschema
vendorName: go-authn/authnd
vendorVersion: v0.11.11.3.6.1.4.1.4203.1.11.1 ist die Password-Modify-Operation aus RFC 3062.
subschemaSubentry benennt das Schema,
das ebenfalls einem anonymen Client beantwortet wird.
supportedSASLMechanisms: OAUTHBEARER erscheint nur mit einem
oidc-Block.
Wie es weitergeht
| Installation | das Release-Binary, das Konto authnd, die systemd-Unit, Upgrades |
| Woher die Personen kommen | user- und group-Blöcke, eine SQL-Datenbank, ein anderes LDAP-Verzeichnis |
| Die Einträge und das Schema | als was jede Person und jede Gruppe veröffentlicht wird, cn=Subschema, Attribute, was weggelassen oder zurückgehalten wird |
check | die Konfiguration vor einem Neustart zurücklesen |
| TLS | ldaps:// oder StartTLS, und publish_nt_hash |
| Ein Passwort ändern | ldappasswd, ldapmodify, und warum immer nach dem alten Passwort gefragt wird |
| Ein Kerberos-Realm | der Keytab, und wem ein Ticket ausgestellt werden kann |
| Ein zweiter Faktor | ein Einmalcode am Ende des Passworts |
| Ein Token beim Bind | OIDC über SASL OAUTHBEARER |
| Betrieb | Signale, Neustarts, was es protokolliert, woran man erkennt, dass es läuft |
Zu den Transkripten
Jede Startzeile, das Root-DSE und die --version-Zeilen wurden vom
Release-Binary v0.11.1 ausgegeben (authnd-darwin-arm64, go version -m:
mod github.com/go-authn/authnd v0.11.1, vcs.modified=false), ebenso jeder
andere Befehl, der im selben Transkript wie eine Startzeile steht. v0.11.1
ändert nichts außer dieser Zeile. Jede check-Tabelle, die mit
ldapsearch zurückgelesenen Einträge, cn=Subschema und die
samba-Ablehnungen wurden vom Release-Binary v0.11.0 ausgegeben
(mod github.com/go-authn/authnd v0.11.0, vcs.modified=false). Ebenso die
Konfigurationsablehnungen auf diesen Seiten, die v0.11.0 byte für byte so
ausgab wie v0.10.0. Die übrigen Binds, kinits, Passwortänderungen und
Token-Austausche wurden vom Release-Binary v0.10.0 ausgegeben und nicht erneut
ausgeführt, da weder die Release-Notes von v0.11.0 noch die von v0.11.1 einen
davon ändern. Alle wurden von den OpenLDAP- und Heimdal-Clients gestellt, die mit
macOS ausgeliefert werden, auf 127.0.0.1 an nicht privilegierten Ports, in einem
Arbeitsverzeichnis unter /tmp. Deshalb nennen die zugrunde liegenden Konfigurationen Dateien
über relative Pfade wie etc/authnd/passwords/alice.pw, und deshalb haben die Passwortdateien
Namen wie alice.pwin. Die Pfade unter /etc/authnd in den Beispielen sind die, die ein
installierter Server verwendet.
Erstellt am von tannevaled
Geändert am von tannevaled