Maja Górecka-Wolniewicz
UCI UMK Toruń
Maja.Wolniewicz@uni.torun.pl

Temat zadania:

Efektywność serwera LDAP realizującego obsługę uwierzytelniania użytkowników

(opracowanie przygotowane w ramach realizacji zadań projektu KBN)

Data opracowania: 10.2003

Spis treści

  1. Wprowadzenie
  2. Konfiguracja LDAP-a i bazy danych
    1. Indeksacja
    2. Listy kontroli dostępu
    3. Konfiguracja bazy danych
  3. Przebieg eksperymentu
  4. Podsumowanie

1. Wprowadzenie

Celem opracowania jest prezentacja wyników pomiarów efektywności obsługi uwierzytelniania użytkowników poprzez serwis LDAP. Dokument LDAP jako serwis informacji systemowej w sieci przedstawia najistotniejsze aspekty związane z użyciem LDAP-a jako bazy użytkowników systemu, a także zalety takiego podejścia. Gdy decydujemy się na zastosowane opisanego tam rozwiązania do przechowywania danych o użytkownikach systemu padają zazwyczaj pytania:
czy takie podejście jest elastyczne? czy możemy planować, że docelowo w bazie LDAP będzie np. kilkadziesiąt tysięcy kont użytkowników i system pozostanie niezawodny i szybki?

Aby sprawdzić wydajność serwera LDAP przeprowadzono testy polegające na pomiarach:

przy zmieniającej się liczbie kont w bazie danych LDAP. Liczba kont zmieniała się od 1 tys. do 50 tys. Wzięto pod uwagę dwa sposoby rozłożenia danych: w pierwszym przypadku wszystkie konta były umieszczane w gałęzi dc=test,dc=uni,dc=torun,dc=pl, w drugim powstało 5 poziomów w drzewie dancyh, na poziomie docelowo było 10 tys. kont.

2. Konfiguracja LDAP-a i bazy danych

Nawet przy niewielkiej liczby kont przechowywanych w bazie LDAP, tak samo jak w przypadku dowolnych danych w tej bazie, niezbędna jest właściwa konfiguracja serwera oraz współpracującej z nim bazy danych.

a. Indeksacja

Ważną rzeczą jest wspieranie efektywności poprzez wprowadzanie indeksacji odpowiedznich atrybutów. Zgodnie z zaleceniami, gdy korzystamy z LDAP-a jako repozytorium danych o użytkownikach niezbędne jest stosowanie następujących indeksów:
index   objectClass  pres,eq
index   cn,uid  pres,eq,sub
index   uidnumber,gidnumber  pres,eq
W ten sposób ułatwiamy realizację najczęściej stosowanych przeszukań, o takich filtrach, jak:
(&(objectClass=posixAccount)(uid=nazwa))
(&(objectClass=shadowAccount)(uid=nazwa))
(objectClass=posixGroup)
W przeprowadzonych testach nie zajmowano się efektywnością w sytuacji, gdy nie są stosowane indeksy kluczowych atrybutów.

b. Listy kontroli dostępu

Istotny wpływ na czas uzyskania odpowiedzi na zapytanie ma stosowanie oraz sposób konfiguracji list kontroli dostępu do danych (dyrektywa access w pliku konfiguracyjnym slapd.conf). Sterowanie kontrolą dostępu jest niezbędne w przypadku używania LDAP-a jako repozytorium danych o użytkownikach, ponieważ w bazie LDAP są wówczas umieszczone zaszyfrowane hasła, do których, podobnie jak do pliku /etc/shadow w tradycyjnej organizacji bazy użytkowników, nikt, poza właścicielem oraz administratorem nie może mieć dostępu.

Typowo definiujemy listę kontroli dostępu o postaci:

access to attr=userPassword
 by self write   
 by anonymous auth    
 by * none 
W ten sposób dajemy prawo odczytu i modyfikacji atrybutu userPassword właścicielowi, a domyślnie takie prawo ma również administrator ustalony poprzez wpis rootdn w sekcji database dotyczącej danej bazy (plik slapd.conf). Jeśli w drzewie danych znajduje się inny wpis, który ma otrzymać prawa dostępu do danego atrybutu to musimy rozszerzyć listę, przykładowo do postaci:
access to attr=userPassword
 by dn.exact="cn=manager,dc=uni,dc=torun,dc=pl" write
 by self write   
 by anonymous auth    
 by * none 
Należy pamiętać, że w takiej sytuacji, gdy chodzi o konkretny wpis z bazy, któremu przypisujemy dodatkowe własności, konieczne jest użycie klauzuli by dn.exact=. Klauzula by dn= jest równoważna by dn.regex= i oznacza konieczność rozwikłania wyrażenia regularnego, a twórcy oprogramowania OpenLDAP, ostrzegają, że wszelkie działania na tego typu wyrażeniach istotnie obniżają wydajność. Rzeczywiście, przeprowadzone testy wykazały istotne wydłużenie czasu odpowiedzi przy takiej konfiguracji list kontroli dostępu opartej na wyrażeniach regularnych. W niektórych przypadkach czas oczekiwania na odpowiedź przy przeszukiwaniu wzrastał nawet 10-krotnie.

c. Konfiguracja bazy danych

Baza danych używana przez LDAP-a jako tzw. baza podkładowa jest definiowana w dyrektywie database w pliku slapd.conf. Do niedawna najczęściej używanym typem danych był typ LDBM. Obecnie zaleca się stosowanie typu BDB, którego naistotniejszą własnością jest lepsza organizacja transakcyjności. Należy jednak pamiętać, że dobrej transakcyjności wymagają przede wszystkim bazy dynamiczne, charakteryzujące się dużą liczbą operacji zapisu, takie w których zależy nam na możliwości odtworzenia stanu czy wycofania wcześniej zakończonej operacji. Kosztem transakcyjności jest dużo większa komplikacja zasad działania bazy, co może pociągać za sobą gorszą efektywność.

Typ LDBM może być skonfigurowany jako baza Berkeley DB lub GDBM. Nie zaleca się jednak używania GDBM - nadaje się on wyłącznie do niewielkich zasobów danych, ma duże ograniczenia dotyczące rozmiarów plików.
Jeśli chcemy używać typu BDB, to musimy dysponować dużo bardziej szczegółową wiedzą na temat konfiguracji bazy. Typ LDBM można zastosować nie znając mechanizmów funkcjonowania bazy, natomiast BDB wymaga świadomej, precyzyjnej konfiguracji, przede wszystkim w zakresie cache'owania oraz lokalizacji dzienników używanych do realizacji transakcyjności. Często tak konfiguracja musi być dopracowywana na bieżąco na podstawie analizy stanu bazy w zakresie liczby trafień w cache'u.

Przeprowadzone testy wykazały, że pod względem wydajności baza LDBM nie ustępuje bazie BDB, przy założeniu, że baza BDB zostanie dobrze skonfigurowana. Otrzymane wyniki czasu wyszukiwania danych są w takiej sytuacji niemal identyczne. Jeśli baza BDB stosuje zbyt mały rozmiar cache'a, np. domyślny rozmiar ok. 256kB, to przy dużej liczbie wpisów, rzędu 10 tys. znacznie wzrasta czas realizacji zapytań. Również lokalizacja plików dziennika na tym samym dysku fizycznym co baza danych ma negatywny wpływ na wydajność, dlatego zaleca się umieszczanie ich na innym dysku. W realizowanych testach baza BDB została skonfigurowana za pomocą pliku DB_CONFIG (plik ten jest zlokalizowany w katalogu przeznaczonym na bazę danych) o następującej zawartości:

set_cachesize   0  102400000 0
set_lg_dir /local/slapd/logs-dc
set_lg_bsize 2000
Pierwsze polecenie, set_cachesize ustala rozmiar cache'a - w tym przypadku jest to 0 GB + 102400000 B (ok. 122 KB); ostatnie 0 wskazuje, że cache ma być ciągły, nie może być podzielony na części.
Drugie, set_lg_dir, wskazuje katalog przeznaczny na dziennik (log) bazy.
Trzecie polecenie, set_lg_bsize ustala cache w pamięci na informacje dotyczące dziennika; w tym przypadku po umieszczeniu 2000 B informacji w pamięci cache'a dane są zapisywane do pliku logu na dysku.

3. Przebieg eksperymentu

Przeprowadzone testy polegały na stopniowym ładowaniu do bazy LDAP wpisów dotyczących kont użytkowników i sprawdzaniu dla poszczególnej liczby wpisów czasów realizacji:
  1. polecenia ldapsearch w celu wyszukania atrybutu uid o zadanej wartości;
  2. polecenia telnet;
  3. polecenia ssh - uwierzytelnienie poprzez moduł pam_ldap i hasło w LDAP-ie;
  4. polecenia finger z zadaną wartością identyfikatora użytkownika (atrybut uid).
Pierwszy test wiązał się z wykonaniem przeszukania z filtrem (uid=nazwa). Czas odpowiedzi pozostawał niezmienny i wynosił od 0.49 do 0.51 sekundy dla próbek 1 tys., 5 tys., 10 tys., 20 tys. oraz 50 tys. wpisów umieszczonych płasko na poziomie dc=test,dc=uni,dc=torun,dc=pl. Tak samo było w testach z 50 tys. wpisów umieszczonymi na pięciu poziomach, tj.: 10 tys. wpisów w dc=test,dc=uni,dc=torun,dc=pl, 10 tys. w dc=test1,dc=test,dc=uni,dc=torun,dc=pl, 10 tys. w dc=test2,dc=test1,dc=test,dc=uni,dc=torun,dc=pl, 10 tys. w dc=test3,dc=test2,dc=test1,dc=test,dc=uni,dc=torun,dc=pl, 10 tys. w dc=test4,dc=test3,dc=test2,dc=test1,dc=test,dc=uni,dc=torun,dc=pl (wpisy były umieszczane w paczkach po 10 tys. i testy realizowano kolejno dla 10, 20, 30 i 50 tys.). Wszystkie przeszukania były realizaowane z podstawą dc=test,dc=uni,dc=torun,dc=pl.

Test nr 2 był zrealizowany w oparciu o skrypty przygotowane w językach expect oraz perl i polegał na wykonaniu 100 kolejnych poleceń telnet z różnymi identyfikatorami (różnymi wartościami atrybutu uid). Natychmiast po wlogowaniu było wywoływane polecenie exit. Mierzono czas realizacji poszczególnych wywołań telnet. Pomiędzy kolejnymi logowaniami wprowadzono przerwę 1 s. - bez tej zwłoki system operacyjny wykazywał zbyt duże obciążenie sekwencyjnie wykonywanymi operacjami. Zalogowanie poprzez telnet, gdy korzystamy z bazy LDAP (mechanizmy PAM oraz NSS) jako bazy użytkowników oznacza wykonanie następujących operacji w bazie LDAP:

Niektóre operacje wyszukania są powtarzane kilkakrotnie, co wynika z faktu, że z LDAP-a korzystają naprzemiennie dwa moduły: pam_ldap oraz nss_ldap. Czas realizacji procedury zalogowania i wylogowania via telnet wyliczony jako czas średni 100 kolejnych logowań wynosił od 0.49 do 0.58 s. z tendencją do nieznacznego wzrostu przy rosnącej liczbie wpisów. Zwiększał się również wówczas rozrzut pomiędzy czasem maksymalnym logowania, w pojedynczych pomiarach, dla dużej liczby wpisów czas ten wynosił do 1 s.

W pomiarze nr 3, przeprowadzonym za pomomocą analogicznych narzędzi jak w teście telnet, uzyskane wyniki potwierdziły, że nawet znaczący wzrost liczby wpisów nie ma istotnego wpływu na czas realizacji polecenia logowania. Tym razem testom poddano program ssh. Procedura logowania i natychmiastowego wylogowania poprzez ssh oznacza realizację szeregu operacji LDAP:

Podobnie jak dla polecenia telnet niektóre z opisanych wyżej operacji LDAP są powtarzane kilka razy. Czas realizacji procedury zalogowania i wylogowania via ssh wyliczony jako czas średni 100 kolejnych logowań wynosił od 0.83 do 1.18 s. z tendencją do nieznacznego wzrostu przy rosnącej liczbie wpisów.

Pomiar czasu trwania polecenia finger dla rosnącej liczby kont obsługiwanych przez bazę LDAP nie wypadł tak dobrze jak poprzednie testy. Zaobserwowano istotny wzrost czasu odpowiedzi. Dla 1 tys. kont czas odpowiedzi wynosił ok. 0.2 s. Dla 5 tys. kont - ok. 0.5 s., dla 10 tys. - ok. 0.85 s., dla 20 tys. 1.9 s., a dla 50 tys. - 3.8 s. Z analizy logów LDAP wynika, że realizacja polecenia finger to zaledwie dwie operacje LDAP:

Ta druga operacja - w przypadku znaczącej liczby wpisów - implikuje istotne wydłużenie czasu oczekiwania na odpowiedź. Trudno wytłumaczyć cel tego wyszukania. Wydaje się, że jest to błąd implementacyjny po stronie modułu pam_ldap lub nss_ldap.

4. Podsumowanie

Z przeprowadzonych pomiarów wynika, że LDAP może być z powodzeniem wykorzystywany jako baza użytkowników systemu. Nawet przy dużej liczbie użytkowników, rzędu 50 tys., w systemie Redhat 8 współpracującym z serwerem OpenLDAP 2.1.13 poprzez moduły pam_ldap i nss_ldap nie wystąpiły podczas przeprowadzonego eksperymentu żadne zacięcia. W testach korzystano z lokalnej bazy LDAP, działającej na tym samym serwerze. Nie została oceniona wydajność przy rozproszeniu danych dotyczących użytkowników między kilka serwerów i efektywność współpracy poprzez odesłania adresowe (referrals).