Authentification SSO depuis Apache sur backend AD via Kerberos
Contents
Software version | 5 |
---|---|
Operating System | Red Hat 6 Debian 6 |
Website | |
Last Update | 29/10/2012 |
Others |
1 Introduction
Le but de cet article 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/2008 Server. Les clients seront des machines Windows ou Linux participant au domaine AD (Active Directory) utilisant un navigateur internet.[1]
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.
Kerberos fonctionne avec un système de jetons, qu'on appelera des 'tickets'. L'authentification se passe en plusieurs étapes :
- le poste client demande un ticket au serveur Kerberos (ici le DC Win2003)
- le KDC retourne un ticket, vu que le client est déjà identifié sur le réseau
- 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
2 Prérequis
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)
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. 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.
WARNING |
Il est impératif que toutes vos machines soient à la bonne heure, donc connectez les toutes à un serveur NTP. |
3 Installation
3.1 Windows Server
Installer les support tools[2].
3.2 Linux Server
Nous allons installer les paquets suivants :
aptitude |
aptitude install krb5-clients krb5-config krb5-user libkrb53 libapache2-mod-auth-kerb |
4 Configuration
4.1 Windows Active Directory
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 dans l'Active Directory.
WARNING |
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 :
ktpass |
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 |
Copiez le fichier généré sur le serveur Linux dans /etc/krb5.keytab.
4.2 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 :
/etc/resolv.conf |
search local.domain nameserver 192.168.22.1 |
Vérifiez que modauthkerb est activé :
a2enmod |
a2enmod auth_kerb |
Créez un .htaccess ou éditez apache2.conf pour sécuriser le site :
Reloadez votre serveur Apache
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 :
5 Validation
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 |
kinit <username>@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 :
- Si tout va bien, vérifiez ensuite votre authentification de service :
kvno |
> 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 |
> kinit <username> 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 |
kinit -k -t /etc/krb5.keytab HTTP/lx-1.local.domain@LOCAL.DOMAIN |
WARNING |
Ne passez pas à la suite tant que les trois tests précédents génèrent des erreurs ! |
6.1 Internet Explorer
- Dans les options avancées, vérifiez que l'Authentification Windows est activée : "Enable Integrated Windows Authentication"
- Ensuite ajoutez le site sécurisé dans la zone Local intranet : http://lx-1.local.domain
Acceptez les changements, et naviguez sur http://lx-1.local.domain : le site s'affiche sans authentification par mot de passe.
6.2 Firefox
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 comme valeur le domaine "local.domain".
7 FAQ
7.1 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 :
Pour lister les SPN associés a un utilisateur, utilisez l'option "-L", pour supprimer, utilisez l'option "-D", par exemple :
setspn |
setspn -D HTTP/lx-1.local.domain lx-1 |
7.2 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.