Wednesday 31 March 2010

OpenLdap proxy ActiveDirectory 2003

Stanąłem przed problemem migracji usług katalogowych książki adresowej i telefonicznej opartej na OpenLdap do środowiska domeny Windows na Active Directory 2003. Chodziło to to by pozbyć się unix'owego ldap'a bez miany konfiguracji kilkuset komputerów oraz drukarek skanujących na mail'a i by system zaczął odpytywać kontrolery domeny. W sieci znalazłem trochę informacji na ten temat jednak najciekawsze artykuły były dostępne wyłącznie odpłatnie więc zdecydowałem się posiedzieć nad tym osobiście.

Postanowiłem zrobić to za pomocy proxy ldap jednak środowisko na którym mogłem to zrobić nie posiadało w miarę nowej wersji openldap i musiałem go odpowiednio ręcznie przekompilować z nowszych źródeł. Wziąłem zatem OpenLdap ver. 2.4.21.

Proxy podłączone do kontrolera domeny wymusza konieczność włączenia autoryzacji w openldap'ie bowiem Active Directory 2003 nie pozwala domyślnie na anonimowe odpytywanie swoich usług katalogowych (i słusznie) dlatego do tych celów należy utworzyć w AD2003 specjalne konto zwykłego użytkownika z niewygasającym hasłem - tym kontem będziemy bindować się do domeny.

Zacznijmy od konfiguracji i kompilacji (lub ściągnięcia i instalacji gotowej paczki) OpenLdap:
$>tar -zxvf openldap-stable-20100219.tgz 
$>cd openldap-2.4.21
$>./configure --enable-backends=no --enable-ldap=yes --enable-rewrite=yes \
--enable-relay=yes --enable-overlays=yes --with-cyrus-sasl=yes \
--enable-ipv6=no --enable-proxycache --with-threads --with-tls
$>make depend
$>make
$>make install
$>make clean

Nie potrzebowałem żadnego natywnego backend'u oprócz ldap. Potrzebowałem wkompilować reguły przepisywania (rewrite), przekazywania (relay), nadpisywania (overlay), proxy (proxycache) i wątków (threads). Pozostałe są przydatne opcjonalnie.

Wątki są niezbędne by daemon mógł w swoim drugim wątku przychodzące zapytanie przekierować do AD2003 i odpytać zewnętrzny inny ldap. Reguły nadpisywania były mi potrzebne do dynamicznej zmiany suffixu drzewa ldap ze starego na nowy bez konieczności rekonfiguracji mnóstwa komputerów.

Plik konfiguracji daemon'a slapd.conf wygląda następująco:
# $OpenLDAP: slapd.conf,v 1.24.21 2010/03/27 11:19:14 saphire Exp $
#
# See slapd.conf(5) for details on configuration options.
# This file should NOT be world readable.
#
include         /usr/local/etc/openldap/schema/core.schema
include         /usr/local/etc/openldap/schema/cosine.schema
include         /usr/local/etc/openldap/schema/inetorgperson.schema
include         /usr/local/etc/openldap/schema/nis.schema
include         /usr/local/etc/openldap/schema/misc.schema

pidfile         /var/run/slapd.pid
argsfile        /var/run/slapd.args

loglevel 832

# Load dynamic backend modules:
moduleload      back_ldap.la

# also allowed prot
allow bind_v2

# ldbm database definitions
defaultsearchbase       "dc=ad2003,dc=windows,dc=domain,dc=in,dc=pl"

database        ldap

#old unix ldap suffix
suffix          "dc=ldap,dc=unix,dc=domain,dc=in,dc=pl"

# connect to domain controller to ldaps

# full ldap access (possible outlook errors)
#uri             "ldaps://srv.ad2003.windows.domain.in.pl"

# limited attributed access (no outlook errors)
uri             "ldaps://srv.ad2003.windows.domain.in.pl:3268"

# no modification datetime becouse we do not change attributes
lastmod         off

# no refferrals
rebind-as-user no
chase-referrals no

#how to bind to AD2003 ldap (simple or sasl)
idassert-bind   bindmethod=simple
                binddn="CN=someaccount,OU=somecontainer,DC=ad2003,dc=windows,dc=domain,dc=in,dc=pl"
                credentials="stro-ng.passw0rd"
                authzID="dn:CN=CN=someaccount,OU=somecontainer,DC=ad2003,dc=windows,dc=domain,dc=in,dc=pl"
                mode=self

idassert-passwd "stro-ng.passw0rd"

authz-policy            from
idassert-authzFrom      "*"

# Define global ACLs to disable default read access.
access to dn.base="dc=ldap,dc=unix,dc=domain,dc=in,dc=pl" by * read
access to dn.base="dc=ad2003,dc=windows,dc=domain,dc=in,dc=pl" by * read
access to dn.subtree="dc=ad2003,dc=windows,dc=domain,dc=in,dc=pl" by * read
access to dn.subtree="dc=ldap,dc=unix,dc=domain,dc=in,dc=pl" by * read

access to *
 by self read
 by users read
 by anonymous read

access to * by * read

# overlay rules
overlay rwm

rwm-suffixmassage       "dc=ldap,dc=unix,dc=domain,dc=in,dc=pl" "dc=ad2003,dc=windows,dc=domain,dc=in,dc=pl"
rwm-map attribute       sAMAccountName *
rwm-map attribute       cn *
rwm-map attribute       givenName *
rwm-map attribute       mail *
rwm-map attribute       sn *
rwm-map attribute       department *
rwm-map attribute       description *
rwm-map attribute       title *
rwm-map attribute       physicalDeliveryOfficeName *
rwm-map attribute       displayName *
rwm-map attribute       company *
rwm-map attribute       telephoneNumber *
#rwm-map attribute       co *
rwm-map attribute       countryname co
rwm-map attribute       workurl wWWHomePage
rwm-map attribute       name *
rwm-map attribute       mobile *
rwm-map attribute       homePhone *
rwm-map attribute       ipPhone *
rwm-map attribute       pager *
rwm-map attribute       info *
rwm-map attribute       facsimileTelephoneNumber *
rwm-map attribute       orgunit *
rwm-map attribute       postalCode *
rwm-map attribute       postOfficeBox *
rwm-map attribute       streetAddress *
rwm-map attribute       l *
rwm-map attribute       st *

#disable other attributes
rwm-map attribute       *

Oczywiście daemona startujemy w standardowy sposób dla systemu na którym go instalujemy (skrypty startowe itp.).

Komputery posiadają nadal starą bazę wyszukiwania ldap: "dc=ldap,dc=unix,dc=domain,dc=in,dc=pl" slapd w locie podmienia ja na nową domenową: "dc=ad2003,dc=windows,dc=domain,dc=in,dc=pl" tak więc niczego nie musiałem modyfikować na komputerach.

Slapd łączy się do kontrolera domenowego i binduje dedykowanym kontem "someaccount" z hasłem, odpytuje AD2003 o niektóre atrybuty i zwraca wyniki do anonimowo podłączonych do niego klientów.

Część z rozszerzonych atrybutów jest dostępnych tylko przy bindowaniu do standardowego portu ldap lub ldaps (wymaga instalacji certyfikatu na kontrolerze domeny bo tylko wtedy po restarcie wstanie usługa ldaps). Wtedy jednak ze względu na zabezpieczenia w AD2003 klienci typu Outlook wyświetlają błąd "Operation error" pomimo że zatwierdzenie go skutkuje wyszukaniem i wyświetleniem znalezionych danych. Jest to pochodna współistnienia "global catalog" wraz ze zwykłym ldap'em na kontrolerze domeny.

Jest to trochę denerwujące tym bardziej że np. Mozilla Thunderbird działa poprawnie i bez tego błędu. Dlatego też rezygnując z części rozszerzonych atrybutów można przestawić slapd na podłączenie do standardowego ldap'a na port 3268 a wtedy nie ma błędu i są tylko podstawowe dane kontaktowe (jednak w zupełności wystarczające). Alternatywą jest także zmiana zasad przeszukiwania AD2003 atrybutem dsHeuristics jednak ja wolę nie ingerować zbytnio w schemat domenowy.

Dodatkowo można także firewallem ograniczyć dostęp do naszego unix'owego proxyldap dla wybranego zakresu adresów itp. itd.

Przydatne linki o ldap w AD2003:
OpenLdap.org
Anonymous LDAP operations to Active Directory are disabled on Windows Server 2003 domain controllers
Active Directory Services Interface in the Microsoft Exchange 5.5 Environment
DS-Heuristics Attribute