Tévedtem: új fícsört fejlesztettem az AD-ba

Létrehozva: 2009 nov. 06.
Módosítva: 2009 nov. 09.

Szerző: Szalay Márton

Ültem az október 7-ei TechNeten, hallgattam ahogy GT a Windows Server 2008 R2 DSRM-jelszószinkronizáció szolgáltatásáról beszélt, és azon gondolkodtam, hogy ezt miért nem csinálták meg korábban.

A Windowsban a SAM (Security Account Manager) felel a helyi felhasználók, jelszavaik és a csoportok nyilvántartásáért. Mint tudjuk, az Active Directory nem a SAM-ben, hanem egy Jet alapú, LDAP interfésszel (is) rendelkező adatbázisban tárolja az AD-objektumokat. Feltehetően kompatibilitási okokból az Active Directoryt is lehet a SAM-hez hasonló módon (a SAM függvényeivel) kezelni.
A DSRM-re (Directory Services Restore Mode, magyarul címtár-helyreállítási mód) akkor van szükség, ha a tartományvezérlő meghalt, vagy épp nem úgy működik, ahogy azt szeretnénk. Ilyenkor a DC-t restore módban kell bebootolni, majd a gépre a DSRM-jelszóval lehet bejelentkezni. Ez az a jelszó, amit a DC telepítésekor adunk meg, és nagyjából abban a pillanatban el is felejtjük, akkor pedig már biztosan nem tudjuk, amikor szükség lenne rá. A Windows Server 2008 R2-ben (és a Windows Server 2008 SP2-ben is) az ntdsutil kapott egy új, „Sync from domain account” névre hallgató parancsot, amely összesen annyit tesz, hogy kiolvassa a megadott Active Directorybeli felhasználó NTLM jelszóhashét, majd beállítja azt DSRM jelszóhashnek. Ezzel a megoldással mindig hozzáállíthatjuk (azaz szinkronizálhatjuk) a DSRM jelszavát egy tartományi felhasznaló (mondjuk a domain admin) jelszavához, így nem kell emlékeznünk a DC telepítésekor megadott jelszóra, hanem tudhatjuk, hogy a DSRM-jelszó megegyezik a megadott tartományi felhasználó jelszavával.

A named pipe (magyarul nevesített cső) a folyamatok közötti kommunikációt segítő, akár hálózaton keresztül is használható megoldás. Ezt valóban úgy kell elképzelni, mint egy csövet. Az egyik program a cső egyik végén „belekiabál”, a cső másik végén lévő másik program pedig „meghallja” azt. Technikailag ugyanúgy kell kezelni, mint egy fájlt: az egyik (a szerver) létrehozza a \\gépnév\pipe\pipeneve csövet, a másik (a kliens) pedig megnyitja a named pipe-ot ugyanazon az UNC címen. Ezek után hagyományos fájl írási-olvasási műveletekkel küldhetnek egymásnak adatot. Biztonsági okokból, a fájlokhoz hasonlóan, a nevesített csövekhez is hozzárendelhetünk hozzáférési listát (ACL).
Az ntdsutil egyszer állítja be a jelszót, így ha azt szeretnénk, hogy a DSRM-jelszó mindig megegyezzen az adott felhasználó jelszavával, vagy minden jelszócsere után lefuttatjuk kézzel, vagy időzítjük a futtatást.

Már ott, a TechNeten elkezdtem gondolkodni, hogy miért ne lehetne a jelszószinkronizációt megvalósítani korábbi Windows Servereken is. Aztán hazamentem, gondolkodtam tovább, és megírtam a szolgáltatást. Mivel a fícsört azelőtt nem ismertem, és Tamás előadását félreértettem, az én megoldásom némileg másképp működik: a rendszer folyamatosan figyel, és ha megváltozik a megadott felhasználó jelszava, automatikusan beállítja az összes tartományvezérlő DSRM-jelszavát az új jelszóra.

DSRM Password Sync architektúra
A program két fő komponensből áll: egy szervizből és egy jelszószűrőből. Kezdjük az utóbbival! A jelszószűrő egy .dll-fájl, amely beépül a SAM-be (Security Account Manager), és minden jelszócsere során lefut. (A Windowsban ez az egyetlen pont, ahol a titkosítatlan jelszavakhoz „legálisan” hozzá lehet férni.) Pontosabban a tartományvezérlőn a jelszószűrő(ke)t az lsass.exe hívja meg minden alkalommal, amikor bármelyik tartományi felhasználó jelszót cserél. A jelszószűrő ellenőrzi, hogy az éppen jelszót cserélő felhasználó az a felhasználó-e akinek a jelszavával a DSRM-jelszót szinkronizálni kell. Ha igen, egy named pipe-on keresztül elküldi az új jelszót a szerviznek, a szerviz pedig módosítja a helyi DSRM-jelszót. Mivel a jelszócsere (és így a jelszószűrő meghívása) csak azon a DC-n történik, amelyik a felhasználót az adott sessionben bejelentkeztette, így – több DC esetén – a szerviznek értesítenie kell a többi tartományvezérlőn futó szervizt is. A tartományvezérlők közötti kommunikáció szintén named pipe-okon keresztül történik, de tekintettel arra, hogy a named pipe-okon áthaladó adatok titkosítatlanok – ez pedig nem a legmegfelelőbb módja a rendszergazdai jelszó továbbításának – a szerviz a jelszót RSA algoritmussal titkosítva küldi át. Ha egy másik tartományvezérlő nem elérhető, az a DC, amelyiken a jelszócsere történt, 5 percenként újra megpróbálja értesíteni.

Bár a program először csak proof-of-concept jelleggel készült, később sokat teszteltem különböző környezetekben (pl. Windows 2000–Windows Server 2003–Windows Server 2008 R2, vegyes, három DC-s tartomány) és teljesen stabilnak bizonyult, ezért már élesben is működik.

Ennek az az előnye az ntdsutil-os megoldással szemben, hogy teljesen automatizált, és minden tartományvezérlőn megváltoztatja a DSRM-jelszót. A program telepítője és forráskódja (C++ és C# nyelven) letölthető a honlapomról. A szerviz a DSRM-jelszó módosításához a samlib.dll fájlban lévő SamiSetDsrmPassword függvényt hívja meg. Tekintettel arra, hogy ez egy nem dokumentált API, semmi garancia nincs arra, hogy a jövőben nem fog megváltozni, azaz, hogy a későbbi Windows Servereken is működni fog a program; bár figyelembe véve, hogy a függvény a Windows 2000-es verziója óta semmit sem változott, ennek nem látom nagy esélyét.


Szalay Márton (MCSE, MCITP, MCPD, MCT, CCNA, Security+)

A Magyar Export-Import Bank rendszermérnöke, konzulens, a SZAK Kiadó szerzője, mérnök-informatikus hallgató. Képesítései szerint MCSE, MCITP, MCPD, MCT, MVP, CCNA, CNA, Security+.

Hozzászólások

Ehhez a cikkhez jelenleg nincs hozzászólás.

Új hozzászólás

Név:
E-mail:
Web URL:
Hozzászólás: A formázáshoz használható kódok: [b]vastag[/b], [i]dőlt[/i] és [u]aláhúzott[/u]