Można stosować jeden z trzech trybów uwierzytelniania:
disallow bind_anonEfektem uwierzytelniania bez hasła, polegającego na tym, że jest dostarczana nazwa (identyfikator), ale nie podaje się hasła, jest również dostęp do bazy jako użytkownik anonymous.
allow bind_anon_credale ponieważ wiele aplikacji LDAP błędnie generuje zlecenia dowiązania "bez hasła" w przypadkach, gdy w rzeczywistości wymaga się dowiązania za pomocą hasła, zaleca się, by ta własność nie była uaktywniana.
disallow bind_bind_simple_unprotectedJeśli, z jakiegoś powodu, jest pożądane wyłączenie możliwości dowiązania w trybie nazwa i hasło, to należy w pliku konfiguracyjnym slapd.conf wpisać dyrektywę:
disallow bind_simple
b. Uwierzytelnianie za pomocą schematu SASL
Zarówno serwery, jak i klienci LDAP mogą korzystać z uwierzytelniania zgodnego ze specyfikacją SASL (wg RFC2222). SASL pozwala na stosowanie różnych mechanizmów (Kerberos, DIGEST-MD). Standardowe interfejsy (np. ldapsearch, ldapmodify) domyślnie próbują uwierzytelniać użytkownika w serwerze za pomocą SASL-a. Dodatkowa konfiguracja pozwala na zastosowanie specyficznej własności SASL-a, dzięki której można dokonać pośredniej autoryzacji (użytkownik po uwierzytelnieniu może przełączyć swoją tożsamość na innego użytkownika lub usługę i otrzymać odpowiednie prawa dostępu).
Najpopularniejszą dostepną bezpłatnie implementacją SASL-a jest Cyrus SASL. Obecnie zalaca się do współpracy z OpenLDAP-em SASL w wersji 2.x.
Uwaga: w systemie Redhat 8.0 OpenLDAP niepoprawnie współpracuje z pakietem Cyrus SASL 2.x. Operacja przeszukania bazy wysłana bez opcji -x powoduje upadek procesu slapd. Zaleca się stsowanie w tej sytuacji wersji 15. SASL-a.
Należy pamiętać, że mechanizmy dopuszczane w SASL-u oferują różny poziom bezpieczeństwa. Na przykład mechanizmy PLAIN i LOGIN nie dają większego zaufania niż proste uwierzytelnienie w LDAP-ie. Obowiązkowym mechanizmem SASL-a zaimplementowanym w LDAPv3 jest DIGEST-MD5, który nie jest wprawdzie zaliczany do mechanizmów silnego uwierzytelniania (jak np. system Kerberos czy techniki korzystające z kryptografii klucza publicznego), ale daje znaczącą ochronę przed atakami. DIGEST-MD5 jest zalecany jako następca stanowiących duże zagrożenie mechanizmów korzystających z haseł podawanych otwartym tekstem. DIGEST-MD5 wypiera obecnie swojego poprzednika CRAM-MD5. Innym popularnymi mechanizmami SASL są KERBEROS_V4 (oparty na Kerberosie IV) oraz GSSAPI (używany razem z Kerberosem V). Analizę tych rozwiązań, z powodów licencyjnych, w tym opracowaniu pomijam. Mechanizm typu EXTERNAL korzysta z technik uwierzytelniania dostarczanych przez usługi sieciowe niższej warstwy, jak np. TLS/SSL. Jeśli TLS bazuje na technologii kluczy publicznych X.509, to taki mechanizm EXTERNAL gwarantuje silne uwierzytelnianie.
Aby uwierzytelnianie zgodne ze schematem SASL zaczęło funkcjonować, należy wykonać kilka kroków. Po pierwsze serwer slapd musi wiedzieć, z jakiego systemu bezpieczeństwa ma korzystać do komunikacji z programami klienckimi (zazwyczaj oznacza to konieczność stworzenia odpowiedniego klucza usługi, czy klucza publicznego lub tajnego). Jeżeli będziemy używać mechanizmu DIGEST-MD5, to klucze tajne (secrets) są zapamiętywane albo bezpośrednio w bazie LDAP, albo we własnej bazie danych Cyrus SASL-a (w DIGEST-MD5 klient i serwer dysponują wspólnym kluczem tajnym, czyli hasłem). Serwer, po zainicjowaniu przez klienta połączenia z nim, generuje wyzwanie, czyli sygnał zmuszający do ujawnienia tożsamości (challenge), klient w odpowiedzi musi udowodnić znajomość hasła (np. szyfruje hasłem wyzwanie). W tej metodzie hasło nie jest przekazywne w sieci.
Hasła są zazwyczaj przechowywane w bazie sasldb (sasldb2 w wersji 2.x). Jeśli OpenLDAP został skompilowany z Cyrus SASL-em 2.1, to hasła mogą być również zapammiętywane w samej bazie LDAP. W przypadku haseł umieszczonych w plikach sasldb lub sasldb2 należy pamiętać o prawach zabraniających postronnym użytkownikom dostępu do tych plików.
Aby umieścić hasła w bazie sasldb2, należy dodać odpowiednich użytkowników za pomocą polecenia:
saslpasswd2 -c <username> -u <domena>
Polecenie saslpasswd2 służy również do zmiany hasła.
Aby korzystać z haseł zapamiętanych w LDAP-ie, należy umieścić hasło jawnym tekstem w atrybucie userPassword odpowiedniego wpisu. Jednocześnie w konfiguracji slapd.conf trzeba dodać:
password-hash {CLEARTEXT}Hasłami zapamiętananymi w ten sposób można zarządzać za pomocą polecenia ldappasswd lub poprzez modyfikację atrybutu userPassword.
Przykładem realizacji wyszukania z uwierzytelnieniem SASL są polecenia:
ldapsearch -U manager "cn=Jan*" ldapsearch -U manager@uni.torun.pl -Y DIGEST-MD5W pierwszym przypadku użytkownik o identyfikatorze manager uwierzytelnia się poprzez SASL-a w domyślnej domenie SASL (domenę taką można ustalić poprzez dodanie w konfiguracji slapd.conf dyrektywy sasl-realm).
Niezależnie od tego, gdzie zostały zapamiętane hasła, następuje odwzorowanie identyfikatora uwierzytelnienia SASL do postaci nazwy wyróżnionej (distinguished name, DN). Mechanizm DIGEST-MD5 produkuje identyfikator o postaci:
uid=<username>,cn=<realm>,cn=digest-md5,cn=authprzy czym, jeśli jest używana domyślana domena (realm), to w identyfikatorze jest pominięty komponent cn=<realm>. Wpisy o takich DN-ach nie mają być umieszczane w bazie LDAP. Jeśli jednak jest możliwe dokonanie jednoznacznego przypisania użytkownikowi username, charakteryzującemu się powyższym identyfikatorem uwierzytelnienia, wpisu w bazie LDAP, to taki wpis może się stać DN-em uwierzytelnienia. Należy jednak pamiętać, że nie jest niezbędne, by wpis związany z DN-em uwierzytelnienia istniał w bazie LDAP, ale jeśli istnieje, to uzyskujemy dodatkową funkcjonalność.
Sposób odwzorowania identyfikatora uwierzytelnienia do postaci DN-u uwierzytelnienia określa się w pliku slapd.conf za pomocą dyrektywy
sasl-regexp <search pattern> <replacement pattern>search pattern jest dopasowywany do identyfikatora uwierzytelnienia w postaci DN-u, jeśli wystąpi zgodność, to zastępuje go replacement pattern. Napis powstający na podstawie replacement pattern powinien być DN-em uwierzytelnienia użytkownika, może również mieć postać URL-a do LDAP-a. Jeśli np. efektem uwierzytelnienia metodą DIGEST-MD5 jest identyfikator
uid=manager,cn=uni.torun.pl,cn=digest-md5,cn=autha dyrektywa sasl-regexp została zapisana następująco:
sasl-regexp "uid=(.*),cn=uni.torun.pl,cn=digest-md5,cn=auth" "cn=$1,dc=uni,dc=torun,dc=pl"to identyfikator zostanie odwzorowany na następujący DN uwierzytelnienia: uid=manager,dc=uni,dc=torun,dc=pl. Tym samym, użytkownik uwierzytelniony za pomocą identyfikatora manager w SASL-u otrzymuje wszystkie prawa przypisane właścicielowi wpisu uid=manager,dc=uni,dc=torun,dc=pl w bazie LDAP.
Przy tworzeniu reguł odwzorowania sasl-regexp należy działać bardzo ostrożnie. Ustawienie tych reguł w zbyt szerokim zakresie (np. uid=(.*),cn=.*,cn=digest-md5,cn=auth" może doprowadzić do niezamierzonego przydzielania praw użytkownikom.
Zdarza się, że dane uzyskane po uwierzytelnianiu SASL nie sa wystarczające, by bezpośrednio otrzymać DN uwierzytelniania. Wówczas dyrektywa sasl-regexp może jako wynik dawać URL do LDAP-a. Taki URL będzie używany do wykonania wewnętrznego przeszukania bazy LDAP, w celu znalezienia DN-a uwierzytelnionej osoby.
Ogólna postać URL-a jest następująca:
ldap://<host>/<base>?<attrs>?<scope>?<filter> <host> to nazwa serwera LDAP (powinna być pusta, przeszukanie dotyczy aktualnego serwera <base> to DN wskazujący korzeń przeszukania <attrs> to poszukiwane atrybuty (ignorowane, bo poszukujemy DN-a) <scope> to zakres przeszukania ("bas", "one" lub "sub")Przykładem może być poniższa postać dyrektywy sasl-regexp:
sasl-regexp "uid=(.*),cn=uni.torun.pl,cn=digest-md5,cn=auth" ldap:///dc=uni,dc=torun,dc=pl??sub?(&(uid=$1)(objectClass=person))SASL pozwala na użycie dodatkowej funkcjonalności, zwanej autoryzacją pośrednią (proxy authorisation), dzięki której pozytywnie uwierzytelniony użytkownik może występować jako użytkownik o innym DN-ie. Taka usługa jest przydatna, gdy z jakimś wpisem chcemy powiązać funkcje, które może realizować wybrana grupa użytkowników (np. funkcje administracyjne przydzielone ściśle określonemu gronu osób, każda z tych osób uwierzytelnia się za pomocą własnych danych, a następnie otrzymuje prawa przypisane administratorowi). Innym dobrym przykładem jest rozwiązanie następującego problemu: dajemy użytkownikom możliwość modyfikacji własnego wpisu w bazie LDAP poprzez interfejs WWW. Użytkownik uwierzytelnia się poprzez serwer WWW, a serwer WWW (dokładnie jego komponent, np. skrypt CGI), nie ma uprawnień, by zrealizować uwierzytelnienie w serwerze LDAP jako konkretny użytkownik, dlatego uwierzytelnia się jako np. cn=Webservices,dc=uni,dc=torun,dc=pl, a następnie za pomocą autoryzacji SASL uzyskuje uprawnienia konkretnego użytkownika, wg reguł skonfigurowanych w serwerze LDAP.
Należy pamiętać, że po pozytywnej autoryzacji pośredniej oryginalny DN uwierzytelnienia zostaje zastąpiony nowym DN-em otrzymanym na podstawie zlecenia autoryzacji.
Identyfikator autoryzacji jest wysyłany do serwera LDAP np. za pomocą opcji -X w poleceniu ldapsearch. Identyfikator może mieć jedną z dwóch postaci:
u:<username>lub
dn:<dn>W pierwszej postaci nazwa <username> wywodzi się z tej samej przestrzeni nazw co identyfikator uwierzytelnienia SASL - jest to nazwa użytkownika, zdefiniowana w odniesieniu do odpowiedniego mechanizmu uwierzytelnienia. Taki identyfiaktor jest konwertowany do formatu DN-a przez tę samą funkcję, z której korzysta proces uwierzytelnienia. W efekcie powstaje DN zlecenia autoryzacji (authorization request DN) o postaci:
uid=<username>,cn=<realm>,cn=digest-md5,cn=authTen DN jest poddawany działaniu reguł sasl-regexp, które konwertują go do postaci prawomocnego DN-a autoryzacji, dotyczącego wpisu umieszczonego w bazie LDAP. Jeśli nie jest możliwe skojarzenie z DN-em zlecenia autoryzacji rzeczywistego wpisu w bazie, to zlecenie autoryzacji kończy się niepowodzeniem (rodzaj błędu inappropriate access).
Serwer slapd po otrzymaniu DN-a autoryzacji rozpoczyna proces zatwierdzenia. We wpisie prezentującym dane w bazie LDAP można umieścić dwa wielowartościowe atrybuty kontrolujące przebieg autoryzacji:
saslAuthzTo saslAuthzFrom(oba te atrybuty są wbudowane w wewnętrzny schemat serwera OpenLDAP, nie należy ich szukać w plikach ze schematami).
Wartości obu atrybutów mają taką samą postać jak wynik działania replacement pattern w dyrektywie sasl-regexp - jest to albo DN, albo URL do LDAP-a. Jeśli wartością saslAuthzTo jest jakiś DN, to uwierzytelniony użytkownik może zautoryzować się na podstawie tego DN-a (czyli uzyskać prawa dostępu zgodne z tym DN-em). Dodatkową funkcjonalnością jest możliwość wpisania w wartości będącej DN-em wyrażenia regułowego, np.
saslAuthzTo: uid=.*,ou=Managers,dc=uni,dc=torun,dc=plWówczas uwierzytelniony użytkownik zostaje zautoryzowany z dowolnym DN-em zgodnym z danym wzorcem (znacznie podnosi to prędkość wyznaczenia wartości). Jeśli wartość saslAuthzTo jest URL-em do usługi LDAP, to zgodnie z tym URL-em jest realizowane przeszukanie bazy danych. W efekcie uwierzytelniony użytkownik może przyjąć dowolny DN będący wynikiem przeszukania. W przypadku zastosowania jako wartości atrybutu saslAuthzTo lub saslAuthzFrom URLA-a do bazy LDAP należy zwrócić uwagę na to, by produkowane wyniki przeszukania nie składały się z listy o dużej liczbie DN-ów, gdyż znacznie wydłuża to proces autoryzacji (sprawdzany jest każdy DN). Poza tym ważne jest indeksowanie przez serwer slapd atrybutów, które są poszukiwane (np. atrybutu objectclass, jeśli saslAuthzTo ma wartość ldap:///dc=uni,dc=torun,dc=pl??sub?(objectclass=organizationalRole))
Aktywizacja domyślnie wyłączonej realizacji autoryzacji pośredniej odbywa się za pośrednictwem dyrektywy sasl-authz-policy. Można podać wartości none (bez autoryzacji), from (autoryzacja wg reguł źródłowych), to (autoryzacja wg reguł docelowych) lub both (autoryzacja wg reguł źródłowych i docelowych).
Należy pamiętać, że reguły docelowe dają bardzo duże możliwości i jeśli zwykły użytkownik ma możliwość aktuualizacji tego atrybutu, to może wpisać do niego reguły dające mu np. możliwość autoryzacji jako dowolny użytkownik. Dlatego atrybut saslAuthzTo musi być chroniony za pomocą reguł kontroli dostępu.
Poniżej jest przedstawiony opis obu metod, ale zaleca się stosowanie techniki statycznej, ze względu na to, że jest ona określana jako pewniejsza i lepiej zaimplementowana.
W celu ustalenia praw dostępu należy określić:
Dyrektywy access są wpisywane albo bezpośrednio do pliku konfiguracyjnego slapd.conf, albo do dowolnego pliku (lub plików), który jest włączany do konfiguracji w pliku slapd.conf dyrektywą include.
access to dn="(.*),o=(.*),c=PL" by group="cn=org admins,o=$2" write by aci write by * readBardziej ogólna Dyrektywa access to * by aci write włącza pełną kontrolę za pomocą atrybutu aci w całym drzewie na danym serwerze.
W każdym obiekcie bazy LDAP można zdefiniować informację dotyczącą kontroli dostępu (ACI). Gdy przystępujemy do zamieszczania ACI we wpisach, należy wziąć pod uwagę kilka rzeczy. Po pierwsze na końcu każdej definicji ACI niejawnie występuje deny, czyli dezaktywacja wszystkich innych uprawnień. Poza tym, tryb dostępu do obiektu jako całości nie wynika z przyznanego trybu dostępu do atrybutów tego obiektu, np. mimo że mamy prawo odczytu atrybutu cn wpisu, to nie możemy przeczytać go, dopóki nie zostanie przydzielone prawo odczytu całego wpisu ([entry]).
Wartość atrybutu przechowującego dane o kontroli dostępu ma postać:
OID # SCOPE # RIGHTS # TYPE # SUBJECT OID - pole ignorowane (liczba całkowita) SCOPE - obecnie może mieć jedną wartość: entry RIGHTS - na ogół trzy pola oddzielone średnikami: ACTION ; PERMISSION ; TARGET ACTION - grant lub deny PERMISSION - dowolna kombinacja: "r" (read), "s" (search", "w" (write), "c" (compare), np. "r,s,c" TARGET - lista (oddzielona przecinkami): atrybut (np. cn, sn), [all], [entry], [children] TYPE - jedno z następujących słów kluczowych: access-id (DN administratora), group (DN grupy), self SUBJECT - DN wpisu uprawnionego do operacji na danym wpisieKażdy obiekt, w którym chcemy wpisać atrybut służący do kontroli dostępu musi należeć do klasy openLDAPacl. Reguły dostępu umieszczamy według powyżej określonych zasad w atrybucie OpenLDAPaci.
Szczegółowe wyjaśnienie składni atrybutu OpenLDAPaci i techniki ACI można znaleźć w sekcji OpenLDAP Faq-O-Matic na stronach projektu OpenLDAP ( http://www.openldap.org/faq/index.cgi?file=634).
4. Przykładowe rozwiązanie kontroli dostępu
cn=Administrator danych BU cn=Administrator danych WNHGałąź ou=Baza LDAP,o=Uniwersytet Mikołaja Kopernika w Toruniu,c=PL jest specjalnie chroniona - zakładamy, że ma charakter czysto operacyjny i nie może być widoczna dla użytkowników anonimowych oraz innych użytkowników dowiązanych do bazy. Wyjątkiem jest administrator całego poddrzewa o=Uniwersytet Mikołaja Kopernika w Toruniu,c=PL. Administratorowie jednostek widzą tylko swój wpis w gałęzi ou=Baza LDAP,o=Uniwersytet Mikołaja Kopernika w Toruniu,c=PL.
Pełne ukrywanie administratorów jednostek w drzewie uniemożliwiłoby
zrealizowanie procesu uwierzytelnienia, dlatego są również potrzebne
dodatkowe reguły dające anonimowemu użytkownikowi szansę uwierzytelnienia.
Realizują to wszystko następujące dyrektywy (*):
access to dn.base="cn=Administrator danych AU,ou=Baza LDAP,o=Uniwersytet Mikołaja Kopernika w Toruniu,c=PL" attrs=userPassword by * auth by self write by dn="uid=manager,dc=uni,dc=torun,dc=pl" write by * none access to dn.base="cn=Administrator danych AU,ou=Baza LDAP,o=Uniwersytet Mikołaja Kopernika w Toruniu,c=PL" by self write by dn="uid=manager,dc=uni,dc=torun,dc=pl" write by * noneUwaga: w powyższym przykładzie dla czytelności podano prawidłowe polskie znaki jako wartości dn.base, w rzeczywistości reguły kontroli dostępu (umieszczane w pliku konfiguracyjnym slapd.conf lub włączane do niego za pośrednictwem innego pliku) MUSZĄ zostać przekonwertowane do postaci UTF-8.
Natomiast ukrycie drzewa "ou=Baza LDAP,o=Uniwersytet Mikołaja Kopernika w Toruniu,c=PL" przed użytkownikami następuje poprzez poniższą dyrektywę (**):
access to dn.subtree="ou=Baza LDAP,o=Uniwersytet Mikołaja Kopernika w Toruniu,c=PL" by dn="uid=manager,dc=uni,dc=torun,dc=pl" write by * nonePonieważ dyrektywa (**) jest bardziej ogólna niż dyrektywy (*), więc kolejność dyrektyw MUSI być taka, w jakiej zostały przedstawione, tzn. najpierw wszystkie reguły dotyczące administratorów, potem reguła dotycząca gałęzi.
Administratorzy jednostek, zgodnie z ustaleniami przyjętymi w procedurach zarządzania bazą LDAP Uniwersytetu Mikołaja Kopernika w Toruniu, mogą modyfikować tylko część danych o użytkownikach:
Administratorzy mają uprawnienia do niekórych operacji na podlegających mu poddrzewach danych, dzięki zamieszczeniu w pliku slapd.conf sekwencji następujących dyrektyw:
access to dn.subtree="ou=Archiwum, o=Uniwersytet Mikołaja Kopernika w Toruniu, c=PL" attrs=roomnumber,telephonenumber,facsimileTelephoneNumber, mail,description,jpegPhoto by dn="cn=Administrator danych Archiwum,ou=Baza LDAP, o=Uniwersytet Mikołaja Kopernika w Toruniu,c=PL" write by dn="uid=manager,dc=uni,dc=torun,dc=pl" write by * read access to dn.subtree="ou=Archiwum, o=Uniwersytet Mikołaja Kopernika w Toruniu, c=PL" by dn="uid=manager,dc=uni,dc=torun,dc=pl" write by * readKażdy użytkownik w bazie ma przypisany identyfikator (pochodzący z systemu kadrowego), jest on umieszczony w atrybucie uniident. Atrybut ten jest widziany tylko przez głównego administratora danych. Regulują to dyrektywy:
access to dn.subtree="o=Uniwersytet Mikołaja Kopernika w Toruniu,c=PL" attrs=uniident by dn="cn=manager,dc=uni,dc=torun,dc=pl" write by dn="cn=Administrator danych UMK,ou=Baza LDAP, o=Uniwersytet Mikołaja Kopernika w Toruniu,c=PL" write by * nonektóre muszą być umieszczone przed wszystkimi wcześniej wymienionymi, gdyż dotyczą osób, a więc są bardziej szczegółowe od reguł omówionych wcześniej. Jeżeli zakłada się, że osoby umieszczone w bazie LDAP mają możliwość ochrony części swoich atrybutów, np. pracownik może zakazać publikacji swojego stanowiska, wówczas konieczne jest dodanie reguł dotyczących konkretnych osób. Takie dyrektywy MUSZĄ pojawić się przed opisanymi wyżej, gdyż dotyczą atrybutów obiektów typu person, zlokalizowanych w najniższych częściach drzewa danych. W takich przypadkach w bazie UMK ochrona części atrybutów opisujących osoby jest możliwa poprzez wprowadzenie następujących dyrektyw:
access to dn.base="cn=Jan Kowalski, ou=Pracownia Fotograficzna, ou=Instytut Zabytkoznawstwa i Konserwatorstwa, ou=Wydział Sztuk Pięknych, o=Uniwersytet Mikołaja Kopernika w Toruniu, c=PL" attrs=plposition by dn="cn=Administrator danych WSP, ou=Baza LDAP, o=Uniwersytet Mikołaja Kopernika w Toruniu, c=PL" write by dn="cn=Gateway User, ou=Baza LDAP, o=Uniwersytet Mikołaja Kopernika w Toruniu,c=PL" read by * noneObiekt o nazwie wyróżnionej "cn=Gateway User, ou=Baza LDAP,o=Uniwersytet Mikołaja Kopernika w Toruniu,c=PL", zlokalizowany w operacyjnej gałęzi "ou=Baza LDAP,o=Uniwersytet Mikołaja Kopernika w Toruniu,c=PL", ma specjalne znaczenie. Gateway do zasobów LDAP UMK dowiązuje się do bazy LDAP jako użytkownik o tej nazwie, tylko gdy połączenie z bazą następuje z adresu klienckiego interpretowanego przez ten gateway, jako adres lokalny (intranetowy). W ten sposób może być zrealizowane ograniczenie dostępu do atrybutów różnego typu obiektów, nie tylko typu person, w sieci globalnej. Tak chronione zasoby pozostają dostępne w całości w sieci lokalnej.
Bibliografia