Wie geht es eigentlich mit OpenLDAP weiter?

Heute mal was zum OpenLDAP. Ja, der Eine oder Andere wird jetzt sagen: „Der ist doch eh tot“. Nur stimmt das nicht. Die Entwicklung geht auch hier weiter. Zur Zeit hat die aktuelle Version die Versionsnummer 2.5.6, die auch schon sehr stabil läuft und auch schon genutzt werden kann. Leider gibt es noch für keine Distribution die entsprechenden Pakte. Selber bauen ist angesagt. Nur im Debian Experimental gibt es die Pakte schon, aber wer möchte Experimental schon produktiv einsetzen? Genau, niemand.

Aber wie geht es weiter mit OpenLDAP?

Für 2.4 gibt es nur noch kritische Updates, Neuerungen wird es hier nicht mehr geben. 2.4 hat den Status „end of live“ erreicht. Im September dieses Jahres wird es dann die Version 2.6 geben, die dann über längere Zeit mit Updates versorgt wird. Mit dem Erscheinen der Version 2.6 wird es keine Updates mehr für 2.4 geben. Ob das wieder 14 Jahre sind wie bei 2.4 wage ich zu bezweifeln. Im nächsten Jahr wird dann eine Version 2.7 erscheinen. Mit dem Erscheinen der 2.7 wird es keine Updates für 2.5 mehr geben.

Lohnt der Umstieg auf OpenLDAP 2.6? Ja, auf jeden Fall, denn einen performanteren Verzeichnisdienst wird man so schnell nicht finden.

Warum denken viele OpenLDAP sei tot? Da gibt es eine Firma die unbedingt ihren 389DS durchsetzen will und OpenLDAP das Wasser abgraben möchte. Wer von OpenLDAP auf 389DS wechsel will, sollte sich das aber genau überlegen. Eine Übernahme der Daten ist nicht so einfach realisierbar. Das Sicherheitskonzept ist ein komplett anderes. Die ACLs sind komplett anders und müssen alle neu eingerichtet werden. Auch fehlen viele Funktionen, die der OpenLDAP bereitstellt, noch komplett. Im 389DS so ist es momentan (so mein Stand) noch nicht möglich einen LDAP-Proxy zu realisieren. Wer also seine LDAP-Server z.B. in einer DMZ eingerichtet hat und damit die Daten für die Authentifizierung externe Mitarbeiter aus dem Active Directory holen will, kann das nur mit OpenLDAP realisieren.

Alles vielleicht für den Einen oder Anderen kein Thema, aber zu bedenken ist auch, mit dem 389DS wir IMMER Java auf dem LDAP-Server benötigt, auch wenn keine grafische Oberfläche installiert werden soll. Dann kommt dazu, dass die Java-Version die mit dem 389DS installiert wird, eine Oracle-Lizenz unterliegt. Spätestens an dem Punkt sollte man sich Gedanken machen warum man eigentlich auf open source Software gesetzt hat.

Ich habe die Version 2.5 jetzt schon eine Zeit lang getestet und viele neue Möglichkeiten haben schon was, so gibt es jetzt die Möglichkeit automatisch Client-Zertifikate vom OpenLDAP erstellen zu lassen. Einfach die eigene CA hinterlegen und alles andere geht dann automatisch. Auch die Passwortverschlüsselung mit Argon2 funktioniert jetzt mit einem eigenen Overlay. Zusammen mit der Möglichkeit der Einrichtung einer zwei Faktoren Authentifizierung kann man den Sicherheitsstandard schon sehr hoch ansetzen.

Endlich wird auch in den dynamischen Gruppen das „member“-Attribut bei der Suche ausgewertet, so ist es jetzt möglich, dynamische Posix-Gruppen zu erzeugen, denn dann im Dateisystems eines Fileservers Rechte zugewiesen werden können. Was bringt das? Ich erzeuge für jede meiner Abteilung oder Projektgruppe eine eigene dynamische Posic-Gruppe. Der Gruppe gebe ich auf unterschiedlichen Fileservern verschieden Rechte. Dann suche ich mir ein Benutzerattribut, das beim Eintrag eins bestimmten Wertes, den Benutzer automatisch zum Mitglied der Gruppe macht. Entferne ich das Attribut, wir der Benutzer automatisch auch aus der Gruppe entfernt und verliert somit auch sofort die Rechte auf den den Fileservern.

Auch was die Performance angeht wurde viel gearbeitet. Die Replikation wurde komplett überarbeitet auch wird durch ein effektives Loadbalancing werden die anfragen beim Einsatz mehrerer LDAP-Server besser auf die alle LDAP-Server verteilt.

Wer mehr über die Neuerungen wissen möchte, hier ist ein interessanter Artikel der auf jeden Fall lesenswert ist.

Also, immer ein Auge auf die tot gesagten haben 😉

Posted in Allgemein | Leave a comment

Das neue Samba4 Buch ist da

Am 13.08 ist es endlich so weit, die neue Auflage meines Samba4 Buches erscheint. Dieses Mal konnte ich im Januar direkt mit der Version 4.14 beginnen. Der Dank dafür gilt auf jeden Fall Louis van Belle und Björn Baumbach. Beide haben mir, direkt beim erscheinen der rc1 Version, die Pakte für Debian gebaut, so dass ich sofort beginnen konnte. Auch der Lektor und der Verlag haben dafür gesorgt, dass das Buch schnell fertig geworden ist. So schnell habe ich eine neue Auflage noch nie geschrieben. Wegen Corona war ich viel zu Hause und konnte so erheblich mehr Zeit mit dem Schreiben des Buchs verbringen. Vieles habe ich aus der alten Auflage entfernt, da es entweder nicht mehr relevant oder veraltet war. Aber auch sehr viel Neues ist dazu gekommen. Endlich ist es möglich auch GPOs für Linux-Clients einzurichten. 

Wie immer freue ich mich auch hier wieder über Feedback zum Buch. 

Posted in Samba | Leave a comment

OpenLDAP ACLs mit Sets

Heute möchte ich mal ein Thema zum OpenLDAP ansprechen, dass nicht so bekannt ist, aber doch nützlich sein kann. Das Thema ACLs wird in vielen Büchern und auf vielen Webseiten ausführlich beschrieben, so auch in meinem Buch und allen meinen Unterlagen, aber einen Teil finden Sie recht selten und zwar die Nutzung von „sets“. Beim Einsatz von „sets“ geht es um die Vergabe von Berechtigungen in Relation zu anderen Objekten. Worum geht es dort:
1. Vergabe von Berechtigungen über ACLs an verschachtelte Gruppen.
Wenn Sie die Gruppe (A) in der Gruppe (B) als Mitglied eintragen und anschließend der Gruppe (A) Rechte im LDAP-Baum geben, heißt das nicht, dass auch die Mitglieder der Gruppe (B) die Rechte erhalten, denn normaler Weise verfolgt der OpenLDAP verschachtelte Gruppen nicht. Mit den „sets“ ist das aber möglich.
2. Verfolgung von Referenzen
Stellen Sie sich vor, Sie haben bei allen Benutzern einer Abteilung im Attribut „manager“ den Abteilungsleiter eingetragen und der soll über eine ACL Rechte an bestimmten Attributen seiner Mitarbeiter erhalten. Dann können Sie diese Aufgabe sehr einfach über „sets“ realisieren. Hier soll als Beispiel, bei allen Benutzerobjekten der „ou=Verwaltung“, der Abteilungsleiter „cn=Verw al,ou=users,ou=Verwaltung,dc=example,dc=net“ im Attribute „manager“ eingetragen werden.
3. Stellvertreter Regeln
Nehmen wir den Fall aus Punkt 2. und gehen mal davon aus, dass der Abteilungsleiter einen Stellvertreter hat der ebenfalls diese Rechte erhalten soll. Der Stellvertreter ist über das Attribut „secretary“ beim Abteilungsleiter eingetragen und erhält die benötigten Rechte über eine entsprechend angepasste ACL. Gehen wir auch hier noch mal einen Schritt weiter. Der Abteilungsleiter hat mehrere Stellvertreter von denn aber nur eine bestimmte Gruppe die Rechte erhalten soll, dann können Sie hier auch noch über eine Gruppenmitgliedschaften die Rechte nur diesen Stellvertretern geben.

Wenn Sie sich die Technik einmal genauer angeschaut haben, werden Sie bestimmt schnell auf eigene Ideen kommen.

Da bekanntlich alle Theorien grau sind, folgen jetzt zu den einzelnen Punkten Beispiele:

Beginnen möchte ich mit den verschachtelten Gruppen.
Für die Vergabe von Passwörtern soll eine neue Gruppe des Typs groupOfNames erstellt werden, in der ein Benutzer, in diesem Fall „uid=skania,ou=users,dc=example,dc=net“, eingetragen ist. Dieser Benutzer soll für alle Benutzer der Abteilung „ou=verwaltung,dc=example,dc=net“ die Passwörter ändern können.
Hier eine Auszug der beiden Gruppen:

dn: cn=pw-set,ou=groups,dc=example,dc=net
objectClass: groupOfNames
cn: pw-set
member: cn=all-sec,ou=groups,ou=verwaltung,dc=example,dc=net
member: uid=skania,ou=users,dc=example,dc=net

dn: cn=all-sec,ou=groups,ou=Verwaltung,dc=example,dc=net
objectClass: groupOfNames
cn: all-sec
member: cn=sec1,ou=users,ou=verwaltung,dc=example,dc=net
member: cn=sec2,ou=users,ou=verwaltung,dc=example,dc=net
member: cn=sec3,ou=users,ou=verwaltung,dc=example,dc=net

Die Gruppe „cn=all-sec“ hat drei Mitglieder und ist wiederum selbst Mitglied der Gruppe „cn=pw-set“. Jetzt fehlt noch die ACL die der Gruppe cn=pw-set das Recht zur Änderung der Passwörter gibt und dadurch auch indirekt den Mitglieder der Gruppe cn=all-sec. Starten wir mir der ACL für die Gruppe cn=pw-set, die dann um das „set“ erweitert wird.

Da es hier darum geht die Passwörter zu ändern, wird die ACL für die Passwörter erweitert:

access to attrs=userPassword,shadowLastChange
by anonymous auth
by self write
by group/groupOfNames/member=“cn=pw-set,ou=groups,dc=example,dc=net“ write
by * none

So erhalten erst mal nur die Mitglieder der Gruppe „cn=pw-set“ das Recht die Passwörter zu ändern. Jetzt geht es dann darum, die ACL für die Verschachtelte Gruppe zu erweitern. Dazu passen Sie die ACL wie folgt an:

access to attrs=userPassword,shadowLastChange
by anonymous auth
by self write
by set=“[cn=pw-set,ou=groups,dc=example,dc=net]/member* & user“ write
by * none

Beide Regeln können natürlich auch in die dynamische Konfiguration eingetragen werden, dazu sehen Sie hier erst die LDIF-Datei für die einfache Gruppen ACL:

ACHTUNG! Übernehmen Sie die LDIF-Dateien nicht einfach in Ihr System, sondern passen Sie die Dateien an Ihre Konfiguration an.

dn: olcDatabase={2}mdb,cn=config
changetype: modify
delete: olcAccess
olcAccess: {1}

add: olcAccess
olcAccess: {1}to attrs=userPassword
by self write
by group/groupOfNames/member=“cn=pw-set,ou=groups,dc=example,dc=net“ write
by anonymous auth
by * none

delete: olcAccess
olcAccess: {2}

add: olcAccess
olcAccess: {2}to attrs=shadowLastChange
by self write
by group/groupOfNames/member=“cn=pw-set,ou=groups,dc=example,dc=net“ write
by anonymous auth
by * none

Jetzt folgt die ACL mit der Anpassung für die Verschachtelten Gruppen:

dn: olcDatabase={2}mdb,cn=config
changetype: modify
delete: olcAccess
olcAccess: {1}

add: olcAccess
olcAccess: {1}to attrs=userPassword
by self write
by set=“[cn=pw-set,ou=groups,dc=example,dc=net]/member* & user“ write
by anonymous auth
by * none

delete: olcAccess
olcAccess: {2}

add: olcAccess
olcAccess: {2}to attrs=shadowLastChange
by self write
by set=“[cn=pw-set,ou=groups,dc=example,dc=net]/member* & user“ write
by anonymous auth
by * none

Jetzt können Sie Gruppen vom Typ groupOfNames oder groupOfUniqeNames verschachteln und Rechte im LDAP-Baum vergeben. Soll eine weitere Gruppe die Möglichkeit erhalten, wie hier im Beispiel, die Passwörter zu ändern, brauchen Sie lediglich die Gruppe in die Gruppe cn=pw-set eintragen, die ACL brauchen Sie jetzt nicht mehr anzupassen.

Aber was ist, wenn in der Gruppe auf die Sie verweisen wollen nicht der vollständige DN als Mitglied enthalten ist? Also zum Beispiel bei einer Posix-Gruppe. Auch das ist kein Problem, auch die Verschachtelung dieser Gruppen ist möglich, dann ist die Syntax für die ACL aber etwas anders. Hier sehen Sie ein Beispiel für die statischen Konfiguration:

access to attrs=userPassword,shadowLastChange
by anonymous auth
by self write
by set=“[cn=posix,ou=groups,dc=example,dc=net]/memberUID & user/uid“ write
by * none

Auch hierzu folgt noch ein Beispiel für die dynamische Konfiguration:

dn: olcDatabase={2}mdb,cn=config
changetype: modify
delete: olcAccess
olcAccess: {1}

add: olcAccess
olcAccess: {1}to attrs=userPassword
by self write
by set=“[cn=posix,ou=groups,dc=example,dc=net]/memberUID & user/uid“ write
by anonymous auth
by * none

Kommen wir jetzt zum nächsten Punkt: Verfolgung von Referenzen.
Ähnlich wie Sie es vielleicht von dynamischen Gruppen her kennen, wird bei der Verfolgung von Referenzen der Inhalt eines Attributs ausgewertet. Bei dem entsprechenden Attribut handelt es sich um eine Attribut in dem der vollständige DN eines Benutzers eingetragen ist. Im Beispiel habe ich geschrieben, dass die Benutzerobjekte in der „ou=verwaltung“ alle den DN „cn=Verw al,ou=users,ou=verwaltung,dc=example,dc=net“ als „manager“ eingetragen haben. Jetzt soll der Abteilungsleiter an allen Benutzern seiner Abteilung das Schreibrecht erhalten.

Nachdem Sie das Attribut bei den gewünschten Benutzer gesetzt haben, benötigen Sie nur noch die ACL um die Rechte zu vergeben. Auch hier zeige ich Ihnen als erstes wieder ein Beispiel für eine statische ACL:

access to dn.sub=“ou=users,ou=verwaltung,dc=example,dc=net“
by set=“this/manager & user“ write
by * break

Für die dynamische Konfiguration schauen Sie sich das folgende Listing an. Achten Sie auch hier darauf, dass Sie die Nummerierung der ACL nicht einfach übernehmen, sonder an Ihre Umgebung anpassen.

dn: olcDatabase={2}mdb,cn=config
changetype: modify
add: olcAccess
olcAccess: {3}to dn.sub=ou=users,ou=verwaltung,dc=example,dc=net
by set=“this/manager & user“ write
by * break

Nach dem Sie die ACL eingespielt haben, kann jetzt, der als „manager“ eingetragenen Benutzer, die von Ihnen freigegeben Attribute ändern.

Last but not least geht es im folgenden Beispiel um die Stellvertreter des Abteilungsleiters. Hier gibt es wieder zwei Möglichkeiten. Fangen wir mit der einfacheren an:

Beim Abteilungsleiter wurden bestimmte Benutzerobjekte als „secretary“ eingetragen, siehe das folgende Listing:

dn: cn=Verw al,ou=users,ou=verwaltung,dc=example,dc=net
objectClass: posixAccount
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
loginShell: /bin/bash
homeDirectory: /home/verw-al
uid: verw-al
cn: Verw al
userPassword:: e1NTSEF9OURIWjB4ZVVmekl5WHVhcC9lOHo5OWZvQkRrMFdqaFo=
uidNumber: 10006
gidNumber: 10000
sn: al
givenName: Verw
employeeType: Abteilungsleiter
secretary: cn=sec1,ou=users,ou=verwaltung,dc=example,dc=net
secretary: cn=sec2,ou=users,ou=verwaltung,dc=example,dc=net
secretary: cn=sec3,ou=users,ou=verwaltung,dc=example,dc=net

Diese Hier eingetragen Benutzerobjekte sollen jetzt in der Lage sein, die Eigenschaften der Benutzer in der „ou=verwaltung“ zu ändern. Sie sollen aber nicht alle in der Lage sein die Passwörter der Benutzer anzupassen. Deshalb wird nur die ACL für den Zugriff auf die „ou=verwaltung“ geändert. Da die ACL für die Passwörter vor der entsprechenden ACL steht, betrifft die Änderung nicht die Passwörter. Achten Sie daher stehts auf die richtige Reihenfolge der ACLs. Hier die geänderte statische ACL für den Zugriff auf die Objekte:

access to dn.sub=“ou=users,ou=verwaltung,dc=example,dc=net“
by set=“this/manager & user“ write
by set=“this/manager/secretary & user“ write
by * break

Sie können hier die Abhängigkeit der Attribute von einander sehen. Ein Benutzer der bei Objekten als „manager“ eingetragen wurde und selbst über „secretary“-Einträge verfügt gewährt diesen den Zugriff.

Hier folgt jetzt noch die geänderte ACL für die dynamische Konfiguration:

dn: olcDatabase={2}mdb,cn=config
changetype: modify
delete: olcAccess
olcAccess: {3}

add: olcAccess
olcAccess: {3}to dn.sub=ou=users,ou=verwaltung,dc=example,dc=net
by set=“this/manager & user“ write
by set=“this/manager/secretary & user“ write
by * break

Jetzt hat unser Abteilungsleiter aber drei Stellvertreter, aber nur zwei von denen sollen in der Lage sein die Passwörter der Benutzer zu ändern. Diese beiden Stellvertreter wurden in der Gruppe „cn=secretary,ou=groups,ou=verwaltung,dc=example,dc=net“ zusammengefasst:

dn: cn=secretary,ou=groups,ou=verwaltung,dc=example,dc=net
objectClass: groupOfNames
cn: secretary
member: cn=sec1,ou=users,ou=verwaltung,dc=example,dc=net
member: cn=sec2,ou=users,ou=verwaltung,dc=example,dc=net

Als erstes entfernen Sie jetzt die Gruppe „cn=all-sec“ aus der Gruppe „cn=pw-set“, denn in der Gruppe sind alle Stellvertreter Mitglied und hätten durch die Verschachtelung der Gruppe immer das Recht die Passwörter zu verändern.

Damit nur noch der als „manager“ eingetragene Benutzer und die Stellvertreter aus der Gruppe „cn=secretary“ das Recht habe Passwörter zu ändern, wird jetzt die ACL wie folgt angepasst:

access to attrs=userPassword,shadowLastChange
by anonymous auth
by self write
by set=“this/manager & user“ write
by set=“this/manager/secretary & [cn=secretary,ou=groups,ou=verwaltung,dc=example,dc=net]/member* & user“ write
by * none

Auch diese Regel können Sie einfach von links nach rechts lesen: Der als „manager“ eingetragene Benutzer und die beim „manager“ eingetragen „secretary“ (wenn sie dann Mitglied der Gruppe cn=secretary sind) erhalten das Recht die Passwörter zu ändern.

Da Benutzer der Verwaltung über andere ACLs (die hier nicht erklärt werden) nur Zugriff auf die Objekte der „ou=verwaltung“ erhalten, können sie auch nur die Passwörter der Benutzer anpassen, denn auf die anderen Benutzerobjekte anderer Abteilungen haben Sie keinen Zugriff.

Fehlt nur noch die Anpassung der dynamischen Konfiguration. Dafür folgt jetzt der Inhalt der LDIF-Datei für die Anpassungen:

dn: olcDatabase={2}mdb,cn=config
changetype: modify
delete: olcAccess
olcAccess: {1}

add: olcAccess
olcAccess: {1}to attrs=userPassword
by self write
by set=“this/manager & user“ write
by set=“this/manager/secretary & [cn=secretary,ou=groups,ou=verwaltung,dc=example,dc=net]/member* & user“ write
by anonymous auth
by * none

delete: olcAccess
olcAccess: {2}

add: olcAccess
olcAccess: {2}to attrs=shadowLastChange
by self write
by set=“this/manager & user“ write
by set=“this/manager/secretary & [cn=secretary,ou=groups,ou=verwaltung,dc=example,dc=net]/member* & user“ write
by anonymous auth
by * none

Ich hoffe, dass ich Ihnen mit dieser kleinen Anleitung ein paar Anregungen für die vereinfachte Umsetzung von ACLs gegeben habe. Vielleicht kann der Eine oder Andere damit auch Aufgaben im eigen LDAP lösen, die vorher nur schwer lösbar waren.

 

Posted in LDAP | Leave a comment

2FA und OpenLDAP mit Argon2 als Passwordhash

Im letzten Artikel ging es um die Einrichtung von TOTP für die Authentifizierung. In dem Artikel habe ich auf das OpenLDAP-Modul pw-totp gesetzt, da es auf den ersten Blick recht einfach einzurichten war. Ist es auch, nur habe ich dann erfahren, dass das Modul alt ist und nicht mehr genutzt werden soll, besser sei es das Modul otp zu nutzen, das neu ist und im OpenLDAP 2.5 bereitgestellt wird. Dann macht es Sinn auch gleich eine gute Verschlüsselung der Passwörter einzubringen. Der Tipp war, die Argon2-Verschlüsselung zu nutzen, das von OpenLDAP in der Version 2.5 voll unterstützt wird. Also, alles wieder auf Anfang und das ganze neu Eingerichtet. Als Grundlage für den OpenLDAP habe ich dieses mal Debian Experimental (Danke Roland für den Tipp) genutzt, denn da ist die Version 2.5.5 schon vorhanden. Also jeder der das hier nachbauen will, ist nicht mehr auf den Bau des OpenLDAP angewiesen. Leider ist das Module autoca hier nicht enthalten, sprich die Einrichtung der Client-Zertifikate aus dem letzten Artikel klappt hier noch nicht.

Als Pakete habe ich installiert:

  • slapd
  • ldap-utils
  • argon2

Debian generiert sofort eine dynamische Konfiguration für den OpenLDAP, auf die ich auch aufgesetzt habe. Mein erst Schritt war dann den Passwordhash {ARGON2} einzurichten. Dafür wird das entsprechende Modul im OpenLDAP benötigt. Mit der folgenden LDIF-Datei wird das Modul geladen:

dn: cn=module{0},cn=config
changetype: modify
add: olcModuleLoad
olcModuleLoad: {1}argon2.la

Anschließend kann der Passwordhash mit der folgenden LDIF-Datei gesetzt werden:

dn: olcDatabase={-1}frontend,cn=config
changetype: modify
add: olcPasswordHash
olcPasswordHash: {ARGON2}

Wichtig ist hier, dass der Passwordhash in der Datenbank {-1}frontend,cn=config eingetragen wird und nicht direkt in cn=config.

Nach dem jetzt der OpenLDAP-Server den Passwordhash kennt, soll jetzt als erstes das Passwort des rootdn umgestellt werden. Durch die Umstellung des Passworts des rootdn können Sie auch gleich testen, ob die Authentifizierung mittels eines Argon2-Passworts funktioniert. Das folgende Listing zeigt die Änderung des Passworts:

dn: olcDatabase={1}mdb,cn=config
changetype: modify
replace: olcRootPW
olcRootPW: {ARGON2}$argon2i$v=19$m=4096,t=3,p=

1$MTIzNDU2Nzg5$t0cMsY/yM7a2wxx

btHWiTtEso2cW2iKrsOHvVCa0+A

Aber warum jetzt Argon2 und nicht mehr SSHA oder PBKDF2 als Passwordhash? Bei diesen Passwordhashes kann, mit relativ preiswerter Hardware ein Brute-Force Angriff auf die Passwörter durchgeführt werden. Oft werden hierfür Grafikprozessoren benutzt. Was dieser preiswerten und schnellen Hardware aber fehlt, ist Arbeitsspeicher. Da kommt dann Argon2 ins Spiel, denn Argon2 erzeugt große Vektoren im Arbeitsspeicher, wie viel Speicher dafür benötigt wird, kann beim erzeugen des Passworts festgelegt werden. Mehr zu Argon2 gibt es hier. Zu beschreiben, wie jetzt welche Parameter beim erzeugen eines Passworts gesetzt werden sollten, würde den Rahmen hier sprengen. Ein guter Einstig zu dem Thema finden Sie hier.

Das Passwort für den rootdn wurde von mir mit den Standardwerten von Argon2 erzeugt. Das Passwort habe ich mit dem folgenden Kommando erzeugt:

echo -n „geheim“ | argon2 „123455678“ -e

Das Passwort ist später „geheim“, „12345678“ ist der salt-Wert für den Passwordhash.

Jetzt können Sie, mittels „ldapsearch -x -D cn=admin,dc=example,dc=net -W -LLL“ den LDAP-Baum abfragen. Wenn das klappt, funktioniert auch der Passwordhash in Argon2.

Um die Passwörter in Argons2 und später auch TOTP testen zu können, habe ich eine OU „ou=users,dc=example,dc=net“ angelegt in der alle neuen Benutzer abgelegt werden. Den ersten Benutzer sehen Sie in der folgenden LDIF-Datei:

dn: cn=u1,ou=users,dc=example,dc=net
objectClass: posixAccount
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
loginShell: /bin/bash
homeDirectory: /home/u1
uid: u1
uidNumber: 10010
gidNumber: 10000
sn: u
givenName: 1
userPassword: {ARGON2}$argon2i$v=19$m=4096,t=3,p=

1$MTIzNDU2Nzg5$t0cMJsY/yM7a2w

xxbtHWiTtEso2cW2iKrsOHvVCa0+A
cn: u1

Nach dem Anlegen des Benutzers können sie auch hier wieder mit ldapsearch testen, ob eine Authentifizierung mit dem Argon2-Passwort möglich ist. Damit ist der erste Schritt zur zwei-Faktoren-Authentifizierung mit sicherem Passwort schon abgeschlossen.

Jetzt kommt der zweite Teil, Einrichten von TOTP mit dem neuen OpenLDAP-Modul otp.la. Das Modul muss als erstes geladen werden, dafür sehen Sie hier die folgenden LDIF-Datei:

dn: cn=module{0},cn=config
changetype: modify
add: olcModuleLoad
olcModuleLoad: {2}otp.la

Jetzt tragen Sie noch mittels einer LDIF-Datei das Overlay in die Objektdatenbank ein:

dn: olcOverlay=otp,olcDatabase={1}mdb,cn=config
objectClass: olcOverlayConfig

Achten Sie bei der Nummerierung der Datenbank auf Ihre Konfiguration.

Die manpage zu slapo-otp beschreibt zwar alle Parameter die benötigt werden genau, aber wie jetzt welcher Parameter zu setzen ist, fehlt ganz. Was sagen Entwickler dazu? „Wieso Dokumentation, steht doch alles im Quellcode!“ Im folgenden Listing sehen Sie die Konfiguration für TOTP:

dn: ou=users,dc=example,dc=net
changetype: modify
add: objectClass
objectClass: oathTOTPParams

add: oathOTPLength
oathOTPLength: 6

add: oathHMACAlgorithm
# choose SHA1, algorithm OIDs are specified in RFC 8018
oathHMACAlgorithm: 1.2.840.113549.2.7

add: oathTOTPTimeStepPeriod
oathTOTPTimeStepPeriod: 30

add: oathTOTPTimeStepWindow
oathTOTPTimeStepWindow: 3

Hier werden für die OU ou=users,dc=example,dc=net drei Parameter gesetzt:
– oathOTPLength: 6 (Die Länge des OTP-Tokens für den zweiten Faktor)
– oathHMACAlgorithm: 1.2.840.113549.2.7 (Der ODI für den Verschlüsselungsalgorithmus)
– oathTOTPTimeStepPeriod: 30 (Die Dauer der Gültigkeit des Tokens)
– oathTOTPTimeStepWindow: 3 (maximales Gültigkeitsfenster hier 3*30 Sekunden)

Dieses sind die Standardwerte, die auch vom Googleauthenticator und freeOTP+ genutzt werden.

Die Parameter werden immer eine OU zugewiesen und könne anschließend an die Benutzer übergeben werden.

Jetzt wird ein sharedkey für die Errechnung des Tokens benötigt, die folgenden Kommandos erstellen eine Datei mit einem sharedkey im data-Format:

  • $ touch sharedkey
    $ chmod 600 sharedkey
    $ openssl rand 20 > sharedkey
    $ base32 sharedkey
    7XNAA3KOAFGUTBSPWUGTNC6OSKMRKANW

Das Ergebnis ist der Schlüssel der in die entsprechende App, z.B. Googleauthenticator, eingetragen werden muss, aus der dann der sechs-Stellige Token generiert wird.

Jetzt fehlt nur noch die Anpassung des Benutzers. Dazu erzeugen Sie eine LDIF-Datei mit dem folgenden Inhalt:

dn: cn=u1,ou=users,dc=example,dc=net
changetype: modify
add: objectClass
objectClass: oathTOTPToken

add: oathTOTPParams
oathTOTPParams: ou=users,dc=example,dc=net

add: oathSecret
oathSecret:< file:///root/sharedkey

add: objectClass
objectClass: oathTOTPUser

add: oathTOTPToken
oathTOTPToken: cn=u1,ou=users,dc=example,dc=net

Damit wird das Benutzerobjekt um die benötigten Parameter erweitert. Damit der Benutzer den Schlüssel nicht von Hand in die App eintragen muss, kann aus dem Schlüssel ein QR-Code erzeugt werden, der dann einfach mit der App gescanned werden kann.

Ist der Schlüssel eingetragen, kann der erste Test mit dem Benutzer durchgeführt werden. Einfach ein:

ldapsearch -x -D cn=u1,ou=users,dc=example,dc=net“ -W -LLL

Ausführen. Bei der Fragen nach dem Passwort geben Sie als erstes das Passwort ein, unmittelbar im Anschluss den sechs-Stelligen Token, z.B „geheim123456“ Ohne Leer- oder Trennzeichen.

Das war es dann schon, jetzt können Sie nach und nach alle Benutzer auf eine zwei-Faktoren-Authentifizierung umstellen.

Damit die Anwender nicht den Schlüssel in die App eintragen müssen, ist es sinnvoll einen QR-Code aus dem Schlüssel zu erstellen, der dann eingescanned werden kann. Dazu wird das Programm qrencode benötigt. Erst wird der Text für den QR-Code erstellt und anschließend der QR-Code.

QR=“otpauth://totp/ldap:u1@example.net?secret=7XNAA3KOAFGUTBSPWUGTNC6OSKMRKANW&issuer=stka&30&digits=6&algorithm=SHA1″
echo $QR | qrencode -s9 -o u1@example.net.png

Selbstverständlich können Sie den Text für den QR-Code auch direkt an das Programm übergeben.

Das war der zweite Teil zur zwei-Faktoren-Authentifizierung. Ich denke, ein Teil wird noch kommen. Darin wird es dann wieder darum gehen, dass ganze über Ansible einzurichten.

Posted in LDAP | Tagged , , , | Leave a comment

Der Fehlerteufel hat beim letzten Artikel zugeschlagen

Leider ist mir beim erstellen des tar-Files für die Rollen ein Fehler unterlaufen, der LDAP-Server wird leider nach der Installation mit der Rolle nicht starten. Problem ist, das Attribut „olcPasswordHash“ habe ich dort (wie bei anderen Konfigurationen auch) direkt nach cn=config geschrieben, die neuen Passwordhashes wie {TOTP} müssen aber unter {-1}frontend eingetragen werden. Ich habe das entsprechende Skript geändert neu Verlinkt. Wenn Sie die Dateien schon runtergeladen haben, dann einfach erneut runterladen. Oder einfach diesem Link hier folgen, da sind auch die richtigen Dateien hinterlegt. 

Posted in Allgemein | Leave a comment

OpenLDAP 2.5 mit TOPT und autoca

Seit einiger Zeit gibt es nun endlich den OpenLDAP 2.5. Lange wurde er angekündigt. Ich habe hier die Version 2.5.4 genutzt um die beiden neuen Overlays autoca und totp einzurichten und zu testen. Da es noch keine Pakete für Debian 10 gibt, habe ich OpenLDAP aus den Quellen gebaut. Um bei späteren Versionen möglichst schnell einen Server einrichten zu können, habe ich hier wieder voll auf Ansible gesetzt. Ich habe eine neue Rolle definiert, die folgende Tasks durchführt:

  • Installation der Build-Umgebung mit allen Abhängigkeiten
  • Download der Quellen vom OpenLDAP
  • Bauen des OpenLDAP und allen benötigten Modulen
  •  Einrichten der Systemd-Skripte zum Start des OpenLDAP
  • Konfigurieren des OpenLDAP über ein Template
  • Einspielen der ersten Objekte
  • Anlegen eines simpleSecurityObjecs ldap-admin. Dieses Objekt hat alle Rechte an allen Objekten 
  • Anlegen eines simpleSecurityObjects repl-user später für die Replikation genutzt werden soll
  • Einrichten der Overlays autoca und totp

Um totp anschließend testen zu können, habe ich in der rolle openldap25 im Verzeichnis files ein Skript (create-qr.bash) abgelegt, dass den shared-key und den QR-Code für einen Benutzer erstellt.
Das Overlay autoca erzeugt für jeden Benutzer, ein Client-Zertifikat. Das Zertifikat wird bei einer Suche nach dem entsprechenden Attribut im Objekt des Benutzer abgelegt. Auch dieser Schritt wird mit dem Script durchgeführt.
In der aktuellen Konfiguration wird lediglich die Anmeldung mit einem TOTP eingerichtet. Durch Anpassung des Passwort-Hashes ist es auch möglich, auf eine zwei Faktoren Authentifizierung umzustellen. Die Umstellung werde ich hier zu einem späteren Zeitpunkt ergänzen. 

Die benötigten Rollen um den Server einzurichten finden Sie HIER.

Posted in Allgemein | Leave a comment

Benutzer gelöscht

Ich bin heute mal durch die List der hier angemeldeten Benutzer gegangen und habe aufgeräumt. Dabei habe ich alle Konten gelöscht, deren Emaildomäne nicht auflösbar war. Auch habe ich einige Benutzer gelöscht mit kryptischen Namen und die dazu auch keinen echten Namen angegeben haben. Sollte ich jemande gelöscht haben der hier noch aktiv ließt und unter einen der Kategorien gefallen sein, dann tut es mir Leid. Bitte dann einfach neu Anmelden und eine Emailadresse verwenden die  nachvollziehbar ist, In Zukunft werde ich alle Benutzer, die sich mit einer Wegwerfadresse registrieren sofort löschen. Sonst wird das für mich zu unübersichtlich.

Posted in Allgemein | Leave a comment

Ein neues Samba-Buch entsteht

Im Januar dieses Jahres ist die aktuelle Samba-Version 4.14 erschienen, dank Louis van Belle und Björn Baumbach konnte ich vom ersten Tag an auf Pakte für Debian zugreifen und sie für die neue Auflage nutzen.

Das ist das erste Mal, dass ich in so einem frühen Stadium mit dem Schreiben eines neuen Buchs begonnen habe. Wie zu erwarten, wenn man ein Buch mit dem rc1 Release beginnt, habe ich den einen oder anderen Bug gefunden. Gerade bei ganz neuen Möglichkeiten die die neue Version bringt, hakte es dann doch noch an der einen oder anderen Stelle. Diese Bugs wurden aber alle bis zur Version 4.14.2 behoben und so sind jetzt alle von mir beschrieben Neuerungen auch produktiv nutzbar.

Durch den frühen Zugriff wird diese Auflage (die im Juli oder August erscheinen wird) die erste Auflage sein, die auf der aktuellen Samba-Version beim Erscheinen basiert.

Von Anfang an war mir klar, dass ich einige Dinge aus dem Buch nehme will, dafür aber andere Dinge neu aufgenommen werden sollen. Raus gefallen ist der gesamte Abschnitt zum Kompilieren von Samba, denn es gibt heute so viele Möglichkeiten auf aktuelle Pakete zuzugreifen, dass ein selber kompilieren nicht mehr unbedingt erforderlich ist. Durch die Komplexität der neuen Version sind die Abhängigkeiten auch so viele, dass der Abschnitt, hätte ich ihn weiter gepflegt, zu groß geworden wäre. Insgesamt sind gut 50 bis 70 Seiten komplett aus der neuen Auflage raus gefallen, aber die Auflage hat trotzdem fast 100 Seiten mehr als die letzte Auflage. Sie sehen, ich habe viele neue Dinge aufgenommen. Bei den neuen Abschnitten geht es darum bestimmte Techniken der Administration noch besser zu erklären.

Damit Sie schon einmal einen kurzen Überblick über die kommenden Änderungen erhalten, hier eine (nicht vollständige) Auflistung der neuen Inhalte:

  • Erweiterte Verwaltung  von Freigaben
  • Einrichtung der Heimatverzeichnisse via GPO
  • Einrichtung von servergespeicherten Profilen via GPO
  • Umleitung der Ordner aus Profilen via GPO
  • Einrichten der neuen GPOs für Linux-Clients
  • Recovery eine Domäne
  • Neue Möglichkeiten mit dem Kommando samba-tool
  • Einrichten einer Domäne mit mehreren Domaincontrollern mittels Ansible

Selbstverständlich wurden die bestehenden Kapitel alle überarbeitet. So ist in doch relativ kurzer Zeit eine komplett überarbeitete Auflage entstanden. Das es dieses Mal so schnell ging, hat auch was mit der derzeitigen Corona-Situation zu tun, denn dank Homeoffice hatte ich auch viel Zeit am Buch arbeiten zu können.

Ich hoffe das auch diese Auflage wieder ein Erfolg wird und wie immer, freue ich mich über Feedbacks zum Buch. Lob sowieso, Kritik aber auch, solange sie konstruktiv ist.

Jetzt heißt es warten 

Posted in Allgemein, Samba | Tagged | Leave a comment

Die neue Auflage vom Linux-Server Buch ist da

Im Februar 2011 ist die erste Auflage des Linux-Server Buchs erschienen. Jetzt, 10 Jahren später ist es schon die sechste Auflage. Am Anfang waren es noch gerade 900 Seiten, dieses Mal mussten wir aufpassen, dass wir nicht das Maximum von 1300 Seiten überschreiten. Es hat geklappt es sind jetzt fast genau 1300 Seiten. Viele neu Dinge sind ins Buch gekommen und noch mehr wurde überarbeitet. Von mir wurden vor allen Dingen die Kapitel zum LDAP, Kerberos und Samba komplett überarbeitet. Die wohl größte Neuerung ist, dass ich sowohl im Kapitel LDAP als auch im Kapitel Kerberos neben der statischen Konfiguration des LDAPs auch die dynamische Konfiguration beschreibe. Bleibt mir nur, Ihnen viel Spaß beim Lesen zu wünschen.

Posted in Allgemein | Leave a comment

Loghost mit journald

Heute möchte ich mal zeigen, wie einfach es ist mithilfe des journald einen zentralen Loghost einzurichten.

Wie auch mit einigen der älteren Log-Daemons, lässt sich mit dem journald ein Log-Host einrichten um alle Meldungen Ihrer Server zentral an einer Stelle zu speichern. Die Übertragung der Daten wird dabei über TLS verschlüsselt, sodass ein Mitlesen mit einem Netzwerksniffer nicht möglich ist.

Für das Beispiel werde ich einen LDAP-Server als Log-Client einrichten, der seine Log-Informationen dann auf den Log-Host speichert. Auf allen Clients und dem Server installieren Sie das Paket systemd-journal-remote.

Achten Sie bei der Einrichtung des Servers darauf, dass Sie ausreichend Festplattenplatz bereitgestellt haben. Je mehr Clients die Logs dort ablegen und je länger Sie die Logs speichern wollen, um so mehr Plattenplatz wird benötigt. Damit der Server, für den Fall, dass der Plattenplatz nicht ausreicht, nicht abstürzt, lagern Sie das Verzeichnis /var auf eine eigene Partition aus. Die Standardgröße einer Log-Datei ist 8 MB, auch wenn noch keine Meldungen im Log eingetragen sind.

Im ersten Schritt aktivieren Sie den Dienst und den dazugehörigen Socket auf dem Server, über den sich die Clients verbinden. Das folgende Listing zeigt die entsprechenden Kommandos:

root@loghost:~# systemctl enable –now systemd-journal-remote.socket
Created symlink /etc/systemd/system/sockets.target.wants/systemd-
journal-remote.socket -> /lib/systemd/system/systemd-journal-remote.socket.
root@loghost:~# systemctl enable systemd-journal-remote.service

Im ersten Kommando wird der Dienst durch die Option –now sofort gestartet. Der zweite Dienst wird erst gestartet wenn Sie das TLS-Zertifikat bereitgestellt haben. Der Port, der hier verwendet wird, ist der Port 19532. Prüfen Sie mit dem Kommando ss, ob der Port geöffnet wurde.

Erstellen Sie ein Zertifikat für den Server, falls noch keins vorhanden ist.

Auf allen Clients, die sich mit dem Log-Host verbinden sollen, aktivieren Sie jetzt auch den systemd-journal-remote.service. Auch auf den Clients wird der Dienst aber noch nicht gestartet.

Einrichten des Servers

Die Konfiguration des Log-Servers finden Sie in der Datei /etc/systemd/journal-remote.conf. In der Datei sind schon bestimmte Vorgaben vorhanden, die aber alle auskommentiert sind. Im folgenden Listing sehen Sie die Datei für unser Beispiel:

[Remote]
# Seal=false
SplitMode=host
ServerKeyFile=/etc/ssl/zertifikate/loghost-key.pem
ServerCertificateFile=/etc/ssl/zertifikate/loghost-cert.pem
TrustedCertificateFile=/etc/ssl/zertifikate/demoCA/cacert.pem

Die Variablen haben die folgenden Bedeutungen:

Seal
Wenn Sie maximale Sicherheit haben wollen, was das Manipulieren der Einträge angeht, können Sie diese Variable aktivieren und auf true setzen. Dann werden die einzelnen Einträge zusätzlich signiert.

SplitMode
Alle Einträge, werden aufgrund des Hostnamen, in eigene Dateien gespeichert. Das verbessert die Übersichtlichkeit der Daten, gerade wenn Sie viele Hosts auf dem Server loggen wollen.

ServerKeyFile
Der Pfad und der der Name des Keyfiles Ihres Zertifikats.

ServerCertificateFile
Der Name und der Pfad zum Zertifikat.

TrustedCertificateFile
Der Name und Pfad zum root-Zertifikat. Ohne diese Angabe das kann die Gültigkeit der Zertifikate nicht geprüft werden.

Damit die Zertifikate auch vom Log-Daemon genutzt werden können, ist es notwendig, dass Sie die Rechte wie im folgenden Listing anpassen:

root@loghost:~# chgrp systemd-journal-remote /etc/ssl/zertifikate/loghost-*
root@loghost:~# chmod 640 /etc/ssl/zertifikate/loghost-*

Sollten Sie das Zertifikat auch noch für andere Dienste benötigen, setzen Sie die erweiterten Dateisystem-ACLs für die Gruppe.

Erst jetzt können Sie den Dienst mit dem Kommando systemctl start systemd-journal-remote.service starten. Danach ist der Log-Host bereit, die Log-Daten der Clients anzunehmen.

Einrichten des Clients

Nachdem der Server im vorherigen Abschnitt eingerichtet wurde, geht es jetzt darum, den ersten Client anzubinden, der seine Log-Daten an den Log-Server schickt.

Für die Übermittlung der Daten wird ein eigener Benutzer benötigt. Legen Sie einen neuen Benutzer an, indem Sie das Kommando aus dem folgenden Listing übernehmen:

root@loghost:~# adduser –system –home /run/systemd –no-create-home \
–disabled-login –group systemd-journal-upload
Lege Systembenutzer »systemd-journal-upload« (UID 107) an …
Lege neue Gruppe »systemd-journal-upload« (GID 113) an …
Lege neuen Benutzer »systemd-journal-upload« (UID 107) mit \
Gruppe »systemd-journal-upload« an …
Erstelle Home-Verzeichnis »/run/systemd« nicht.

Bei dem neuen Benutzer handelt es sich um einen Systembenutzer, der sich nicht lokal anmelden kann. Vergeben Sie auch kein Passwort für den Benutzer.

Sorgen Sie auf dem Client dafür, dass das Zertifikat von der Gruppe systemd-journal-remote gelesen werden kann.

Auch auf dem Client folgt jetzt die Anpassung der Konfiguration, dieses Mal in der Datei /etc/systemd/journal-upload.conf. Auch auf dem Client ist die Datei schon vorhanden, aber alle Optionen sind noch auskommentiert. Im folgenden Listing sehen Sie die an mein Beispiele angepasste Datei:

[Upload]
URL=https://loghost.example.net:19532
ServerKeyFile=/etc/ssl/zertifikate/provider-stat-key.pem
ServerCertificateFile=/etc/ssl/zertifikate/provider-stat-cert.pem
TrustedCertificateFile=/etc/ssl/zertifikate/demoCA/cacert.pem

Im Unterschied zur Konfiguration des Servers, wird hier die URL angegeben, unter der der Server erreichbar ist. Die drei Zeilen für die Zertifikate sind identisch mit denen auf dem Server.

Starten Sie den Log-Daemon jetzt mit dem Kommando systemctl restart systemd-journal-upload.service auf dem Client.

Testen der Log-Umgebung

Wechseln Sie auf den Log-Server, und lassen Sie sich den Inhalt des Verzeichnisses /var/log/journal/remote anzeigen. Dort sehen Sie jetzt eine neue Datei. Ihr Name enthält den vollständigen Namens des Clients, wie er im Zertifikat genannt ist. Einen Eintrag zu meinem Beispiel sehen Sie im folgenden Listing:

root@loghost:~# ls /var/log/journal/remote/
‚remote-C=DE,ST=SH,L=St.\\x20Michel,O=Adminbuch,OU=CA\
,CN=provider-stat.example.net.journal‘

Sollten Sie, so wie im Beispiel, ein Leerzeichen im Namen des Zertifikats haben, dann wird das Leerzeichen durch die Zeichenfolge \x20 ersetzt. Der Backslash muss später, beim einlesen der Datei, zusätzlich mit einem Backslash entwertet werden, auch wenn Sie den Pfad in gerade Hochkommata setzen.

Ist die Datei vorhanden, hat alles geklappt und der Server nimmt Meldungen vom Client entgegen. Sie können jetzt warten, bis der Client eine Nachricht generiert und auf den Server überträgt. Sie können aber auch selber eine Testmeldung mit dem Kommando logger generiert,  so wie im folgenden Listing:

root@provider-stat:~# logger -p syslog.debug „Das ist ein Test vom \\
Client provider-stat“

Auf dem Log-Server können Sie jetzt das Log genau so auswerten, wie ich es in den Abschnitten vorher beschrieben habe, aber mit einen Unterschied, als Quelle geben Sie die Datei des Clients an, den Sie auswerten wollen. In folgenden Listing sehen Sie das Kommando und das Ergebnis der durch logger erzeugten Meldung:

root@loghost:~# journalctl –file=’/var/log/journal/remote/remote-C=DE\
,ST=SH,L=St.\\x20Michel,O=Adminbuch,OU=CA,CN=provider-stat.\
example.net.journal‘

Jan 11 19:48:18 provider-stat root[1081]: Das ist ein Test vom Client\ provider-stat\

So können Sie jetzt alle weiteren Clients einrichten und testen und haben damit eine zentrale Log-Umgebung geschaffen.

Posted in Allgemein | Tagged , | Leave a comment