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 :
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 :
Prérequis et nominations
Dans la suite de l'article, je vais supposer que vous avez les éléments suivants :
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 :
Exemple de configuration du reverse DNS :
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 :
En version graphique cela donne :
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 :
Configurez les DNS :
Dans cet exemple, j'utilise une machine en Debian Lenny, l'installation des packages se fait donc avec apt :
Vérifiez que modauthkerb est activé :
Créez un .htaccess ou éditez apache2.conf pour sécuriser le site :
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 :
Ensuite éditez krb5.conf :
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 :
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 :
Il ne doit pas avoir d'erreur non plus mais voici quelques messages d'erreurs classiques et leur signification :
Vous n'avez pas de ticket valide : lancez la commande kinit <nom d'utilisateur>
Plusieurs possibilités ici :
- Pour finir, ce test de keytab ne doit pas retourner d'erreur :
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 :
Ensuite ajoutez le site sécurisé dans la zone Local intranet :
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 :
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 :
Pour lister les SPN associés a un utilisateur, utilisez l'option "-L", pour supprimer, utilisez l'option "-D", par exemple :
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
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 :
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 :
Exemple de configuration du reverse DNS :
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 :
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
# 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
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>
<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
}
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
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
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 :
Ensuite ajoutez le site sécurisé dans la zone Local intranet :
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 :
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"
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