Tag-arkiv: Token bloat

Kerberos problemer på webserveren?

Jeg har tidligere skrevet om problemer med kerberos´ tokenstørrelser i forhold til at logge på ADFS servere, men det gælder alle webservices der understøtter kerberos og jeg synes derfor jeg ville lave en uddybende forklaring og også give den helt rigtige opskrift på hvordan man retter sin egen http.

Problemet med et for stort kerberos token opstår når der er brugere der er medlem af så mange Active Directory grupper at deres token bliver for stort til at kunne overføres via http protokollen. Grundlæggende tillader http på en windows server at tokenet er 16384 Byte stort altså 16KB. Dette kan man rette ganske simpelt, men der er nogle overvejelser man skal gøre sig før man begiver sig ud i det. Den første er hvor meget ram man har i serveren kontra hvor mange brugere der tilgår serveren samtidig. Eksemplet i denne artikel omhandler en exchange server der reelt kun videresender brugere der leder efter deres exchange server (autodiscover) og i det tilfælde er der ingen fare ved at udvide til 64Kb altså en faktor 4 i forhold til det serveren accepterer ved installation. Men hvis ens server i forvejen er belastet eller er tæt på at være det, kan det betyde nedsatte svartider og dårligere service overfor ens brugere. Så vær varsom.

Selve tilretningen er simpel og bør ikke tage særlig lang tid, men husk på at når http servicen genstarter, afbryder den forbindelsen til alle brugere der er forbundet. Så alt efter forretningens politik for den slags, skal man nok forberede brugerne og foretage tilretningen udenfor perioder hvor serveren er tungt belastet.
For at rette størrelsen på det tilladte token skal vi have fat i nøglen HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\HTTP\Parameters i registreringsdatabasen. Under denne skal vi lægge 2 nye parametre ind, mm de er der allerede så skal vi bare tilrette dem. ;) Parametrene er MaxFieldLength og MaxRequestBytes og de skal se ud som nedenstående for at øge værdien til 64K.

“MaxFieldLength”=dword:0000fffe
“MaxRequestBytes”=dword:0000fffe

Når disse er lagt ind skal vi have genstartet http servicen. Denne er ikke tilgængelig under services konsollen da det er en kernelservice. Den skal stoppes og startes fra en kommando prompt ved at skrive:

Net stop http

Bemærk at den forespørger om man nu er sikker og samtidig fortæller hvad den trækker med ned. De services den trækker med ned kommer ikke op igen når http servicen startes, de skal startes manuelt. Jeg gør det normalt fra en powershell prompt og så laver jeg et hurtigt lille script der starter de berørte services, på den måde kan jeg minimere mine nedetider til få minutter. I dette tilfælde meddeler http at den stopper 5 ekstra services:

net stop http

 

 

 

 

for at starte dem enkeltvis i powershell skrives:
start-service servicenavn

Efter gentart af http servicen og start af de 5 services er webserveren klar til at modtage brugere med token størrelser på op til 64k. Så kan man spørge sig selv hvorfor jeg ikke korrigerer for base64 encodingen og sætter grænsen til 48K? Det er fordi problemet her er hvor meget der kan overføres til serveren og der er base64 encodingen ikke et problem. Det er til gengæld meget vigtigt når man vælger MaxTokenSize på sine klienter. For hvis man tillader dem at benytte tokens der er større en 48K, risikerer de ikke at kunne logge på webservere når deres token er blevet base64 obfuskeret. ;)

ADFS fejlfinding

Jeg har brugt det meste af 2 dage på at finde en fejl i et ADFS system hvor enkelte brugere, ikke får lov at logge på systemer der ellers er federede med ADFS farmen.

Problem:

Når brugeren tilgår en side hos en federationspartner, bliver han som forventet sendt videre til ADFS serverens webside sts.domænenavn.dk. Men istedet for at blive logget på eller bedt om brugernavn/password, får han en 400 error.

Hurtigt tænkte jeg at dette kunne være et problem med brugerens token størrelse. Husk på at antallet af grupper en bruger er medlem af, øger størrelsen på det token han bruger til at opnå godkendelse med, når kerberos benyttes. Jeg talte hans grupper ved at bruge repadmin til at vise hans grupper.

repadmin /showobjmeta DCBrugerens DN” /nocache /linked >c:\temp\objectmeta.txt

Åbn objectmeta.txt i excel og så har du et overblik over hvor mange grupper han har. Dette burde kunne gøres i powershell med measure-object eller count, men jeg brugte en quick and dirty, da problemets omfang ikke tillod tid til at lege! ;)

Brugeren havde 400 grupper og alt efter hvilken type grupper det er kan hans token udemærket være ude over grænsen på 12KB som er standard i windows. Jeg øgede derfor MaxTokenSize på serverne og genstartede services, dette hjalp ikke. Her gjorde jeg noget dumt og troede at hans token ikke var en del af problemet.

Næste step var at undersøge om brugeren havde specielle settings vedr. kerberos delegation. Men heller ikke her var der noget at komme efter.

Jeg loggede også på med brugeren og tjekkede loggen på den DC han kom via og så at han benyttede kerberos mod andre systemer uden problemer.

Tjekkede at brugeren ikke havde nogle politikker enablet der kunne forårsage dette, ved at køre RSOP og tjekke network security settings, heller intet at se.

Til sidst benyttede jeg Microsoft Network monitor 3.4 til at se trafikken når brugeren loggede på. Umiddelbart var der intet at bemærke, men når han ramte webserveren kunne jeg se at han rent faktisk begyndte at overføre sit token, men at webserveren så til sidst smed ham af og meldte fejl 400. Altså nægter webserveren ham ikke at logge på men kan ikke modtage hele hans token.

Forvirringen i hele dette er at MaxTokenSize indstillingen giver os lov til at benytte tokens der er større end default og det burde vel have løst dette problem? NEJ for problemet er ikke kun størrelsen af tokenet der må benyttes. Problemet er derimod hvor stort et token der må overføres i request headeren til serverens http service. Husk på at tokenet bliver overført, base 64 encoded til http servicen i request headeren. Denne tillader også kun 12KB standard. Efter at have rettet MaxFieldLength og MaxRequestBytes, genstartet http servicen og startet alle de andre services igen manuelt, på alle serverne, virkede det!