Univention Bugzilla – Bug 28361
nscd + libnss-ldap Gruppenauflösung
Last modified: 2023-06-08 11:51:29 CEST
Aktuell in bei einem Kunden aufgetreten (Ticket #2012082821001308) aber auch in einer Testumgebung mit 30.000 Benutzern in Domain Users. Der nscd schafft es nicht die Daten in den lokalen Cache zu bekommen. Dabei ist es egal, ob die Daten aus dem LDAP per libnss-ldap oder aus der lokalen Datei bezogen werden. Stehen alle Gruppen in der lokalen Datei, so kann Domain Users nicht zuverlässig aufgelöst werden, zwei "ls -la /home"-Befehle direkt nacheinander: root@master141:~/eglibc-2.11.3/nscd# ls -la /home total 16 drwxr-xr-x 4 root root 4096 Apr 27 16:12 . drwxr-xr-x 24 root root 4096 Apr 27 13:57 .. drwxr-xr-x 2 root Domain Users 4096 Apr 27 16:12 a drwxr-xr-x 2 root root 4096 Apr 26 13:25 groups root@master141:~/eglibc-2.11.3/nscd# ls -la /home total 16 drwxr-xr-x 4 root root 4096 Apr 27 16:12 . drwxr-xr-x 24 root root 4096 Apr 27 13:57 .. drwxr-xr-x 2 root 5001 4096 Apr 27 16:12 a drwxr-xr-x 2 root root 4096 Apr 26 13:25 groups Aus der Logdatei: Sat 28 Apr 2012 06:12:43 AM CEST - 6007: handle_request: request received (Version = 2) from PID 6017 Sat 28 Apr 2012 06:12:43 AM CEST - 6007: GETFDPW Sat 28 Apr 2012 06:12:43 AM CEST - 6007: handle_request: request received (Version = 2) from PID 6017 Sat 28 Apr 2012 06:12:43 AM CEST - 6007: GETPWBYUID (0) Sat 28 Apr 2012 06:12:43 AM CEST - 6007: Haven't found "0" in password cache! Sat 28 Apr 2012 06:12:43 AM CEST - 6007: add new entry "0" of type GETPWBYUID for passwd to cache (first) Sat 28 Apr 2012 06:12:43 AM CEST - 6007: add new entry "root" of type GETPWBYNAME for passwd to cache Sat 28 Apr 2012 06:12:43 AM CEST - 6007: short write in cache_addpw: Success Sat 28 Apr 2012 06:12:43 AM CEST - 6007: handle_request: request received (Version = 2) from PID 6017 Sat 28 Apr 2012 06:12:43 AM CEST - 6007: GETFDGR Sat 28 Apr 2012 06:12:43 AM CEST - 6007: handle_request: request received (Version = 2) from PID 6017 Sat 28 Apr 2012 06:12:43 AM CEST - 6007: GETGRBYGID (0) Sat 28 Apr 2012 06:12:43 AM CEST - 6007: Haven't found "0" in group cache! Sat 28 Apr 2012 06:12:44 AM CEST - 6007: add new entry "0" of type GETGRBYGID for group to cache (first) Sat 28 Apr 2012 06:12:44 AM CEST - 6007: add new entry "root" of type GETGRBYNAME for group to cache Sat 28 Apr 2012 06:12:44 AM CEST - 6007: short write in cache_addgr: Success Sat 28 Apr 2012 06:12:44 AM CEST - 6007: handle_request: request received (Version = 2) from PID 6017 Sat 28 Apr 2012 06:12:44 AM CEST - 6007: GETGRBYGID (5001) Sat 28 Apr 2012 06:12:44 AM CEST - 6007: Haven't found "5001" in group cache! Sat 28 Apr 2012 06:12:44 AM CEST - 6007: handle_request: request received (Version = 2) from PID 6017 Sat 28 Apr 2012 06:12:44 AM CEST - 6007: GETGRBYGID (5001) Sat 28 Apr 2012 06:12:44 AM CEST - 6007: Haven't found "5001" in group cache! Sat 28 Apr 2012 06:12:44 AM CEST - 6007: add new entry "5001" of type GETGRBYGID for group to cache (first) Sat 28 Apr 2012 06:12:44 AM CEST - 6007: add new entry "Domain Users" of type GETGRBYNAME for group to cache Sat 28 Apr 2012 06:12:44 AM CEST - 6007: short write in cache_addgr: Broken pipe Sat 28 Apr 2012 06:12:44 AM CEST - 6007: handle_request: request received (Version = 2) from PID 6017 Sat 28 Apr 2012 06:12:44 AM CEST - 6007: GETGRBYGID (5001) Sat 28 Apr 2012 06:12:44 AM CEST - 6007: cannot write result: Broken pipe Sat 28 Apr 2012 06:12:44 AM CEST - 6007: handle_request: request received (Version = 2) from PID 6017 Sat 28 Apr 2012 06:12:44 AM CEST - 6007: GETGRBYGID (5001) Sat 28 Apr 2012 06:12:44 AM CEST - 6007: add new entry "5001" of type GETGRBYGID for group to cache (first) Sat 28 Apr 2012 06:12:44 AM CEST - 6007: add new entry "Domain Users" of type GETGRBYNAME for group to cache Sat 28 Apr 2012 06:12:44 AM CEST - 6007: short write in cache_addgr: Broken pipe Sat 28 Apr 2012 06:12:44 AM CEST - 6007: handle_request: request received (Version = 2) from PID 6017 Sat 28 Apr 2012 06:12:44 AM CEST - 6007: GETGRBYGID (5001) Sat 28 Apr 2012 06:12:44 AM CEST - 6007: cannot write result: Broken pipe Sat 28 Apr 2012 06:12:44 AM CEST - 6007: cannot write result: Broken pipe Sat 28 Apr 2012 06:12:44 AM CEST - 6007: handle_request: request received (Version = 2) from PID 6017 Sat 28 Apr 2012 06:12:44 AM CEST - 6007: GETGRBYGID (5001) Sat 28 Apr 2012 06:12:44 AM CEST - 6007: handle_request: request received (Version = 2) from PID 6017 Sat 28 Apr 2012 06:12:44 AM CEST - 6007: GETGRBYGID (5001) Sat 28 Apr 2012 06:12:44 AM CEST - 6007: handle_request: request received (Version = 2) from PID 6017 Sat 28 Apr 2012 06:12:44 AM CEST - 6007: GETGRBYGID (5001) Sat 28 Apr 2012 06:12:44 AM CEST - 6007: handle_request: request received (Version = 2) from PID 6017 Sat 28 Apr 2012 06:12:44 AM CEST - 6007: GETGRBYGID (5001) Sat 28 Apr 2012 06:12:44 AM CEST - 6007: cannot write result: Resource temporarily unavailable Sat 28 Apr 2012 06:12:44 AM CEST - 6007: handle_request: request received (Version = 2) from PID 6017 Sat 28 Apr 2012 06:12:44 AM CEST - 6007: GETGRBYGID (5001) Sat 28 Apr 2012 06:12:44 AM CEST - 6007: cannot write result: Resource temporarily unavailable Sat 28 Apr 2012 06:12:44 AM CEST - 6007: cannot write result: Broken pipe Sat 28 Apr 2012 06:12:44 AM CEST - 6007: cannot write result: Broken pipe Sat 28 Apr 2012 06:12:44 AM CEST - 6007: cannot write result: Broken pipe Weitere Tests haben ergeben, dass libnss-ldap in Bezug auf die Gruppenauflösung extrem langsam ist, ohne nscd: root@master141:~# time getent group >group.getent real 1m50.711s user 1m22.533s sys 0m4.036s Das gleiche mit einem Python Skript, welches auch auf Gruppen in Gruppen und Rekursionen prüft: root@master141:~# time ./dump-groups.py >group.python real 0m4.217s user 0m2.104s sys 0m0.208s Wenn die Daten aus dem python Skript an /etc/group ergänzt werden, so ist der Zugriff sehr schnell: root@master141:~# time getent group | wc -l 2802 real 0m0.015s user 0m0.020s sys 0m0.000s Eine mögliche Lösung: - deaktivieren des nscd Cache für Gruppen - libnss-ldap für Gruppen entfernen - ein neues nss-Modul schreiben, welches die Gruppen aus einer lokalen Datei (/etc/group.ldap) ausliest, siehe libnss-passwdcache - in regelmäßigen konfigurierbaren Abständen die Datei (/etc/group.ldap) neu generieren, zum einen per Cron, aber auch aus dem Listener heraus, siehe auch UCR Variable nscd/group/invalidate_cache_on_changes Eine Alternative wäre es libnss-ldapd zu verwenden, allerdings fehlt dort derzeit die Gruppen in Gruppen Auflösung.
(In reply to comment #0) > root@master141:~# time getent group >group.getent > > real 1m50.711s > user 1m22.533s > sys 0m4.036s > > Das gleiche mit einem Python Skript, welches auch auf Gruppen in Gruppen und > Rekursionen prüft: > > root@master141:~# time ./dump-groups.py >group.python > > real 0m4.217s > user 0m2.104s > sys 0m0.208s libnss-ldap benötigt so lange, weil jedes Gruppenmitglied nochmal gesucht wird. In dem python-Skript wird derzeit uid= direkt als Benutzer eingetragen.
(In reply to comment #0) > - ein neues nss-Modul schreiben, welches die Gruppen aus einer lokalen Datei > (/etc/group.ldap) ausliest, siehe libnss-passwdcache Dafür kann und sollte libnss-extrausers verwendet werden.
Das ist in einer ersten Version im Paket univention-pam umgesetzt. Beim Update wird automatisch der nscd Cache für die Gruppen deaktiviert und die nss-Auflösung per ldap für die Gruppen wird ebenfalls deaktiviert. Das Tool /usr/lib/univention-pam/ldap-group-to-file.py wir jetzt entweder per Cron alle 15 Minuten aufgerufen oder per Listener Modul nss.py, dort aber nur wenn der Listener 15 Sekunden nichts mehr zu tun hat. Beides ist per UCR konfigurierbar: nss/group/cachefile/invalidate_on_changes nss/group/cachefile/invalidate_interval Das Tool schreibt die Änderungen in die Datei /var/lib/extrausers/group, diese wird vom nss-Modul extrausers ausgelesen. Das bisherige Verhalten kann so wieder hergestellt werden: ucr set nss/group/cachefile=no nscd/group/enabled=true /etc/init.d/nscd restart Weitere Tests stehen noch aus. Zusätzlich sollen die Pakete für UCS 3.0 in einem Scope bereitgestellt werden.
Das Listener-Modul, das den Gruppencache invalidiert muss ebenfalls angepasst werden, so dass es nichts macht wenn die Option aktiviert ist.
Das ist jetzt soweit für UCS 3.1 umgesetzt. Die Pakete stehen ebenfalls als Backport für UCS 3.0 zur Verfügung. Dort können sie wie folgt eingebunden werrden: ucr set repository/online/component/groupcache=true \ repository/online/component/groupcache/server=apt.univention.de \ repository/online/component/groupcache/parts=unmaintained apt-get update && apt-get -u dist-upgrade Das System wird dann direkt so umkonfiguriert, dass die Gruppenauflösung nicht mehr per libnss-ldap und nscd gemacht wird, sondern über ein Tool, welches die Daten in eine lokale Datei schreibt. Das alte Verhalten kann so wieder hergestellt werden: ucr set nss/group/cachefile=no nscd/group/enabled=true invoke-rc.d nscd restart invoke-rc.d univention-directory-listener restart Je nach Status vor dem Update müsste die Cache Invalidierung ebenfalls wieder hergestellt werden: ucr nscd/group/invalidate_cache_on_changes=true invoke-rc.d univention-directory-listener restart Getestet habe ich bisher: - Umgebung mit > 30000 Benutzern - Diverse Gruppenverschachtelungen - Ungültige Gruppenmitglieder - Beendeter LDAP Server - Doppelte Gruppenmitglieder über Gruppen in Gruppen - Rekursionen In der QA bitte nochmal die 3.0 und 3.1 Pakete testen.
Verified: * Gruppen in Gruppen, invalid users, Umlaute * i386 und amd64 * UCS 3.0 und UCS 3.1 * Wird auch bei Neuinstallation standardmäßig aktiviert. * postrun delay funktioniert, Cronjob funktioniert. * Changelog OK Neue UCR Variablen: nss/group/cachefile?yes nss/group/cachefile/invalidate_on_changes?yes Geänderte Defaults: nscd/group/enabled?no nscd/group/invalidate_cache_on_changes=false Eigenheiten der neuen Lösung: * Gruppenmitlieder, die lokal nicht per getent passwd aufgelöst werden, werden als Gruppenmitglieder aufgeführt (getent group $gruppenname). Bei nss_ldap wurden diese herausgefiltert und nicht angezeigt. Dafür gibt es jetzt Bug 28401. * Wenn man viele Gruppen jeweils im Abstand von <15 sek. anlegt, dann wird der groupcache längere Zeit nicht geschrieben, weil die postrun-Funktion des neuen nss-Listeners nicht aktiv wird. Der Cron-Job läuft aber alle 15 min. * Der Name von Gruppen mit Umlaut wird jetzt in der Ausgabe von 'getent group' mit Umlauten dargestelt, mit nss_ldap wurde da jeder Umlaut als zwei escapte hex-Bytes ausgegeben. In der Praxis scheint das keinen Unterschied zu machen. Insbesondere treten in der Ausgabe von "getent group grüppe" und in der Ausgabe von "id user1" weiterhin die Hex-bytes auf. * In einem Fall verwendete 'getent group group1' nach dem Update auf die neue Lösung weiterhin den nscd (strace zeigt das). Daher ist nach dem Update ein Reboot zu empfehlen, zumindest aber ein '/etc/init.d/nscd stop; getent group guests; /etc/init.d/nscd start'.
Gerade bei der Bearbeitung von Bug #25656 aufgefallen. libnss-ldap + nscd funktionieren case-insensitive, libnss-extrausers hingegen case-sensitive. Neu: SG@master52:~$ getent group domain\ users SG@master52:~$ getent group Domain\ Users Domain Users:*:5001:test1,Administrator,SG2,SG SG@master52:~$ Alt: SG@master52:~$ getent group domain\ users Domain Users:*:5001:test1,Administrator,SG2,SG SG@master52:~$ getent group Domain\ Users Domain Users:*:5001:test1,Administrator,SG2,SG SG@master52:~$
Ist angepasst und gebaut. Die Anpassung ist für den groupcache Scope noch nicht veröffentlicht.
Verifed: * libnss-extrausers verhält sich jetzt case insensitive * Advisory muss nicht upgedatet werden root@master:~# getent group UpperGroup1 UpperGroup1:*:7234:user1 root@master:~# getent group uppergroup1 UpperGroup1:*:7234:user1 root@master:~# getent group übergroup1 \C3\9CberGroup1:*:7235:user1 root@master:~# getent group Übergroup1 \C3\9CberGroup1:*:7235:user1 root@master:~# getent group ÜberGroup1 \C3\9CberGroup1:*:7235:user1 root@master:~# getent group UPPERGROUP1 UpperGroup1:*:7234:user1
(In reply to comment #9) > Verifed: > * libnss-extrausers verhält sich jetzt case insensitive > * Advisory muss nicht upgedatet werden groupcache Scope für UCS 3.0 wurde auch aktualisiert.
(In reply to comment #10) > (In reply to comment #9) > > Verifed: > > * libnss-extrausers verhält sich jetzt case insensitive > > * Advisory muss nicht upgedatet werden > > groupcache Scope für UCS 3.0 wurde auch aktualisiert. libnss-extrausers ist nicht im 3.0 Scope nicht für amd64 gebaut/veröffentlicht.
Das amd64 war nicht vorhanden. Paket für amd64 neu gebaut und veröffentlicht: http://apt.univention.de/3.0/unmaintained/component/groupcache/amd64/
(In reply to comment #12) > Das amd64 war nicht vorhanden. Paket für amd64 neu gebaut und veröffentlicht: Das amd64-Verzeichnis war nicht vorhanden. Paket für amd64 neu gebaut und veröffentlicht:
Da die Anpassung nur den 3.0 Backport betraf, habe ich den Bug wieder auf Verified gesetzt.
Wenn /tmp und /var nicht auf der gleichen Partition liegen, kommt es in ldap-group-to-file.py zu einem Traceback. Traceback (most recent call last): File "/usr/lib/univention-pam/ldap-group-to-file.py", line 124, in <module> os.rename(fdname, options.file) OSError: [Errno 18] Invalid cross-device link Restarting bind9 daemon: . done. os.rename kann wahrscheinlich nicht über Partitionsgrenzen hinweg arbeiten.
Ich habe es bei mir nun mit (fdtemp, fdname) = tempfile.mkstemp(dir=os.path.dirname(options.file)) behoben.
Ist angepasst.
ok, es wird nun shutil zum Verschieben verwendet. -> /usr/lib/univention-pam/ldap-group-to-file.py --check_member debug shutil.move(/tmp/tmpPxyWxQ, /var/lib/extrausers/group)
UCS 3.1-0 has been released: http://forum.univention.de/viewtopic.php?f=54&t=2125 If this error occurs again, please use "Clone This Bug".