Věcem, které popisuji v tomto článku, jsem se věnoval nově a detailněji a připravil rozsáhlý seriál Kerberos protokol se zaměřením na SSO v AD DS. S tímto článkem nejvíce souvisí díl Kerberos část 10 - nastavení webových prohlížečů.
Pro provedení Single sign-on (SSO) budeme uvažovat bezpečný protokol Kerberos, jeho popis naleznete v předchozím článku Kerberos protokol a Single sign-on. MS klientské OS od verze Windows 2000 podporují protokol Kerberos nativně a dokonce jej upřednostňují před starším proprietárním protokolem Microsoftu NTLM (který se dnes nepovažuje za bezpečný). Windows také poskytují API pro aplikace, aby mohly využít tento protokol. Local Security Authority (LSA) zařizuje autentizaci uživatele a volá Security Support Provider Interface (SSPI), což je rozhraní které komunikuje s autentizačními protokoly (a jeho funkce může využít aplikace), například Kerberos SSP.
Problémy ve Windows
V praxi, při nasazování SSO pro aplikace, jsme na klientovi narazili na dva problémy. Oba vznikají stále větším zabezpečením klientů, o které se MS snaží. Následuje jejich stručný popis a možné řešení.
Poskytnutí TGT a session key
Microsoft zvedl bezpečnost v OS tím, že omezil rozhraní pro získání TGT/session key páru z Kerberos autentizačního balíčku. Když máme na Windows klientovi aplikaci (napsanou třeba v Jave), která používá Kerberos autentizaci, tak může používat jedno ze dvou rozhraní. Buď SSPI, které zajistí kompletní Kerberos služby nebo LsaCallAuthenticationPackage z Windows SDK, jehož funkce poskytují mechanismus pro získání ticketu z Kerberos cache. A právě při použití LsaCallAuthenticationPackage potřebujeme mít možnost získat ze systému i session key. Pro takové účely je možno jej povolit pomocí registrů. Jde o hodnotu AllowTGTSessionKey, která je defaultně [dword] 0
(funkce vrací pouze TGT bez session key, takže nelze použít pro SSO) a my ji můžeme změnit na 1
. Ve Windows XP se tento klíč nachází v
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\
Ve Windows 7, Vista, 2000, Server 2003, Server 2008, je to
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\Kerberos\Parameters\
Popis je v článku Registry Key to Allow Session Keys to Be Sent in Kerberos Ticket-Granting-Ticket. Změna se projeví až po restartu. Dalším poznatkem je, že aplikace musí běžet pod lokálním administrátorem (při použití UAC ve Windows 7 se musí manuálně spustit), jinak se jí nepodaří získat TGT. Vše by se zlepšilo, kdyby programátoři použili SSPI, jako je tomu v Internet Exploreru nebo ve Firefoxu.
Popsaný problém může být doprovázen chybou v Jave:
GSSException: No valid credentials provided (Mechanism level: No valid credentials provided (Mechanism level: Integrity check on decrypted field failed (31)))
Extended Protection for Authentication
Další zvýšení bezpečnosti přinesla technologie Extended Protection for Authentication (channel binding token - CBT). Pokud je s ní problém, je možno ji vypnout. Chyba se projeví, například když na serveru běží Java (bylo opraveno ve verzi JRE 6 update 21) a my se připojujeme z Internet Exploreru. Při SSO zaloguje chybu ChannelBinding not provided!
. Popis se nachází v MS článcích Extended Protection for Authentication Overview a Extended Protection for Authentication. Problém se vyřeší následujícím nastavením registrů (i když hodnotu 2 MS neuvádí jako možnou), na Windows XP je třeba restart.
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\SuppressExtendedProtection=dword:00000002
SSO do webové aplikace
Obecný způsob, jak funguje SSO pro webové aplikace. Ve webovém prohlížeči otevřeme nějakou adresu (odešleme HTTP/Post/Get požadavek na web server). Zde je vyžadována autentizace a aplikace má nastaveno použití SSO, které podporuje web server. Takže web server odešle klientovi SPNEGO vyjednávání o autentizaci (HTTP 401 Authenticate/Negotiate). Prohlížeč přijme žádost a nyní záleží na tom, zdá má povoleno IWA a také webovou adresu serveru. Pokud ne, tak odmítne vyjednávání a je již na web serveru nebo spíše aplikaci, jak se zachová. Pokud má povoleno, tak se vyjednává protokol, my uvažujeme pouze Kerberos, takže web server musí podporovat tento. Pokud je vše v pořádku, tak webový prohlížeč využije sytémové knihovny SSPI (Security Support Provider Interface) a získá service ticket od KDC. Tento service ticket odešle jako odpověď na web server (authorization SPNEGO token v HTTP hlavičce). Server jej zpracuje, získá uživatelské ID a ověří jej, a když je vše v pořádku, tak předá aplikaci uživatelovi údaje.
Nastavení Internet Exploreru
Internet Explorer (IE) jako MS aplikace samozřejmě podporuje Integrated Windows Authentication. Tuto metodu je možno v nastavení zakázat, ale defaultně je povolena. Uplatňuje se pouze na internetové adresy, které patří do skupiny Local Intranet.
Takže požadavky, aby fungoval SSO v IE jsou:
- povolit Integrated Windows Authentication - defaultně povoleno (nastavení v menu Tools - Internet Options - Advanced - část Security)
- nastavit adresu serveru mezi Local Intranet - defaultně je povolena možnost Automatically detect intranet network, takže by se měly automaticky detekovat lokální adresy (nastavení v menu Tools - Internet Options - Security - Local Intranet - Sites - Advanced), ale bezpečnější je nastavit přímo adresu
Když zadáváme adresy mezi Local Intranet, tak můžeme zadat přímo adresu serveru, třeba www.domena.com
(pak se uplatňuje na http i https protokol) nebo můžeme specifikovat i protokol https://www.domena.com
nebo můžeme zahrnutou celou doménu (a všechny podřízené adresy) pomocí *.domena.com
. Místo DNS jmen můžeme použít i IP adresy (volitelné oktety nahradit hvězdičkou), ale v praxi jsem měl s tímto nastavením problémy.
Konfigurace pomocí Group Policy
Nastavení věcí okolo Local Intranet v IE můžeme provést pomocí Group Policy (GP) a aplikovat buď na uživatele, nebo na počítač. Doporučované je provést nastavení pro uživatele. Hodnoty se v GP nachází:
User Configuration - Policies - Administrative Templates - Windows Components - Internet Explorer - Internet Control Panel - Security Page
Otevřeme položku Site To Zone Assignment List, povolíme tuto politiku a přidáme adresy, které chceme zařadit do zóny. Pro každou adresu je jeden řádek, do value name zadáme adresu (třeba *.domena.local) a do value dáme číslo zóny, do které chceme zařadit adresu (1 - intranet, 2 - trusted, 3 - internet, 4 - restricted). Vedlejším efektem, který může být vítaný nebo naopak ne, je, že po nastavení této politiky se uživatelům zakáže přidávat (upravovat) adresy v zónách. Hodit se může i informace, kde se nastavení zón nachází v registrech (ale ne pokud jej nastavujeme politikou):
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\Domains\
Na stejném místě můžeme také zapnout politiky Intranet Sites: Include all sites that bypass the proxy server
, Intranet Sites: Include all network paths (UNC)
a Intranet Sites: Include all local (intranet) sites not listed in other zones
.
Mozilla Firefox
Ve Firefoxu je použití Integrated Windows Authentication také možné již dlouhou dobu. Firefox využívá systémové knihovny SSPI (Security Support Provider Interface nebo na Linuxu GSS-API). Funkce je obecně zapnutá, ale je třeba nakonfigurovat adresy, pro které se použije. Pro všechny ostatní Firefox odmítá všechna vyjednávání od web serveru (mohlo by dojít ke zneužití, hlavně při použití NTLM, které odesílá hash hesla). Ruční konfigurace ve Firefoxu se provádí tak, že do adresního řádku zadáme text:
about:config
Po potvrzení varování, že změny konfigurace mohou být nebezpečné, vidíme jednotlivé konfigurační parametry. Do filtru zadáme proměnnou, kterou chceme měnit. V našem případě jsou k dispozici dvě
pro Kerberos je to network.negotiate-auth.trusted-uris
pro použití NTLM je
network.automatic-ntlm-auth.trusted-uris
My používáme Kerberos, takže zadáme první hodnotu a po vyfiltrování ji rozklikneme. Nyní zadáváme textový řetězec. Do hodnoty můžeme zadat přímo adresu serveru, třeba www.domena.com
(pak se uplatňuje na http i https protokol) nebo specifikovat i protokol https://www.domena.com
případně můžeme zahrnutou celou doménu (a všechny podřízené adresy) pomocí domena.com
. Více hodnot můžeme oddělit čárkou. Změna se projeví okamžitě.
Konfigurace pomocí Group Policy
Konfiguraci Firefoxu můžeme provádět pomocí JavaScriptových konfiguračních souborů. Těch je celá řada, uživatelské konfigurace se nachází pod uživatelským profilem. Například na Windows 7 je to c:\Users\{profil}\AppData\Roaming\Mozilla\Firefox\Profiles\{firefox-profil}.default\
. Zde je soubor prefs.js
, který se vytváří automaticky a neměl by se modifikovat. Můžeme vytvořit souboru user.js
, kam zadáme nastavení pro uživatele. Jednodušší jsou globální konfigurace, které se nachází v adresáři, kde je nainstalovaný Firefox. Defaultní cesta na 64 bitových Windows 7 je c:\Program Files (x86)\Mozilla Firefox\defaults\pref\
. Zde můžeme vytvořit soubor all.js
případně all-{jméno firmy}.js
. Do souboru zadáme příkaz
pref("network.negotiate-auth.trusted-uris", "seznam adres oddělených čárkou");
Když chceme provést hromadnou konfiguraci více stanic, tak můžeme opět použít Group Policy, i když trochu složitěji. Pomocí GP zajistíme zkopírování konfiguračního souboru. Budeme vycházet z toho, že máme k dispozici "novinku" Group Policy Preferences, která nám celou věc usnadní.
Nejprve musíme vytvořit soubor s konfigurací, zmíněný all.js
. Ten potom potřebujeme umístit do sdíleného úložiště na síti, kam bude mít počítač/uživatel při startu přístup. Jednou možností je adresář NETLOGON na doménovém řadiči (díky replikaci tedy na všech = na doménovém sharu).
Dále si musíme rozmyslet, jestli budeme politiku aplikovat na uživatele nebo počítač. Soubor budeme nahrávat do Program Files, takže můžeme vytvořit politiku pro počítač, ale jde o to, jak se nám bude lépe aplikovat. Podle toho pak volíme část Computer Configuration nebo User Configuration v GP. V příkladu zvolíme uživatelskou část, potřebná konfigurace je v
User Configuration - Preferences - Windows Settings - Files
Klikneme do plochy pravým tlačítkem a zvolíme New - File. Zvolíme metodu, dostatečná může být Create. Zadáme zdrojovou cestu ke sdílenému souboru a cílové umístění. Budeme počítat pouze s defaultní lokalitou instalace, takže pro 64 bitové Windows 7 je to C:\Program Files (x86)\Mozilla Firefox\defaults\pref\all.js
. Tím můžeme mít politiku hotovou.
Pokud ale máme v síti i 32 bitové OS a nebudeme řešit rozdělení pomocí aplikace GPO na kontejner, který obsahuje pouze počítače s 32 bitovým OS a jinou politiku aplikovat na 64 bitové OS (což zde nemůžeme, když jsme zvolili uživatelskou část konfigurace). Tak to můžeme vyřešit pomocí Item-level targeting. Máme stále otevřené vlastnosti vytvoření souboru, přepneme se na záložku Common. Zde se nachází Item-level targeting, zaškrtneme a klikneme na Targeting. Přes New Item zadáme parametr, který chceme porovnávat. Nabízela by se položka Operating System, ale v praxi mi nefungovala správně, takže zvolíme File Match a porovnávám, jestli existuje adresář C:\Program Files (x86)\Mozilla Firefox\defaults\pref
. V tom případě se vytvoří soubor zde.
Potom doplníme druhý soubor s cestou C:\Program Files\Mozilla Firefox\defaults\pref\all.js
, kde změníme pouze u porovnání Item Option z Is na Is Not.
Velmi pěkný článek, spousta užitečných informací o problematice pohromadě na jednom místě.
Zdravím,
po nějaké době jsme se opět vrátili na vývojovém serveru k autentizaci pomocí kerberos. Když jsem v doméně, stránka se otevře. Jakmile jsem mimo doménu, ve firefoxu nastavím network.negotiate...uris na název domény DEVELOPMENT. tak vyskočí okno, ale uživatele mi to tam nepustí.
Netušíte, kde by mohl být problém?
odpověď na [2]Ladislav Jech: Když nejste autentizovaný vůči doméně, tak nemáte Kerberos klíče (TGT) a tudíž nemůže fungovat autentizace.
k Vaší odpovědi - díky za info, ale od toho mám v konfiguraci modulu řádku:
KrbMethodK5Passwd On
Ta mi zajistí, že mi vyskočí okno, kde zadám jméno a heslo doménového uživatele a vše by mělo fachat.
Už si nepamatuji, čím jsem to opravil, ale na windows 2003 doméně mi kerberos funguje jak automaticky, když je uživatel zalogovaný, tak když je zalogovaný lokálně na stroji a po výzvě zadá doménové přihlašovací údaje, což je požadovaná funkcionalita.
--------------------------------------------------------------------
Nový problém:
v testovacím prostředí se provedla migrace z Windows 2003 R2 na Windows 2008 R2, můj konfigurák modulu pro apache vypadá takto:
# Načtení modulu
LoadModule auth_kerb_module modules/mod_auth_kerb.so
# Konfigurace modulu
<Location />
SSLRequireSSL
AuthType Kerberos
AuthName "Prihlaseni - Testovaci prostredi"
KrbServiceName HTTP/iptst.domena.local@DOMENA.LOCAL
KrbMethodNegotiate On
KrbMethodK5Passwd On
KrbSaveCredentials Off
KrbAuthRealms fnkv.local
Krb5KeyTab /ip/kerberos/iptstkerberos.keytab
KrbAuthoritative On
require valid-user
</Location>
V tuto chvíli na klientovi Windows 7 i XP po přihlášení k doméně autentizace funguje korektně, tj. aplikace se v prohlížeči načte. Pokud se však na klientských strojích zaloguji pod lokálním účtem, otevřu aplikaci v browseru, vyskočí přihlašovací okno, do kterého zadám doménové přihlašovací údaje, tak mě to neověří. Používám stejné přihlašovací údaje, kterými se přihlašuji na stanicích přímo do domény.
hláška v logu apache je:
gss_accept_sec_context() failed: Invalid token was supplied (No error)
KrbAuthRealms fnkv.local vnímejte jako domena.local, tj. všude je to nastaveno identicky.
Díky za případnou pomoc.
Další zajímavostí je, že ikdyž SSO funguje (případ, kdy je uživatel korektně zalogován v doméně v rámci svého stroje), tak v logu je stále následující chyba:
krb5_get_init_creds_password() failed: Cannot resolve network address for KDC in requested realm, referer
Toto chování je se ukazuje jak na vývojovém prostředí (DC Windows 2003), tak na testu (DC Windows 2008)
Super článek, díky za něj. Pěkně jsem se potrápil implementací SSO v Java klientoví a až zde jsem poprvé příšel na to proč mi to nefunguje - ona zmínka o potřebných admin právech aby zafungovalo nastavení AllowTGTSessionKey.
Je to ale trošku jinak - ona potřeba spouštet aplikaci jako správce je pouze v případě, že uživatel je mezi lokálními adminy, resp. má Managed-by práva. Mám Managed-by, musím aplikaci spustit pod zvýšenými oprávněněními (spustit jako Správce). Pokud jsem jen obyč uživatel, tak to funguje, není potřeba pouštět aplikaci se zvýšenými oprávněními. Takto mi to aspoň funguje ve Win7.