Autentizační systémy

Pavel Březina, 359290@mail.muni.cz

Obsah

Kerberos

Kerberos je síťový autentizační protokol jehož hlavními vlastnostmi jsou:

Existují dvě hlavní implementace tohoto protokolu. MIT Kerberos je původní implementací, která ovšem v době svého vydání podléhala zákazu exportu kryptografických nástrojů. Proto vznikla švédská implementace Heimdal. Obě implementace jsou stále ve vývoji a jsou navzájem kompatibilní.

Kerberos podporuje replikaci serveru na principu master/slave. Master slouží jako primární server a z něj se replikují data na jeden nebo více slave (sekundárních) serverů, které primární server zastoupí v případě jeho výpadku.

Základní pojmy

Key Distribution Center
Obsahuje databázi klíčů (uživatelů i služeb). Skládá se ze dvou služeb: Authentication Server (vydává ticket-granting ticket) a Ticket-granting Server (vydává ostatní tickety).
Realm
Doména, oblast spravovaná jedním KDC.
Principal
Identita uživatele/služby, skládá se z primary[/instance]@REALM. primary je jméno uživatele/služby, instance rozšiřující údaj k primary, může být prázdný.
Např.:
krbtgt/MYCORP.COM@MYCORP.COM
pavel@MYCORP.COM
pavel/admin@MYCORP.COM
Ticket
Používá se k prokázání identity klienta vůči službě. Je to struktura obsahující: principal klienta, principal služby, IP adresy klienta, časové razítko vytvoření ticketu, délku života ticketu a session key. Celá struktura je zašifrována klíčem služby.
Autentizátor
Principal klienta a časové razítko, zašifrování pomocí session key.

Průběh autentizace

Získání ticket-granting ticketu (kinit):

  1. Klient zažádá KAS o TGT.
    Žádost není šifrovaná a obsahuje: principal klienta, principal služby (v tomto případě krbtgt/REALM@REALM), IP adresu uživatele a délku života ticketu.
  2. KAS zjistí jestli principal klienta i služby existuje v databázi. Pokud ano vygeneruje session key, ze získaných údajů vytvoří ticket a klientovi odešle odpověď obsahující:

Pokud nechceme využívat TGT, můžeme uvést přímo principal služby, kterou chceme využít a následující krok se pak vynechá.

Získání ticketu pro službu:

  1. Klient zažádá TGS o vydání ticketu, žádost obsahuje:
  2. TGS zkontroluje jestli klient může využívat službu. Pokud ano, pomocí svého klíče dešifruje TGT a získá tak session key. Pomocí něj dešifruje autentizátor. Zkontroluje platnosti TGT a IP adresu.
  3. Pokud je vše platné, TGS vygeneruje session key, ze získaných údajů vytvoří ticket a klientovi odešle odpověď obsahující:

Prokázání klienta vůči službě:

  1. Klient zašle službě autentizátor (zašifrovaný pomocí session key) a ticket (zašifrovaný klíčem služby).
  2. Služba pomocí svého klíče dešifruje ticket a získá tak session key.
  3. Pomocí session key dešifruje autentizátor.
  4. Zkontroluje platnost ticketu a porovná údaje (principal, IP adresy) - tím se klient prokáže službě.
  5. Časové razítko z autentizátoru zvýší o jedna a výsledek, zašifrovaný pomocí session key, pošle klientovi.
  6. Klient zkontroluje hodnotu - pokud je správná, služba je ověřena.

Konfigurace klienta

Konfigurace klienta se nachází v /etc/krb5.conf a může vypadat například takto:


[logging]
 default = FILE:/var/log/krb5.log

[libdefaults]
 default_realm = MYCORP.COM
 ticket_lifetime = 24h
 forwardable = yes

[realms]
 MYCORP.COM = {
  kdc = kerberos.mycorp.com
  admin_server = kerberos.mycorp.com
  default_domain = mycorp.com
 }

[domain_realm]
 .mycorp.com = MYCORP.COM
 mycorp.com = MYCORP.COM

Informace o konfiguraci klienta najdete v man krb5.conf

Užitečné příkazy

PAM - Pluggable Authentication Modules

PAM je modulární autentizační systém jehož účelem je odstranit autentizační logiku ze zdrojových kódů programů a umožnit tak snadnou změnu autentizační metody.

PAM rozlišuje následující fáze autentizace:

account
Verifikace účtu. Např. jestli nevypršela platnost hesla.
auth
Ověření autentizačních údajů. Např. heslo, otisk prstu.
password
Změna autentizačních údajů. Např. změna hesla, nový hardwarový klíč.
session
Úkony které jsou provedeny těsně před započetím a po ukončení sezení. Obvykle se používá pro audit.

Všechny tyto fáze jsou obsluhovány moduly, které definujeme v konfiguračním souboru.

Konfigurace

Konfigurační direktivy se ukládají buď do jediného souboru /etc/pam.conf, ve formátu:

service type control module-path module-arguments

Nebo do souboru v adresáři /etc/pam.d (pokud tento adresář existuje, /etc/pam.conf je ignorován). Soubor má název shodný se službou pro kterou se mají pravidla aplikovat a jejich formát je:

type control module-path module-arguments

Pro stejnou kombinaci service a type může být použito i více než jeden modul.

service je název služby ke které se direktiva vztahuje, type označuje fázi autentizace (account, auth, password, session), module-path určuje cestu k modulu, který chceme použít, a module-arguments jeho argumenty. control určuje jakým způsobem naložit s výsledkem modulu a může nabývat těchto hodnot:

required
Pokud modul zamítne autentizaci, selže celá autentizace. I přesto jsou však provedeny všechny moduly ve stacku.
requisite
Jako required, ale výsledek se vrátí okamžitě aniž by se volaly ostatní moduly.
sufficient
Pokud modul autentizuje uživatele, je to dostatečné a ostatní moduly se nevyhodnocují.
optional
Výsledek modulu se použije pouze pokud je jediný v této fázi a službě.
include
Vloží všechny řádky se stejným type z jiného souboru určeného v module-path.

Jednotlivé moduly jsou typicky uloženy v /lib/security. Například:

Autentizace uživatele v C

Ukázka autentizace uživatele:

#include <security/pam_appl.h>
#include <security/pam_misc.h>

pam_handle_t *pam_handle;
struct pam_conv pam_conv = {misc_conv, NULL};
int pam_ret;

pam_ret = pam_start("service_name", "user_name", &pam_conv, &pam_handle);
if (pam_ret != PAM_SUCCESS) {
  fprintf(stderr, "pam_start() failed: %s\n", pam_strerror(pam_handle, pam_ret));
  goto fail;
}

pam_ret = pam_authenticate(pam_handle, PAM_DISALLOW_NULL_AUTHTOK);
switch(pam_ret) {
    case PAM_SUCCESS:
        /* success */
        break;

    default:
        /* error */
        fprintf(stderr, "pam_authenticate() failed: %s\n",
                pam_strerror(pam_handle, pam_ret));
        ret = 0;
        goto fail;
}

pam_end(pam_handle, pam_ret);

Více informací v man 3 pam.

Literatura