📱 Erkannter Endgerättyp ⛱️ Tag und Nacht. Verbraucht keinen oder einen 🍪.
guest
Login 🧬 0 Ihre DNS in den Krei.se-DNS-Servern, führt zum Bio-Labor 🍪 1 Anzahl Ihrer gespeicherten Kekse, führt zur Keksdose

OpenLDAP olcAccess đź‘® verstehen

https://linux.die.net/man/5/slapd.access

Da LDAP quasi jede Struktur auf jede andere für Zugriffsrechte abbilden kann ist oft schwer zu verstehen, welche Regeln letztendlich angewandt werden. Gerade wenn regex ins Spiel kommt oder ein Zweig mehrere Regeln benötigt.

Was hilft? Debugging!

In cn=config olcLogLevel ACL hinzufügen, hier läuft sonst stats und stats2, also fürs Testen immer gut: stats stats2 ACL

base? exact? sub? children???

dn. (default) == dn.exact == dn.base => exakt dieser DN

dn.one = Eine Ebene darunter, aber NICHT der DN selbst und auch nur 1 Ebene, nicht alle! (aliase: dn.onelevel)

dn.subtree = Alle Einträge unter dem Eintrag, inkl. des Eintrags selbst. (aliase: dn.sub)

dn.children = Alle Einträge unter dem Eintrag, aber NICHT der DN selbst.

Hier 2 Beispiele, einmal fĂĽr ou=Gruppen (1) und ou=Kundendienst,ou=Mitarbeiter,ou=Gruppen (2)

dn                                  base        one         subtree     children

ou=Gruppen                          1                       1           
├── ou=Mitarbeiter                              1           1           1
│   ├── ou=Manager                                          1           1
│   │   ├── cn=Inhaber                                      1           1
│   │   ├── cn=Partner                                      1           1
│   │   └── cn=Geschäftsführer                              1           1
│   ├── ou=Kundendienst               2                     1 2         1 
│   │   ├── cn=HomeOffice                         2         1 2         1 2
│   │   └── cn=Kundendienstleitung                2         1 2         1 2
│   └── cn=Aussendienst                                     1           1
├── cn=Lieferanten                              1           1           1
└── cn=Gäste                                    1           1           1   

Grundaufbau

Eine olcAccess-Regel setzt immer:

  • Was (1x)
  • Wer (mehrfach)
  • Was dann? (Standard: stop)

    access to [ by [ ] [ ] ]+

"Was" (to) ("what")

Kann ein DN sein (z.B. ein Abzweig), ein Fiter (nutzen wir nie) oder eine Liste von Attributen - es geht natĂĽrlich auch die Kombination, also Attribute eines bestimmten DNs.

"Wer" (by) ("who)

gibt den Match an auf wen die Regel zutrifft. Wichtig ist zu verstehen, dass IMMER ein by * none hinten angehängt wird den wir u.U. abfangen müssen wenn wir das "Was" später nochmal prüfen wollen.

"Wie" () ("access")

read, write, etc ....

"Was dann?" ("control")

FĂĽr leserliche Rechte-Listen ist das eigentlich der wichtigste Aspekt und wenn man das einmal verstanden hat schreiben sich die Regeln fast wie von selbst!

Hier ist stop Standard wenn nichts angeben ist und bedeutet, dass sobald ein "Was" zutrifft die Regelauswertung nach dieser Regel beendet wird. Das ist wichtig zu verstehen, denn das implizierte by * none mit stop schliesst so jede Regel ab.

Möglich ist zudem break - dann geht die Auswertung mit der nächsten Regel weiter, selbst wenn to= greift after Zugriff verweigern würde.

Ich benutze das in Deploys nicht weil das magisches LDAP-Wissen ist was Admins verwirrt, aber auch machbar ist continue. Es bedeutet NICHT die nächste Regel mit einzubeziehen, sondern in dieser Zeile eine weitere who-Klausel einzubauen. Ein Beispiel:

    to dn.subtree="ou=Benutzer,dc=domain,dc=tld" attrs=mail

    by * read continue (statt break und dann dasselbe nochmal in einer neuen Regel)

    by self write (by * none stop)

Bedeutet, dass jeder das mail-Attribut der Benutzer lesen darf, aber nur self (der User selbst) dieses schreibt. Die who-Klausel greift hier fĂĽr den User bereits bei * (logisch), grenzt mit self aber weiter ein.

Wie gesagt - benutz ich nie.

Permissive vs. Restriktiv

Das Problem an olcAccess ist, dass es eine Zugriffsmatrix als Liste abbildet - möglich, aber im Kopf hantieren muss man trotzdem alle Fälle.

Mein Tipp:

  • Definieren Sie als erstes alle Passwort-Hash Regeln fĂĽr self (write), Verwalter (write) und lookups (read) dann full stop mit by * none stop

  • FĂĽr Attribute der User mit break-regeln schreibrechte fĂĽr manche Attribute gewähren (anschrift, telefonnummer)

  • Danach definieren Sie fĂĽr Abzweige break regeln, z.B. dass der dns-User seinen Baum schreiben darf

  • FĂĽr alle ĂĽbrigen Attribute ein Catch-All fĂĽr die Lookup-Dienste

  • Und fĂĽr alle ĂĽbrigen Einträge ein Catch-All fĂĽr self read

Beispiel-Liste mit Kommentaren

Da es in olcAccess keine Möglichkeit zum Kommentieren gibt (warum auch immer, super nervig) hier eine sehr restriktive olcAccess-Liste mit Erklärungen:


Gewähre auf das userPassword nur dem gleichen DN schreibzugriff, anonym darf dagegen authentifizieren und der users-Dienst darf (den Hash) lesen. Ansonsten darf keiner irgendwas und mit by * none stop werden alle anderen Regeln ignoriert.

{0}to attrs=userPassword by self write by anonymous auth by dn="cn=users,ou=Dienste,dc=domain,dc=tld" read by * none stop

Gewähre auf das Attribut shadowLastChange nur dem gleichen DN Schreibzugriff. ABER setze mit by * break die Regelauswertung fort. Das sorgt dafür, dass Dienste wie lookup oder users in Regel 6 und 7 dieses Attribut lesen dürfen

{1}to attrs=shadowLastChange by self write by * break

Das gleiche hier mit Attributen zu Wohnort, Handy, Straße, PLZ: Der gleiche DN darf diese Attribute ändern (lassen Sie NIE einen User seine Mail-Adresse selbstständig ändern!!), aber die Regelauswertung wird für alle anderen fortgesetzt. Denn Leserechte hat wieder auch ein Dienst-DN ab Regel 6.

{2}to attrs=l,mobile,street,postalCode by self write by * break

Das sind Kerberos-Passwörter, ähnlich wie Attribut User-Passwort. Die darf nur der gleiche DN schreiben (das ist i.d.R. der Principal im Kerberos-Container, kann aber auch ein erweiterter User-DN woanders sein). Der KDC muss das lesen dürfen und Kadmin darf es überschreiben. Alle anderen dürfen nix und wir beenden daher die Regelauswertung an dieser Stelle wieder mit by * none stop

{3}to attrs=krbPrincipalKey by self write by anonymous auth by dn.exact="uid=kdc,ou=Dienste,dc=domain,dc=tld" read by dn.exact="uid=kadmin,ou=Dienste,dc=domain,dc=tld" write by * none stop

Das ist der Container fĂĽr Kerberos, hier setzen wir Rechte fĂĽr den kompletten Sub-Baum. Den darf KDC lesen, Kadmin schreiben.

{4}to dn.subtree="cn=krbContainer,ou=Dienste,dc=domain,dc=tld" by dn.exact="uid=kdc,ou=Dienste,dc=domain,dc=tld" read by dn.exact="uid=kadmin,ou=Dienste,dc=domain,dc=tld" write by * none stop

Checks die es bis hierher geschafft haben sind meist Attribute die wir nicht gesondert behandeln mĂĽssen. Diese darf jeder DN fĂĽr sich selbst lesen. Danach geht die Regelauswertung weiter

{5}to * by self read by * break

Auch der Lookup-Dienst darf lesen was noch ĂĽbrig ist.

{6}to * by dn="cn=lookup,ou=Dienste,dc=domain,dc=tld" read by * break

Ebenso der Users-Dienst. Die könnte man in einer Regel zusammenfassen, so ist es aber leserlicher.

{7}to * by dn="cn=users,ou=Dienste,dc=domain,dc=tld" read by * break

đź‘·đź‘·đź‘· Das ist eine leider notwendige ganz gemeine Extra-Regel weil Kerberos derzeit noch im ganzen Baum nach Sachen sucht - das lassen wir hier zu, denn die sehen ohnehin nur noch Daten die unkritisch sind.

{8}to * by dn.exact="uid=kdc,ou=Dienste,dc=domain,dc=tld" search by dn.exact="uid=kadmin,ou=Dienste,dc=domain,dc=tld" read by * break

Die letzte Regel sperrt alle anderen Anfragen aus. Das ist hier so, wir lassen generell keine anonymen Suchen, etc. zu, auch nicht von jedem authentifizierten Nutzer.

{10}to * by * none stop

Alle Regeln:

{0}to attrs=userPassword by self write by anonymous auth by dn="cn=users,ou=Dienste,dc=domain,dc=tld" read by * none stop
{1}to attrs=shadowLastChange by self write by * break
{2}to attrs=l,mobile,street,postalCode by self write by * break
{3}to attrs=krbPrincipalKey by self write by anonymous auth by dn.exact="uid=kdc,ou=Dienste,dc=domain,dc=tld" read by dn.exact="uid=kadmin,ou=Dienste,dc=domain,dc=tld" write by * none stop
{4}to dn.subtree="cn=krbContainer,ou=Dienste,dc=domain,dc=tld" by dn.exact="uid=kdc,ou=Dienste,dc=domain,dc=tld" read by dn.exact="uid=kadmin,ou=Dienste,dc=domain,dc=tld" write by * none stop
{5}to * by self read by * break
{6}to * by dn="cn=lookup,ou=Dienste,dc=domain,dc=tld" read by * break
{7}to * by dn="cn=users,ou=Dienste,dc=domain,dc=tld" read by * break
{8}to * by dn.exact="uid=kdc,ou=Dienste,dc=domain,dc=tld" search by dn.exact="uid=kadmin,ou=Dienste,dc=domain,dc=tld" read by * break
{10}to * by * none stop

Hintergrund ändern. Verbraucht keinen oder einen 🍪.

Verknüpften Viewport öffnen

Sie sind leider kein Entwickler :(

FPS

Vertex-Count