V několika posledních dílech jsme popisovali, co musí být splněno u aplikačního serveru, aby na něm bylo možno použít Kerberos autentizaci. Takže zde nebudeme řešit DNS záznamy, servisní účty a keytab soubory, ale budeme se věnovat vlastnímu nastavení aplikačního serveru.
Java aplikace
Pro Java aplikace nemusíme nechat řešení Kerberos autentizace na aplikačním serveru, ale můžeme využít knihovny Java Authentication and Authorization Service (JAAS). Ta podporuje Kerberos V5 a využívá Java Generic Security Service API (Java GSS-API). Nějaké informace nalezneme v oficiálním článku Single Sign-on Using Kerberos in Java.
Apache Tomcat
Tomcat s použitím Kerberos SSO, nebo jinak řečeno Integrated Windows Authentication, počítá a popisuje možnosti přímo v oficiální dokumentaci Tomcat 7 - Windows Authentication How-To. Nativní metoda využívá JAAS a konfiguraci v souborech krb5.ini
a jaas.conf
, ale záleží na aplikaci, ta může řešit nastavení JAAS jinak. Další možnost je využít knihovny třetích stran. Řešení pomocí reverzní proxy mi připadá dost divoké a zbytečné.
Apache HTTP Server
Na Apachi máme k dispozici asi jedinou funkční a využívanou možnost a to modul Kerberos Module for Apache se jménem mod_auth_kerb
. Problém je, že je běžně k dispozici pouze pro Linuxové distribuce (i když máme k dispozici zdrojové kódy). Jeho poslední úprava proběhla před řadou let, to ale nevadí, protože vše funguje.
Pro Windows jsem nalezl několik různých modulů, třeba Apache 2.0 module mod_auth_sspi, ale většinou jsou staré a ne moc používané. Při hlubším pohledu se navíc zdá, že všechny podporují pouze NTLM SSP. Jde o mod_authn_ntlm, mod_auth_sspi, mod_ntlm_winbind, mod_auth_ntlm_winbind, mod_auth_ntlm.
Modul mod_auth_kerb
Lehce se podíváme na použití serveru Apache 2.2 s autentizačním modulem mod_auth_kerb
. Chceme provozovat metodu označovanou Integrated Windows Authentication, což znamená Kerberos a SPNEGO (Simple and Protected GSSAPI Negotiation Mechanism) nebo jiným označením Negotiate. Kroky, které musíme pro zprovoznění modulu provést:
- nainstalujeme modul
mod_auth_kerb
, dle distribuce Linuxu, třeba na Red Hat
yum install mod_auth_kerb
- při instalaci by se mělo nastavit načítání v Apache konfiguraci, pokud se tak nestane, můžeme provést ručně v souboru
httpd.conf
(samozřejmě se správnou cestou)
LoadModule auth_kerb_module modules/mod_auth_kerb.so
- do bezpečné složky na serveru (kam má přístup uživatel, pod kterým běží Apache) nahrajeme keytab soubor (který jsme připravili pro DNS jméno webového serveru)
- v konfiguračním souboru Apache nakonfigurujeme složku, kde chceme Kerberos autentizaci využít (popis níže)
- znovu načteme konfiguraci do Apache, třeba
service httpd reload
Když máme keytab soubor, tak můžeme nastavit i parametry Kerberosu pro operační systém a to využít třeba pro testování. Upravíme konfigurační soubor /etc/krb5.conf
a pro test můžeme využít příkaz kinit
(zmiňovali jsme v článku o troubleshootingu).
Nastavení složky - vlastní konfigurace modulu mod_auth_kerb
Zapnout Kerberos autentizaci můžeme na celý web, ale pak se bude každý přístup autentizovat, což je zbytečná zátěž navíc. Běžně se využívá to samé, jako při formulářové autentizaci k webu. Jedna stránka provádí autentizaci (u formuláře chce zadat jméno a heslo, u Kerberosu proběhne SSO) a tím se autentizuje session. Aplikace si pak hlídá přístupy na ostatní stránky. Před zobrazením neveřejné stránky, se zkontroluje, jestli je session ověřená a jestli má potřebná oprávnění. Pokud ne, tak se přesměruje na přihlašovací stránku nebo se zobrazí chyba.
Na serveru Apache se autentizace (pokud ji neřeší přímo aplikace) konfiguruje pro složku. Můžeme tedy zvolit složku, kam umístíme skript, který bude autentizaci řešit, a na ni nastavit vyžadování Kerberos autentizace. Konfiguraci provádíme v hlavním konfiguračním souboru (tedy nejčastěji httpd.conf
) nebo souboru .htaccess
v dané složce webu (to musí být povoleno). Obecné informace nalezneme v dokumentaci Authentication and Authorization.
Nejčastěji se konfigurace provádí v sekci <Directory>
, ale je možno využít také třeba <Location>
. Příklad konfigurace:
<Directory /var/www/intranet/sso/> AuthType Kerberos KrbAuthRealms FIRMA.LOCAL KrbServiceName HTTP/www.firma.local@FIRMA.LOCAL Krb5KeyTab /etc/httpd/intranet.keytab KrbMethodNegotiate on KrbMethodK5Passwd off Require valid-user </Directory>
Pro nastavení autentizace se používá řada direktiv:
AuthType
- volí metodu, která se použije pro autentizaci, v našem případěKerberos
AuthName
- definuje Realm (ale nejde o Kerberos Realm), což je informace pro klienta, kam se vlastně připojuje (zobrazuje se v přihlašovacím okně). Používá se pro Basic autentizaci. Kerberos (Negotiate) provádí SSO, takže je tato informace zbytečná (žádné okno se nezobrazuje) a v praxi konfigurace funguje bez této direktivy (dle dokumentace Apache je ale povinná).Require
- provádí autorizaci (kdo má povolen přístup na stránku/složku), můžeme zde uvést seznam uživatelů či skupin, nebo použít klíčové slovovalid-user
, takže všichni autentizování uživatelé mají povolen přístup (autorizaci řešíme v aplikaci, což je běžný způsob)KrbAuthRealms
- definuje Kerberos Realm, patrně není nutnéKrbServiceName
- jméno služby (Service Principal Name včetně Realmu), které se má využít pro autentizaci, musí být přesně stejné v keytab soubor (slouží pro výběr správného klíče z keytabu)Krb5KeyTab
- určuje Kerberos V5 keytab soubor, který se má použítKrbMethodNegotiate
- explicitní zapnutí (on) Kerberos protokolu (metoda Negotiate), defaultně je zapnutoKrbMethodK5Passwd
- vypnutí (off) autentizace heslem (Basic), modulmod_auth_kerb
defaultně podporuje metodu Negotiate a Basic, tu ale většinou nechceme, defaultně je zapnutoKrbSaveCredentials
- zapíná (on) ukládání tiketů do cache, pro některé aplikace je potřeba
Pozn.: Většina hodnot Kerberos parametrů se může přebrat z nastavení systému, pokud nejsou definovány v konfiguraci.
Obecně se doporučuje, pro větší bezpečnost, posílat jakékoliv autentizační údaje pouze šifrovaným kanálem. Proto můžeme ještě doplnit direktivu:
SSLRequireSSL
- na danou složku povolí přístup pouze pomocí TLS/SSL (tedy HTTPS)
Jak jsme si uvedli, modul mod_auth_kerb
provádí defaultně autentizaci Negotiate (Kerberos) a Basic. Takže v hlavičce posílá
HTTP/1.1 401 Authorization Required WWW-Authenticate: Negotiate WWW-Authenticate: Basic Realm="co jsme zadali do AuthName"
Pokud direktivou vypneme Basic autentizaci, tak se při selhání Kerberos SSO rovnou zobrazí chybová hláška Apache. Internet Explorer nabídne přihlašovací dialog (téměř stejný jako pro Basic autentizaci) a pokusí se provést získání Kerberos ticketu (zadané údaje použije pro autentizaci na KDC).
Použití Kerberos autentizace v PHP
Na určitou složku nastavíme Kerberos autentizaci, jak jsme si popsali v předchozí kapitole. Do této složky umístíme PHP skript. Pokud se nyní pokusíme přistoupit na tuto stránku, tak se webový prohlížeč pokusí provést SSO přihlášení. V případě, že něco selže (například nemáme nastavený prohlížeč či nejsme přihlášeni do domény), se zobrazí chyba. PHP stránka se zavolá pouze v případě, že úspěšně došlo k ověření.
V kódu stránky tedy můžeme předpokládat, že máme úspěšně autentizovaného uživatele. Když Apache modul provedl ověření, tak ze Service Ticketu získal uživatelovo jméno (včetně domény, tedy například bouska@FIRMA.LOCAL
) a uložil jej do serverové proměnné REMOTE_USER
. Jako zajímavé ještě můžeme nalézt proměnné PHP_AUTH_USER
a AUTH_TYPE
. PHP stránka může pro test obsahovat pouze jeden příkaz, který vypíše všechny serverové proměnné:
<?php print_r($_SERVER); ?>
Trochu více smysluplný skript může být /sso/login.php
(na složku sso jsme nastavili autentizaci). Využijeme session, abychom zachovali proměnné, a jméno uživatele si uložíme. Pak provedeme přesměrování na hlavní stránku webu, kde již budeme přihlášeni. Samozřejmě by to ještě chtělo ověřit, jestli přihlašovaný uživatel existuje na našem webu a třeba načíst další jeho údaje z DB.
<?php session_start(); $_SESSION['username'] = $_SERVER['REMOTE_USER']; header('Location: /'); ?>
V praxi je častá situace, kdy nechceme, aby klient, který nepodporuje Kerberos, dostal chybové hlášení serveru, ale místo toho možnost se přihlásit do aplikace pomocí formuláře (form-based autentizaci). Určitým řešením je poslat klientovi hlavičku, že požadujeme autentizaci a ověřit, jestli přihází v hlavičce odpověď. Klient posílá Authorization: Negotiate
pouze, pokud může provést Kerberos autentizaci. Když tedy hlavička obsahuje tuto část, tak teprve klienta přesměrujeme na stránku, kde je nastavena autentizace pomocí modulu mod_auth_kerb
. V opačném případě zobrazíme přihlašovací formulář.
<?php session_start(); $headers = apache_request_headers(); if(empty($headers['Authorization'])) { header("HTTP/1.1 401 Authorization Required"); header("WWW-Authenticate: Negotiate"); // SSO není podporováno, zobrazím standardní login či informace echo "SSO autentizace neprobehla."; exit; } else { // SSO OK, přesměruju na SSO login header('Location: /sso/login.php'); exit; } ?>
Zatím zde nejsou žádné komentáře.