Magazyn danych Active Directory

Magazyn danych Active Directory

Odnosząc się do wpisu dotyczącego fizycznej architektury Active Directory , a konkretniej przedstawionej na Rys.4 architektury magazynu danych Active Directory – w pliku Ntds.dit przechowującym bazę usług katalogowych wyróżnić można 3 główne tablice, które zostały już wstępnie omówione. Są jednak również dodatkowe tablice, o których niestety często się zapomina lub są one pomijane, mimo że pełnią bardzo istotne role. Przedstawmy więc te tablice oraz pełnione przez nie role:

  • Tablica ukryta (ang. Hiddentable) –tablica, która zawiera tylko jeden wiersz, lecz kilka kolumn, które definiują stan bazy Active Directory. Przykładem takiej kolumny może być kolumna „backupexpiration_col”, która określa, czy kopia zapasowa bazy jest jeszcze ważna, czy już przeterminowana.
  • Tablice propagacji deskryptorów zabezpieczeń (Sdpropcounttable oraz Sdproptable) – tablice, które są wykorzystywane przez demona propagacji deskryptorów zabezpieczeń (SDProp). Jego zadaniem jest rozpowszechnianie deskryptorów, które są dziedziczone zgodnie z hierarchią drzewa w lokalnej bazie danych Active Directory.
  • Tablica przydziałów (Quota_table) – tablica, która przechowuje dane o przydziałach Active Directory, które mogą być ustalane od czasu wprowadzenia Windows Server 2003. Przydziały są definiowane w kontekście identyfikatora zabezpieczeń (np. użytkownika) oraz w kontekście konkretnej partycji Active Directory. Oznacza to, że ten sam użytkownik może mieć zdefiniowane różne poziomy przydziałów dla różnych partycji Active Directory. (O samych partycjach więcej opowiemy w kolejnych częściach cyklu dotyczących logicznej architektury Active Directory)
  • Tablica procesów przebudowy przydziałów (Quota_rebuild_progress_table) – tablica wykorzystywana podczas procesu przebudowy przydziałów Active Directory. Zawiera informacje o dokonywanych i procesowanych właśnie zmianach quot. Pozwala demonowi poprawnie dokonywać wszelkich zmian przydziałów i śledzić informacje o przetworzonych już obiektach.
  • Tablice wewnętrzne aparatu magazynu rozszerzalnego ESE :
    • MSysObjects
    • MSysObjectsShadow
    • MSysUnicodeFixupVer2
    • MSysDefrag2

Powyższe tablice systemowe nie dotyczą bezpośrednio Active Directory, dlatego zostaną pominięte w tym artykule. Osoby zainteresowane odsyłam do źródeł na temat mechanizmów działania ESE np.: http://forensic-proof.com/wp-content/uploads/2011/07/Extensible-Storage-Engine-ESE-Database-File-EDB-format.pdf

Powracając jeszcze do jednej z tabel omówionej w pierwszym artykule – mianowicie tabeli połączeń. Otrzymałem kilka pytań dotyczących sposobu tworzenia i zasady działania takich odniesień. Żeby nie zostawiać niedomówień wyjaśnijmy sobie to zagadnienie. Tabela połączeń zawiera dane, które pozwalają na ustalenie konkretnego obiektu. Dane te mają postać znacznika nazwy wyróżniającej (ang. Distinguished Name Tag – DTN), który odnosi się z kolei do binarnego znacznika reprezentującego atrybut.

DNT – jest w istocie rzeczy wartością DWORD o długości 4 B. Każdy obiekt w tabeli danych posiada swój unikalny odnośnik, który jest niepowtarzalny, dzięki czemu na tej podstawie można obsłużyć przypisania w tabeli połączeń. Dzięki temu, że korzysta się ze słów 4 B a nie z GUID’ów – oszczędzana jest przestrzeń potrzebna do obsługi bazy w ten sposób. Co istotne – DTN’y są tworzone w sposób odrębny przez każdy kontroler domeny. Po utworzeniu obiektu w usłudze katalogowej, kontroler domeny inkrementuje/wylicza wartość DTN, którą przypisuje nowemu obiektowi. Podczas replikacji obiektów do innego kontrolera wartości DTN’ów na docelowym kontrolerze domeny mogą być inne z racji na kolejność odbierania zmian w Active Directory. Istnieje oczywiście możliwość „wymuszenia” spójności znaczników na różnych kontrolerach domeny. Sytuacja taka ma miejsce, gdy promujemy nowy kontroler domeny z nośnika IFM (ang. Install From Media). W takim przypadku nowy kontroler domeny będzie mieć identyczne znaczniki do tych, które otrzymał z kontrolera domeny, na którym utworzony został nośnik IFM.

Zatrzymując się jeszcze na chwilę przy zagadnieniu połączeń utrzymywanych w tabeli połączeń Active Directory – wyróżnić można dwa zasadnicze typy takich relacji:

  1. Relacja rodzic-dziecko (ang. Parent-child) – taki typ relacji występuje w przypadku obiektu znajdującego się w kontenerze, jednostce organizacyjnej.
  2. Relacja odniesienia (ang. Reference) – taki typ relacji występuje w przypadku obiektów powiązanych, które nie są ze sobą bezpośrednio skojarzone przez relację rodzic-dziecko. Sytuacja taka ma miejsce na przykład w wypadku członkostwa obiektu w grupie domenowej.

W przypadku relacji rodzic-dziecko, aby uzyskać lepsza wydajność, usługi katalogowe w tabeli danych dla każdego rekordu reprezentującego pojedynczy obiekt Active Directory przechowują dodatkową kolumnę reprezentującą znacznik nadrzędnej nazwy wyróżniającej PDNT (ang. Parent Distinguished Name Tag), w którym przechowywany jest znacznik nazwy wyróżniającej DNT obiektu nadrzędnego. Dzięki temu usługi katalogowe potrzebują znacznie mniej czasu na odnalezienie i powiązanie ze sobą obiektów.

Z kolei w przypadku relacji odniesienia, często nie zauważa się najniższego poziomu działania usług katalogowych. Przykładem są grupy domenowe, które zawierają wielu członków. W momencie obserwacji takiego obiektu w konsolce Active Directory Users and Computers, czy z Powershell’a jako jeden z atrybutów grupy prezentowany jest atrybut „ Members” – widoczny na Rys.1.

Rys.1 Przykładowa zawartość atrybutu „members” grupy domenowej
Rys.1 Przykładowa zawartość atrybutu „members” grupy domenowej

Powyższy widok jest dosyć mylący jeśli patrzy się tylko z tego poziomu a zapomina o działaniu w warstwie bazy Active Directory. Przytoczony przykład wydaje się być wielowartościowym atrybutem przypisanym do konkretnej grupy. W żadnym wypadku jednak tak nie jest! Atrybut „Members” jest za to przykładem atrybutu wielowartościowego odniesienia (ang. Multi-vauled link atribute), który tworzy połączenia między grupą a obiektami, które są jej członkami.

Spróbujmy prześledzić to na przykładzie. W momencie jeśli dodamy nowy obiekt do grupy domenowej, to grupa nie przechowuje w rzeczywistości nazwy wyróżniającej (DN) tego obiektu, lecz Active Directory przechowuje DNT, który pozwala na ustalenie członkostwa w grupie. Co dzięki temu zyskujemy? Chociażby tyle, że w przypadku zmiany nazwy grupy, czy obiektu – Active Directory nie musi przeszukiwać wszystkich grup celem aktualizacji nazw wyróżniających jej członków, co byłoby ogromnie nieoptymalne… Zamiast tego zmienia się tylko nazwa danego obiektu, a znaczniki DNT pozostają niezmienne i w dalszym ciągu pozwalają na ustalenie zależności. Dla osób, które mimo wszystko „nie czują” tej zależności – przygotowałem Tabelę 1 oraz Tabelę 2, które pozwolą zobrazować sposób działania połączeń w Active Directory.

 DNT PDNT Klasa obiektu Nazwa pospolita (CN)
27111 27002 Jednostka Organizacyjna IT
27234 27111 Grupa Grupa_IT
27507 27111 Użytkownik Marcin Krzanowicz

Tab.1 Przykładowa zawartość tabeli danych bazy Active Directory

 Atrybut DNT Odnośnik przekazujący
Członek 27234

27507

Tab.2 Przykładowa zawartość tabeli połączeń bazy Active Directory

Analizując powyższe tabele – Mamy jednostkę organizacyjną o nazwie IT, w której znajdują się dwa obiekty – grupa domenowa „Grupa_IT” oraz użytkownik „Marcin Krzanowicz” – po czym to poznać mając samą tablicę danych? Po znacznikach DNT oraz PDNT. DNT, jak wcześniej wspomniałem jest znacznikiem danego obiektu, natomiast PDNT jest znacznikiem obiektu nadrzędnego, czyli jeśli grupa i użytkownik mają przypisane PDNT, które jest tożsame z DNT jednostki organizacyjnej – oznacza to, że znajdują się bezpośrednio w tej jednostce. Jednakże na podstawie samej tabeli danych nie można ustalić członkostwa w grupie – do tego właśnie potrzebna jest tablica połączeń! Rozpatrzmy naszą tablicę połączeń – mamy w niej jeden rekord, który odpowiada za ustalenie członka innego obiektu Active Directory. Aby ustalić, jakiego obiektu dotyczy, wystarczy odczytać znacznik DTN, który odpowiada grupie domenowej „Grupa_IT”, z kolei aby ustalić, kto jest członkiem tej grupy należy odnaleźć obiekt, na który wskazuje odnośnik przekazujący – w powyższym przykładzie jest to użytkownik „Marcin Krzanowicz”. W taki prosty sposób możliwe jest ustalenie członkostwa w grupach Active Directory. Natomiast w przypadku zmiany nazwy obiektu, cała struktura połączeń pozostaje bez zmian. Na przykład jeśli nazwa grupy ulegnie zmianie i jej nowa nazwa będzie brzmieć:
„Nowa_grupa_IT”, to wszystkie znaczniki pozostaną niezmienione, przez co usługi katalogowe nie są zbędnie obciążane. Prawda, że proste? J

Jako ciekawostka – Active Directory wykorzystuje nie tylko odnośniki przekazujące (ang. Forward links), lecz również odnośniki wsteczne (ang. backward links). Ten typ odnośników wykorzystywany jest między innymi podczas odczytu wartości atrybutu „MemberOf” obiektu. Patrząc od strony schematu Active Directory każdy atrybut obiektu ma przypisany numeryczny znacznik odnośnika dla par atrybutów, które mogą się odwoływać zarówno do odnośników przekazujących, jak i odnośników wstecznych – zasada jest taka, że atrybut z odnośnikiem przekazującym ma wartość połączenia o jedną jednostkę mniejszą, niż atrybut wsteczny. Na przykład w schemacie Active Directory atrybut obiektu „Member” będzie mieć wartość połączenia 2, a atrybut „MemberOf” wartość połączenia 3, z kolei atrybut „ManagedBy” będzie mieć przypisaną wartość 72, natomiast atrybut „ManagedObjects” wartość 73 itd.

W tym miejscu Active Directory kolejny raz rozpatrywane na wyższym poziomie abstrakcji „płata figla”, ponieważ zarówno z poziomu przystawki MMC, jak i powershell’a użytkownik ma złudzenie, że jest w stanie modyfikować atrybuty reprezentujące odnośniki wsteczne, takie jak przytoczony „MemberOf” – widoczne na Rys.2.

Rys. 2 Złudna modyfikacja odnośnika wstecznego.
Rys. 2 Złudna modyfikacja odnośnika wstecznego.

W rzeczywistości jednak modyfikowany jest atrybut reprezentowany przez odnośnik przekazujący, czyli „Member” przypisany do grupy i reprezentowany rekordem w tabeli połączeń Active Directory, z kolei odnośnik wsteczny modyfikowany jest niejako w tle. Dlaczego taki model działania? Co dzięki temu zyskujemy? Otóż przeprowadźmy mały eksperyment – weźmy zwyczajnego użytkownika, bez praw administratora domeny i każmy mu dodać się do grupy – w przypadku niepowodzenia wydelegujemy mu uprawnienia najpierw do swojego obiektu użytkownika, a w następnej kolejności odbierzemy uprawnienia do konta użytkownika, lecz nadamy uprawnienia do samej grupy. Wiecie jaki będzie efekt? 🙂

Rys. 3 Próba modyfikacji członkostwa w grupie po delegacji uprawnień dla konta użytkownika.
Rys. 3 Próba modyfikacji członkostwa w grupie po delegacji uprawnień dla konta użytkownika.
Rys. 4 Próba modyfikacji członkostwa w grupie po delegacji uprawnień dla grupy.
Rys. 4 Próba modyfikacji członkostwa w grupie po delegacji uprawnień dla grupy.
Rys. 5 Potwierdzenie poprawnej modyfikacji członkostwa w grupie.
Rys. 5 Potwierdzenie poprawnej modyfikacji członkostwa w grupie.

Jak widać na dwóch powyższych rysunkach – w przypadku delegacji pełnych uprawnień dla użytkownika, do obiektu jego własnego konta, próba dodania się do grupy kończy się niepowodzeniem, ponieważ nie posiada on uprawnień do grupy. Z kolei w przypadku wydelegowania uprawnień do grupy, pomimo braku pełnych uprawnień do obiektu swojego konta – ta sama akcja jest możliwa do wykonania. Tym samym mamy potwierdzenie, że Active Directory w rzeczywistości bazuje na odnośnikach przesyłających, takich jak „Member”, które mogą być modyfikowane. Odnośniki wsteczne z kolei nie mogą być wprost modyfikowane i nie są one replikowane między kontrolerami domeny. Każdy kontroler domeny zarządza nimi lokalnie.

Wychodząc nieco przed szereg i ubiegając pytania na temat powiązań między obiektami z innych domen, które nie są całościowo przechowywane w tabeli danych – to zagadnienie rozwiązywane jest dzięki istnieniu jednej z pięciu ról FSMO (ang. Flexible single master operation) mianowicie roli wzorca infrastruktury (ang. Infrastructre Master) oraz obiektów zwanych fantomami (ang. Phantoms).

Fantom jest obiektem przechowywanym w tabeli danych bazy Active Directory, który odnosi się do obiektu z innej domeny. W tabeli danych przechowywane są między innymi atrybuty tego obiektu takie jak objectGUID, objectSID oraz nazwa wyróżniająca DN. To pozwala usługom katalogowym przyporządkować DNT obiektu do atrybutu Member grupy domenowej. Jeżeli natomiast dany kontroler domeny jest równocześnie wykazem globalnym (ang. Global catalog) – nie ma w tym wypadku konieczności tworzenia wpisów w tabeli danych, ponieważ wymagane dane są już na nim przechowywane.

Jak w takim razie wygląda obsługa fantomów? Kontroler domeny utrzymujący rolę wzorca infrastruktury okresowo sprawdza wpisy w swojej tabeli danych i porównuje je z danymi w wykazie globalnym. Jeżeli wykryta zostanie zmiana polegająca na przykład na zmianie nazwy takiego obiektu, jego przeniesieniu lub usunięciu – wzorzec infrastruktury aktualizuje najpierw dane w swojej tabeli danych a następnie replikuje je do pozostałych kontrolerów domeny w swojej domenie.

Powiedzieliśmy sobie, że Active Directory jest w stanie poradzić sobie z obiektami spoza swojej domeny, ale mogą być jeszcze obiekty spoza… całego lasu i jak wtedy są one obsługiwane? W takim wypadku, gdy ustanowimy na przykład zewnętrzne zaufanie Active Directory – usługi katalogowe posłużą się obiektami FSP (ang. Foreign Security Principal), które przechowywane będą w jednostce organizacyjnej CN=ForeignSecurityPrincipals. Każdy z takich obiektów posiada między innymi atrybut objectSID oraz dodatkowe, które pozwalają na jego identyfikację w obcej domenie. Niestety w tym wypadku nie ma automatycznego mechanizmu pozwalającego na utrzymywanie obiektów FSP jako aktualne. Dlatego też takie obiekty powinny być traktowane podobnie do zwykłych obiektów Active Directory i weryfikowane podczas okresowych przeglądów środowiska.

Tematyka magazynu danych została już zasadniczo omówiona – dowiedzieliśmy się jakie tabele wykorzystywane są przez usługi katalogowe Active Directory, jak obsługiwane jest członkostwo w grupach oraz przynależność do jednostek organizacyjnych a także w jaki sposób katalogowaniu podlegają obiekty z obcych domen. Jako bonus na zakończenie artykułu przedstawiona zostanie tematyka indeksów w bazie Active Directory oraz możliwe sposoby na zwiększenie wydajności zapytań i odpowiedzi kontrolerów domeny. W tym momencie przejdźmy jednak do zagadnienia cyklu życia obiektu w Active Directory, ponieważ dotychczas dowiedzieliśmy się jak tworzone są obiekty, natomiast nie wiemy jeszcze co dokładnie dzieje się po ich usunięciu.

Cykl życia obiektu Active Directory składa się z trzech zasadniczych części:

  1. Obiekt żywy – od momentu utworzenia obiektu Active Directory, czyli nadania mu identyfikatorów zabezpieczeń oraz zapisania danych o obiekcie w bazie Active Directory obiekt utrzymywany jest w stanie żywym. Może on być wykorzystywany do nadawania uprawnień, logowania z jego użyciem, przekazywania poświadczeń, może być dodawany i usuwany z grup itd.
  2. Obiekt logicznie usunięty – od poziomu funkcjonalności domeny 2008 R2 oraz aktywowania dodatkowej funkcjonalności kosza na śmieci Active Directory (ang. Active Directory Recycle-Bin) usunięcie obiektu Active Directory jest w istocie jedynie jego logicznym usunięciem, z pełną możliwością przywrócenia obiektu do stanu poprzedniego, bez utraty jego atrybutów.
  3. Obiekt przerobiony (ang. Recycled) – stan obiektu tożsamy z obiektem usuniętym w Active Directory przed poziomem funkcjonalności 2008 R2 i bez aktywnej funkcjo kosza na śmieci Active Directory. Obiekt w takim stanie może być zreanimowany, przez co dla systemów i aplikacji widoczne będą jego identyfikatory zabezpieczeń, jednak część jego atrybutów zostanie utracona w procesie reanimacji.
  4. Obiekt fizycznie usunięty – obiekt zostaje trwale usunięty z bazy usług katalogowych. Jedyną możliwością jego przywrócenia jest odtworzenie bazy z backupu i wykonanie autorytatywnego przywracania obiektu.

Cykl życia przykładowego obiektu Active Directory został zaprezentowany na Rys. 6.

Rys. 6 Cykl życia obiektu Active Directory.
Rys. 6 Cykl życia obiektu Active Directory.

Na powyższym rysunku widoczne są możliwe stany, w których znajduje się obiekt Active Directory. W podstawowym stanie – żywy obiekt charakteryzuje się wartościami atrybutów określającymi jego stan tj: isDeleted oraz isRecycled ustawionymi na „fałsz” lub względnie „not set”, które są w tym wypadku identyczne jeśli chodzi o określenie stanu obiektu. W momencie usunięcia obiektu w środowisku Active Directory z aktywnym koszem na śmieci –zostaje on usunięty logicznie, a jego atrybut isDeleted zmienia wartość na „prawda”. W tym stanie utrzymywany jest minimalnie przez okres określający czas życia obiektu usuniętego tj. „msDS-DeletedObjectLifetime” Przykładowa wartość tego czasu oraz sposób sprawdzenia (wymaga instalacji modułu powershell’owego Quest for Active Directory. Można oczywiście również sprawdzać natywnymi przystawkami, jednak dla mnie ten moduł jest wygodniejszy) został zaprezentowany na Rys. 7.

Rys. 7 Sprawdzenie czasów życia obiektów
Rys. 7 Sprawdzenie czasów życia obiektów

Rys. 7 Sprawdzenie czasów życia obiektów.

Na tej podstawie widać, że obiekt logicznie usunięty będzie utrzymywany w tym stanie nie krócej niż 266 dni. (domyślnie w przypadku tej funkcjonalności Active Directory jest to 180dni). Jest jednak kilka wyjątków od tej reguły. W Active Directory występują pewne typy obiektów, które zaraz po usunięciu przejdą do stanu, w którym mogą zostać fizycznie usunięte, bez zachowania stanu pośredniego, mimo aktywnego kosza na śmieci Active Directory. Są to obiekty takie jak:

  • Obiekty dynamiczne, których czas życia dobiegł końca
  • Metadane usuwane razem z depromowaniem kontrolera domeny
  • Kontekst nazewnictwa (NC) tylko do odczytu (np. usunięcie wykazu globalnego z kontrolera domeny)
  • Obiekty powracające (ang. Lingering Objects)
  • Obiekty, które zostały zmigrowane do innej domeny.

Dla pozostałych, standardowych obiektów Active Directory – czas, kiedy nastąpi ich przerobienie zapisywany jest w tablicy danych w kolumnie „recycle_time_col”. W przypadku osiągnięcia tego czasu obiekt zostaje poddany „przerobieniu” i staje się reliktem. Ustawiana jest mu wartość atrybutu isRecycled na „prawda”. W kolumnie „time_col” zapisywany jest znacznik czasu zawierający datę, kiedy ma mieć miejsce kolejna zmiana stanu obiektu –kiedy będzie on gotowy do fizycznego usunięcia.

Aby logiczne usuwanie obiektu zakończyło się powodzeniem spełniony musi być szereg warunków środowiskowych Active Directory. Najistotniejszymi z nich są:

  • Posiadanie uprawnień do usunięcia obiektu
  • Konieczność obecności obiektu w zapisywalnym kontekście nazewnictwa, na którym agent Active Directory próbuje wykonać operację usunięcia

Z kolei sytuacjami, w których próba logicznego usunięcia zostanie odrzucona przez agenta Active Directory są między innymi:

  • Próba usunięcia obiektu schematu bądź konfiguracji Active Directory na kontrolerze domeny, który nie jest członkiem głównej domeny w lesie Active Directory
  • Próba usunięcia obiektu schematu bądź konfiguracji Active Directory na kontrolerze domeny, który nie jest członkiem domeny, do której należy usuwany obiekt
  • Na obiekcie ustawiona jest flaga chroniąca go przed usunięciem
  • Atrybut obiektu isDeleted ma wartość „prawda”, natomiast kosz na śmieci Active Directory nie jest aktywowany
  • Próba logicznego usunięcia obiektu, który został przetworzony/ma wartość atrybutu isRecycled ustawioną jako „prawda”
  • Próba usunięcia obiektu nadrzędnego Active Directory, który zawiera w sobie obiekty potomne nie spełniające wymagań co do możliwości ich logicznego usunięcia
  • Próba usunięcia drzewa głównego kontekstu nazewnictwa (ang. Root naming context)
  • Próba usunięcia drzewa obiektów krytycznych – posiadających wartość atrybutu isCriticalSystemObject = „prawda”
  • W przypadku, gdy nastąpiła próba usunięcia obiektu, która wymaga opóźnionego przetwarzania odnośników lub czyszczenia odnośników na obiekcie, na którym ten proces właśnie ma miejsce

Oczywiście nie są to wszystkie sytuacje, w których próba logicznego usunięcia obiektu skończy się niepowodzeniem, jednakże daje to obraz sytuacji, w której trzeba pamiętać o pewnych zależnościach oraz całościowej architekturze Active Directory, żeby mieć możliwość panowania nad tym środowiskiem i wiedzieć skąd się biorą pewne ograniczenia.

Po udanym logicznym usunięciu obiektu Active Directory z aktywną funkcjonalnością kosza na śmieci AD –obiekt trafia następnie do specjalnej jednostki organizacyjnej przeznaczonej dla obiektów usuniętych. Każdy z kontekstów nazewnictwa w domenie, z wyjątkiem kontekstu schematu posiada swój własny kontener, w których przechowywane są obiekty usunięte. Domyślnie te jednostki organizacyjne nie są widoczne z poziomu zapytań LDAP ani też w przystawce ADSI. Występuje jednak znowu kilka wyjątków, w których pomimo udanej próby logicznego usunięcia obiektu Active Directory nie może on zostać przeniesione do specjalnego kontenera przechowującego obiekty usunięte. Takie sytuacje obejmują wypadki, w których:

  • Nie ma kontenera dla obiektów usuniętych w danym kontekście nazewnictwa
  • Obiekt posiada ustawioną flagę systemową: FLAG_DISALLOW_MOVE_ON_DELETE
  • Obiekt jest korzeniem kontekstu nazewnictwa
  • Obiekt jest częścią procesu usuwania kontekstu nazewnictwa tylko do odczytu.
  • Obiekt nie wspiera stanu pośredniego, lecz jest usuwany od razu fizycznie

Jako kolejna ciekawostka – sam kontener obiektów usuniętych jest utrzymywany w Active Directory w stanie tożsamym z obiektami usuniętymi – posiada wartość atrybutu „isDeleted” ustawioną na „prawda”. Jak to się dzieje, że nie jest on usuwany z bazy danych? Cały trick polega na tym, że data, kiedy kontener będzie mógł zostać usunięty domyślnie ustawiona jest na czas „9999-12-29 23:59:59”, więc usunięcie nam raczej nie grozi J Gdyby jednak ktoś się uparł i zmienił ten czas na możliwy do spełnienia, to usługi katalogowe w istocie usuną kontener.

OK – mamy już sytuację, w której obiekt logicznie usunięty spełnił warunki aby zostać przeniesionym do specjalnej jednostki organizacyjnej – ale pojawia się drobny problem… Po przeniesieniu obiektu zmienia się jego nazwa rozróżniająca. Jak więc zapewnić stan, w którym obiekty usunięte nie będą posiadać identycznych względnych nazw rozróżniających? Otóż obiekt po przeniesieniu do tego kontenera przyjmuje względną nazwę rozróżniającą w postaci:

<stara względna nazwa rozróżniająca> 0x0ADEL<objectGUID>

Dodatkowo mechanizmy wewnętrzne usług katalogowych dbają o to, aby nowa nazwa nie była dłuższa niż 255 znaków, z kolei stara względna nazwa rozróżniająca zapisywana jest w parametrze „msDs-LastKnownRDN” tego obiektu.

W tym miejscu nie można zapomnieć o samej architekturze bazy Active Directory. Mianowicie oprócz samej tabeli danych, ma ona jeszcze tabelę połączeń. Co więc dzieje się z tabelą połączeń i odnośnikami w momencie usunięcia obiektu Active Directory?

Otóż zanim wdrożony został system Windows Server 2003 i oparte na nim usługi katalogowe – nie istniał mechanizm replikacji wartości atrybutów powiązanych (ang. Linked Value Replication – LVR), przez co atrybuty były usuwane wprost z tabeli połączeń Active Directory na każdym kontrolerze domeny. Natomiast dzięki wprowadzonemu później mechanizmowi LVR – każda właściwość wielowartościowego atrybutu obiektu może być replikowana oddzielnie. Co dzięki temu zyskano? Przede wszystkim zwiększono wydajność usług katalogowych oraz zmniejszono transfery między poszczególnymi kontrolerami domen wykorzystywane podczas replikacji. Biorąc na przykład grupę domenową, w której zmieniliśmy jednego członka grupy – bez mechanizmu LVR, cały wielowartościowy atrybut musi zostać zreplikowany. Jeśli będzie to grupa „Domain Users” to do replikacji jest często kilka-kilkadziesiąt tysięcy wartości. Mając natomiast mechanizm LVR zreplikowana zostanie dokładnie jedna zmieniona wartość.

Wykorzystując mechanizm LVR, jego działanie w przypadku usuwania obiektów Active Directory jest zasadniczo zbieżne ze zwykłymi obiektami. Bazuje również na czasie życia obiektu i jest w stanie obsługiwać logiczne oraz fizyczne usunięcie obiektu, na który wskazuje. Aby było to możliwe do tablicy połączeń Active Directory wprowadzone zostały pomocnicze kolumny widoczne w Tab. 3.

Kolumna

Przeznaczenie

link_deltime

 Znacznik czasu, kiedy dane zostają przeznaczone do usunięcia

link_usnchanged

Przechowanie numeru USN oznaczającego „numer wersji” wykorzystywanego przez agenta Active Directory

link_metadata

 Przechowanie matdanych potrzebnych do aktualizacji oraz replikacji

link_ncdnt

Wykorzystywana wraz z LVR. Służy określeniu kontekstu nazewnictwa, którego obiekt dotyczy.

Tab. 3. Dodatkowe kolumny tablicy połączeń Active Directory.

W obrębie tabeli połączeń oraz aktualizacji i usuwania obiektów w niej rezydujących działają dwa najistotniejsze mechanizmy:

  • Oczyszczania połączeń (ang. Link cleaner) – wprowadzony od Windows 2003
  • Opóźnione przetwarzanie połączeń (and. Delayed Link Processing) – Wprowadzony od Windows 2008 R2

Pierwszy z nich rozpoczyna swe działanie po 30 minutach od uruchomienia systemu/usług katalogowych. Wyzwalany jest po 60 sekundach od odznaczenia obiektu do „oczyszczenia” lub co każde 12h w przypadku braku nowych oznaczonych obiektów. W trakcie jednej transakcji mechanizm jest w stanie przetworzyć do 1000 połączeń. Z kolei drugi mechanizm również rozpoczyna swe działanie po 30 minutach od startu systemu/usług katalogowych i jest powtarzany co 12 godzin, jednakże wyzwalany jest natychmiast po oznaczeniu obiektu do oczyszczenia oraz potwierdzeniu tej transakcji na bazie Active Directory a podczas jednej transakcji przetwarza do 10000 połączeń.

Prześledźmy więc możliwe do wystąpienia sytuacje usunięcia połączenia oraz sposoby działania przedstawionych mechanizmów:

Mechanizmy

Przyczyna

Kosz na śmieci Active Directory

Akcja

1 +2

Obiekt z ponad 10000 połączeń zostaje logicznie usunięty

Wyłączony

Fizyczne usunięcie połączenia

1 +2

Obiekt z ponad 10000 połączeń zostaje fizycznie usunięty(W tablicy danych pozostaje fantom oczekujący na usunięcie wszystkich połączeń)

Nie dotyczy

Fizyczne usunięcie połączenia

2

Obiekt z ponad 10000 połączeń zostaje logicznie usunięty

Włączony

Dezaktywacja połączeń

2

Obiekt z ponad 10000 połączeń zostaje przerobiony z logicznie usuniętego na relikt

Włączony

Fizyczne usunięcie połączenia

2

Obiekt z ponad 10000 połączeń zostaje przywrócony

Włączony

Aktywacja połączenia

 

Dla osób bardziej dociekliwych w kwestii ustalonego limitu połączeń przetwarzanych w ramach jednej transakcji – oczywiście limit ten idzie zmodyfikować, jednak jest to wysoce niezalecane. Przede wszystkim ze względu na mechanizmy wewnętrzne ESE oraz możliwości buforowania danych.

Parametrem, którym można modyfikować ilość przetwarzanych połączeń jest klucz rejestru:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\NTDS\ Parameters\Links process batch size , w którym podaje się oczekiwaną wartość DWORD. 0 nie jest wspierane J a modyfikacji można dokonać na systemach Windows Server 2008 R2 i późniejszych.

Przechodząc więc do tablicy danych – również w niej potrzebne są dodatkowe kolumny i mechanizmy, które wspierają oczyszczanie i przetwarzanie połączeń na obiektach usuniętych. Wykorzystywane w tym procesie kolumny zaprezentowane zostały w Tab.4.

Kolumna

Przeznaczenie

CNT_col

Utrzymuje informację o tym, jak wiele jest odwołań do aktualnego wiersza przez inne wiersze bazy Active Directory. Składa się z liczników odwołań bezpośrednich, pośrednich oraz odowłań mechanizmów oczyszczania połączeń

processlinks_col

Jeśli w tej kolumnie jest jakaś niezerowa wartość, to mechanizm opóźnionego przetwarzania połączeń właśnie przetwarza połączenia danego obiektu

clean_col

Jeśli w tej kolumnie jest jakaś niezerowa wartość, to mechanizm oczyszczania połączeń właśnie przetwarza połączenia danego obiektu

clean_index

Wykorzystywana przez mechanizm oczyszczania połączeń w celu identyfikacji obiektów wymagających przetworzenia

processlinks_index

Wykorzystywana przez mechanizm opóźnionego przetwarzania połączeń w celu identyfikacji obiektów wymagających przetworzenia

 

Powyższe oznacza mniej więcej tyle, że tak długo jak wartość w kolumnie CNT_col danego obiektu jest niezerowa, tak długo nie może on zostać fizycznie usunięty z bazy Active Directory.

W całym procesie usuwania obiektów Active Directory istotnym mechanizmem jest również odśmiecanie pamięci (ang. Garbage Collector). Działa ono domyślnie co 12h na każdym kontrolerze domeny oraz w odstępach 15 minutowych pomiędzy kolejnymi kontrolerami domeny. Interwal uruchamiania tego mechanizmu jest definiowalny w atrybucie garbageCollPeriod obiektu “CN=Directory Service,CN=Windows NT,CN=Services,CN=Configuration,DC=X,DC=Y” Active Directory i może się zawierać w przedziale od 1h do 7 dni. W czasie jego uruchomienia generowane jest zdarzenie 1005 pod warunkiem włączenia logowania zdarzeń Active Directory co najmniej na poziomie ‘3’.

Jak dokładniej działa odśmiecanie pamięci? Otóż jest ono odpowiedzialne za kilka głównych zadań, na które składają się między innymi:

  • Fizyczne usuwanie obiektów
  • Przerabianie obiektów logicznie usuniętych
  • Fizyczne usuwanie wielowartościowych obiektów wskazujących
  • Modyfikacja obiektów, do których są nadal aktywne odwołania w bazie Active Directory

W przypadku usunięcia obiektów przez odśmiecanie pamięci logowane jest zdarzenie ‘1132’, natomiast w przypadku przerobienia obiektu – zdarzenie ‘2918’. Aby mieć podgląd tych zdarzeń należy włączyć logowanie dla odśmiecania pamięci co najmniej na poziomie ‘4’.

W trakcie jednego przebiegu odśmiecania pamięci przetworzonych może być maksymalnie 5000 obiektów. Zachowanie w przypadku przekroczenia tego limitu jest różne w stosunku do poszczególnych poziomów funkcjonalności domeny. W przypadku Windows 2000 zadanie jest uruchamiane w połowie normalnego interwału działania, natomiast od czasów Windows Server 2003 zadanie jest uruchamiane natychmiast. Trzeba jednak pamiętać, że w przypadku nowszych wersji usług katalogowych limit zawiera w sobie nie tylko standardowe obiekty, lecz również obiekty dynamiczne, czy nieobecne wartości odwołań.

Jak już doskonale wiemy usługi katalogowe Active Directory działają w oparciu o bazę danych, którą przedstawialiśmy wstępnie w pierwszym artykule niniejszego cyklu, natomiast rozwinęliśmy tą tematykę w tymże artykule. Jednak obok tradycyjnych obiektów podlegających katalogowaniu oraz wewnętrznych mechanizmów działających w Active Directory jest jeszcze jeden niezwykle istotny składnik bazy danych –indeksy. Osoby pracujące na co dzień z bazami danych pewnie znają doskonale to zagadnienie. Dla reszty natomiast wyjaśnijmy czym są właściwie indeksy. Otóż indeksy są sposobem organizowania danych przechowywanych w bazie – w sposób umożliwiający ich błyskawiczne otrzymywanie lub w sposób umożliwiający szybką odpowiedź bazy danych.

Wykorzystanie indeksów w bazie Active Directory ma tym większe znaczenie, im więcej obiektów znajduje się w Twojej organizacji. Mając na przykład 20 000 kont użytkowników, z czego 100 osób ma na imię ‘Anna’ podczas zadawania standardowego zapytania o osoby z takim imieniem usługi katalogowe są zmuszone przeszukać 20 000 obiektów użytkowników. Trochę sporo zważywszy na to, że interesuje Cię tylko 100 osób. Sytuacja byłaby o tyle gorsza, gdyby zapytanie powtarzało się częściej lub było wykonywane cyklicznie przez jakiś system pobierający dane z Active Directory. W takim właśnie przypadku z pomocą przychodzą indeksy. Oczywiście powyższy przykład jest jedynie obrazowy, natomiast wykorzystanie dla niego indeksów, czyli przygotowanej struktury zawierającej listę użytkowników o interesującym nas imieniu jest tematem, który postaramy się zgłębić. Inżynierowie Microsoftu zadbali o to, by ich usługi katalogowe domyślnie tworzyły indeksy dla popularnych i najczęściej wykorzystywanych atrybutów obiektów. Ich lista jest dostępna np. pod adresem: http://support.microsoft.com/kb/257218

Większość administratorów nie buduje własnych indeksów – do czasu… Sytuacja, w której są zmuszeni zainteresować się indeksami ma miejsce w przypadku niewydajności kontrolerów domeny spowodowanego zbyt wysokim obciążeniem lub po prostu zbyt wolnymi odpowiedziami do klientów. Ci bardziej przezorni – działający proaktywnie mogą uniknąć takiej sytuacji i konfigurując odpowiedni poziom logowania sprawdzić, które zapytania są przetwarzanie nieefektywnie, zanim kontroler domeny odmówi współpracy. Aby osiągnąć ten cel wystarczy zmodyfikować trzy wpisy rejestru systemowego:

  • HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NTDS\Diagnostics\15 Field Engineering – Ustawiając wartość ‘5’
  • HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NTDS\Parameters\Expensive Search Results Threshold – zmieniając wartość na odpowiednio niższą w zależności od ilości obiektów lub efektywności działania środowiska
  • HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NTDS\Parameters \Inefficient Search Results Threshold – zmieniając wartość na odpowiednio niższą w zależności od ilości obiektów lub efektywności działania środowiska

Po powyższych zmianach konieczny jest restart systemu. W tym momencie należy skupić się na zdarzeniach 1614 notowanych w dzienniku usług katalogowych, które zawierać będą zapytania LDAP wymagające od kontrolera przeszukania większej ilości obiektów niż ustawione w monitoringu. Na tej podstawie możemy określić które atrybuty są wyszukiwane w sposób nieefektywny i spróbować je zaindeksować odciążając w sposób znaczący nasze kontrolery domeny. W kwestii samej optymalizacji zapytań – od razu powiedzieć sobie trzeba, że aby optymalizacja była wykonana rzetelnie, potrzeba do tego zaangażowania administratora domeny (budującego indeksy) oraz administratora systemu generującego nieoptymalne zapytania (który dostosuje zapytanie zgodnie z sugestiami administratora domeny). Dotyczy to najczęściej sytuacji, w których obcy system chcący wyciągnąć dane o użytkownikach domeny zamiast generować zapytanie na poziomie jednostki organizacyjnej, w której przechowujemy użytkowników, generuje zapytanie na samym korzeniu usług katalogowych, przez co kontroler domeny musi przejrzeć tysiące zbędnych obiektów. Przyczyny takiego stanu rzeczy leżą przede wszystkim w braku informacji do osób utrzymujących aplikację korzystającą z usług katalogowych o tym, jak wygląda struktura jednostek oraz jak organizowane są obiekty. Inną przyczyną jest pewnie wygoda programistów, którym łatwiej i szybciej jest odpytać korzeń Active Directory w swoim kodzie niż pytać klienta/administratora o strukturę jego organizacji. Wracając jednak do optymalizacji po stronie Active Directory. Namierzyliśmy już przykładowe nieefektywne zapytania, które wymagają przejrzenia tysięcy obiektów – co dalej? W pierwszej kolejności weryfikujemy, czy zapytanie rozpoczyna się we właściwej jednostce organizacyjnej, następnie budujmy odpowiednie indeksy. Zapytacie pewnie co miałem na myśli pisząc „odpowiednie”. Otóż Active Directory korzysta z kilku typów indeksów m.in.:

  • Indeks atrybutowy – ten typ indeksuje wartości danego atrybutu. Struktura indeksu zawiera wszystkie wartości danego atrybutu w bazie Active Directory, co za tym idzie kontroler domeny potrzebuje więcej czasu na jego utworzenie, a sam indeks zajmuje stosunkowo dużo miejsca w magazynie danych.
  • Wskaźniki kontenerowe (PDNT) – ten typ indeksuje wartości odnoszące się do nazw kontenerów Active Directory, przez co zajmuje niewiele miejsca w bazie oraz przyspiesza wyszukiwanie jednostek organizacyjnych.
  • Indeks zbiorowy (ang. Tuple index) – ten typ indeksu jest zoptymalizowany pod kątem tak zwanych przeszukiwań pośrednich (ang. Medial search), czyli np. zapytań o imię w postaci „*anna*”. Indeks zawiera wariacje danej wartości atrybutu, przez co w stosunku do innych indeksów potrzebuje znacznie większych przestrzeni w magazynie danych. Działa zauważalnie w zapytaniach pośrednich dłuższych niż 3 znaki, gdzie dramatycznie poprawia wydajność w stosunku do stanu sprzed indeksacji.
  • Indeksy ARN – w gruncie rzeczy ARN (ang. Ambiguous Name resolution) nie jest sposobem indeksacji, jednakże dodanie atrybutu do listy ARN skutkuje koniecznością przeszukania wszystkich wartości tego atrybutu w zapytaniach ARN, których największym konsumentem są serwery Exchange. Nierozważne modyfikacje listy ARN mogą mieć bardzo negatywny wpływ na wydajność kontrolerów domeny.
  • Indeksy poddrzew – jest to bardzo specyficzny typ indeksu. W istocie przygotowuje on kontroler domeny do tworzenia struktury widoku listy wirtualnej VLV (ang. Virtual List View). VLV z kolei nie jest indeksem, lecz strukturą pozwalająca klientowi na zapytania LDAP, które zwrócą mu posortowaną listę obiektów. W ten sposób klient będzie mógł na przykład przewijać zwrócone wyniki pobierając dane o obiektach wcześniejszych i późniejszych niż aktualnie obsługiwany. Jest to najbardziej obciążająca operacja, więc szczerze odradzam udostępnianie takiej struktury klientom. Niestety w pewnych scenariuszach struktura VLV jest wymagana na przykład znowu przez serwery Exchange.

Zlokalizowaliśmy już niewydajne zapytania LDAP do naszych kontrolerów domeny, zoptymalizowaliśmy je po stronie aplikacji, która je generuje, poznaliśmy możliwe do wykorzystania typy indeksów Active Directory – pora więc z nich skorzystać. W tym celu należy podłączyć się na przykład za pomocą narzędzia ADSIEdit do kontrolera domeny utrzymującego rolę wzorca schematu wybierając kontekst nazewnictwa jako schemat – Rys. 8 Następnie przejść do schematu oraz odnaleźć interesujący nas atrybut (w przypadku jeśli chcemy indeksować dany atrybut dla wszystkich obiektów Active Directory). Po jego odnalezieniu przechodzimy do właściwości i odnajdujemy atrybut „searchFlags”, który edytujemy – podając interesującą nas wartość indeksu – pełna lista wartości podana została w tabeli 5. Jako ciekawostka – dodając do siebie wybrane wartości z tabeli można uzyskać na przykład dwa różne typy indeksów, jak na Rys. 9, gdzie uzyskaliśmy zarówno indeks atrybutowy, jak i indeks zbiorowy dla atrybutu „title” poprzez dodanie wartości indeksu atrybutowego (1) oraz zbiorowego (32).

Rys.8. Podłączenie do schematu Active Directory.
Rys.8. Podłączenie do schematu Active Directory.
Rys.9. Modyfikacja indeksów dla atrybutu Active Directory.
Rys.9. Modyfikacja indeksów dla atrybutu Active Directory.

Lista popularnych wartości atrybutu searchflag oraz ich wykorzystanie w usługach katalogowych Active Directory przedstawiona została w poniższej tabeli.

Typ Atrybut FAS Wyłączenie audytu Atrybut poufny Indeks VLV Indeks zbiorowy Kopia Utrzymany po usunięciu Indeks
ANR
Indeks PDNT Indeks atrybutowy
Dane 512 256 128 64 32 16 8 4 2 1

Tab. 5. Znaczenie wartości atrybutu searchFlags.

Zachęcam więc do bliższego przyjrzenia się swojemu środowisku Active Directory oraz poznania mechanizmów, które w nim działają, a także optymalizacji wydajności na przykład poprzez rekonfigurację indeksów. Działanie proaktywne pozwala uniknąć problemów wydajnościowych, a zadowolenie klientów którym nagle LDAP zwraca wyniki na skomplikowane zapytania kilka/kilkanaście minut szybciej niż dotychczas również bywa bezcenne J Jedynym zagrożeniem jest to, że każdy indeks powoduje rozrost bazy Active Directory – w skrajnych przypadkach nawet o 20% oraz dodatkowo na czas tworzenia nowego indeksu może wystąpić krótka przerwa w świadczeniu usług katalogowych. Warto więc wykonywać takie modyfikacje poza godzinami produkcyjnymi.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *