• Les cookies assurent le bon fonctionnement de nos services. En poursuivant votre navigation, vous acceptez l'utilisation de cookies.

Portail captif basé sur le proxy et le serveur d'authentification SSO
Cadoles , EOLE , Technique

 

Dans un environnement ouvert comme le sans-fil, il n'est pas toujours possible de contrôler la configuration des postes se connectant sur le réseau (notamment la configuration du proxy dans le navigateur web). Pour des raisons légales et pratiques, il est important de pouvoir conserver les traces des navigations web nominativement.

Souvent, pour gérer les postes nomades, on met en place un portail captif.

Le problème du portail captif, c'est qu'il ne s'intègre pas forcément bien dans un environnement existant. Il n'est pas possible de mixer facilement authentification par proxy, pour les navigateurs avec une configuration du proxy et l'authentification par portail captif pour les navigateurs sans configuration du proxy.

Pour gérer ces deux cas, il faudrait imaginer un portail captif intégré directement sur le proxy. Dans un environnement EOLE, il serait intéressant de profiter du portail d'authentification EOLE-SSO.

Ce travail a été initié par Cadoles pour un projet qui ne verra pas la jour. Son fonctionnement a été validé sur un petit parc de test dans un environnement virtuel. Il n'a jamais été testé en production.

L'authentification proxy et proxy transparent

Avant tout, il faut comprendre la problématique de l'authentification sur le proxy.

Le mécanisme d'authentification proxy est partagé entre le navigateur web et le proxy. Il fonctionne comme l'authentification HTTP.

Lors de l'accès à une ressource, soit le client à un en-tête d'authentification proxy (Proxy-Authenticate) et le proxy valide la session, soit le client ne le transmet pas et le serveur répond par une erreur 407. Le client affiche alors une popup d'authentification permettant à l'utilisateur de saisir son compte utilisateur et son mot de passe (cela peut se faire de façon transparente avec NTLM et Kerberos).

Le problème de cette méthode, c'est que le navigateur web ne s'attend à avoir une erreur 407 que si un proxy est configuré. En mode proxy transparent, il est donc impossible d'utiliser la technique de l'authentification proxy : l'erreur n'est pas traitée comme attendu.

Il faut alors utiliser un mécanisme d'authentification externe (comme par exemple une page d'authentification).

Dans le cas d'une authentification proxy, le serveur mandataire peut conserver une session entre le client et le serveur. Dans ce cas, une même adresse IP peut être associée à plusieurs utilisateurs. Avec une authentification externe, c'est à l'application tiers de gérer la session. La plupart du temps grâce à son adresse IP (couplée éventuellement à l'adresse MAC).

En mode proxy transparent, c'est EOLE-SSO qui pourrait se charger de l'authentification.

Fonctionnement de EOLE-SSO

EOLE-SSO est d'abord un portail web d'authentification pour les applications "CASsifiées". L'application web redirige l'utilisateur vers le portail avec le paramètre "service" comprenant l'URL de la ressource web source.

Si l'utilisateur a entré un bon couple compte utilisateur/mot de passe, le serveur stock dans un cookie un ticket TGC permettant de suivre la session SSO.

Le serveur SSO redirige alors l'utilisateur vers la ressource originale avec un paramètre "ticket" contenant un ticket ST que l'application devra valider auprès de EOLE-SSO.

Dans notre portail captif, il faudra pouvoir rediriger l'utilisateur vers le serveur SSO, avec comme service l'URL source. Le serveur SSO renverra vers la ressource voulue avec un ticket SSO. Ce ticket permettra de valider la session et de récupérer le nom du compte utilisateur.

Méthodes d'authentification Squid

Squid implémente deux manières de gérer l'authentification des utilisateurs. Ces méthodes peuvent être complémentaires.

La première méthode, auth_param, permet d'utiliser les mécanismes d'authentification supportés par Squid (avec l'entête Proxy-Authenticate). Il y a quatre protocoles :

  • basic : compte utilisateur + mot de passe ;
  • digest : compte utilisateur + un hash de mot de passe ;
  • NTLM : authentification permettant d'utiliser le mot de passe de la session Windows ;
  • negociate : authentification via Kerberos.
Pour chacune des méthodes, Squid envoie à un programme externe des lignes, suivant le protocole, contenant différentes informations. Ce programme renvoyant alors OK en cas d'authentification ou ERR en cas d'échec. Aucune autre information ne pourra être transmise au programme externe (donc pas moyen de passer l'URL).

De plus, il n'est pas non plus prévu de pouvoir étendre facilement ces mécanismes.

Une second méthode, external_acl_type, permet d'authentifier l'utilisateur sur d'autres critères. Par exemple :

  • SRC : l'IP source ;
  • URI : l'URI du site visité ;
  • un élément du header de la page.
Comme pour l'autre méthode, ces informations sont données dans une ligne à un programme externe. Si le critère n'a pas de valeur (par exemple l'élément du header n'existe pas), la valeur sera "-". Le programme retournera OK ou ERR. Mais il est possible d'ajouter des informations, comme le compte utilisateur avec une réponse du type : "OK user=admin".

L'idée serait d'utiliser cette méthode pour retrouver le ticket directement dans l'URL de la ressource. Si l'URL contient un attribut "ticket" alors il sera testé sur le serveur SSO. Si l'authentification réussi alors la session sera acceptée et l'application retournera le compte utilisateur obtenu dans la réponse du serveur. Sinon l'authentification sera rejetée.

La redirection des utilisateurs non authentifiés

Il faut pouvoir mixer facilement ces deux méthodes : une authentification proxy traditionnelle (basic, NTLM ou autre) si le navigateur est bien configuré ou une authentification externe pour valider le ticket SSO.

La première problématique est de savoir comment diriger l'utilisateur vers le portail EOLE-SSO en mode proxy transparent.

Pour cela, nous allons utiliser la directive "deny_info" de Squid. Cette directive sert a spécifier une page, locale ou distance (dans ce cas le navigateur reçoit un erreur 302 redirection temporaire), si l'utilisateur n'a pas réussi à obtenir une session légitime.

L'adresse du serveur SSO sera spécifiée avec le paramètre : service=%s (%s sera remplacé par l'URI de la ressource originale).

Donc, si l'utilisateur n'a pas de session légitime, il devra s'authentifier sur le serveur SSO. Lorsque l'utilisateur validera sa session, il sera redirigé vers la ressource originale avec un ticket SSO. Ce ticket sera intercepté par le mécanisme d'authentification externe qui validera le ticket.

C'est bien le comportement que nous recherchons.

Reste une dernière problématique. Deny_info ne fonctionne que pour les authentifications externes. En effet, les échecs d'authentification proxy retourne une erreur 407 (pour forcer l'authentification). Il n'y alors plus de redirection possible vers un service externe (sinon l'authentification proxy ne fonctionne plus).

Il faut donc chercher à n'authentifier l'utilisateur que si le proxy est configuré dans le navigateur. Il n'y a pas, a priori, de moyen simple pour déterminer si le navigateur a un proxy de configuré. Nous allons utiliser un entête HTTP non standard (mais implémenté dans les navigateurs Mozilla Firefox, IE et Google Chrome) : Proxy-Connection. Si l'entête existe, l'authentification proxy est utilisée sinon c'est l'authentification externe.

Session par IP

Dans cette configuration, à chaque ressource (page web, CSS, image, ...), il sera redemandé une validation SSO. Cette solution n'est pas tenable.

Comme tout portail captif, un système de cache permet d'associer un utilisateur à une adresse IP. Au moment de la vérification du ticket SSO, l'association est enregistrée dans une base de donnée. A chaque ressource demandée, si la durée de validité de la session n'est pas dépassée, l'utilisateur est récupéré dans la base de données en fonction de l'adresse IP source.

Il est alors impossible d'avoir plusieurs utilisateurs sur une même adresse IP (donc pas d'Eclair ou pas de SNAT).

De plus, il ne faut pas proposer ce type d'authentification pour des postes en libre service. Lorsqu'un utilisateur se déconnecte, le nouvel utilisateur pourra récupérer sa session pendant un temps déterminé.

Dans le même ordre d'idée, il est également important de ne pas définir une durée de session trop longue.

Schémas

Schéma du fonctionnement si le proxy est configuré dans le navigateur :

Schéma du fonctionnement si le proxy n'est pas configuré dans le navigateur :

Les fichiers

Voici une archive avec trois fichiers :
  • 00_proxy_sso.xml : un dictionnaire Créole à mettre dans le répertoire /usr/share/eole/creole/dicos/local/ ;
  • squid.conf.patch : patch du template Créole squid.conf à mettre dans le répertoire /usr/share/eole/creole/patch/ ;
  • auth_sso.py : script Squid à mettre dans le répertoire /usr/lib/squid3/.
proxy-sso.tgz

Il faut ensuite créé la base de données. Pour cela, lancer "sqlite3 /var/lib/squid/auth_sso.sqlite" et taper :

CREATE TABLE sessions (ip TEXT(16) NOT NULL, name TEXT(50) NOT NULL, time NUMERIC NOT NULL, PRIMARY KEY(ip));

Améliorations possibles

Voici une série de piste d'améliorations possibles :
  • la méthode de détection du "mode transparent" n'est pas facile à détecter avec Squid. La méthode utilisant l'entête Proxy-Connection n'est pas sûre. En effet, cet entête n'est pas standard et il est tout à fait possible que les navigateurs web le retire à un moment donné ;
  • il faudrait voir si utiliser le SSO en mode proxy ne permettrait pas d'améliorer le fonctionnement de la solution. Pour cela il faudrait conserver le cookie SSO ;
  • dans les tests effectués, nous avons pu constater que l'ajout d'un attribut "ticket" dans l'URL peut poser des problèmes à certains sites. Il faudrait passer par une page intermédiaire pour supprimer cette attribut ;
  • au niveau du SSO, une ressource sera ajouté par URL validée.
 

Commentaires

Aucun commentaire pour l'instant, soyez le premier !

Cadoles recrute !

Nous recherchons de nouveaux coopérateurs :