Systémy pro sdílení uživatelů (LDAP)

Vlastimil Krejčíř, xkrejci4@fi.muni.cz


Obsah


Co je to obecně

Terminologie, architektura

Adresář je speciální databáze optimalizovaná pro čtení, procházení a vyhledávání dat. Běžným příkladem takového adresáře může být například katalog knih nebo telefonní seznam. Předpokládá se, že telefonní čísla se nemění příliš často a stejně tak seznam knih v knihovně. Obecněji se takový adresář skládá z jednoznačně identifikovatelných položek, každá položka se pak skládá z atributů (přičemž u každé položky musí být alespoň jeden atribut). Atributy jsou různých typů určujících možné hodnoty atributu. Cílem takto zavedené architektury je usnadnit maximálně rychlý a jednoduchý přístup k informacím.

Jak to pracuje

Práce s adresářem je postavena na modelu klient-server. Klientská aplikace pro přístup k adresáři pošle požadavek na adresářový server, ten ho vyhodnotí a posílá zpátky.


Standardy, protokoly (historické souvislosti)

X.500

Rodina standardů definujících adresářové služby, práci s nimi, jejich chování a další. Vše je definováno nad referenčním síťovým modelem ISO.OSI (klasických 7 vrstev, viz. přednášky doc. Staudka :-)). Konkrétně se jedná o dokumenty X.500 až X.521. Definují nad klasickou architekturou klient-server protokol DAP (Directory access protocol). Protože model ISO.OSI je zbytečně složitý a v podobě, jak byl navržen, se prakticky neimplementuje, vznikl "odlehčený" protokol tzv. LDAP (Lightweight DAP).

LDAP

Verze 1 protokolu je definována v RFC 1478 a je skutečně postavena na DAP jen s tím rozdílem, že je jednodušší - komunikace však musí stále probíhat s plnohodnotným X.500 serverem. Následující verze 2 a 3 se protokol se plně osamostatnili a již nevyžadují podporu DAP podle X.500. Rozdíly mezi verzemi 2 a 3 budou popsány dále. Verze 2 je popsána v v následujících RFC: 1777-1779, 1959, 1960. Verze 3 pak v RFC 2251-2256.

LDAP je definován nad TCP/IP (na rozdíl od ISO.OSI DAPu). Dále oproti DAPu vypustil několik specializovaných operací a některé operace sloučil do jedné a pro reprezentaci jmen používá textové řetězce (X.500 definuje složité struktury pro totéž).


LDAP protokol

Průběh komunikace

Interakce mezi klientem a serverem probíhá v několika krocích. Klient naváže spojení se serverem (binding), v této fázi probíhá autentizace. Následně může klient provádět různé operace nad adresářem. Nakonec proběhne ukončení spojení (unbinding).

Atributy, typy

Protokol definuje typy atributů, typ určuje jaká syntax je pro zapsání hodnoty použita, jak se bude atribut při různých operacích chovat a podobně. Atributy mohou mít pro přehlednost aliasy. Atribut může být binárního typu (bin), řetězec znaků (cis je non-case sensitive a ces je case sensitive), typ rozlišovací jméno (dn) nebo třeba typ telefonní číslo (tel). Toto jsou některé vybrané základní typy. Běžně užívanými atributy jsou pak například commonName alias cn je typu cis (jméno například zaměstnance), owner je typu dn (rozlišovací jméno osoby vlastnící položku) a další.

Co je to Schema

Schema je množina pravidel nad adresářem - rozhoduje o počtech, typech, významem a jiných vlastnostech položek a atributů v adresáři. Především definuje třídy objektů (object classes), určující jaké položky (objekty) mohou být uloženy v adresáři. Třída určuje počet a typ atributů, které se mohou v položce nacházet (kontrola probíhá procesem zvaným schema-checking). Každá položka (objekt) pak má povinný atribut objectClass, určující v jaké třídě se položka nachází. Třídy mohou samozřejmě dědit od jiných tříd (objektový model), přičemž je definována nejvyšší třída, která má jediný atribut a tím je právě objectClass, od této třídy (nazývané top) pak musí být odvozeny všechny třídy ostatní. Aby byla možná spolupráce mezi LDAP servery (každý z nich může mít nadefinováno vlastní schéma) existuje několik standardizovaných schemat. Pokud klient schema adresáře nezná, dotazuje se na speciální položku.

LDIF

LDIF je textový formát pro výměnu dat mezi LDAPím adresářem a čímkoli jiným. Aneb jakákoli data lze převést do LDIFu a následně pomocí standardních klientů vložit do LDAPího adresáře.

Organizace položek

Položky jsou organizovány ve stromové struktuře zvané Direct Information Tree (DIT). Každá položka je identifikována svým jednoznačným rozlišovacím jménem (distinguished name - DN). Rozlišovací jméno se tvoří hierarchicky podobným procesem jako třeba IP adresy, jen syntaxe je jiná. Typicky <atribut1>=<hodnota1>, <atribut2>=<hodnota2>, ..., přičemž každá dvojice atribut-hodnota se nazývá Relative DN (RDN). Suffixem se pak nazývá jméno nejvýše umístěné položky na daném serveru. Existuje i speciální položka zvaná referral, která může fungovat jako odkaz na DIT v jiném adresáři - tím to způsobem se spravují distribuované LDAP servery (mohu například odkazovat na nejvyšší položku v nějakém vzdáleném adresáři).

Operace na adresářem

Můžeme získávat operace z adresářového stromu (operace search a compare) a měnit položky ve stromě (add, delete, modify a modify RDN). Speciálními operacemi jsou pak autentizační služby (bind, unbind a abandon).

Operace search dovoluje prohledávat určité podstromy DIT do dané hloubky. Jejím výsledkem je vrácení nalezených dat (neexistuje něco jako operace read, vše je zakomponováno do search). Lze samozřejmě určit, které z atributů se mají vracet. Vyhledávací výraz (filtr) lze konstruovat pomocí obvyklých booleovských operátorů plus některých speciálních relací (například ~= znamená "přibližně stejná hodnota"). Operace compare je naproti tomu jednodušší, pouze porovná zadanou hodnotu s hodnotou nějakého atributu. Ostatní výše uvedené operace mají obvyklou sémantiku.

Protokol není omezen na jmenované operace. Lze vytvářet nové operace, popř. měnit ty stávající (seznam dostupných operací vypíše LDAP server při dotazu na speciální položku nazývanou root DSE).

Zabezpečení komunikace

LDAP podporuje komunikaci klasicky na úrovni TCP/IP přes SSL. Autentizace buď není žádná (obvykle jsou-li položky adresáře přístupné všem), nebo probíhá na úrovni ověřování DN vlastníka položky a jeho hesla (zahashovaného) a nebo proběhne pomocí SASL (Simple Authentication and Security Layer, RFC2222).


LDAP v UN*Xu a autentizace

Proč se ovšem tím vším okolo LDAPu zaobírat? Vtip je v tom, že pomocí LDAPu lze autentizovaně spravovat jakékoli informace. A také lze pomocí něj řešit centrální správu uživatelů v unixových systémech. V principu nejsou informace o uživatelích a skupinách v /etc/passwd (/etc/shadow) a /etc/group, ale nacházejí se na nějakém LDAP serveru. Při přihlašování na daný unixový stroj je pak uživatel kontrolován nikoli s /etc/passwd, ale s informacemi na LDAP serveru. Odpadá tak práce s uživatelskými účty rozstrkanými po všech stanicích a vše je uloženo pouze na jednom (popř. několika) místech. Tutéž srandu můžete udělat s /etc/services, /etc/limits etc. etc. :-)

V adresáři budeme mít položky s atributy jako uid, uidNumber, gidNumber, loginshell a další, které se uživatelského účtu týkají. To vše je určeno schematem nis, které bývá dodáváno s implementací LDAPu. V tomto schématu jsou již definovány příslušné třídy, které strukturu uživatelského účtu v LDAP adresáři definují (např. posixAccount, shadowAccount).


OpenLDAP

V současnosti je k dispozici několik implementací LDAPu, zejména komerčních (od oblíbeného Microsoftu, přes Sun a IBM až po třeba Novell). Stačí si jen vybrat - nutnou a netriviální podmínkou je být v balíku. Pro nás zajímavější je však OpenLDAP, který je zadarmo, a kterému se budu nadále věnovat.

OpenLDAP je projekt na vytvoření open source balíku implementujícího vše potřebné pro provoz LDAP serverů, který by se vyrovnal dostupným komerčním řešením. Je dostupný zdarma na http://www.openldap.org/ a obsahuje vše potřebné (knihovny, servery, klientské aplikace).


Instalace OpenLDAPu

Instalace asi záleží na distribuci. Já mám lehce masochistickou "distribuci" LFS, takže jsem překládal a dělal všechno ručně. Proto popíšu, jak tímhle univerzálním způsobem na to a to pro verzi 2.2.6. Hodit se vám budou knihovny OpenSSL, SASL, BerkeleyDB (pozor, u poslední verze jsou dva patche, já je raději použil) nebo GDBM a v neposlední řadě to chce mít nějakou podporu vláken (to už je dneska snad v každé distribuci). Podrobnosti najdete na stránkách OpenLDAPu. Rozhodně to není úplný výčet toho, co je potřeba, spíš to berte tak, že konkrétně tyhle věci jsem musel doinstalovat já.

Kvůli autentizaci uživatele budete potřebovat knihovnu PAM a pro získávání informací o uživateli (jeho login, home adresář atd.) budete potřebovat NSS pro LDAP. Ve skutečnosti by vám k centrální správě stačil jen ten NSS (Name Service Switch), ale pak by chodily po síti i hesla v otevřené podobě, což není zrovna bezpečné.

Nepříjemné může být to, že nemáte přeloženy programy jako login a passwd s podporou PAMu. Pak vám nezbude než znovu přeložit balík Shadow.

Zmíním některé zajímavé parametry, které je dobré předhodit ./configure skriptu a které jsou defaultně nastaveny jinak, než je pro nás zdrávo. Doporučuji:

--enable-crypt - umožňuje hashovat hesla pomocí klasické funkce crypt(3)

--enable-slurpd - replikační démon, potřeba pro sdílení účtů více LDAP servery, defaultně se nepřekládá

--libexecdir=PATH - spíš jen informačně, pokud to nezadáte, tak se vám přeložené binárky nacpou někam do $PREFIX/etc/...

--enable-syslog - přeloží podporu syslogu

Kromě několik zajímavých prográmků se přeloží hlavně démon slapd (defaultně pak běží na portu 389).


Konfigurace OpenLDAPu

Zmíním zde příklad konfiguračního souboru, který se týká centrální správy uživatelů. V LDAPím adresáři lze skladovat prakticky cokoli, takže můžete narazit na spoustu jiných konfiguračních souborů, které budou fungovat. Tohle je jen jedna z možností.

Podle toho, jaký jste zadali při konfiguraci před překladem $PREFIX (nebo hodnotu parametru --sysconfdir, naleznete konfigurační soubor pro OpenLDAP démona, který se jmenuje slapd. Konfigurační soubor je obvykle v $PREFIX/etc/openldap a jmenuje se slapd.conf. Může vypadat takto:

database  	ldbm 
suffix          "dc=mylan,dc=net" 
rootdn          "cn=root,dc=mylan,dc=net" 
rootpw          {MD5}nejaky_hash_hesla 
index           objectClass,uid,uidNumber,gidNumber eq 
index           cn,mail,surname,givenname	    eq,subinitial 
password-hash	{crypt}
password-crypt-salt-format	"$1$%.8s" 

Po řadě definuje použitou backend databázi, suffix, rozlišovací jméno kořene (tedy v tomto případě jde o uživatele root), dále heslo pro root-a (použitý je hash MD5). index říká, které atributy se budou indexovat (pro rychlejší přístup), dále se určuje, hashování a formát hesla (hesla se budou kryptovat stejně jako v unixu, čili pomocí crypt(3)). Podrobnosti se dozvíte na stránkách OpenLDAPu.

Hash hesla můžete získat pomocí programu slappasswd. Parametrem určíte hashovací funkci. Program vás vyzve k vložení hesla, jeho potvrzení a výstupem je příslušný hash hesla. Například:

# slappasswd -h {MD5} 

vyhodí na výstup MD5 hash vloženého hesla. Více viz. manové stránky.

Dále je potřeba nastavit ACLs (Acces Control Lists), kterými určíme politiku přístupu uživatelů k účtům (uživatel si může měnit heslo, uživatel nesmí vidět účtu jiných uživatelů atd.). Nejdřív do slapd.conf přidáte řádek určující, kde se bude hledat soubor s politikami. Může to vypadat takto:

include /etc/openldap/slapd.access.conf

V daném adresáři pak vytvoříte soubor slapd.access.conf. Jeho obsah může vypadat následovně:

access to dn.regex=".*,dc=mylan,dc=net" attr=userPassword 
          by dn="cn=root,dc=mylan,dc=net" write 
	  by self write 
	  by * auth

access to dn.regex=".*,dc=mylan,dc=net" attr=mail 
          by dn="cn=root,dc=mylan,dc=net" write 
	  by self write 
	  by * read

access to dn.regex=".*,ou=People,dc=mylan,dc=net" 
          by * read

access to dn.regex=".*,dc=mylan,dc=net" 
          by self write 
	  by * read 

Nejdřív omezíme přístup k atributu uchovávajícímu hash hesla (userPassword). Čili zapisovat hesla může root (druhý řádek) a jejich vlastník (vlastník dané položky ~ účtu viz. třetí řádek). Hesla mohou být samozřejmě použita pro autentizaci všemi (by * auth). Další část se týká nastavení poštovních účtů, v následující části omezujeme uživatele, tak aby si nemohli měnit home adresář, login shell, uid a další. V poslední části pak nastavujeme, že si uživatel jinde v LDAPu může posloužit na svých záznamech jak je mu libo a ostatní může číst. Základní nastavení LDAP serveru tím máte dokončeno. Nyní můžete spustit slapd, popř. si připravit startovací skripty. Pro logování používá server syslog démona, defaultně je typ zprávy nastaven na local4, takže si nějak rozumně nastavte /etc/syslog.conf (popravdě řečeno, mně se to logování nějak nedařilo rozjet).

Konfigurace OpenLDAP klienta

Předchozí část se týkala nastavení serveru. Nyní je nutné nastavit i klientskou stranu (kde běží LDAP server zajišťující autentizaci a další). V souboru /etc/ldap.conf by mělo být asi toto:

host 127.0.0.1 
base dc=mylan,dc=net 
rootbinddn cn=root,dc=mylan,dc=net
scope one 
pam_filter objectclass=posixaccount 
pam_login_attribute uid
pam_member_attribute gid 
pam_password md5 
nss_base_passwd ou=People,dc=mylan,dc=net?one 
nss_base_shadow ou=People,dc=mylan,dc=net?one 
nss_base_group ou=Group,dc=mylan,dc=net?one 

Položka host udává IP, kde běží LDAP server, dané nastavení je pro počítač, který je zároveň serverem i klientem, v opačném případě musí být na daném místě plná IP (nebo FQDN). Hodnota položky base musí odpovídat suffixu, který je nastaven v konfiguračním souboru serveru /etc/openldap/slapd.conf. Ostatní položky musí korespondovat taktéž. Položka rootbinddn říká, kdo bude navazovat spojení s LDAP serverem (bind). Heslo musí být uloženo v /etc/ldap.secret, tento soubor musí být uložen s vlastníkem a skupinou root a musí mu být nastavena práva na 0600 (pouze rw pro roota). Heslo je tam uloženo přímo nezahashované a odpovídá tomu, jehož hash je uložen v konfiguračním souboru OpenLDAP serveru. POZOR, tento soubor musí končit až na druhém řádku (čili za heslem ještě <Enter>).

Konfigurace PAMu a NSS

Nejdříve NSS. Předpokládá se samozřejmě nainstalování nss_ldap knihovny (jinak se k LDAPu nedostanete). V souboru /etc/nsswitch.conf nastavíte pořadí místa, kde se postupně budou informace o uživatelských účtech hledat (kromě toho jsou tam i další věci, které nás momentálně nemusí trápit). Protože chceme, aby se informace o uživatelských účtech hledali nejdřív lokálně a pak v LDAPu, tak může konfigurace u příslušných položek vypadat třeba takto:

passwd:     files ldap
shadow:     files ldap 
group:      files ldap

Nyní konfigurace PAMu. Konfigurační soubory se nachází obvykle v /etc/pam.d/. Zbytek už se hodně liší distribuci od distribuce. Konfigurace a spol. byla probrána v jiném referátu, takže se tím nebudu nijak podrobně zabývat. Nicméně letecky například login:

auth        required      pam_nologin.so 
auth        sufficient    pam_ldap.so 
auth        sufficient    pam_unix.so shadow use_first_pass 
auth        required      pam_deny.so

account     sufficient    pam_unix.so 
account     sufficient    pam_ldap.so
account     required      pam_deny.so
a passwd:
password    required      pam_cracklib.so 
password    sufficient    pam_ldap.so 
password    sufficient    pam_unix.so 
password    required      pam_deny.so 

Příklady těchto konfiguračních souborů naleznete v adresáři pam.d po přeložení balíku pam_ldap. Klidně je můžete použít.

Chcete-li používat LDAP například i se Sambou a s SSL/TLS, doporučuji podívat se na tutoriál od Mandraků.


Migrace účtů

Jak na účty? Pro začátek je dobré použít pro migraci nějaký šikovný nástroj. Aplikaci, která dovede přečíst /etc/passwd, /etc/shadow a /etc/group, vytáhnout odtamtud údaje a převést je do LDIFu. Takové záznamy už můžete snadno importovat do LDAP databáze. Pravděpodobně naleznete na webu celou řadu nástrojů (hlavně různých perl skriptů je mnoho), které tohle umí. Například yap2lc (Yet Another Passwd 2 LDIF Converter), ten je napsaný v Céčku nebo perlovské Migration Tools. Zkoušel jsem druhý jmenovaný, je v něm k dispozici spousta skriptů na migraci všeho možného (shadow, networks, hosts, ...). Je potřeba nastavit nějaké údaje v konfiguračním souboru migrate_common.ph. Důležité je:

$DEFAULT_MAIL_DOMAIN = "mylan.net"; 
$DEFAULT_BASE = "dc=mylan,dc=net";
$DEFAULT_MAIL_HOST = "mail.mylan.net"; 
$EXTENDED_SCHEMA = 1;

Tyto hodnoty je třeba nastavit podle hodnot v konfiguračním souboru OpenLDAP serveru. Jednotlivé skripty dávají na výstup LDIF soubory, které pak za pomoci programu ldapadd vložíte do adresáře. Dále uvedu příklad, podrobnosti si můžete posléze nastudovat sami na příslušných stránkách (doporučuji v odkazech Tutoriál od Mandraků). Příprava adresáře a migrace shadow a group:

# ./migrate_base.pl >base.ldif 
# ldapadd -x -D "cn=root,dc=mylan,dc=net" -W -f base.ldif 
# ETC_SHADOW=/etc/shadow ./migrate_passwd.pl /etc/passwd passwd.ldif
# ldapadd -x -D "cn=root,dc=mylan,dc=net" -W -f passwd.ldif
# ./migrate_group.pl /etc/group group.ldif
# ldapadd -x -D "cn=cn=root,dc=mylan,dc=net" -W -f group.ldif

Výše zmíněné perlovské migrační skripty mají jednu nevýhodu - počítají i s tím, že máte nějaká schemata, která ovšem nejsou obsažena přímo v balíku s OpenLDAPem. Pak se připravte na to, že výsledné LDIF soubory budou chtít nějaké to SEDování. Ale záleží to asi distribuci od distribuce.


Klienti pro práci s adresářem

Spolu s OpenLDAP balíkem jsou dodávány programy ldapadd, ldapdelete a ldapsearch. Jsou to klasičtí řádkový klienti a práce s nimi není příliš pohodlná. Kromě toho existuje řada GUI klientů. Níže uvádím pár odkazů na ty použitelné. První dva jsem rozjel, třetí se mi nedařilo přeložit (něco se mu nelíbilo na mojí iconv knihovně), pokud máte distribuci s podporou rpm nebo deb, tak asi nebudete mít problém. Konkrétně ten java klient vypadá docela dobře, odzkoušel jsem ho, jde pěkně editovat položky, jednotlivé atributy, včetně nastavení a verifikace hesla.

gq - GTK klient pro práci s adresářem

LDAP Browser/Editor - Java klient

Directory Administrator


Replikace údajů (slurpd)

Pokud máte všechny uživatele pěkně na jedno místě, hrozí riziko, že zrovna daný počítač s ldap serverem nebude přístupný a tudíž se nikdo nenaloguje. Proto můžete používat sekundární LDAP servery. Kvůli uchování konzistence je nutno obsah serverů synchronizovat. K tomu slouží speciální démon zvaný slurpd. V praxi to vypadá tak, že tenhle démon jen čeká na změny (které čte ze speciálního souboru, do kterého ukládá informace o provedených operacích slapd), když nějakou změnu zjistí, přečte si, jaké operace byly provedeny a pošle požadavek na jejich provedení sekundárnímu LDAP serveru.

Stručně jak na to

Především je nutné v konfiguračním souboru LDAP serveru nastavit jestli se jedná o master nebo slave. U masteru to znamená přidat položky replica s příslušnými adresami sekundární LDAP serverů. Například:

replica uri=ldaps://slave.example.com:636
        binddn="cn=Replicator,dc=example,dc=com"
	bindmethod=simple credentials=secret

V konfiguračním souboru slave serveru nesmíte hlavně nastavovat žádné položky replica a replogfile. Dále musíte nastavit vazbu na primární server pomocí položky uptdatedn (odpovídá příslušnému binddn= v položce replica na straně masteru). Konečným krokem je nakopírování databáze primárního serveru na sekundární (záleží na použitém backendu).


Závěr

Závěrem nutno říct, že jsem se na tomhle tématu docela vydusil, protože jsem o něm nevěděl téměř nic (zapsal jsem si to, abych se to dobře naučil). Záměrně jsem volil poměrně dlouhý úvod do adresářových služeb, protože mám pocit, že se to v žádném předmětu neprobírá a neprobíralo ani ve Správě UNIXu II. (cca 2 roky zpět). Nicméně všechno jsem si vyzkoušel, na vlastním počítači (pro velký provoz a neustálé štěstí na HW krach počítačů jsem to nezkoušel v laborce) nakonfiguroval a popřekládal. Jen nevím proč mi nefunguje logování, takže nevím proč se mi nechce uživatel autentizovat. Možná něco z toho vyřeším ještě po odevzdání referátu. Ale jak jsem již zmínil i výše - všechno je to hodně závislé na distribuci Linuxu jakou používáte a jaký máte základ, proto při instalaci hodně doporučuji konzultovat stránky vaší distribuce. Výše zmíněné rady se týkají LFS 4.0. Spoustu problémů si hlavně ušetříte, pokud máte většinu věcí přeloženou už s PAMem. Každopádně instalaci na LFS like systémech doporučuji jen skalním, protože se nadřete jak koně (o to ovšem jde, že :-)).


Odkazy

Většinu odkazů uvádím u příslušných témat přímo v textu ...

OpenLDAP - kromě jiného je tam hlavně ten administrátorův průvodce

Tutoriál od Mandraků

Další tutoriálek - docela stručný, ale není dělaný na konkrétní distribuci

Beyond LFS - aneb jak přeložit správně v referátu zmiňované programy a knihovny

Google :-)