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
-
Wprowadzenie
-
Konfiguracja LDAP-a i bazy danych
-
Indeksacja
-
Listy kontroli dostępu
-
Konfiguracja bazy danych
-
Przebieg eksperymentu
-
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:
-
czasu wyszukiwania atrybutu uid o zadanej wartości;
-
czasu logowania za pomocą telneta oraz ssh;
-
czasu odpowiedzi na polecenie finger.
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.
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.
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:
- polecenia ldapsearch w celu wyszukania atrybutu uid o zadanej wartości;
- polecenia telnet;
- polecenia ssh - uwierzytelnienie poprzez moduł
pam_ldap i hasło w LDAP-ie;
- 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:
- wyszukanie w bazie dc=test,dc=uni,dc=torun,dc=pl z filtrem
(&(objectClass=posixAccount)(uid=nazwa))
- wyszukanie w bazie dc=test,dc=uni,dc=torun,dc=pl z filtrem
(&(objectClass=shadowAccount)(uid=nazwa))
- dowiązanie anonimowe do bazy
- dowiązanie do bazy jako użytkownik uid=nazwa,dc=test,dc=uni,dc=torun,dc=pl
(w przypadku drzewa wielopoziomowego użytkownik ma nazwę
uid=nazwa na określonym poziomie)
- wyszukanie w bazie dc=test,dc=uni,dc=torun,dc=pl z filtrem
(uid=nazwa)
- wyszukanie w bazie dc=test,dc=uni,dc=torun,dc=pl z filtrem
(&(objectClass=posixGroup)(|(memberUid=nazwa)
(uniqueMember=uid=nazwa,dc=test,dc=uni,dc=torun,dc=pl)))
- wyszukanie w bazie dc=test,dc=uni,dc=torun,dc=pl z filtrem
(&(objectClass=posixAccount)(uidNumber=liczba))
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:
- wyszukanie w bazie dc=test,dc=uni,dc=torun,dc=pl z filtrem
(&(objectClass=posixAccount)(uid=nazwa))
- wyszukanie w bazie dc=test,dc=uni,dc=torun,dc=pl z filtrem
(&(objectClass=shadowAccount)(uid=nazwa))
- dowiązanie anonimowe do bazy
- dowiązanie do bazy jako użytkownik uid=nazwa,dc=test,dc=uni,dc=torun,dc=pl
(w przypadku drzewa wielopoziomowego użytkownik ma nazwę
uid=nazwa na określonym poziomie)
- wyszukanie w bazie dc=test,dc=uni,dc=torun,dc=pl z filtrem
(uid=nazwa)
- wyszukanie w bazie dc=test,dc=uni,dc=torun,dc=pl z filtrem
(&(objectClass=posixGroup)(|(memberUid=nazwa)
(uniqueMember=uid=nazwa,dc=test,dc=uni,dc=torun,dc=pl)))
- wyszukanie w bazie dc=test,dc=uni,dc=torun,dc=pl z filtrem
(&(objectClass=posixAccount)(uidNumber=liczba))
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:
- wyszukanie w bazie dc=test,dc=uni,dc=torun,dc=pl z filtrem
(&(objectClass=posixAccount)(uid=nazwa))
- wyszukanie w bazie dc=test,dc=uni,dc=torun,dc=pl z filtrem
(objectClass=posixAccount)
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).