Temat zadania:
Data opracowania: 30.12.2002
Do zagadnienia autentykacji i autoryzacji w serwisie WWW, która ma wykorzystywać LDAP podejść można na dwa sposoby. Po pierwsze, możemy zdecydować się na korzystanie z metod oferowanych pośrednio przez sam serwer, a więc sięgnąć po dynamiczne i statyczne moduły serwera, które wzbogacają standardową procedurę uwierzytelniania serwera (Basic) chociażby o możliwość korzystania z zasobów LDAP do przechowywania identyfikatorów i haseł osób uprawnionych do logowania. Drugim, alternatywnym podejściem, jest ominięcie metod serwera i zaprojektowanie własnego systemu autoryzacji dostępu do określonych serwisów WWW np. w języku PHP, bądź też w HTML-u z użyciem skryptów CGI.
W niniejszym opracowaniu przyjrzymy się modułom serwera Apache służącym do autentykacji i autoryzacji w serwisie WWW. W dalszym ciągu opracowania często świadomie używać będziemy zamiennie pojęć autoryzacja i autentykacja ponieważ moduły zwykle obie te operacje wykonują prawie jednocześnie a czasem autoryzacja jest równoznaczna z poprawną autentykacją.
Przegląd obejmuje 5 różnych modułów korzystających z LDAP:
1 | mod_auth_ldap v. 0.5.1 | http://nona.net/software/ldap |
2 | mod_auth_ldap v. 2.4 | http://www.muquit.com/muquit/software/mod_auth_ldap/mod_auth_ldap.html |
3 | mod_ldap v. 1.8 | http://kie.berkeley.edu/people/jmorrow/mod_ldap/ |
4 | auth_ldap | http://www.rudedog.org/auth_ldap/ |
5 | mod_authz_ldap | http://authzldap.othello.ch/ |
Dla celów przeglądu został wykorzystany system Linux RedHat v . 7.2 wraz z oprogramowaniem OpenLDAP w wersji 2.0.23, Apache wersja 1.3.24 z dynamicznym modułem PHP v. 4.1.2 . Serwer OpenLDAP został zainstalowany w katalogu /usr/local/openldap a serwer Apache w katalogu /usr/local/apache.
Ogólnie, przygotowanie bazy danych wymaganej przez dany moduł sprowadza się do utworzenia bazy użytkowników o spójnej strukturze. Oznacza to, że dobrze jest zadbać o to, aby dane użytkowników (identyfikatory, hasła) przechowywane były w jednym poddrzewie bazy. Ułatwia to poźniejszą konfigurację, gdyż moduły autoryzacji często nie pozwalają na przeszukiwanie wielu poddrzew. Zwykle w poszukiwaniu użytkowników przeszukują one bazę LDAP w dół od podanego RDN-u (nie można podawać wielu RDN-ów). Dodatkowo można utworzyć poddrzewo zawierające nazwy grup, w przypadku chęci korzystania z autoryzacji opartej na przynależności użytkownika do danej grupy.
Dla celów niniejszego przeglądu przygotowana została baza o następującej strukturze:
dc=poczta,dc=umk,dc=pl - główny DN
ou=Osoby,dc=poczta,dc=umk,dc=pl - drzewo zawierające dane
użytkowników (dla celów autentykacji)
ou=Grupy,dc=poczta,dc=umk,dc=pl - drzewo zawierające definicje
grup
Przedstawimy definicję powyższych obiektów:
dn: dc=poczta,dc=umk,dc=pl
objectClass: top
objectClass: dcObject
objectClass: organization
o: Baza autoryzacji przez moduly Apache
dc: BA
dn: ou=Osoby,dc=poczta,dc=umk,dc=pl
ou: Osoby
objectClass: top
objectClass: organizationalUnit
dn: ou=Grupy,dc=poczta,dc=umk,dc=pl
ou: Grupy
objectClass: top
objectClass: organizationalUnit
Wpisy na poziomie ou=Osoby,dc=poczta,dc=umk,dc=pl są postaci:
dn: cn=jerzy,ou=Osoby,dc=poczta,dc=umk,dc=pl
objectclass: inetOrgPerson
cn: Jerzy Szymanski
sn: Szymanski
uid: jerzy
userPassword: {SSHA}rMk1TdWR8r1oiZllHFNQkApUBi+HUMOS
title: ml. programista
organizationName: PSU
streetAddress: Chopina 12/18
l: Torun
st: kujawsko-pomorskie
postalCode: 87-100
mail: Jerzy.Szymanski@umk.pl
telephoneNumber: +48566113372
roomNumber: 412
dn: cn=search,ou=Osoby,dc=poczta,dc=umk,dc=pl
objectclass: inetOrgPerson
cn: Search user
sn: Search
uid: search
userPassword: {SSHA}PBUXxVj+4cx4uncBDW5agCRexwVZCVSm
zaś na poziomie ou=Grupy,dc=poczta,dc=umk,dc=pl postaci
dn: cn=grupa1,ou=Grupy,dc=poczta,dc=umk,dc=pl
objectclass: top
objectclass: groupOfUniqueNames
cn: grupa1
description: Grupa Uczestnikow Projektu LDAP
uniquemember: cn=jerzy,ou=Osoby,dc=poczta,dc=umk,dc=pl
Kompilacja
Rozpakowujemy pakiet mod_auth_ldap-0.5.1.tar.gz do podkatalogu
src/modules w drzewie źródeł Apache.
Moduł rozpakuje się nam do podkatalogu mod_auth_ldap.
W katalogu tym należy skonfigurować moduł używając polecenia configure
.
Ustawiamy w systemie potrzebne zmienne środowiskowe:
export LDFLAGS="-L/usr/local/openldap/lib -L/usr/local/ssl/lib"
export INCLUDES="-I/usr/local/openldap/include -I/usr/local/ssl/include"
LDFLAGS - powinna wskazywać na miejsce, w którym w systemie przechowywane
są biblioteki OpenLDAP
INCLUDES - powinna wskazywać na miejsce przechowywania plików nagłówkowych
dla biblioteki
Opcjonalnie dodaliśmy analogiczne wskazania także dla bibliotek i plików nagłówkowych pakietu SSL, gdyż zamierzamy skompilować Apache z obsługą SSL.
Poniższe komendy wykonane w katalogu ze źródłami Apache skonfigurują nam i statycznie skompilują serwer WWW wraz z modułem mod_auth_ldap.
./configure --prefix=/usr/local/apache --enable-module=so -enable-module=ssl --activate-module=src/modules/mod_auth_ldap/mod_auth_ldap.c
make
Z naszego punktu widzenia istotna jest opcja --activate-module=src/modules/mod_auth_ldap/mod_auth_ldap.c dołączająca nasz moduł do kompilacji Apache.
Konfiguracja
Gdy mamy już skompilowany serwer Apache wraz z modułem możemy chronić wybrane katalogi naszego serwera WWW korzystając z dyrektywy <Directory> serwera Apache. W pliku httpd.conf serwera Apache dla chronionego katalogu wpisujemy klauzulę
<Directory /usr/local/apache/htdocs/ldap>
...
</Direcory>
w obrębie której dostępne są następujące dyrektywy:
Poniżej podajemy przykładową konfigurację dla serwera Apache pozwalającą chronić katalog /usr/local/apache/htdocs/ldap za pomocą omawianego modułu.
<Directory /usr/local/apache/htdocs/ldap>
AuthName "Tylko dla wtajemniczonych"
AuthType Basic
AuthLDAPHosts ldap.uci.uni.torun.pl:389
AuthLDAPBindAsUser on
AuthLDAPBaseDN "ou=Osoby,dc=poczta,dc=umk,dc=pl"
AuthLDAPUserKey cn
AuthLDAPSearchScope onelevel
AuthLDAPSchemePrefix on
require valid-user
</Directory>
Powyższa konfiguracja na serwerze spowoduje, że w trakcie próby dostępu do stron WWW umieszczonych w katalogu /usr/local/apache/htdocs/ldap moduł wykona próbę dowiązania do bazy LDAP umieszczonej na komputerze ldap.uci.uni.torun.pl jako DN cn=username,u=Osoby,dc=poczta,dc=umk,dc=pl.
Ustawień powyższych można dokonywać także w pliku .htaccess w chronionym katalogu. Należy jednak pamiętać aby włączyć tę możliwość za pomocą dyrektywy AllowOverride.
Kompilacja
Rozpakowujemy pakiet mod_auth_ldap.tar.gz do podkatalogu src/modules
w drzewie źródeł Apache.
Moduł rozpakuje się nam do podkatalogu modauthldap. W
katalogu tym należy skonfigurować moduł.
Lokalizację bibliotek OpenLDAP oraz plików nagłówkowych
podajemy w pliku mod_auth_ldap.module. W naszej sytuacji
w odpowiednim miejscu w pliku wystarczy dopisać
LDAP_INCLUDES='-I/usr/local/openldap/include'
LDAP_LIBS='-L/usr/local/openldap/lib -lldap -llber'
Przy pierwszym podejściu do kompilacji warto w kodzie modułu w pliku mod_auth_ldap.c odkomentować dyrektywę
#define DEBUG_LDAP 1
dzięki czemu w trakcie pracy moduł będzie generował logi do pliku.
Poniższe komendy wykonane w katalogu ze źródłami Apache skonfigurują nam i statycznie skompilują serwer WWW z modułem mod_auth_ldap.
./configure --prefix=/usr/local/apache --enable-module=so -enable-module=ssl --activate-module=src/modules/modauthldap/mod_auth_ldap.c
make
Z naszego punktu widzenia istotna jest opcja --activate-module=src/modules/modauthldap/mod_auth_ldap.c dołączająca nasz moduł do kompilacji Apache.
Alternatywnie, możliwe jest skompilowanie modułu jako dynamiczny moduł Apache. W tym celu należy w katalogu modauthldap wydać polecenie
/usr/local/apache/bin/apxs -c -I/usr/local/openldap/include -L/usr/local/openldap/lib -lldap -llber mod_auth_ldap.c
Konfiguracja
Standardowo już, w pliku httpd.conf serwera Apache dla chronionego katalogu wpisujemy klauzulę
<Directory /usr/local/apache/htdocs/ldap>
...
</Direcory>
w obrębie której dostępne są następujące dyrektywy:
Jeśli autentykacja powiedzie się, moduł ustawia dwie zmienne środowiskowe:
LDAP_USER
MOD_AUTH_LDAP_VERSION
zawierające odpowiednio identyfikator użytkownika i wersję modułu.
Poniżej podajemy przykładową konfigurację dla serwera Apache pozwalającą chronić katalog /usr/local/apache/htdocs/ldap za pomocą omawianego modułu.
<Directory /usr/local/apache/htdocs/ldap>
AuthName "Tylko dla wtajemniczonych"
AuthType Basic
LDAP_Server ldap.uci.uni.torun.pl
LDAP_Port 389
Base_DN "dc=poczta,dc=umk,dc=pl"
Bind_DN "cn=search,ou=Osoby,dc=poczta,dc=umk,dc=pl"
Bind_Pass "search"
UID_Attr uid
require group cn=grupa1,ou=Grupy
</Directory>
Powyższa konfiguracja na serwerze spowoduje, że w trakcie próby dostępu do stron WWW umieszczonych w katalogu /usr/local/apache/htdocs/ldap moduł wykona próbę dowiązania do bazy LDAP umieszczonej na komputerze ldap.uci.uni.torun.pl jako DN cn=search,ou=Osoby,dc=poczta,dc=umk,dc=pl, rozpocznie przeszukiwanie drzewa bazy od podanego Base_DN i pozwoli na dostęp tym użytkownikom (spośród tych którzy podadzą prawidłowy identyfikator i hasło), którzy należą do grupy grupa1.
Wygodnym rozwiązaniem, które wnosi ten moduł w stosunku do poprzedniego
jest to, ze pozwala na autentykację ze względu na filtr LDAP.
Pozwala to przy odpowiednich założeniach na bazę LDAP, wyszczególniać
uprawnione osoby ze względu na przynależność do "naturalnych" grup, np.
osoby pracujące w tym samym pomieszczeniu można objąć filtrem "(roomNumber=412)".
Kompilacja
Rozpakowujemy plik mod_ldap1.8.c.tar.gz do podkatalogu src/modules
w drzewie źródeł Apache.
Cały moduł to jeden plik mod_ldap.1.8.c. W src/modules
zakładamy podkatalog mod_ldap, w którym umieszczamy plik
modułu. Dla wygody zmieniamy nazwę pliku na mod_ldap.c. Dodatkowo
zakładamy w tym miejscu plik Makefile.tmpl o zawartości:
$(OBJS) $(OBJS_PIC): Makefile
mod_ldap.o: mod_ldap.c
Następnie w pliku src/Configuration.tmpl w drzewie serwera
Apache specyfikujemy lokalizację bibliotek OpenLDAP.
W naszej sytuacji w odpowiednim miejscu w pliku wystarczy dopisać:
EXTRA_LIBS=-llber -lldap
Jak zwykle podajemy też (najlepiej w zmiennych środowiskowych LDFLAGS oraz
INCLUDES) lokalizację bibliotek i plików nagłówkowych
bibliotek SSL oraz OpenLDAP.
Dopiero teraz możemy przystąpić do konfiguracji serwera Apache.
Poniższe komendy wykonane w katalogu ze źródłami Apache skonfigurują nam i statycznie skompilują serwer WWW z modułem mod_auth_ldap.
./configure --prefix=/usr/local/apache --enable-module=so -enable-module=ssl --activate-module=src/modules/modauthldap/mod_ldap.c
make
Konfiguracja
W pliku httpd.conf serwera Apache dla chronionego katalogu wpisujemy klauzulę
<Directory /usr/local/apache/htdocs/ldap>
...
</Direcory>
w obrębie której dostępne są następujące dyrektywy:
Poniżej podajemy przykładową konfigurację dla serwera Apache pozwalającą chronić katalog /usr/local/apache/htdocs/ldap za pomocą omawianego modułu.
<Directory /usr/local/apache/htdocs/ldap>
AuthName "Tylko dla wtajemniczonych"
AuthType Basic
LDAPAuth on
LDAPServer "ldap://ldap.uci.uni.torun.pl:389"
LDAPBindName cn=search,ou=Osoby,dc=poczta,dc=umk,dc=pl
LDAPBindPass search
LDAPBase "ou=Osoby,dc=poczta,dc=umk,dc=pl"
LDAPuseridAttr uid
require valid-user
</Directory>
Konfiguracja powyższa realizuje identyczne zadanie jak w poprzednio omawianym
module przy czym autoryzowany będzie każdy użytkownik, którego wpis znajduje
się w bazie LDAP i który poprawnie dokona autentykacji (poda poprawną nazwę
użytkownika i hasło).
Kompilacja
Rozpakowujemy plik auth_ldap-1.6.0.tar.gz. Pakiet rozpakuje się nam do podkatalogu auth_ldap-1.6.0. Zgodnie z zaleceniem autora konfigurujemy moduł jako dynamiczny moduł Apache. W katalogu auth_ldap-1.6.0 wykonujemy:
./configure --with-apxs=/usr/local/apache/bin/apxs --with-ldap-sdk=openldap
--with-sdk-headers=/usr/local/openldap/include --with-sdk-libs=/usr/local/openldap/lib
--with-activate
i kompilujemy
make
a następnie instalujemy moduł w odpowiednim miejscu (standardowo
w katalogu libexec w drzewie Apache) poleceniem
make install
Opcja --with-activate polecenia configure sprawi, że powyższa komenda spowoduje włączenie modułu w pliku conf/httpd.conf serwera Apache, dokładniej w pliku konfiguracyjnym serwera WWW zostanie automatycznie dołączona opcja
LoadModule auth_ldap_module libexec/auth_ldap.so
Konfiguracja
W pliku httpd.conf serwera Apache dla chronionego katalogu wpisujemy klauzulę
<Directory /usr/local/apache/htdocs/ldap>
...
</Direcory>
w obrębie której dostępne są następujące dyrektywy:
Poniżej podajemy przykładową konfigurację dla serwera Apache pozwalającą chronić katalog /usr/local/apache/htdocs/ldap za pomocą omawianego modułu.
<Directory /usr/local/apache/htdocs/ldap>
AuthName "Tylko dla wtajemniczonych"
AuthType Basic
AuthLDAPURL ldap://ldap.uci.uni.torun.pl:389/ou=Osoby,dc=poczta,dc=umk,dc=pl
AuthLDAPBindDN cn=search,ou=Osoby,dc=poczta,dc=umk,dc=pl
AuthLDAPBindPassword search
AuthLDAPRemoteUserIsDN on
AuthLDAPStartTLS on
require valid-user
</Directory>
Konfiguracja powyższa realizuje identyczne zadanie jak w poprzednio omawianym
module przy czym włączono opcje użycia TLS i zażądano ustawienia po autentykacji
zmiennej REMOTE_USER na pełny DN użytkownika.
Kompilacja
Rozpakowujemy plik mod_authz-ldap-0.21.tar.gz. Pakiet rozpakuje
się nam do podkatalogu mod_authz_ldap-0.21.
Następnie ustawiamy w systemie potrzebne do konfiguracji i kompilacji
zmienne środowiskowe:
export CPPFLAGS=-I/usr/local/openldap/include
export LDFLAGS=-L/usr/local/openldap/lib
Ponieważ nowsze wersje modułu są przeznaczone wyłącznie do kompilacji dynamicznej
w katalogu mod_authz_ldap-0.21 wykonujemy (dodatkowo warto przy
testowej kompilacji włączyć debugowanie):
./configure --with-openssl-path=/usr/local/ssl --with-apxs=/usr/local/apache/bin/apxs
--with-debug
i kompilujemy
make
a następnie kopiujemy moduł w odpowiednie miejsce (standardowo
do katalogu libexec w drzewie Apache) oraz dodajemy w pliku
konfiguracyjnym Apache wpis:
LoadModule authz_ldap_module libexec/mod_authz_ldap.so
Konfiguracja
W pliku httpd.conf serwera Apache dla chronionego katalogu wpisujemy klauzulę
<Directory /usr/local/apache/htdocs/ldap>
...
</Direcory>
w obrębie której dostępne są następujące dyrektywy:
(issuer, subject)
lub też
(issuer, serial).
Patrz: Uwagi dotyczące certyfikatów. Domyślna
wartość off.
numeru seryjnego certyfikatu
zamiast pola subject. Domyślna wartość off.AuthzLDAPUser*
należy w dyrektywie
podać pełny DN użytkownika.groupOfNames
. Dodatkowe parametry dla
obsługi grup ustalają dyrektywy AuthzLDAPGroupBase, AuthzLDAPGroupKey,
AuthzLDAPGroupScope, AuthzLDAPMemberKey.
require owner
require group-owner
--with-owner
programu configure.
Autentykacja
tymi metodami nie jest jednak efektywna i zalecana, gdyż zwykle serwer WWW
pracuje z niskimi przywilejami i może nie być uprawniony do sprawdzania parametrów
plików.Aby używać autentykacji z użyciem certyfikatów klienta należy w w przypadku
serwera OpenLDAP dołączyć do jego plików schematów następujący schemat
authzldap.schema:
attributetype ( 1.3.6.1.4.1.4263.5.1 NAME 'issuerDN'
DESC 'The user friendly version of the distinguished name of the
issuer of a certificate'
EQUALITY caseExactIA5Match
SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.4263.5.2 NAME 'subjectDN'
DESC 'The user friendly version of the distinguished name of
the subject of a certificate'
EQUALITY caseExactIA5Match
SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE )
objectclass ( 1.3.6.1.4.1.4263.5.3 NAME 'authzLDAPmap'
DESC 'Map Entry for mod_authz_ldap'
SUP top AUXILIARY
MUST ( issuerDN $ owner )
MAY ( subjectDN $ serialNumber $ userCertificate )
Schemat ten możemy znaleźć w pakiecie modułu w podkatalogu ldap.
W bazie LDAP należy też umieścić skrócony opis certyfikatów klientów analogiczny
z poniższym:
dn: ou=AuthzLDAPCertmap,dc=poczta,dc=umk,dc=pl
objectclass: top
dn: cn=jerzy,ou=AuthzLDAPCertmap,dc=poczta,dc=umk,dc=pl
objectclass: top
objectclass: authzLDAPmap
issuerDN: /C=PL/ST=kujawsko-pomorskie/L=Torun/O=UMK/OU=UCI/CN=Jerzy Szymanski/Email=Jerzy.Szymanski@uni.torun.pl
subjectDN: /C=PL/ST=kujawsko-pomorskie/L=Torun/O=UMK/OU=UCI/CN=Jerzy Szymanski/Email=jerzy@umk.pl
owner: cn=jerzy,ou=Osoby,dc=poczta,dc=umk,dc=pl
W konfiguracji Apache należy wtedy dodać dyrektywy wzorem:
SSLRequireSSL
AuthzLDAPUseCertificate on
AuthzLDAPMapBase ou=AuthzLDAPCertmap,dc=poczta,dc=umk,dc=pl
AuthzLDAPMapScope subtree
require valid-user
Poniżej podajemy przykładową konfigurację dla serwera Apache pozwalającą
chronić katalog /usr/local/apache/htdocs/ldap za pomocą omawianego modułu.
<Directory /usr/local/apache/htdocs/ldap>
AuthName "Tylko dla wtajemniczonych"
AuthType Basic
AuthzLDAPServer ldap.uci.uni.torun.pl:389
AuthzLDAPBindDN cn=search,ou=Osoby,dc=poczta,dc=umk,dc=pl
AuthzLDAPBindPassword search
AuthzLDAPLogLevel debug
require valid-user
</Directory>
Konfiguracja powyższa realizuje identyczne zadanie jak w poprzednio omawianym module.
8. Warto przyglądać się pracom związanym z Apache 2.x. Do wersji 2.0.41 i wyższych równolegle z serwerem Apache powstaje moduł do autentykacji przy wsparciu LDAP. Niestety na razie jest to wersja eksperymentalna. Wspiera jednak SSL (dla Netscape SDK) oraz TLS (dla OpenLDAP 2.x SDK). Patrz. Polecane linki.
[RFC1960]
T. Howes, A
String Representation of LDAP Search Filters, Request for Comments 1960,
June 1996.
[RFC2255] T. Howes, M.Smith, The LDAP URL format, Request for Comments
2255, December 1997.
[RFC2307]
L. Howard, An Approach for Using LDAP as a Network Information Service,
Request for Comments 2307, March 1998.
http://httpd.apache.org/docs-2.0/mod/mod_auth_ldap.html - dokumentacja modułu autoryzacji via LDAP dla Apache od wersji 2.0.41 wzwyż.