Co je LDAP?

LDAP je protokol pro výměnu dat z centrálního adresáře směrem ke klientům (další servery, uživatelé, apod.). Základním příkladem použití je třeba sdílení identity mezi e-mailem, firemním chatem, vzdáleným úložištěm a dalšími. My bychom se dnes podívali na jednu implementaci a to projekt OpenLDAP. LDAP protokol integruje také FreeIPA, který je také v repozitářích (a ke kterému bychom se rádi dostali v nějakém budoucím pokračování).

V této minisérii si vytvoříme centrální server a umožníme uživatelům se na námi spravovaných stanicích přihlašovat s jednotným uživatelským účtem.

Struktura adresáře LDAP

struktura ldap

Struktura ldap, taková jaké bychom chtěli dosáhnout.

Struktura je stromová, kreslí se typicky s kořenem nahoře. V terminologii se tak používá rodič, potomek. Každý prvek má nějaký druh/funkci. Prvky jsou jednoznačně rozlišitelné podle DN (distinguished name - rozlišovací jméno), které zároveň určuje pozici v daném stromu. Ačkoliv není nutné provozovat doménu k zprovoznění celé služby, vychází z ní (typicky) organizační struktura adresáře. Běžným příklade je třeba mojefirma.cz, my pro účely tohoto článku použijeme doménu mojefedora.cz

Instalace služby a první nakouknutí

Potřebuje několik balíčků, pohodlně si je nainstalujeme ze standardních repozitářů. Celý seriál byl tvořen pod účtem roota, ale vy samozřejmě můžete používat sudo před příkazy, není-li uvedeno jinak. Doporučujeme také pracovat v kontejneru (lxc) nebo ve virtuálním počítači.

sudo dnf install openldap openldap-servers openldap-clients

Balíčky obsahují jak klientskou část, tak serverovou část. Po instalaci máme připravenou základní službu - slapd. Ověřte si, že jí máte pomocí systemctl status slapd. Zatím nebude nutné ji startovat.

Služba slapd ukládá data na více místech. /var/lib/ldap obsahuje data a /etc/openldap/slapd.d obsahuje konfiguraci adresáře. Data needitujte ručně, můžete tím poškodit jejich integritu. Proto hned na začátku využijeme první příkaz slapcat -n 0, který umožní vypsat konfigurační databázi. Poznámka: Protože slap* nástroje pracují přímo s daty, nepřipojují se přes běžné API, snažím se je tedy omezovat právě na úlohy spojené se čtením dat.

...
dn: olcDatabase={2}mdb,cn=config
...
olcDbDirectory: /var/lib/ldap
olcSuffix: dc=my-domain,dc=com
olcRootDN: cn=Manager,dc=my-domain,dc=com
...

Výpis obsahuje komplexní data o naší konfigurace, o tom, co indexovat, kde se co naposledy hnulo a podobně. Pro nás jsou nejzajímavější data na konci. Jde o nastavení databáze dn: olcDatabase={2}mdb,cn=config, která nám říká, kde má uložená data, jakou očekává, že budou daná data mít příponu (umístění v LDAP stromu) a jaká je DN toho, kdo je spravuje (čti administrativní účet). Pokud není doména my-domain.com Vaše vysněná, půjdeme to teď změnit.

Zkratky, které se hodí

DN: Distinguished name / Rozlišující jméno
CN: Common name / běžné jméno
DC: Domain Component / část domény
OU: Organizational unit / organizační jednotka

Naše doména, naše pravidla

Prvně je tedy nutné nakonfigurovat databázi 2 (to už je ta, kde budeme mít data) na ukládání toho našeho stromu, domény, to určuje atribut alcSuffix. Doména mojefedora.cz má dvě doménové části, tedy budu ji zapisovat jako dc=mojefedora,dc=cz. Administrátorský účet olcRootDN bude mít DN cn=admin,dc=mojefedora,dc=cz. Heslo získáte z příkazu slappasswd,

# Použil jsem heslo brambora, ale vy si vyrobte svůj hash.
slappasswd
New password: 
Re-enter new password: 
{SSHA}QcVLBxRH8REdc55PIN7Kh3jTwTgws4u9

Měníme adresář k obrazu svému

Editaci záznamů provádí příkaz ldapmodify, kde chceme komunikovat protokolem ldapi:/// (lokální připojení na ldap server). Protože už chceme komunikovat s ldap serverem, musíme si ho zapnout: systemctl start slapd. Připravme si tedy soubor init.ldif s konfigurací (v defacto stejném formátu je uložena i konfigurace).

dn: olcDatabase={2}mdb,cn=config
changetype: modify
replace: olcSuffix
olcSuffix: dc=mojefedora,dc=cz

dn: olcDatabase={2}mdb,cn=config
changetype: modify
replace: olcRootDN
olcRootDN: cn=admin,dc=mojefedora,dc=cz

dn: olcDatabase={2}mdb,cn=config
changetype: modify
replace: olcRootPW
olcRootPW: {SSHA}QcVLBxRH8REdc55PIN7Kh3jTwTgws4u9

Každá instrukce říká, kdo (DN), co chceme (changetype), nahraď: co (replace: olcRootDN) a pak už co přesně se má dosadit. Trochu roztahané, ale vcelku čitelné. Do olcRootPW si vložte vygenerovaný hash hesla.

Připravený soubor předáme přes příkaz ldapmodify -Y EXTERNAL -H ldapi:/// -f init.ldif. -Y EXTERNAL říká, že autorizace k serveru je externí (jsem přihlášen jako root - dostanu pseudouživatele s id 0). -H ldapi:/// říká, kam se máme připojit a -f init.ldif říká, že chceme pracovat se souborem (číst instrukce ze souboru). Pokud jako výsledek nastane chyba jako tato: ldap_sasl_interactive_bind_s: Can't contact LDAP server (-1), zapomněli jste zapnout server (viz výše).

ldapmodify -Y EXTERNAL -H ldapi:/// -f init.ldif 
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
modifying entry "olcDatabase={2}mdb,cn=config"

modifying entry "olcDatabase={2}mdb,cn=config"

modifying entry "olcDatabase={2}mdb,cn=config"

Ověřte si, že změny skutečně nastaly. slapcat -n 0 | less vám umožní v klidu si prohlédnout celý výsledek. Pro vyhledávání napište /olcRootDN, potvrďte a hledáte dané slovo, zmáčkněte q a jste pryč. Podobně jako ve vimu. Nebo si hledané věci grepujte pomocí slapcat -n 0 | grep olcRootDN.

Objekty, jejich třídy a schémata a omezení

Jak již výše víme, objekty se v databázi ukládají za sebou. To jak je definován, co má a co může mít, určuje jeho třída - objectClass. To jaké jsou k dispozici třídy určuje schéma databáze uložené v konfiguraci. Výchozí schéma tedy doplníme, pokud vás zajímá (mělo by), jaká data naleznete uvnitř, soubory si prohlídněte v oblíbeném textovém editoru (čti: vim).

Nejprve budeme chtít definovat vršek stromu, tedy doménové části. Schéma naimportujeme jednoduše. cosine.ldif nám poskytne třídy domain a top a core.ldif schéma pro třídu organizationalRole.

ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/cosine.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/core.ldif

Připravme si objekt, který bude editovat náš adresář. Bude obsahovat takovéto údaje, pojmenujeme si ho např. domain.ldif. Obsahovat by měl asi takovéto údaje.

dn: dc=mojefedora,dc=cz
dc: mojefedora
objectClass: top
objectClass: domain

A připravíme se na vložení do databáze. U databáze dva (datové), jsme definovali olcRootDN a olcRootPW- přístupové údaje. Proto musíme použít přihlášení pomocí BindDN (připojovací DN) a s heslem, které si načteme při připojení. Příkaz je teď ldapadd -x -W -D "cn=admin,dc=mojefedora,dc=cz" -f domain.ldif, protože chceme vkládat.

ldapadd -x -W -D "cn=admin,dc=mojefedora,dc=cz" -f domain.ldif
Enter LDAP Password: 
dn: dc=mojefedora,dc=cz
dc: mojefedora
objectClass: top
objectClass: domain
adding new entry "dc=mojefedora,dc=cz"

Nakonec si přidáme uživatele (přesněji "organizační roli") cn=admin,dc=mojefedora,dc=cz. Připravím si soubor org_role.ldif (viz níže). Nahraji pomocí ldapadd -x -W -D "cn=admin,dc=mojefedora,dc=cz" -f org_role.ldif

dn: cn=admin,dc=mojefedora,dc=cz
cn: admin
objectClass: organizationalRole
description: LDAP administrator pro mojefedora.cz

Data podávejte perfektně strukturovaná

Objekty je samozřejmě možné vytvářet přímo v dc=mojefedora,dc=cz, ale lepší je rozdělit si je do několika organizačních struktur. Velké firmy mohou použít objekt umístění pro lepší přehlednost, menší firmy mohou pracovat přímo pod doménou a objekty rovnou dělí do jednotek podle tříd a typů objektu. S umístěním by DN vypadala nějak takto: l=brno,dc=mojefedora,dc=cz.

Pro ilustraci vytvoříme pouze společné místo pro všechny uživatelské účty. Tato organizační struktura se jmenujeme organizationalUnit. Všem objektům můžeme přidat popisky (i když víme, že dobrý kód se komentuje sám). Založím soubor ou_users.ldif s obsahem popisujícím novou organizační jednotku.

dn: ou=People,dc=mojefedora,dc=cz
objectClass: organizationalUnit
ou: People
description: Uzivatele

Aplikuje změny popsané ve vytvořeném ldapadd -x -W -D "cn=admin,dc=mojefedora,dc=cz" -f ou_users.ldif. Řetězce s diakritikou je nutné hashovat pomocí base64 a k definici se připisují dvojtečky. Například description:: VcW+aXZhdGVsw6kK pro description: Uživatelé. Hash si vygenerujete snadno pomocí echo "Uživatelé" | base64.

Plníme jednotky lidmi

Uživatele popisujících struktur je velké množství a každá popisuje jiné údaje. Naštěstí je možné třídy kombinovat. Tento příklad si vystačí s uživatelem posixovým - posixAccount a organizační strukturou organizationalPerson s povinným parametrem sn surname - příjmení. Schéma této třídy zavedeme do adresáře pomocí ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/nis.ldif. Každý uživatel musí mít údaje: cn - běžné ldap jméno, uid - uživatelské jméno, uidNumber - uživatelské číslo, gidNumber - číslo skupiny a homeDirectory - domovský adresář.

dn: cn=Josef Smrk,ou=People,dc=mojefedora,dc=cz
cn: Josef Smrk
objectClass: organizationalPerson
sn: Smrk
objectClass: posixAccount
uid: jsmrk
homeDirectory: /home/jsmrk
gidNumber: 10000
uidNumber: 10000

Sklízíme plody své práce

Pokud máte zapnutý firewall, nezapomeňte si povolit přístup na ldap port (TCP/389). Výsledky si pohodlně prohlédněte slapcat | less. Pokud ale preferujete grafické aplikace, tak můžete použít třeba jxplorer, ve kterém by výsledek vypadal nějak takto:

jxplorer

Náhled na naší adresářovou strukturu pomocí programu JXPlorer.

A co dál?

Zabezpečte si server SSL certifikátem.

V pokračování rozdělíme uživatele do posixGroup skupin. Nastavíme přihlašování přes LDAP a vytvoříme tak centrální přihlašovací službu.