dolezel.net

Co není v hlavě, je v blogu...

Windows XP a zdlouhavé připojování do sítě, nefunkční login skript

Nejhorší závady jsou, když něco řadu měsíců či let běží a pak se to bez zjevné příčiny podělá. Jako v případě jedné firmy, která má AD se dvěma sajtami, DFS s replikací mezi sajtami a klienty smíšenými Windows XP SP3, Windows Vista, Windows 7. Zničehonic si začali uživatelé s WXP v pobočkové sajtě stěžovat na pomalý login do sítě, chybějící síťové disky, zatuhávající explorer.exe a řadu dalších problémů. Procházel jsem komplet všechny servery, virtualizované i Hyper-V mastery, nikde nic. Zvažoval jsem případný problém s TCP offloadem, TCP Chimney, RSS, ale to by problémy nepostihovaly jen WXP. V pobočkové sajtě je jeden AD řadič, je to Global Catalog, eventlog čistý jak lilie. Hlava mi to nebrala, prohledával jsem všemožné stránky, dohledával historické WXP hotfixy týkající se DFS, abych vždy zjistil, že už jsou začleněny do SP3. Kontroloval jsem čas, lokální i síťové firewally, antiviry, DNS zóny dopředné i reverzní, práva na GPO, nic.

Chybové hlášky, které se objevovaly na WXP klientech, byly docela strašidelné:

Event ID: 40961 od LSASRV

The Security System could not establish a secured connection with the server cifs/ad1.domain.local. No authentication protocol was available.

Event ID: 40960 od LSASRV

The Security System detected an attempted downgrade attack for server cifs/ad1.domain.local. The failure code from authentication protocol Kerberos was “There are currently no logon servers available to service the logon request (0xc000005e).”

Event ID: 1097 od Userenv

Windows cannot find the machine account. No authority could be contacted for authentication.

Event ID: 1030 od Userenv

Windows cannot query for the list of Group Policy objects. A message that describes the reason for this was previously logged by the policy engine.

No a po deseti hodinách hledání (teď si nadávám, že mne to nenapadlo dříve) jsem přišel na to, že na vině je RouterOS v kombinaci s implicitním chováním Kerberosu. Pobočka i centrála jsou totiž připojeny k Internetu nějakým Mikrotikem, mezi nimiž je nakonfigurována VPN. Tato VPN bez problémů fungovala, takže nebylo nutné nic měnit. Najednou ale VPN začala fragmentovat packety velikosti 1500 bytů. Pomocí příkazu “ping –l 1432 server” jsem zjistil, že poslední velikostí nefragmentovaného packetu je 1432 bytů. A jakou to má souvislost s výše popisovanými chybami? Kerberos ve Windows XP totiž řídí jedním RFC, které vyžadovalo UDP pakety. Tyto packety byly ale moc velké, takže docházelo k jejich fragmentaci. UDP protokol je ale nespojitý (connectionless), takže není zaručeno doručení paketů ve stejném pořadí, v jakém byly odeslány. A v tom je kámen úrazu. Jakmile se nějaký paket někde krapet zdrží nebo nedojde vůbec, má to neblahý efekt na kontinuitu Kerberosu. Bližší informace až za chvíli.

Rychlým fixem bylo otočit oba Mikrotiky, VPN se sestavila znovu a vše zase začalo fungovat. Nebádal jsem dále, jestli znovusestavená VPN povolila packety o velikosti 1500 bytů nebo se prostě začaly fragmentované pakety na druhém konci sestavovat rychleji a doručovat ve správném pořadí. Začal jsem hledat, proč to ovlivnilo pouze WXP a nikoliv třeba W7 či W2008. Kdyby to ovlivňovalo všechny systémy, došel bych k problémům se sítí pravděpodobně rychleji.

Odpověď na tyto otázky mi poskytl aktualizovaný článek 244474 v MSKB How to force Kerberos to use TCP instead of UDP in Windows. Je to prostě takhle. Windows XP, Windows Server 2003 a Windows 2000 používají Kerberos dle RFC 1510. Toto RFC stanoví, že klient pošle UDP paket na portu 88 na Key Distribution Center (KDC) a ten mu také na UDP odpoví.

RFC 1510 však bylo nahrazeno RFC 4120, které specifikuje, že KDC musí akceptovat TCP požadavky na tomtéž portu 88. Windows Server 2008, Vista a Windows 7 již při prvním požadavku rovnou použijí TCP. To vysvětluje, proč servery (všechny byly W2008R2) i stanice s Vista/W7 neměly žádný problém. A také to vysvětluje, proč jsem nemohl na žádný problém při revizi serverů přijít.

Windows Server 2003 má standardně nastavenu maximální velikost UDP packetu na 1465. Windows 2000 a Windows XP pak mají nastavenu maximální velikost UDP packetu na 2000. V momentě, kdy mi přes VPN prošla maximální velikost 1432, tak nastal problém. Kerberos v uvedených starších systémech totiž standardně používá nespojité UDP datagramy. Některé se vešly do MTU ve VPN, některé už ne. Proto ty podivné chyby. V pobočkové sajtě sice byl místní AD řadič, ale odkazy v DFS vedly na file server v centrále, stejně tak mapované disky v login skriptu odkazovaly na centrálu.

Řešením je donutit i starší systémy, aby pro Kerberos použily TCP. Na všech dotčených systémech je třeba založit záznam v registry ve větvi HKLM\System\CurrentControlSet\Control\Lsa\ Kerberos\Parameters:

Value Name: MaxPacketSize
Data Type: REG_DWORD
Value Data: 1

Novější systémy Vista, W7, W2008 už mají jako implicitní hodnotu (tj. neexistuje fyzicky v registrech, ale je prostě tam) MaxPacketSize nastavenu 0, která také vyřadí UDP a místo toho zařídí TCP.

Pokud jsou klientů se staršími operačními systémy desítky či stovky, je nereálné to měnit po jednom. Nabízí se tak nasazení GPO – samozřejmě pouze v případě, že tito klienti mají ve své sajtě dostupný AD řadič, který komunikuje bezproblémově se zbytkem AD a GPO se tak k němu dostane, což v tomto případě (W2008R2) bylo bezproblémové. Jsou dvě možnosti, jak toho dosáhnout:

  1. hezky moderně pomocí GPO Policies
  2. hezky postaru pomocí ADM šablony naimportované do GPO

Líbila by se mi varianta 1, ale ta má několik nutný předpokladů:

Tohle by znamenalo instalace přes GPO (aby byla jistota, že tam ten hotfix bude a určitě instalaci XMLLite. Znamenalo by to také víc rebootů atd., prostě v tomto případě jsem musel zvolit starý způsob.

Tady jsem si stáhl šablonu pro moji Kerberos Administrative Template. Uložil jako kerberos.adm. Vytvořil jsem si novou GPO “Kerberos over TCP”, do které jsem naimportoval tuto šablonu – Computer Configuration, Policies, Administrative Templates, pravé tlačítko – Add/Remove templates…. Poté jsem aktivoval MaxPacketSize a přiřadil jí hodnotu 1.

kerberos_udp1

Zavřel jsem okno Group Policy Management Editoru, tím se uložila definice GPO. V Group Policy Management jsem pak ještě nastavil User configuration settings disabled (kvůli optimalizaci rychlosti provádění GPO). Vzhledem k tomu, že jsem registry potřeboval změnit sice v celé doméně, ale pouze na strojích s WXP a W2003 (W2000 zaplaťpánbůh už nikde nebyly), tak jsem využil WMI filtru.

kerberos_udp2

U WMI filtru je potřeba počítat s tím, že firewall na lokální stanici musí být nastaven tak, aby si AD řadiče mohly “hrábnout” na ten konkrétní počítač a zjistit si potřebné.

Poté jsem nové GPO v záložce Scope nastavil podmínku WMI Filtering.

kerberos_udp3

Předposledním krokem pak bylo nalinkování nově vytvořené GPO na testovací OU, do kterého jsem umístil virtuální WXP, zreplikoval všechna AD a 2x rebootnul ty WXP (dvakrát je důležité, při prvním startu se aplikuje záznam do registrů, při druhém se již projeví v chování. A ejhle – přilogování trvá chvíli, namapované disky mám všechny, otevírat jdou s rozumnou odezvou, problém vyřešen. Takže jsem GPO nalinkoval na celou doménu.

kerberos.zip (1,41 kb)

wmi_wxp_w2003_only.zip (594,00 bytes)

Pro tisk

Komentáře (1) -

  • AdDragon

    22. 2. 2011 14:27:42 |

    No pěkný!

Komentáře jsou uzavřeny