Nouvel article dans la série sur Alfresco et le SSO, nous allons parler aujourd’hui de Kerberos. Derrière ce terme un peu barbare se cache en réalité un principe d’authentification relativement simple. En deux mots, Kerberos est un protocole d’authentification réseau développé au MIT pendant les années 80-90, son principe de fonctionnement repose sur l’utilisation de tickets signés par des clés secrètes (chiffrement symétrique).

# Principe de fonctionnement de Kerberos

Je ne vais pas détailler dans son intégralité le fonctionnement du protocole Kerberos, ce n’est pas le but de cet article. Je vais juste essayer de poser quelques bases afin de comprendre son intégration dans Alfresco.

Kerberos fait intervenir 3 entités :

  • un KDC (Key Distribution Center) : entité dite « de confiance » permettant de générer les clés secrètes (par exemple : Active Directory)
  • un client : un utilisateur souhaitant accéder à une application sur le réseau
  • une application : dans le cas de cet article, il s’agit d’Alfresco

Le premier échange se fait entre le client et le KDC pour obtenir un TGT (Ticket Granting Ticket).

  • étape 1 – le client demande un TGT au KDC : « Hello, je suis l’utilisateur Laurent et j’ai besoin d’un TGT »
  • étape 2 – réponse du KDC contenant le TGT : « Voici le TGT demandé, tu peux l’utiliser si tu arrives à le déchiffrer avec ton mot de passe »

Dans le cas de l’utilisation de Kerberos dans un environnement Microsoft (postes Windows reliés à un domaine Active Directory), cet échange se fait au moment de l’ouverture de la session et est transparente pour l’utilisateur.

À ce stade, l’utilisateur a en sa possession un TGT. Ce TGT lui permet d’obtenir un ST (Service Ticket) auprès du KDC. Ce ST est utilisé ensuite pour accéder à une application.

  • étape 3 – le client demande un ST au KDC : « Re, voici mon TGT, donne moi un ST pour accéder à App »
  • étape 4 – réponse du KDC contenant le ST : « Voici le ST demandé, tu peux l’envoyer à App »
  • étape 5 – le client envoie le ST à App : « Hello, voici mon ST, tu peux l’utiliser pour m’authentifier »
  • étape 6 – réponse de App au client : « Ok, j’ai pu déchiffrer le ST et tu es bien authentifié »

Lors de l’étape 3, le client demande un Service Ticket lié à l’application à laquelle l’utilisateur souhaite accéder. Dans sa demande, le client doit préciser le « Principal » du service demandé. Ce « Principal » est un terme précis dans le vocabulaire Kerberos. Dans le cas de l’utilisation de Kerberos pour accéder à un service HTTP (comme c’est le cas pour Alfresco), le « Principal » est de la forme suivante : HTTP/<app-dns-entry.exemple.org>@<REALM>

Il faut remplacer :

  • <app-dns-entry.exemple.org> par le nom de domaine associé au service HTTP
  • <REALM> par le nom du Realm Kerberos

Par exemple : HTTP/ged.atolcd.com@AD.ATOLCD.COM

L’étape 4 peut sembler magique. Comment fait l’application pour valider le ST et authentifier l’utilisateur ? Le ticket ST est chiffré avec la clé secrète du compte lié à l’application. Ce ST contient, entre autre, le login de l’utilisateur. Il faut donc une information au niveau de l’application pour déchiffrer le ST et obtenir ainsi le login de l’utilisateur. Et c’est maintenant qu’entre en jeu le fameux fichier keytab. Le keytab est un fichier contenant les clés permettant de déchiffrer le ticket ST. Une fois le ST déchiffré à l’aide du keytab, l’application vérifie le contenu du ST et en extrait le login de l’utilisateur. Et voilà !

Vous remarquerez que le fichier keytab joue un rôle majeur et qu’il contient des informations sensibles. Il est important de protéger ce fichier au maximum et de ne pas le rendre accessible à tout le monde.

Voilà, c’est une rapide présentation du protocole Kerberos. J’ai pris plein de raccourcis, mais cela permet de poser quelques bases et d’expliquer un peu la magie qui gravite autour de Kerberos.

# Et concrètement, ça donne quoi ?

Pour illustrer cet article, je vais prendre l’exemple de la mise en place d’un Alfresco dans un contexte Microsoft : utilisation de Active Directory avec des postes Windows connectés au domaine. Cet exemple correspond à 100% des cas que nous avons pu rencontrés lors de nos installation d’Alfresco avec authentification Kerberos (et ça devrait donc parler à la plupart des lecteurs).

Le contexte lié notre exemple :

  • Active Directory
    • domaine : ad.atolcd.com
    • realm Kerberos associé : AD.ATOLCD.COM (le même, mais en majuscule)
  • Alfresco
    • installé sur un serveur Linux
    • URL d’accès : https://ged.atolcd.com

Les étapes suivantes sont nécessaires à la mise en place de Kerberos :

  • côté Active Directory :
    • création du compte de service associé à Alfresco
    • génération du fichier keytab associé à ce compte de service
  • côté serveur Alfresco :
    • configuration Kerberos au niveau système
    • configuration Kerberos au niveau Java
    • configuration Kerberos au niveau Alfresco
    • configuration Kerberos au niveau Share

# Actions côté Active Directory

Tous les détails sont indiquées dans la documentation Alfresco. Il n’y a rien de plus à ajouter. Ah si ! Une seule chose : n’oubliez pas l’étape 1.m ! Je ne sais pas pourquoi, mais cette étape passe souvent à la trappe, et on en a besoin pour Share.

Pour reprendre notre exemple, cela donne les actions suivantes :

  • création d’un compte utilisateur
    • on le nommera svc_ged (peu importe le nom, utilisez votre convention de nommage, il faut juste bien penser à le reprendre dans les commandes suivantes)
    • bien reprendre les indications données dans la doc Alfresco : le mot de passe n’expire pas, cocher l’option « Do not require Kerberos preauthentication » dans l’onglet « Account Options« .
  • utilisation de la commande ktpass pour créer le fichier keytab (pour rappel, ce fichier keytab permettra de déchiffrer le ticket ST envoyé par le client) :

  • si besoin, on associe d’autres « Principals » à notre compte svc_ged (cette étape est nécessaire uniquement si les utilisateurs accèdent à Alfresco sur un autre hostname que ged.atolcd.com, par exemple https://ged/) :

  • et on n’oublie pas la fameuse étape 1.m de la procédure Alfresco : cocher « Trust this user for delegation to any service (Kerberos only) » dans l’onglet « Delegation« 

Et voilà, on est bon côté Active Directory. Il ne reste plus qu’à copier le fichier ged.atolcd.com.keybab sur le serveur Alfresco.

# Actions côté Alfresco

# Configuration système

Au niveau du système, un seul fichier à configurer pour Kerberos, il s’agit du fichier /etc/krb5.conf. Il sera unique à chaque installation, mais vous pouvez utiliser l’exemple suivant comme base :

# Configuration Java

Premièrement, il faut créer le fichier login.conf avec un contenu ressemblant à ceci :

Il faudra bien sûr adapter le chemin ver le fichier keytab.

Et ensuite, il faut passer des paramètres Java supplémentaires à Tomcat :

# Configuration Alfresco

Côté Alfresco, tout va se passer dans le fichier alfresco-global.properties. Il faut mettre à jour le paramètre authentication.chain pour ajouter une authentification du type kerberos et ensuite indiquer le realm Kerberos à utiliser.

Alfresco utilisera l’entrée AlfrescoHTTP présent dans le fichier login.conf pour identifier le fichier keytab à utiliser.

# Configuration Share

La configuration Kerberos de Share se fait dans le fichier share-config-custom.xml. Vers la ligne 316 de ce fichier, vous trouverez un bloc XML pour la configuration Kerberos. Il faut modifier ce bloc XML pour qu’il ressemble à ceci :

Il n’est pas nécessaire de modifier les balises <password>, <config-entry> et <stripUserNameSuffix>. Uniquement les balises <realm> et <endpoint-spn> doivent être modifiées.

Toujours dans ce même fichier, à la ligne 432, vous trouverez un autre bloc XML :

Il suffit simplement de dé-commenter la totalité de ce bloc XML.

# Dernière étape

Et pour finir, il ne reste plus qu’à redémarrer Tomcat pour prendre en compte la nouvelle configuration. Si tout s’est bien passé, vous devriez avoir accès à Alfresco Share depuis votre navigateur sans avoir besoin de saisir votre login ni votre mot de passe.
Ça c’est la théorie. Dans le monde réel, ça se passe souvent moins bien que prévu. Et quand ça fonctionne du premier coup, je fais une croix dans le calendrier et je paie ma tournée aux collègues pour fêter ça.

# À l’aide, ça ne fonctionne pas !

Dans un premier temps, j’ai envie de dire « Normal, c’est le genre de chose qui ne fonctionne jamais du premier coup ». Et dans un second temps, mon petit doigt me fait signe dans l’oreillette qu’il y a une deadline pour la mise en prod et qu’il faut trouver ce qui coince. Du coup, pour vous aider, je vous ai listé les problèmes les plus couramment rencontrés (le tout agrémenté de quelques pistes de réflexion).

# Les fichiers de logs

Ça devrait être un réflexe pour tout le monde au moindre problème rencontré. Est-ce qu’il y a des erreurs dans les fichiers de logs Alfresco et/ou Share. Si oui, ces erreurs vous donnerons une première piste pour résoudre le problème.

# Valider la configuration Kerberos au niveau système

La configuration Kerberos est en place au niveau système sur votre serveur Alfresco (le fichier /etc/krb5.conf), on va tester ça tout de suite.

En ligne de commande, directement depuis le serveur Alfresco :

# Valider le fichier keytab

Le test prend moins de 30s, pourquoi s’en priver ?

En ligne de commande, directement depuis le serveur Alfresco :

# Configuration du poste client

C’est de là que tout commence, si le poste client n’est pas correctement configuré, point de salut. Il faut vérifier que le navigateur accepte de faire du Kerberos avec le service demandé.

Pour Internet Explorer, l’URL d’accès à Alfresco doit se trouver dans la zone de sécurité « Local Intranet ». Chrome reprenant la configuration d’Internet Explorer, si celui-ci fonctionne, Chrome devrait en faire autant.

Pour Firefox, tout se passe dans « about:config », les paramètre network.negotiate-auth.delegation-uris et network.negotiate-auth.trusted-uris doivent être modifiés pour englober l’URL d’accès à Alfresco.

Si l’accès se fait en HTTPS (ce que je ne peux que vous conseiller), il faut également vérifier que le certificat HTTPS est reconnu comme valide par les navigateurs.

Dernier point, ces trois navigateurs refuseront de faire du Kerberos dans les fenêtres en navigation privée. N’utilisez pas cette méthode pour tester Kerberos, ça ne pourra pas fonctionner.

# Il faut être à l’heure

Quasiment toutes, si ce n’est toutes, les informations échangées par le protocole Kerberos contiennent un timestamp avec une date d’expiration. Autant pour le TGT, la durée de validité est généralement de plusieurs heures. Autant pour le ST, cette durée de validité est de l’ordre de quelques minutes (deux minutes dans la configuration Active Directory par défaut. Si une des trois entités (client, KDC ou application) a une horloge locale avec un écart de plus de 2 minutes, l’authentification Kerberos échouera.

C’est un argument supplémentaire pour la mise en place du protocole NTP sur toute votre infrastructure.

# Ce n’est pas la taille qui compte

Bah, en fait si, elle compte ! Le ticket ST envoyé par le navigateur vers Alfresco contient des informations sur l’utilisateur à l’origine de la demande. La taille de ce ticket peut donc varier d’un utilisateur à l’autre (par exemple, en fonction du nombre de groupes auxquels appartient l’utilisateur). Or, ce ticket transite via l’entête HTTP Authorization, et, dans certains cas, la taille de ce ticket peut dépasser une certaine limite ce qui entraîne le rejet de la requête HTTP.

Cette limite dépend du serveur utilisé et n’est pas spécifiée dans la norme HTTP. Elle est généralement de 8 Ko (en tout cas pour Apache HTTPD et Tomcat). Il faut faire le tour de toute la chaîne entre le navigateur et Alfresco, et vérifier si un des éléments traversés ne serait pas à l’origine d’un blocage : proxy, reverse-proxy, waf, etc.

# Java Cryptography Extension (JCE)

C’était vrai avec les vielles versions de Oracle JDK, mais ce n’est plus le cas avec OpenJDK. Il était nécessaire d’installer manuellement le jar « Java Cryptography Extension (JCE) » car la distribution de Java fournie par Oracle ne contenait pas toutes les bibliothèques nécessaires au déchiffrement des tickets Kerberos.

# Enregistrement DNS (A ou CNAME ?)

Là, c’est un peu plus subtile. Lors de la création de l’enregistrement DNS pour votre Alfresco, vous avez le choix entre deux types d’enregistrement :

  • type A : vous associez directement un nom avec une adresse IP
  • type CNAME : vous associez le nom à un alias (alias qui pourrait également être un CNAME ou de type A)

Il est important de faire la distinction entre les deux, car le « Principal » indiqué par le navigateur au KDC pour obtenir le ST (étape 3 du schéma tout en haut) dépend de ce choix.

Cas d’un enregistrement de type A, le nom ged.atolcd.com est directement associé à l’adresse IP du serveur Alfresco (par exemple 203.0.113.42). Le « Principal » sera : HTTP/ged.atolcd.com@AD.ATOLCD.COM.

Par contre, dans le cas d’un enregistrement de type CNAME, le nom ged.atolcd.com est associé à un alias. Généralement, il s’agit le nom du serveur qui, lui-même, est un enregistrement de type A associé à l’adresse IP du serveur Alfresco (par exemple : ged.atolcd.com → srv-alfresco-62.priv.atolcd.com → 203.0.113.42). Dans ce cas, le « Principal » sera : HTTP/srv-alfresco-62.priv.atolcd.com@AD.ATOLCD.COM.

Plus de détails : http://web.mit.edu/kerberos/www/krb5-latest/doc/admin/princ_dns.html

# Tester avec curl

Si ça ne fonctionne toujours pas, rien de mieux pour tester qu’un outil en ligne de commande en mode verbose. Avec curl, vous devriez récupérer une erreur exploitable et avoir une piste pour résoudre le problème.

En ligne de commande, directement depuis le serveur Alfresco :

# Le mot de la fin

Cet article met en oeuvre Kerberos en utilisant le sous-système d’authentification intégré directement dans Alfresco. Le contenu de cet article reste cependant valide si vous souhaitez intégrer Kerberos à une autre application. Alors n’hésitez pas à vous en servir comme base. C’est notamment le cas si vous utilisez le principe décrit dans le précédent article External authentication avec un module d’authentification Kerberos.

D’ailleurs, dans les versions 6.2 d’Alfresco, l’authentification Kerberos intégré dans Alfresco semble un peu cassé (voir MNT-21363 et MNT-21511). Une des solutions envisageables est justement passer par le module d’authentification mod_auth_gssapi le temps que l’éditeur sorte un correctif.

Prochain article, le mois prochain. Nous aborderons le module d’authentification SAML d’Alfresco. En attendant, je me sauve en congés pendant une semaine pour profiter du dé-confinement !