dimanche, décembre 17, 2017
Nom d'utilisateur : Mot de passe :
Home > Dossiers > Réseaux et sécurité > Authentification "Single Sign-On" d'une application Web avec Kerberos
[NEWS]
Envoyé par unreal
Le but de ce dossier est d'expliquer comment réaliser une authentification forte de type SSO 'Single Sign-On' d'une application Web hébergée en réseau local sur un serveur Linux avec Apache via un Kerberos sous Windows 2003 Server. Les clients seront des machines Windows ou Linux participant au domaine AD (Active Directory) utilisant un navigateur compatible Negotiate.

On peut résumer le fonctionnement de la manière suivante : un utilisateur ouvre une session sur le domaine et navigue vers une page http protégée du réseau Intranet. Habituellement, on affiche une boite invitant l'utilisateur à saisir son nom d'utilisateur et mot de passe alors qu'il est déjà connu de l'AD, vu qu'il a saisi les mêmes informations pour se connecter à son compte Windows. Le but du Single Sign-On est d'authentifier l'utilisateur sans qu'il soit obligé de resaisir plusieurs fois les mêmes informations.


Comment ça marche

Kerberos fonctionne avec un système de jetons, qu'on appelera des 'tickets'. L'authentification se passe en plusieurs étapes :

kerb_schema.png


1 : le poste client demande un ticket au serveur Kerberos (ici le DC Win2003)
2 : le KDC retourne un ticket, vu que le client est déjà identifié sur le réseau
3 : le poste client formule la requête au serveur Web en incluant le ticket

Plusieurs avantages de cette méthode :
  • L'utilisateur s'identifie une seule fois et peut ensuite accéder de façon transparente aux différents services
  • Le nom d'utilisateur et son mot de passe ne sont jamais transmis sur le réseau



Prérequis et nominations

Dans la suite de l'article, je vais supposer que vous avez les éléments suivants :

  • Un 2003 Server configuré en contrôleur de domaine avec le service DNS activé, et au moins un compte utilisateur (dc-1.local.domain)
  • Un serveur Linux avec Apache configuré, capable de servir des pages (lx-1.local.domain)
  • Un client XP ou 2003 enregistré sur le domaine, capable d'ouvrir une session avec un compte du domaine (pc-1.local.domain)


Kerberos étant particulièrement sensible aux noms des machines, il est important que toutes les machines apparaissent dans le serveur DNS et qu'elles aient toutes une entrée PTR (reverse DNS) égale au forward DNS (A). Pour cela, je vous conseille donc d'utiliser le service DNS du 2003 Server.

Exemple de configuration du forward DNS :

dns_setup.png


Exemple de configuration du reverse DNS :

rdns_setup.png


En plus d'être sensible à la nomination, Kerberos est sensible à un quelconque décalage temporel entre les différentes machines. Pour palier à ce problème, je vous conseille donc d'utiliser un service NTP.

Pour finir, il faut choisir un realm Kerberos, par exemple LOCAL.DOMAIN. Notez que le realm s'écrit tout en majuscules.


Configuration du 2003

Pour chaque service à Kerberosiser, les opération suivantes sont à prévoir pour générer un Service Principal :

- Création d'un compte utilisateur pour chaque service. Je vous conseille de choisir un nom qui permette d'identifier le service concerné, par exemple intranet-1. Pour ce faire, rendez-vous dans Active Directory Users and Computers, faites clic-droit, puis New -> User.

Attention : ne pas choisir un nom d'utilisateur qui existe déjà comme nom de contrôleur de domaine ou comme nom d'ordinateur.

- Génération d'un KeyTab. Ce fichier sert à authentifier le serveur Kerberosisé (ici le serveur Web) auprès du KDC. Ce fichier se génère à la ligne de commande après installation des support tools :

ktpass -princ HTTP/lx-1.local.domain@LOCAL.DOMAIN -crypto DES-CBC-MD5 -ptype KRB5_NT_PRINCIPAL -mapuser intranet-1 -pass azerty -out C:\temp\keytab.txt


En version graphique cela donne :

keytab_gen.png
Génération du keytab : vérifiez qu'il n'y a pas d'erreur !


Copiez le fichier généré via sftp/scp sur le serveur Linux dans /etc/krb5.keytab


Configuration du serveur Linux

Commencez par sécuriser le keytab copié précedemment :

# chown www-data:root /etc/krb5.keytab
# chmod 640 /etc/krb5.keytab


Configurez les DNS :

# echo -e "search local.domain\nnameserver 192.168.22.1" > /etc/resolv.conf


Dans cet exemple, j'utilise une machine en Debian Lenny, l'installation des packages se fait donc avec apt :

# apt-get install krb5-clients krb5-config krb5-user libkrb53 libapache2-mod-auth-kerb


Vérifiez que modauthkerb est activé :

# cat /etc/apache2/mods-enabled/auth_kerb.load
LoadModule auth_kerb_module /usr/lib/apache2/modules/mod_auth_kerb.so


Créez un .htaccess ou éditez apache2.conf pour sécuriser le site :

<Files "*">
        <Limit GET POST>
                AuthName "Kerberos Login"
                AuthType Kerberos
                Krb5Keytab /etc/krb5.keytab
                KrbAuthRealms LOCAL.DOMAIN
                KrbMethodNegotiate On
                KrbMethodK5Passwd Off
                KrbVerifyKDC off
                Require valid-user
        </Limit>
</Files>


Je rappelle que le realm s'écrit en majuscule. Dans cet exemple, on active le mode SSO via Negotiate et on désactive l'authentification par mot de passe ; si l'authentification automatique est impossible une page d'erreur 401 Authorization Required s'affichera.

Le dernier fichier à configurer est /etc/krb5.conf ; Lenny a du installer un fichier par défaut, je vous conseille de le renommer :

# mv /etc/krb5.conf /etc/krb5.conf.dist


Ensuite éditez krb5.conf :

[libdefaults]
        ticket_lifetime = 24000
        default_realm = LOCAL.DOMAIN
        dns_lookup_realm = true
        dns_lookup_kdc = false
        default_keytab_name = FILE:/etc/krb5.keytab

[realms]
        LOCAL.DOMAIN = {
                kdc = dc-1.local.domain
                admin_server = dc-1.local.domain
}

[domain_realm]
        .local.domain = LOCAL.DOMAIN
        local.domain = LOCAL.DOMAIN

[appdefaults]
        pam = {
                debug = false
                ticket_lifetime = 36000
                renew_lifetime = 36000
                forwardable = true
                krb4_convert = false
        }



Vérifications

A ce stage, vous avez normalement une configuration fonctionnelle. Nous allons cependant effectuer quelques vérifications parce qu'il existe beaucoup d'erreurs de configuration possibles.

- Test de connexion :

# kinit <nom d'utilisateur>@LOCAL.DOMAIN


Saisissez le mot de passe de l'utilisateur, il ne doit pas avoir d'erreur.

La commande klist permet de vérifier l'état des tickets :

# klist
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: <nom d'utilisateur>@LOCAL.DOMAIN

Valid starting     Expires            Service principal
08/12/09 11:42:08 08/12/09 18:22:08 krbtgt/LOCAL.DOMAIN@LOCAL.DOMAIN


Kerberos 4 ticket cache: /tmp/tkt0
klist: You have no tickets cached


- Si tout va bien, vérifiez ensuite votre authentification de service :

# kvno HTTP/lx-1.local.domain@LOCAL.DOMAIN
HTTP/lx-1.local.domain@LOCAL.DOMAIN: kvno = 28


Il ne doit pas avoir d'erreur non plus mais voici quelques messages d'erreurs classiques et leur signification :

kvno: No credentials cache found while getting client principal name

Vous n'avez pas de ticket valide : lancez la commande kinit <nom d'utilisateur>


kvno: Server not found in Kerberos database while getting credentials for HTTP/lx-1.local.domain@LOCAL.DOMAIN

Plusieurs possibilités ici :

  • Vous avez mal généré votre keytab ; essayez de le regénérer
  • Vous avez affecté le même SPN à plusieurs utilisateurs (voir les pièges)


- Pour finir, ce test de keytab ne doit pas retourner d'erreur :

# kinit -k -t /etc/krb5.keytab HTTP/lx-1.local.domain@LOCAL.DOMAIN


Attention !
Ne passez pas à la suite tant que les trois tests précédents génèrent des erreurs !


Configuration du poste client

Nous allons configurer IE6 et Firefox 3.5 pour accéder au service Web sécurisé :

Internet Explorer 6.0

Ouvrez Internet Options et accédez à l'onglet Advanced et vérifiez que l'Authentification Windows est activée :

ie6_options.png


Ensuite ajoutez le site sécurisé dans la zone Local intranet :

ie6_intranet.png


Acceptez les changements, et naviguez sur http://lx-1.local.domain : le site s'affiche sans authentification par mot de passe.

Firefox 3.5

Lancez Firefox et tapez about:config dans la barre d'adresse, puis filtrez avec le mot auth. Modifiez network.negotiate-auth.trusted-uris et network.negotiate-auth.delegation-uris avec le domaine local.domain :

ff35_options.png



Pièges à éviter

Ce paragraphe vous permettra d'éviter ou de corriger des soucis.

Noms de machines

Il est important de bien définir les noms des machines en utilisant un FQDN avant de commencer. Les entrées DNS doivent être présentes, aussi bien en forward qu'en reverse.

Le realm

Il n'est pas obligatoirement le nom de domaine, et il peut avoir plusieurs realms sur un réseau ayant un seul domaine. Par contre, le realm s'écrit en majuscules, par exemple LOCAL.DOMAIN.

Nom de service sur plusieurs comptes

Si vous avez créé plusieurs comptes pour expérimenter, il n'est pas impossible qu'un même nom de service ou SPN se retrouve associé à plusieurs comptes, ce qui n'est pas possible. Un compte doit être unique pour chaque service Kerberosisé (intranet-1, intranet-2...) et un même nom de service (HTTP/lx-1.local.domain@LOCAL.DOMAIN) ne peut être associé à plusieurs comptes. Si vous avez utilisé ktpass pour associer le même SPN à plusieurs compte, utilisez setspn pour corriger :

C:\Program Files\Support Tools>setspn
Usage: setspn [switches data] computername
Where "computername" can be the name or domain\name

Switches:
-R = reset HOST ServicePrincipalName
    Usage: setspn -R computername
-A = add arbitrary SPN
    Usage: setspn -A SPN computername
-D = delete arbitrary SPN
    Usage: setspn -D SPN computername
-L = list registered SPNs
    Usage: setspn [-L] computername
Examples:
setspn -R daserver1
It will register SPN "HOST/daserver1" and "HOST/{DNS of daserver1}"
setspn -A http/daserver daserver1
It will register SPN "http/daserver" for computer "daserver1"
setspn -D http/daserver daserver1
It will delete SPN "http/daserver" for computer "daserver1"


Pour lister les SPN associés a un utilisateur, utilisez l'option "-L", pour supprimer, utilisez l'option "-D", par exemple :

setspn -D HTTP/lx-1.local.domain lx-1


Choix du nom d'utilisateur

Le nom d'utilisateur est libre, par contre, le nom ne doit pas déjà utilisé comme nom d'ordinateur ou comme contrôleur de domaine.

Versions
- v1.0 - 12/08/2009

Posté le 11/08/09 à 20:50

Authentification "Single Sign-On" d'une application Web avec Kerberos
Vous pourriez commenter si vous aviez un compte !