Předminule jsem tu psal o účtech počítačů a zmínil jsem se o hodnotě lastLogonTimestamp, která obsahuje časové razítko posledního ověření uživatelského účtu (v článku šlo o účet počítačů, které jsou ale také uživateli). A rovnou k tomu přišel dotaz, tak nebude špatné si o tom trošku pohovořit.
Časová razítka ověření v Active Directory
AD databáze uchovává dvě časová razítka posledního ověření. Záměrně mluvím jen o ověření a nikoliv o přihlášení. Na stanice se člověk může přihlásit i když nejsou zrovna připojeny k firemní (prostě klidně k žádné) síti. V takovém případě se do AD nic ani zapsat nemůže. A stanice to ani později nijak zpětně nedoplňují.
Tato razítka jsou dvě - lastLogon a lastLogonTimestamp. To druhé lastLogonTimestamp je tam až od Domain Functional Level 2003 (DFL), tedy až od okamžiku, kdy máte všechny řadiče domény (DC - Domain Controller) verze alespoň Windows Server 2003. Tedy abych to řekl přesně. Ten atribut lastLogonTimestamp je tam už od okamžiku, kdy ho zavedete do Active Directory schema při instalaci prvního DC verze alespoň Windows Server 2003, no ale jeho hodnota se vyplňuje až od povýšení celé domény DFL.
Všechny uživatelské objekty, třídy user i computer, tedy jak účty uživatelů tak i počítačů tyto atributy obsahují a je tedy možno je použít k prohlídce poslední online aktivity daných účtů. Říkám poslední online aktivity, ale to není skoro nikdy ta úplně poslední, což musíme za chvilku vysvětlit. Následující obrázku ukazují příklad z účtu nějakého uživatele i počítače:
Rovnou si můžete všimnout, že hodnoty obou atributů jsou různé. V obou obrázcích je je lastLogon novější, než lastLogonTimestamp. Ale ve skutečnosti můžete vidět všechny možné kombinace - tedy novější lastLogonTimestamp, nebo se může stát, že jedna z hodnot nemusí být vyplněna vůbec, nebo dokonce žádná z nich. Jde o to, na které DC a za jakých okolností se díváte.
Zápis hodnoty do lastLogon a lastLogonTimestamp a odhlášení v atributu lastLogoff
DC pozměňuje hodnotu obou atributů podle určitých pravidel, která vysvětlíme za chviličku. V prvé řadě si však musíte uvědomit, že to může nastat jen v okamžiku ověření uživatele. To znamená v okamžiku, kdy uživatel, nebo počítač, požaduje po DC ověření svého hesla (nebo certifikátu, protože Kerberos PKINIT je nativní technologie).
Pro ověření fungují jen dva protokoly. NTLM a Kerberos. Kerberos vydává na základě přihlašovacích údajů (heslo, certifikát) uživateli tak zvaný tiket (TGT a TGS). Tikety platí vždycky nějakou dobu (ve výchozím stavu 10 hodin) a jsou potřeba pro přístup na každou síťovou službu i stanici, na které uživatel pracuje. Takže tohle ověření probíhá jen několikrát denně - typicky ráno při příchodu a potom pokaždé, když uživatel přistupuje na nějakou služub poprvé - poprvé se dívá na nějaký sdílený adresář, poprvé přistupuje do SQL serveru, poprvé si otevře Outlook s Exchange profilem, nebo poprvé jde na internet přes TMG/ISA proxy nebo do SharePoint.
Takže se Kerberosem budou ty hodnoty někdy až 10 hodin staré, i když je uživatel zrovna v plné činnosti v síti. Zatímco NTLM je rychlejší. NTLM ověřuje uživatele při každém novém přístupu na síťovou službu. Nebo lépe řečeno při každém ustavení nového TCP spojení (v případě SharePoint nebo i jiných HTTP aplikací to nemusí být nutně při každém ustavení TCP/HTTP spojení, pokud se používají cookies).
Takže jestli si uživatel před několika minutami, dneska už po třicáte, otevřel nové okno prohlížeče a podíval se na SharePoint, který ověřuje pomocí NTLM, tak ta hodnota může být velmi aktuální. NTLM je v ideálním případě na ústupu a používá se v sítích ideálně jen občas jako záloha, pokud Kerberos nefunguje, nebo je něco špatně nastaveno (a nebo když Kerberos prostě fungovat nemůže).
Ještě jste si mohli na obrázcích všimnout atributu lastLogoff. Ten je prázdný a také prázdný zůstane. LDAP standard Active Directory tento atribu definuje, takže tam prostě musí být. Ale nic ho nenastavuje. Ani Kerberos ani NTLM při ukončování práce žádnou komunikaci s AD nevyvolává. Nehledě na to, že lidi stejně jenom vytrhnou noťas ze sítě a valí pryč, takže by to stejně byla podivná informace.
Samozřejmě, jestli chcete, můžete si udělat například vlastní logoff script, který by při odhlašování uživatele ze stanice tenhle atribut aktualizoval, ale stejně to nebude moc spolehlivé. Jen pro pořádek, museli byste také daným uživatelům povolit zápis do tohoto atributu - zřejmě něco jako:
DSACLS /Grant "SELF:WP;lastLogoff"
DSACLS /Grant "SELF:WP;Logon Information"
Atribut lastLogon se nereplikuje
Pojďme se podívat na hodnotu atributu lastLogon. Ten je nejstarší, už od Windows 2000. Zapisuje se při každém ověření a zapisuje se přesně daný čas. Takže to vypadá jako ideální hodnota, ne?
Není. Ten atribut se nereplikuje (non-replicated attribute). Už jenom sama replikace vyžaduje ověřování. Kdybyste každou změnu toho atributu replikovali, museli byste u toho aktualizovat další lastLogon atributy a zase je replikovat. Taková nekonečná smyčka :-) Takže každé DC si uchovává tento atribu pouze ve své databázi.
Tím pádem jde o to, na které DC se zrovna díváte. Pokud je to zrovna to uživatelovo aktuální DC, bude hodnota nejnovější možná. Mnohdy máte ale DC, která jsou v různě odlehlých oblastech, kde se daný uživatel ověřoval už hoodně dávno, nebo třeba ještě vůbec nikdy. Takže hodnota se může lišit od úplně nové po úplně žádnou.
Které DC si tedy vybrat na průzkum poslední aktivity a uživatelů? Takové nelze určit. Musíte se podívat na všechny. A musíte si vybrat jen tu nejnovější hodnotu, kterou najdete. A to je v rozlehlých sítích (a to nemyslím rovnou sítě s desítkami DC, stačí, když máte nějakou pobočku za ADSL) dost problém, protože takový průzkum dost trvá.
Atribut lastLogonTimestamp se naopak replikuje
Cože? Před chvilkou jsem tu říkal, že by se to zacyklilo. Jenže my bychom rádi viděli nějakou informaci o aktivitě z každého DC, abychom to nemuseli všechno projíždět a porovnávat. Jak to teda udělat?
Od Windows Server 2003 DFL funguje lastLogonTimestamp a to takto. Možná nám pomůže obrázek:
Funguje to následovně. Každé DC aktualizuje primárně ten starší atribut lastLogon. A při jeho aktualizaci se podívá, jaká je hodnota v tom druhém, lastLogonTimestamp. Pokud tam ještě žádná hodnota není, prostě tam okopíruje to, co se zrovna vložilo do lastLogon. Nic tam není ve dvou případech - buď se ten uživatel nebo počítač ověřuje vůbec poprvé, nebo jsme teprve zrovna zvedli DFL na úroveň Windows Server 2003.
Když tam už nějaká hodnota je, DC se podívá jak je ta původní hodnota stará. Pokud je starší než 14 dnů (mínus náhodný počet dnů z intervalu 0-5), tak ho znovu zaaktualizuje. To znamená, že pokud je jeho původní hodnosta starší než 9-14 dnů, hodnota se změní. V opačném případě se na ten atribut nesahá.
Znamená to, že hodnota atributu lastLogonTimestamp se mění jen jednou za 9-14 dnů a může se tedy v pohodě replikovat. Nezatěžuje to příliš replikaci a ani nemůže dojít k zacyklení. Na druhé straně je tedy ta hodnota stará až 14 dnů i v případě, že ten člověk (nebo počítač) zrovna vesele počítačuje hnedka vedle na stanici.
Může být starší, než 14 dnů? Ano, pokud se člověk během posledních několika dnů nepřihlásil. Takže pro přehled o aktivitě za poslední měsíc, nebo několik týdnů to úplně stačí.
Rychlost aktualizace lastLogonTimestamp a její změna
Hodnota 14 dnů není nijak natvrdo zabetonovaná do ADčka. Je to jen výchozí nastavení. A dá se to změnit. Je to definováno hodnotou atributu msDS-LogonTimeSyncInterval, který najdete ve vlastnostech kořene domény. Můžete tam dát cokoliv od 1 po cokoliv většího. Při hodnotě 1 bude lastLogonTimestamp starý maximálně 1 den. Když tam dáte číslo 3, bude jeho hodnota stará maxímálně 1-3 dny. Pokud tam dáte číslo 48, bude to datum staré nejhůře 48 a nejméně 43 dnů.
Samozřejmě si to můžete zkrátit, jak vám to nejvíc vyhovuje, ale pro veliká prostředí s tisíci uživateli bych se nejdřív zamyslel, jak moc to pohne se množstvím replikací, které se budou muset roztáčet mezi všemi DCčky v doméně.
Domain Functional Level, řadiče a klienti
Když už tu tak přemýšlíme, pojďme se jen pro zajímavost podívat na to, jaký je vliv DFL a případně jestli to nějak ovlivňuje klienty.
Tak klientům je to úplně u prdele. Z počítače se prostě dělá Kerberos. Sám fakt, že si nějaké DC tyhle události poznačuje do databáze, žádného klienta ani žádný členský server domény vůbec nezajímá. Změna DFL, která tuto věc zapne, tedy doménové členy (domain member) absolutně netankuje.
Proč se to zapne až při DFL Windows Server 2003? Co když už máte několik DC s verzí Windows Server 2003 a přitom ještě jen nemáte povýšenou úroveň Domain Functional Level (DFL)? Nemohla by prostě jen ta některá novější DC ten atribut aktualizovat?
No v podstatě technicky mohla. Atribut je už tak definován ve schématu od okamžiku instalace prvního DC verze Windows Server 2003, takže z pohledu replikace to není problém. Starší Windows 2000 by jeho hodnotu prostě jen zobrazovali, ale nesahali na ni. No jo, ale to je právě ten problém.
Co kdyby se člověk ověřoval po třech týdnech vůči nějakému Windows 2000 DCčku? Tak ono by neprovedlo aktualizaci a lastLogonTimestamp by zůstal zastaralý. Strarší než těch 14 dnů. Takže by chování vůči jeho hodnotě bylo nekonzistentní a logika by byla poškozena. Tak proto se čeká na DFL 2003. Prostě to je jen pojistka, že všechna DC umí ten atribut aktualizovat.
Vyhledání neaktivních počítačů
Tak abychom to i na něco použili, následující dva PowerShell skripty vám vyhledají všechny účty počítačů, které se už pět týdnů neověřily. Neznamená to, že jsou úplně mrtvé, jen to nejspíš signalizuje, že už alespoň pět týdnů nebyly v doménovém prostředí.
Import-Module ActiveDirectory
$today = (Get-Date)
$before5Weeks = $today.AddDays(-5 * 7)
$adBaseDate = [DateTime]::Parse("1601-01-01")
$ticksBefore5Weeks = ($before5Weeks - $adBaseDate).Ticks
Get-ADComputer -LDAPFilter "(lastLogonTimestamp>=$ticksBefore5Weeks)" | ft DNSHostName
A nebo to můžete rovnou zprasit všechno dohromady a pustit si na to Active Directory Module for PowerShell z nabídky start:
Get-ADComputer -LDAPFilter
"(lastLogonTimestamp>=$(((Get-Date).AddDays(-5 * 7) - [DateTime]::Parse("1601-01-01")).Ticks))"
| ft DNSHostName
Nezapomeňte jenom, že jestliže to chcete spouštět jinde, než rovnou na DC, musíte mít dostupnou službu Active Directory Web Services na vzdáleném DCčku.
A zajímavost na závěr
Mám dokonce zákazníka, který ten atribut kdysi tak moc chtěl, že si čistě kvůli tomu povýšil svých 11 DC na Windows Server 2003 :-)
Tak pěkný víkend všem! A už neseďte u komplů a jděte se trošku proběhnout. Začíná tam jaro!