Squid : Authentification par groupes avec un annuaire LDAP
Christophe ILKIEWICZ - christophe.ilkiewicz@wanadoo.fr
Version 1.0 - Dernière mise à jour le 2 mars 2004
1 Introduction
Pour réglementer l'usage d'un proxy, il existe plusieurs moyens
d'authentification, souvent par individus, ce qui implique que lorsque l'on
veut modifier des restrictions qui s'appliquent à un groupe d'individus,
il faut les modifier pour chacun des individus, ce qui est assez fastidieux.
Or, le proxy Squid permet d'utiliser une authentification par groupes,
les informations sur les groupes et les individus se trouvant dans un
annuaire LDAP.
Ainsi, on n'applique plus les restrictions à des individus, mais à des groupes,
et pour changer un individu de groupe il suffit d'intervenir sur l'annuaire
LDAP, on n'a pas besoin de modifier la configuration du proxy, les restrictions
s'appliquant à cet individu étant automatiquement celles de son nouveau groupe.
Nous verrons ici comment installer et configurer un annuaire OpenLDAP et
un proxy Squid 2.5 afin d'avoir une telle méthode d'authentification,
puis comment adapter la configuration de Squid pour utiliser Active Directory à la place d'OpenLDAP pour cette authentification.
2 OpenLDAP
OpenLDAP est un annuaire open-source qui implémente le protocole LDAP.
Pour récupérer les sources d'OpenLDAP ainsi que la documentation officielle,
une seule adresse : http://www.openldap.org .
2.1 Installation
OpenLDAP nécessite que BerkeleyDB (http://www.sleepycat.com ) soit installé, ce qui ne pose pas
de problème particulier, que ce soit une installation à partir d'un binaire
ou de sources.
En revanche, pour installer OpenLDAP à partir des sources (afin d'avoir la
dernière version disponible, la 2.2.5, qui nécessite d'ailleurs d'avoir la
version 4.2 de BerkeleyDB ), il faut procéder ainsi, une fois que l'on a
décompressé les sources et que l'on s'est placé dans le répertoire principal
des sources :
$ export CPPFLAGS='-I/usr/local/BerkeleyDB.4.2/include'
# adapter le chemin si celui-ci est incorrect : c'est le chemin d'installation de BerkeleyDB
$ export LDFLAGS='-L/usr/local/BerkeleyDB.4.2/lib'
$ ./configure --with-tls=no --with-cyrus-sasl=no
# les 2 paramètres permettent de désactiver le support tls et cyrus sasl
$ make depend
$ make
$ make test
$ su root -c "make install"
(consulter le fichier INSTALL dans le répertoire principal des sources
d'OpenLDAP , ainsi que le guide d'installation sur http://www.openldap.org pour plus d'informations,
et la section 5.1 pour voir comment utiliser OpenLDAP avec TLS)
2.2 Configuration
Pour configurer OpenLDAP , il faut modifier le fichier slapd.conf
(situé par défaut, si on a installé depuis les sources, dans le répertoire
/usr/local/etc/openldap).
Vers la fin de ce fichier, il faut avoir les lignes suivantes :
allow bind_v2
pour autoriser les clients qui utilisent le
protocole LDAPv2 (par défaut seuls ceux utilisant LDAPv3 sont autorisés).
En effet, squid_ldap_auth peut utiliser LDAPv2, donc dans ce cas
cette ligne devient indispensable (la version de squid_ldap_auth fournie
avec Squid à partir de la version 2.5.STABLE3 permet d'indiquer la version
de LDAP à utiliser à l'aide du paramètre -v ; la version la plus récente
de Squid existant en package RedHat au moment de la rédaction de ce
document est la 2.5.STABLE1).
database bdb
suffix "dc=example,dc=com"
à remplacer par le bon suffixe
rootdn "cn=Manager,dc=example,dc=com"
à adapter également
rootpw secret
mettre un vrai mot de passe, en clair (déconseillé), ou crypté (par exemple
le mot de passe crypté correspondant à "secret" est
{SSHA}qmWiSnPhgOfkfmU0JS1XGVgvfA/0GFKu).
On peut crypter un mot de passe par exemple avec
/usr/local/sbin/slappasswd.
Une fois que le fichier de configuration a été correctement écrit,
l'annuaire est prêt à être utilisé.
2.3 Utilisation
Pour utiliser l'annuaire OpenLDAP , il faut tout d'abord exécuter slapd
(situé par défaut dans /usr/local/libexec/).
Ensuite, on peut consulter l'annuaire, ajouter, modifier, ou retirer des entrées
au moyen de ldapsearch, ldapadd, ldapmodify,
ldapdelete (fournis avec OpenLDAP ) et de fichiers
LDIF (LDAP Data Interchange Format)...
ou bien à l'aide d'outils graphiques comme l'interface php
phpLDAPadmin (http://phpldapadmin.sourceforge.net ) ou l'outil java
LDAP Browser/Editor (http://www.iit.edu/~gawojar/ldap )...
2.4 Exemple
J'ai défini un annuaire d'exemple correspondant à l'arbre suivant :
Figure 1 : Arbre d'exemple
On a ainsi 4 utilisateurs situés dans l'Organizational Unit (ou) Users,
et 2 groupes situés dans l'ou Groups, 2 utilisateurs étant membres du
premier groupe, les 2 autres utilisateurs étant membres du deuxième groupe.
Le fichier LDIF correspondant est le suivant :
version: 1
# LDIF Export for: dc=example,dc=com
# Generated by phpLDAPadmin on February 17, 2004 2:52 pm
# Server: Serveur test (localhost)
# Search Scope: sub
# Total entries: 10
# Entry 1: dc=example,dc=com
dn: dc=example,dc=com
objectClass: dcObject
objectClass: organization
o: my organization
dc: example
# Entry 2: cn=Manager,dc=example,dc=com
dn: cn=Manager,dc=example,dc=com
objectClass: organizationalRole
cn: Manager
# Entry 3: ou=Groups,dc=example,dc=com
dn: ou=Groups,dc=example,dc=com
ou: Groups
objectClass: top
objectClass: organizationalUnit
# Entry 4: ou=Users,dc=example,dc=com
dn: ou=Users,dc=example,dc=com
ou: Users
objectClass: top
objectClass: organizationalUnit
# Entry 5: cn=bart,ou=Users,dc=example,dc=com
dn: cn=bart,ou=Users,dc=example,dc=com
cn: bart
sn: Bart Simpson
userPassword: azerty
objectClass: person
objectClass: top
# Entry 6: cn=homer,ou=Users,dc=example,dc=com
dn: cn=homer,ou=Users,dc=example,dc=com
cn: homer
objectClass: person
objectClass: top
userPassword: azerty
sn: Homer Simpson
# Entry 7: cn=lisa,ou=Users,dc=example,dc=com
dn: cn=lisa,ou=Users,dc=example,dc=com
cn: lisa
objectClass: person
objectClass: top
userPassword: azerty
sn: Lisa Simpson
# Entry 8: cn=marge,ou=Users,dc=example,dc=com
dn: cn=marge,ou=Users,dc=example,dc=com
cn: marge
objectClass: person
objectClass: top
userPassword: azerty
sn: Marge Simpson
# Entry 9: cn=Parents,ou=Groups,dc=example,dc=com
dn: cn=Parents,ou=Groups,dc=example,dc=com
cn: Parents
objectClass: groupOfNames
objectClass: top
description: groupe des parents
member: cn=homer,ou=Users,dc=example,dc=com
member: cn=marge,ou=Users,dc=example,dc=com
# Entry 10: cn=Enfants,ou=Groups,dc=example,dc=com
dn: cn=Enfants,ou=Groups,dc=example,dc=com
cn: Enfants
objectClass: groupOfNames
objectClass: top
description: groupe des enfants
member: cn=bart,ou=Users,dc=example,dc=com
member: cn=lisa,ou=Users,dc=example,dc=com
Cet annuaire d'exemple servira plus loin dans l'exemple d'authentification
par groupes de Squid .
3 Squid
On ne verra ici qu'une utilisation de Squid dans le cadre d'une
authentification par groupes simple, pour une configuration plus avancée
il faudra voir par exemple les documentations officielles.
3.1 Installation
L'installation de Squid à partir des binaires ne pose pas de problème
particulier.
Pour une installation à partir des sources, se référer à la documentation
accessible depuis le site de Squid (http://www.squid-cache.org ).
3.2 Configuration
On configure Squid en modifiant le fichier /etc/squid/squid.conf.
On passe sur tous les paramètres classiques (http_port,
cache_effective_user...).
Pour configurer l'authentification, on utilise squid_ldap_auth et squid_ldap_group .
3.2.1 squid_ldap_auth
squid_ldap_auth est ce qu'on appelle un authentication helper,
c'est-à-dire un petit programme qui détermine si un couple login/pass est
correct : dans ce cas-ci, il communique avec un annuaire LDAP afin de
voir s'il existe une entrée dans l'annuaire ayant le login indiqué dans un
champ uid (ou cn ou autre si on le précise), et le pass correspondant
dans un champ userPassword, mais un autre authentication helper pourrait
tout aussi bien regarder si le couple login/pass se trouve dans un fichier
contenant une liste de login/pass, voire même renvoyer toujours OK...
Ce programme doit renvoyer la chaîne de caractères "OK" en cas de succès
et "ERR" en cas d'échec.
Pour utiliser squid_ldap_auth , on ajoute dans squid.conf
les lignes suivantes :
auth_param basic program /usr/lib/squid/squid_ldap_auth -b ou=Users,dc=example,dc=com -u cn localhost
auth_param basic children 5
auth_param basic realm Identification proxy
auth_param basic credentialsttl 2 hours
Les paramètres ici utilisés pour squid_ldap_auth sont :
-
-b ou=Users,dc=example,dc=com :
indique la base de l'arborescence de l'annuaire à partir de laquelle
on recherche l'utilisateur qui essaie de s'authentifier
- -u cn :
indique le type du login que l'on tape pour s'authentifier (par exemple cn,
uid...)
- localhost : adresse du serveur LDAP, ici il est sur la
même machine que le proxy Squid .
On peut se demander à quoi servent les 3 lignes suivantes.
-
auth_param basic children 5 : le nombre de processus
d'authentification qui seront lancés en permanence sur le serveur, chacun ne
pouvant servir qu'une demande à la fois
- auth_param basic realm Identification proxy : la chaîne de
caractères qui suit realm sera affichée par le navigateur utilisé
lors de la demande d'authentification, elle permet donc d'indiquer à
l'utilisateur que c'est au proxy qu'il essaie de se connecter
- auth_param basic credentialsttl 2 hours : la durée au bout
de laquelle l'authentication helper (squid_ldap_auth ) sera relancé.
Attention, cela ne veut pas dire que la fenêtre demandant le login/pass va se
réafficher (cela ne dépend pas de Squid , mais du navigateur utilisé).
Concrètement, au bout du temps indiqué, il y aura de nouveau un échange de
paquets LDAP entre Squid et le serveur LDAP pour authentifier l'utilisateur,
et éventuellement lui interdire l'accès.
Dans le cas d'une authentification par individus, il ne reste qu'à ajouter
une règle ACL (Access Control List) qui indique l'utilisation du mécanisme
d'authentification.
Cette règle a la forme suivante :
acl password proxy_auth REQUIRED
Explications :
-
acl : indique qu'on va définir une règle acl
- password : nom de la règle, on met ce qu'on veut, l'important
est de pouvoir reconnaître la règle ultérieurement
- proxy_auth : type de règle acl, indique ici que c'est une règle
d'authentification
- REQUIRED : liste des noms des utilisateurs acceptés, ou comme ici
REQUIRED pour indiquer qu'on accepte n'importe quel nom d'utilisateur
valide.
Une fois cette règle ACL définie, on peut l'utiliser dans des règles d'accès,
comme par exemple :
http_access allow password
Cette règle indique que tous les utilisateurs authentifiés auront un accès http
(suivant sa position par rapport à d'autres règles d'accès, cet accès sera
peut-être restreint).
On notera que la règle ACL d'authentification
acl password proxy_auth REQUIRED devient inutile dès qu'on utilise
l'authentification par groupes.
3.2.2 squid_ldap_group
squid_ldap_group est aussi un helper, mais il interroge un annuaire
LDAP pour savoir si un utilisateur donné appartient bien à un groupe donné,
indépendamment d'un quelconque mot de passe.
C'est un complément à squid_ldap_auth qui permet d'établir des règles d'accès
au proxy selon des groupes définis dans l'annuaire.
Pour l'utiliser, on ajoute dans squid.conf la ligne :
external_acl_type ldap_group ttl=3600 %LOGIN /usr/lib/squid/squid_ldap_group
-b ou=Groups,dc=example,dc=com
-B ou=Users,dc=example,dc=com
-f "(&(cn=%g)(objectClass=groupOfNames)(member=%u))"
-F "(&(cn=%s)(objectClass=person))"
localhost
Attention, cette ligne a été découpée pour une lecture plus commode,
mais dans le fichier de configuration, il ne faut pas la couper
par des retours à la ligne.
Explications :
-
external_acl_type : indique qu'on définit une règle externe
(utilisant un programme externe)
- ldap_group : nom de la règle, on peut mettre le nom de son choix
- ttl=3600 : durée (en secondes) au bout de laquelle Squid va
relancer squid_ldap_group afin de savoir si l'utilisateur appartient au groupe
- %LOGIN :
indique que la règle va récupérer le nom de l'utilisateur authentifié
- /usr/lib/squid/squid_ldap_group : programme utilisé dans cette
règle
- -b ou=Groups,dc=example,dc=com : noeud de l'annuaire LDAP
qui servira de base à la recherche du groupe
- -B ou=Users,dc=example,dc=com : noeud de l'annuaire LDAP qui
servira de base à la recherche de l'utilisateur
- -F "(&(cn=%s)(objectClass=person))" :
filtre de recherche de l'utilisateur, %s étant le nom de l'utilisateur
authentifié
- -f "(&(cn=%g)(objectClass=groupOfNames)(member=%u))" :
filtre de recherche du groupe, %g étant le nom du groupe que l'on donnera
plus loin, et %u le dn (distinguished name) de l'utilisateur
- localhost : adresse du serveur LDAP, ici il est sur la
même machine que le proxy Squid .
Pour mieux comprendre le sens de ces paramètres, lire la section suivante.
Pour utiliser l'authentification par groupes, il faut également définir une
règle ACL par groupe, du type :
acl group_Parents external ldap_group Parents
où :
-
group_Parents est le nom de la règle
- external est le type de règle
- ldap_group est le nom de la règle externe que l'on vient
de définir
- Parents est le nom du groupe qu'on donne en paramètre
à la règle externe
puis il faut définir des règles d'accès, comme par exemple :
http_access allow group_Parents
qui autorise l'accès http à tous les utilisateurs vérifiant
l'ACL group_Parents, c'est-à-dire les utilisateurs authentifiés
appartenant au groupe Parents dans l'annuaire LDAP.
3.3 Utilisation
Une fois que le proxy est configuré, on peut le lancer, ce qui se fait dans
le cas d'une installation à partir des binaires Redhat 9 par la commande :
Si on doit le relancer (suite à une modification de squid.conf), on tape :
/etc/init.d/squid restart
On peut maintenant tester le proxy.
3.4 Exemple
On retourne sur son poste client, et on indique à son navigateur préféré
que l'on utilise ce proxy, en lui donnant l'ip de l'ordinateur faisant
office de serveur proxy, ainsi que le port utilisé (défini dans squid.conf
par http_port).
Ensuite, lorsqu'on essaie d'accéder à une page nécessitant une authentification,
une fenêtre devrait s'ouvrir, demandant un nom d'utilisateur et un mot de passe.
Figure 2 : Dialogue d'authentification
On notera qu'on retrouve bien la chaîne de caractères passée en argument
à auth_param basic realm dans squid.conf.
Rentrons par exemple l'utilisateur homer et le mot de passe azerty.
On accède bien à la page demandée, et on n'a plus besoin de rentrer son
login/pass à nouveau (comportement de la plupart des navigateurs, indépendant
de Squid ).
Si maintenant on relance le navigateur et si on réessaie d'accéder à la même
page, la plupart des navigateurs vont redemander le login/pass.
Rentrons cette fois-ci le couple bart/azerty, et on arrive à une
page nous indiquant que l'accès est interdit.
Pour accéder à la page, il faut donc relancer le navigateur et entrer un couple
login/pass ayant les droits d'accès suffisants (en théorie chaque utilisateur
ne connaît qu'un seul login/pass bien évidemment).
Pour bien comprendre le fonctionnement de l'authentification, on peut analyser
les transmissions de paquets avec un outil comme Ethereal.
3.5 Fonctionnement
Ethereal est un outil d'analyse de protocoles réseau (http://www.ethereal.com ).
Il permet d'observer les paquets échangés sur un réseau, de les classer par
protocole...
On ne s'intéresse ici qu'aux paquets LDAP échangés, entre le moment où on
rentre un couple login/pass et le moment où une page s'affiche.
3.5.1 Identifiant incorrect
Dans le cas d'un utilisateur rentrant un mauvais login ou mot de passe,
on observe la succession des paquets suivants :
-
un paquet de type Bind Request envoyé au serveur LDAP
Figure 3 : Bind Request avec mauvais pass
- un paquet de type Bind Result renvoyé par le serveur LDAP,
indiquant que l'authentification a échoué : le champ Result Code
indique Invalid Credentials
- un paquet de type Unbind Request envoyé au serveur LDAP pour
se déconnecter.
3.5.2 Identifiant correct - Personne autorisée
Dans le cas d'un utilisateur autorisé rentrant correctement ses identifiants,
on a d'abord les 3 mêmes paquets que précédemment, avec la nuance que le champ
Result Code du paquet Bind Result indique Success,
puis les paquets suivants :
-
un paquet Search Request correspondant aux -B et -F définis
en paramètre de squid_ldap_group dans squid.conf
Figure 4 : Search Request de l'utilisateur
- un paquet Search Entry contenant certaines informations sur
le noeud correspondant à la requête
Figure 5 : Search Entry de l'utilisateur
- un paquet Search Result similaire à un Bind Result en cas
de succès
- un paquet Search Request correspondant aux -b et -f définis
en paramètre de squid_ldap_group dans squid.conf ;
on remarque que le %u a été remplacé par la réponse de la requête précédente
Figure 6 : Search Request du groupe
- un paquet Search Entry similaire à celui de la requête précédente,
mais contenant des informations sur le groupe correspondant à la requête
- un paquet Search Result indiquant que la recherche s'est effectuée
sans problème
- un paquet Unbind Request envoyé au serveur LDAP pour
se déconnecter.
3.5.3 Identifiant correct - Personne non autorisée
Enfin, dans le cas d'un utilisateur non autorisé rentrant correctement
ses identifiants, on a exactement le même type de paquets échangés jusqu'au
deuxième Search Request, qui, ayant un filtre ne correspondant à
aucune entrée de l'annuaire, n'entraîne pas d'émission de paquet
Search Entry.
Figure 7 : Search Request de groupe inexistant
Le deuxième paquet Search Request est donc immédiatement suivi en réponse
d'un paquet Search Result indiquant que la recherche s'est effectuée sans
problème (en effet le fait de ne pas avoir de réponse n'est pas une erreur),
puis d'un paquet Unbind Request.
ttl de squid_ldap_auth
Dans squid.conf, nous avons mis la ligne suivante :
auth_param basic credentialsttl 2 hours
Lorsqu'on s'est identifié correctement auprès du proxy (que l'on soit autorisé
ou non), si on s'identifie une nouvelle fois avant la fin de la durée associée
à credentialsttl, Squid ne fera pas d'échange avec le serveur LDAP.
Squid possède en quelque sorte un cache d'identifiants, ce qui évite de
solliciter le serveur LDAP trop souvent (en effet si on réduit cette durée
à une seconde, on se rend compte en utilisant Ethereal que Squid effectue un Bind Request/Result/Unbind à chaque nouvelle page demandée
par l'utilisateur).
En contrepartie, si on modifie le mot de passe dans l'annuaire, le changement
ne sera pas perçu avant la fin de la durée choisie ici, l'utilisateur n'aura
donc pas besoin de se ré-authentifier avant la fin de cette durée
(que ce soit l'utilisateur lui-même ou quelqu'un qui lui a volé son mot de
passe et qui se sert de son compte), par contre
une fois que la durée sera écoulée, Squid saura que le mot de passe n'est
plus valide, et donc l'utilisateur devra s'authentifier à nouveau.
ttl de squid_ldap_group
De même, dans la ligne appelant squid_ldap_group de squid.conf, nous
avons mis le paramètre
Ce paramètre a le même rôle concernant squid_ldap_group que credentialsttl
avec squid_ldap_auth .
Ainsi, si on modifie l'annuaire LDAP de sorte à rajouter un
utilisateur non autorisé dans un groupe autorisé, le changement ne sera pas
perçu avant la fin de cette durée, et l'utilisateur ne sera donc
pas autorisé selon Squid avant qu'il ne refasse sa requête au serveur LDAP.
(Remarque : ttl signifie time to live, c'est-à-dire le temps, la durée qu'il reste à vivre...)
4 Active Directory
Active Directory est l'annuaire utilisé par MS Windows 2000 Server
et MS Windows Server 2003.
Une fois qu'on a réussi à interfacer Squid avec OpenLDAP , le passage
à Active Directory n'est pas très compliqué.
Il vaut donc mieux lire la section précédente avant de passer à celle-ci.
4.1 Description rapide des données utilisées dans Active Directory
Dans Active Directory , les utilisateurs sont en général répertoriés dans CN=Users,
mais rien n'empêche de créer une zone plus adaptée, pour différencier
toutes les personnes que l'on va ajouter de toutes les entrées qui se trouvent
déjà par défaut dans CN=Users.
Par exemple, on peut créer une OU=Personnes (OU=Organizational Unit,
c'est-à-dire Unité d'Organisation), ou tout autre chose selon ses souhaits.
On peut alors ajouter des utilisateurs à l'emplacement de son choix.
Pour faire cela, la méthode classique est d'utiliser la console
Utilisateurs et ordinateurs Active Directory, qui est accessible dans les
Outils d'Administration, ou qu'on peut rajouter dans
une console personnalisée au moyen de la Microsoft Management Console
(qu'on peut lancer par la commande mmc).
On crée ainsi des utilisateurs, par exemple Jean MARTIN, Pierre DUPONT et
Jacques DURAND.
On peut aussi créer ces utilisateurs sans passer par la console Microsoft,
mais en utilisant des programmes permettant de modifier les données d'un
annuaire LDAP (les mêmes programmes qui permettent de remplir un annuaire
OpenLDAP). Cependant, c'est un peu plus délicat au niveau des mots
de passe (voir 4.4.1).
Maintenant que des utilisateurs existent, on peut créer un groupe qui
regoupera les personnes ayant accès à Internet par exemple.
Cela se fait aussi aisément avec les mêmes outils que pour les utilisateurs.
On ajoute alors dans ce groupe les utilisateurs à qui on veut donner accès
à Internet.
On peut alors passer à la configuration de Squid .
4.2 Configuration de Squid
Pour passer d'OpenLDAP à Active Directory , il suffit de modifier les 2 lignes d'appel
de squid_ldap_auth et squid_ldap_group .
4.2.1 squid_ldap_auth
Voici la ligne que j'obtiens :
auth_param basic program /usr/lib/squid/squid_ldap_auth
-R -D "CN=Administrateur,CN=Users,DC=demo-cg77,DC=org" -w azerty
-b dc=demo-cg77,dc=org -f sAMAccountName=%s 101.0.50.41
Explications :
-
-R : indique de ne pas suivre les referrals (ne fonctionne pas
dans mon cas si je ne mets pas ce paramètre)
- -b dc=demo-cg77,dc=org : la base peut changer
- -f sAMAccountName=%s :
filtre indiquant ou trouver ce qu'on tape en tant que login. Si on met
sAMAccountName, le login est de la forme jean.martin
(ou Administrateur, alors qu'en mettant à la place
userPrincipalName, le login est de la forme
jean.martin@demo-cg77.org (l'administrateur n'a pas d'attribut
userPrincipalName par défaut).
- -D "CN=Administrateur,CN=Users,DC=demo-cg77,DC=org" -w azerty :
comme on fait une recherche (à cause du filtre -f), il faut apparemment
faire un bind auprès du serveur LDAP en indiquant ici le nom de
l'utilisateur et son mot de passe, à moins que les recherches anonymes soient
autorisées (ce qui n'est pas le cas par défaut)
- 101.0.50.41 : adresse du serveur Active Directory
A ce niveau, on peut déjà procéder à une authentification par individus.
4.2.2 squid_ldap_group
Pour l'authentification par groupes, on modifie la ligne d'appel de
squid_ldap_group ainsi :
external_acl_type ldap_group ttl=3600 %LOGIN /usr/lib/squid/squid_ldap_group
-R -D "CN=Administrateur,CN=Users,DC=demo-cg77,DC=org" -w azerty
-b "cn=Users,dc=demo-cg77,dc=org"
-B "ou=Personnes,dc=demo-cg77,dc=org"
-f "(&(cn=%g)(objectClass=group)(member=%u))"
-F "(&(sAMAccountName=%s)(objectClass=person))"
101.0.50.41
De même que pour squid_ldap_auth , on a rajouté -R, -D ... et
-w ..., on a adapté la base de recherche des utilisateurs et des
groupes, on a mis l'adresse du serveur Active Directory , et on a changé, pour le
filtre des utilisateurs, l'attribut déterminant le login.
Il faut remarquer, concernant le filtre des groupes, que l'on a changé
la classe du groupe : en effet, dans Active Directory , les groupes ne sont pas
de la classe groupOfNames, mais group.
Une fois ces modifications effectuées, on peut relancer Squid , et
l'authentification doit fonctionner par l'intermédiaire d'Active Directory .
4.3 Petite remarque en passant
On observe avec Ethereal qu'Active Directory , contrairement à OpenLDAP ,
renvoie le Search Entry et le Search Result concaténés
au sein du même paquet.
4.4 Utilisateurs
-
On ne peut apparamment pas faire de recherches ldap en anonyme
avec Active Directory (en tout cas pas par défaut), il vaut donc mieux créer
un utilisateur dédié.
- Pour créer un utilisateur avec des outils ldap, ces informations
suffisent :
dn: CN=Paul LEROY, OU=Personnes, dc=demo-cg77,dc=org
objectClass: user
Cependant, pour pouvoir se connecter avec cet utilisateur, on a besoin aussi
de ces informations :
sAMAccountName: paul.leroy
userPrincipalName: paul.leroy@demo-cg77.org
On peut aussi ajouter ces informations qui peuvent être utilisées ailleurs :
givenName: Paul
sn: LEROY
cn: Paul LEROY
displayName: Paul LEROY
On peut bien évidemment définir ces 3 blocs d'informations en même temps.
Pour que l'utilisateur puisse se connecter, il reste encore à l'activer,
mais avant cela on est obligé par défaut de définir un mot de passe.
Si on ne veut pas mettre de mot de passe (attention, l'utilisateur ne pourra
pas se connecter) mais qu'on veut quand même l'activer, passer directement
à la section 4.4.2.
4.4.1 Attribution d'un mot de passe
Un mot de passe doit avoir une forme particulière pour pouvoir être attribué :
-
on doit l'écrire entre double quotes
(par exemple "password")
- il faut le transformer en unicode
("\0p\0a\0s\0s\0w\0o\0r\0d\0"\0)
- il faut ensuite l'encoder en base64
(IgBwAGEAcwBzAHcAbwByAGQAIgA=)
On peut automatiser ceci par le petit script perl suivant :
use MIME::Base64;
print encode_base64(join("\0",split(//,"\"password\"")) . "\0");
ou de manière plus interactive :
use MIME::Base64;
chomp($p=<STDIN>);
print encode_base64(join("\0",split(//,"\"$p\"")) . "\0");
(ce script lit l'entrée standard, rajoute les double quotes,
sépare la chaîne de caractères obtenue en caractères distincts,
rassemble ces caractères en intercalant des "\0", rajoute
le dernier "\0", puis encode en base64 et renvoie la chaîne obtenue)
Il faut ensuite modifier l'utilisateur avec ldapmodify par exemple, mais en
utilisant le port sécurisé (ldaps://).
A priori, ce n'est que pour modifier le mot de passe que l'on est obligé
d'utiliser le SSL (mais il est recommandé de toujours l'utiliser pour plus
de sécurité).
Voir la section 5 pour plus d'informations sur le SSL, et plus
particulièrement 5.2 pour savoir comment utiliser SSL
avec Active Directory .
On peut très simplement automatiser toute l'opération de changement de mot
de passe, par exemple avec le script perl suivant :
#!/usr/bin/perl
use MIME::Base64;
$l=6;
$host="101.0.50.41";
$tmpfile="__chpass__tmp__ldif__file__";
print "DN de l'utilisateur Active Directory : ";
chomp($u=<STDIN>);
$msg = "Entrez un mot de passe ($l car. minimum) : ";
do {
do {
system "stty -echo";
print $msg;
chomp($p=<STDIN>);
print "\n";
system "stty echo";
$msg = "Erreur - mot de passe trop court : "
."il faut au moins $l caracteres\n"
."Entrez un mot de passe ($l car. minimum) : ";
} while (length($p)<$l);
system "stty -echo";
print "Retapez le mot de passe (verification) : ";
chomp($p2=<STDIN>);
print "\n";
system "stty echo";
$msg = "Echec de la verification\n"
."Entrez un mot de passe ($l car. minimum) : ";
} while (not ($p eq $p2));
open (OUTFILE, ">$tmpfile");
$crypt = encode_base64(join("\0",split(//,"\"".$p."\"")) . "\0");
print OUTFILE "dn: $u\n"."unicodePwd:: $crypt";
close (OUTFILE);
print "\nMot de passe Administrateur Active Directory - ";
$res=system "ldapmodify -D cn=Administrateur,cn=Users,dc=demo-cg77,dc=org -W -H ldaps://$host -f $tmpfile";
system "rm -f $tmpfile";
if ($res) {
print "Erreur : le mot de passe n'a donc pas ete change\n";
} else {
print "Le mot de passe a bien ete change\n";
}
4.4.2 Activation de l'utilisateur : userAccountControl
Le champ userAccountControl regroupe plusieurs propriétés sur le compte
utilisateur. C'est un champ de bits d'une taille de 4 octets, soit 32
bits, c'est-à-dire 32 drapeaux (flags), pouvant indiquer autant de propriétes.
En pratique, dans la documentation officielle de Microsoft, il n'y a pas
d'explications pour tous ces bits, et les celles fournies sont
très sommaires, j'ai donc tatonné pour comprendre à quoi correspondent
certains de ces bits.
En voici la description (le bit 0 est celui de poids faible, c'est-à-dire le
plus à droite) :
| Bit n° |
Signification |
Valeur |
Accepté |
| 0 |
Script |
1 |
non |
| 1 |
Compte désactivé |
2 |
oui |
| 3 |
Homedir required |
8 |
oui |
| 4 |
Lockout (verrouillage) |
16 |
non |
| 5 |
Password not required |
32 |
oui |
| 6 |
Password can't change |
64 |
non |
| 7 |
Enregistrer le mot de passe
en utilisant un cryptage réversible |
128 |
oui |
| 8 |
Temp duplicate account |
256 |
non |
| 9 |
Normal account |
512 |
oui |
| 11 |
Interdomain trust account |
2048 |
non |
| 12 |
Workstation trust account |
4096 |
oui |
| 13 |
Server trust account |
8192 |
non |
| 16 |
Le mot de passe n'expire jamais |
65536 |
oui |
| 17 |
MNS logon account |
131072 |
oui |
| 18 |
Une carte à puce est nécessaire
pour ouvrir une session interactive |
262144 |
oui |
| 19 |
Le compte est approuvé pour la délégation |
524288 |
oui |
| 20 |
Le compte est sensible et
ne peut pas être délégué |
1048576 |
oui |
| 21 |
Utiliser les types de
cryptage DES pour ce compte |
2097152 |
oui |
| 22 |
La pré-authentification Kerberos
n'est pas nécessaire |
4194304 |
oui |
La valeur que l'on donne à userAccountControl est la somme des valeurs
associées aux propriétés que l'on veut activer pour le compte
(ces valeurs sont en fait 2 à la puissance le numéro du bit).
Ainsi, si on veut par exemple un compte normal désactivé, on met la valeur
514 (512 + 2), alors que si on veut qu'il soit activé, on met juste 512.
Si on veut que le mot de passe n'expire jamais, il suffit de rajouter 65536.
Si on veut activer l'utilisateur sans avoir défini de mot de passe, on
met 512 + 32 = 544 ...
Attention, on ne peut pas (Active Directory l'empêche) cumuler "normal account" et
"workstation trust account" par exemple, vu qu'un compte ne peut être que
dans l'une de ces 2 catégories à la fois.
En pratique, pour un normal account, l'utilisateur sera automatiquement
membre du groupe Utilisa. du domaine, alors que pour un
workstation trust account, il sera membre du groupe
Ordinateurs du domaine.
Une fois que l'on a créé l'utilisateur, défini son mot de passe, et activé
son compte, on peut enfin l'utiliser pour se connecter...
5 SSL
Afin de sécuriser les échanges d'informations avec les différents serveurs LDAP,
on peut utiliser SSL (Secure Sockets Layer), qui est en fait
une couche se rajoutant dans les paquets transmis, et permettant de crypter
les données transmises.
J'ai tenté d'utiliser SSL avec OpenLDAP et Active Directory .
5.1 SSL avec OpenLDAP
Pour pouvoir utiliser SSL avec OpenLDAP , il faut l'avoir compilé avec le
support SSL/TLS (TLS : Transport Layer Security).
Il faut avoir au préalable installé OpenSSL .
(On peut aussi installer un package rpm, mais au moment de la rédaction de ce
document, la dernière version que j'ai trouvée est OpenLDAP 2.1.25
(pas en paquet officiel, mais sur http://www.int-evry.fr/mci/user/procacci/SRPMS/9/ ).
Cette version possède le support SSL, on peut donc l'utiliser)
Pour compiler OpenLDAP avec le support SSL/TLS, j'ai dû taper les commandes
suivantes depuis le répertoire des sources :
$ export CPPFLAGS='-I/usr/local/BerkeleyDB.4.2/include -I/usr/kerberos/include'
# configure ne trouvant pas les headers kerberos, il a fallu lui indiquer
# où ils se trouvent
$ export LDFLAGS='-L/usr/local/BerkeleyDB.4.2/lib'
$ ./configure --with-tls=yes --with-cyrus-sasl=no
# l'utilisation de tls et de cyrus sasl est choisie automatiquement par défaut,
# ici on force l'utilisation de tls, et on interdit celle de cyrus sasl
# (en effet, il y a déjà une version trop ancienne de cyrus sasl installée,
# que je ne peux pas supprimer car c'est une dépendance de sendmail, mutt
# et squid, et en compilant la dernière version, j'ai un problème de conflit de
# versions que je n'ai pas réussi à résoudre)
$ make depend
$ make
$ make test
$ su -c "make install"
Pour pouvoir utiliser SSL, il faut créer un certificat,
reconfigurer le serveur, et le relancer en lui indiquant d'utiliser ssl.
5.1.1 Création d'un certificat
(cf http://www.openldap.org/pub/ksoper/OpenLDAP_TLS_howto.html (en anglais))
On peut assez aisément créer un certificat à l'aide d'OpenSSL .
En fait, on a besoin de :
-
une Autorité de Certification (CA)
- un certificat du serveur
- une clé privée du serveur
Pour les obtenir, on procède ainsi :
-
on crée un répertoire temporaire : mkdir tmpssl
- on se place dans ce répertoire : cd tmpssl
- on copie le script de création de certificats :
cp /usr/share/ssl/misc/CA .
- on modifie ce script : vers la ligne 56, on a ceci :
-newreq)
# create a certificate request
$REQ -new -keyout newreq.pem -out newreq.pem $DAYS
RET=$?
echo "Request (and private key) is in newreq.pem"
;;
Il suffit de rajouter -nodes à la fin de la troisième ligne,
de sorte à avoir
$REQ -new -keyout newreq.pem -out newreq.pem $DAYS -nodes.
Cette modification permet de ne pas avoir à taper le mot de passe
du certificat au lancement du serveur.
- on crée une CA :
$ ./CA -newca
CA certificate filename (or enter to create) <enter>
Making CA certificate ...
Generating a 1024 bit RSA private key
..++++++
....................++++++
writing new private key to './demoCA/private/./cakey.pem'
Enter PEM pass phrase: <pass phrase>
Verifying - Enter PEM pass phrase: <même pass phrase>
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [GB]:FR
State or Province Name (full name) [Berkshire]:77
Locality Name (eg, city) [Newbury]:Melun
Organization Name (eg, company) [My Company Ltd]:CG77
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:example.com
Email Address []:
ceci crée demoCA/cacert.pem (l'autorité de certification)
ainsi que demoCA/private/cakey.pem (sa clé privée)
- on crée une "requête de signature de certificat" pour le serveur
(Certificate Signing Request - CSR) :
$ ./CA -newreq
Generating a 1024 bit RSA private key
..++++++
................................................++++++
writing new private key to 'newreq.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [GB]:FR
State or Province Name (full name) [Berkshire]:77
Locality Name (eg, city) [Newbury]:Melun
Organization Name (eg, company) [My Company Ltd]:CG77
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:example.com
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Request (and private key) is in newreq.pem
ceci génère le fichier newreq.pem
- on demande à l'autorité de certification de signer la CSR :
$ ./CA -sign
Using configuration from /usr/share/ssl/openssl.cnf
Enter pass phrase for ./demoCA/private/cakey.pem: <pass phrase>
Check that the request matches the signature
Signature ok
Certificate Details:
Serial Number: 1 (0x1)
Validity
Not Before: Feb 27 14:00:30 2004 GMT
Not After : Feb 26 14:00:30 2005 GMT
Subject:
countryName = FR
stateOrProvinceName = 77
localityName = Melun
organizationName = CG77
commonName = example.com
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
Netscape Comment:
OpenSSL Generated Certificate
X509v3 Subject Key Identifier:
21:F6:97:CE:0E:9C:7B:57:F3:AE:9E:2D:34:91:CB:B5:53:16:A3:FE
X509v3 Authority Key Identifier:
keyid:AE:C0:53:F4:6B:D0:ED:F6:FF:00:6F:AF:FD:B8:2E:BF:E7:27:56:A2
DirName:/C=FR/ST=77/L=Melun/O=CG77/CN=example.com
serial:00
Certificate is to be certified until Feb 26 14:00:30 2005 GMT (365 days)
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 1 (0x1)
Signature Algorithm: md5WithRSAEncryption
Issuer: C=FR, ST=77, L=Melun, O=CG77, CN=example.com
Validity
Not Before: Feb 27 14:00:30 2004 GMT
Not After : Feb 26 14:00:30 2005 GMT
Subject: C=FR, ST=77, L=Melun, O=CG77, CN=example.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public Key: (1024 bit)
Modulus (1024 bit):
00:d8:84:5a:24:34:82:7b:63:04:f1:8a:2d:ba:ad:
38:5e:00:50:68:c3:e3:9f:15:e0:7c:4f:b5:13:aa:
88:7d:fa:7d:f3:c4:fe:14:ad:e5:f6:70:e5:da:8e:
7e:e9:97:0c:fb:e1:f6:cf:68:31:53:bb:57:04:41:
7e:05:0e:18:1c:5e:55:d3:62:e0:8e:cd:82:b3:92:
56:14:b5:22:50:ad:17:df:3d:ab:df:55:24:8c:43:
fc:e4:f5:db:9f:64:8b:c3:aa:3e:3f:14:16:ea:f7:
8e:8e:e4:51:4a:96:46:b0:6b:2c:7e:8b:b4:b8:47:
8e:d0:31:60:53:a5:3b:e3:5d
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
Netscape Comment:
OpenSSL Generated Certificate
X509v3 Subject Key Identifier:
21:F6:97:CE:0E:9C:7B:57:F3:AE:9E:2D:34:91:CB:B5:53:16:A3:FE
X509v3 Authority Key Identifier:
keyid:AE:C0:53:F4:6B:D0:ED:F6:FF:00:6F:AF:FD:B8:2E:BF:E7:27:56:A2
DirName:/C=FR/ST=77/L=Melun/O=CG77/CN=example.com
serial:00
Signature Algorithm: md5WithRSAEncryption
30:df:d5:f9:a0:32:6e:8c:3d:e2:58:95:f7:8f:9a:cb:d6:36:
42:01:43:43:96:f1:ba:88:84:06:ce:61:8d:ac:06:14:72:8d:
0e:d2:68:7b:60:1c:9f:6d:fb:32:24:2d:93:ab:ba:4c:21:9f:
6f:67:b6:62:5b:35:a9:a5:1e:fe:93:97:2b:43:00:34:09:bd:
9a:a6:04:0f:21:20:fb:77:70:a9:76:05:e4:fd:de:9d:69:09:
82:eb:a1:84:57:92:fb:27:0a:22:7c:91:d3:55:7c:f7:d1:92:
cc:5f:df:b0:dd:8a:18:5f:94:ce:36:14:f4:fc:c3:5a:66:85:
b1:59
-----BEGIN CERTIFICATE-----
MIIC6TCCAlKgAwIBAgIBATANBgkqhkiG9w0BAQQFADBPMQswCQYDVQQGEwJGUjEL
MAkGA1UECBMCNzcxDjAMBgNVBAcTBU1lbHVuMQ0wCwYDVQQKEwRDRzc3MRQwEgYD
VQQDEwtleGFtcGxlLmNvbTAeFw0wNDAyMjcxNDAwMzBaFw0wNTAyMjYxNDAwMzBa
ME8xCzAJBgNVBAYTAkZSMQswCQYDVQQIEwI3NzEOMAwGA1UEBxMFTWVsdW4xDTAL
BgNVBAoTBENHNzcxFDASBgNVBAMTC2V4YW1wbGUuY29tMIGfMA0GCSqGSIb3DQEB
AQUAA4GNADCBiQKBgQDYhFokNIJ7YwTxii26rTheAFBow+OfFeB8T7UTqoh9+n3z
xP4UreX2cOXajn7plwz74fbPaDFTu1cEQX4FDhgcXlXTYuCOzYKzklYUtSJQrRff
PavfVSSMQ/zk9dufZIvDqj4/FBbq946O5FFKlkawayx+i7S4R47QMWBTpTvjXQID
AQABo4HUMIHRMAkGA1UdEwQCMAAwLAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2Vu
ZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBQh9pfODpx7V/Ouni00kcu1Uxaj
/jB3BgNVHSMEcDBugBSuwFP0a9Dt9v8Ab6/9uC6/5ydWoqFTpFEwTzELMAkGA1UE
BhMCRlIxCzAJBgNVBAgTAjc3MQ4wDAYDVQQHEwVNZWx1bjENMAsGA1UEChMEQ0c3
NzEUMBIGA1UEAxMLZXhhbXBsZS5jb22CAQAwDQYJKoZIhvcNAQEEBQADgYEAMN/V
+aAybow94liV94+ay9Y2QgFDQ5bxuoiEBs5hjawGFHKNDtJoe2Acn237MiQtk6u6
TCGfb2e2Yls1qaUe/pOXK0MANAm9mqYEDyEg+3dwqXYF5P3enWkJguuhhFeS+ycK
InyR01V899GSzF/fsN2KGF+UzjYU9PzDWmaFsVk=
-----END CERTIFICATE-----
Signed certificate is in newcert.pem
ceci génère le fichier newcert.pem (le certificat du serveur
signé par la CA), avec la clé privée dans newreq.pem
Maintenant qu'on a les certificats nécessaires, on peut passer à la
configuration du serveur OpenLDAP .
5.1.2 Configuration
On commence par copier les fichiers que l'on vient de générer à un endroit
accessible par OpenLDAP , par exemple /usr/local/etc/openldap :
$ su
Password: <pass root>
# cp ./demoCA/cacert.pem /usr/local/etc/openldap/
# cp ./newcert.pem /usr/local/etc/openldap/ldap_crt.pem
# cp ./newreq.pem /usr/local/etc/openldap/ldap_key.pem
Puis on modifie le fichier slapd.conf, en ajoutant à la fin les lignes
suivantes :
TLSCertificateFile /usr/local/etc/openldap/ldap_crt.pem
TLSCertificateKeyFile /usr/local/etc/openldap/ldap_key.pem
TLSCACertificateFile /usr/local/etc/openldap/cacert.pem
Ca y est, le serveur OpenLDAP est correctement configuré pour gérer le SSL!
On configure aussi les clients afin de ne pas avoir à demander de
certificat client (dans le cas contraire il faudrait créer des certificats
pour les clients). Pour cela on rajoute dans ldap.conf la ligne :
TLS_REQCERT never
5.1.3 Utilisation
Si un serveur OpenLDAP tournait déjà en tâche de fond, on l'arrête proprement
avec la commande :
kill -2 `cat /usr/local/var/run/slapd.pid`
(faire attention aux backquotes (`) (AltGr-7) qui ne sont pas
des quotes (') ...)
Pour lancer le serveur OpenLDAP avec accès au port sécurisé uniquement,
on tape la commande :
/usr/local/libexec/slapd -h "ldaps:///"
Pour le lancer avec à la fois accès au port sécurisé et au port classique, on
tape :
/usr/local/libexec/slapd -h "ldap:/// ldaps:///"
On peut alors tester que tout fonctionne bien avec :
ldapsearch -b dc=example,dc=com -H ldaps://localhost
Dorénavant, lorsqu'on s'authentifie auprès du serveur LDAP (si on utilise bien
le port ldaps), le mot de passe ne circule plus en clair sur le réseau,
et on ne peut plus l'intercepter à l'aide d'un sniffer...
5.2 SSL avec Active Directory
Pour utiliser le SSL avec Active Directory , il faut aussi créer un certificat.
On procède ainsi :
-
on crée l'autorité de certification, et un certificat signé par cette
autorité (attention, il faut bien mettre en CN le nom complet du
contrôleur de domaine (par ex act2000.demo-cg77.org)) :
$ /usr/share/ssl/misc/CA -newca
$ /usr/share/ssl/misc/CA -newreq
$ /usr/share/ssl/misc/CA -sign
- on convertit ces certificats au format PKCS#12, en incorporant la clé
privée :
$ openssl pkcs12 -export -in demoCA/cacert.pem
-out newserverca.pfx
-inkey demoCA/private/cakey.pem
-name "demo-cg77 CA"
$ openssl pkcs12 -export -in newcert.pem
-out newservercrt.pfx
-inkey newreq.pem
-name "demo-cg77 Certificate"
- on transfère les 2 fichiers .pfx nouvellement créés sur la
machine serveur Active Directory
- on importe le CA dans "Autorités de certification racines de confiance"
de l'"ordinateur local", puis on importe le certificat dans "Personnel"
de l'"ordinateur local". Ceci peut se faire en double-cliquant sur
les fichiers .pfx ou à l'aide du composant logiciel enfichable
"Certificats de l'ordinateur local" de mmc.
- et c'est tout : normalement le certificat sera trouvé automatiquement,
et le port 636 qui était inutilement ouvert en permanence depuis l'installation
de Windows va enfin pouvoir servir à quelque chose...
Remarque
Apparemment, dans Windows 2000 Server (pas vérifié dans le 2003),
s'il y a plusieurs certificats valides dans le magasin de l'ordinateur local,ce sera toujours le 1er trouvé qui sera sélectionné, donc pas forcément
le bon, alors qu'avec OpenLDAP on indique tout simplement quel certificat
on veut utiliser...
On peut maintenant tester la connexion SSL :
$ openssl s_client -connect 101.0.50.41:636 -showcerts -state -CAfile demoCA/cacert.pem
(on remplace bien sûr l'ip après "-connect" par l'adresse du serveur
Active Directory ...)
Si tout se passe bien, on devrait avoir un certain nombre d'informations
qui devraient s'afficher, comme sur l'exemple suivant :
$ openssl s_client -connect 101.0.50.41:636 -showcerts -state -CAfile demoCA/cacert.pem
CONNECTED(00000003)
SSL_connect:before/connect initialization
SSL_connect:SSLv2/v3 write client hello A
SSL_connect:SSLv3 read server hello A
depth=1 /C=FR/ST=77/L=Melun/O=CG77/CN=act2000.demo-cg77.org
verify return:1
depth=0 /C=FR/ST=77/L=Melun/O=CG77/CN=act2000.demo-cg77.org
verify return:1
SSL_connect:SSLv3 read server certificate A
SSL_connect:SSLv3 read server certificate request A
SSL_connect:SSLv3 read server done A
SSL_connect:SSLv3 write client certificate A
SSL_connect:SSLv3 write client key exchange A
SSL_connect:SSLv3 write change cipher spec A
SSL_connect:SSLv3 write finished A
SSL_connect:SSLv3 flush data
SSL_connect:SSLv3 read finished A
---
Certificate chain
0 s:/C=FR/ST=77/L=Melun/O=CG77/CN=act2000.demo-cg77.org
i:/C=FR/ST=77/L=Melun/O=CG77/CN=act2000.demo-cg77.org
-----BEGIN CERTIFICATE-----
MIIDCDCCAnGgAwIBAgIBATANBgkqhkiG9w0BAQQFADBZMQswCQYDVQQGEwJGUjEL
MAkGA1UECBMCNzcxDjAMBgNVBAcTBU1lbHVuMQ0wCwYDVQQKEwRDRzc3MR4wHAYD
VQQDExVhY3QyMDAwLmRlbW8tY2c3Ny5vcmcwHhcNMDQwMjI2MTQxNzI0WhcNMDUw
MjI1MTQxNzI0WjBZMQswCQYDVQQGEwJGUjELMAkGA1UECBMCNzcxDjAMBgNVBAcT
BU1lbHVuMQ0wCwYDVQQKEwRDRzc3MR4wHAYDVQQDExVhY3QyMDAwLmRlbW8tY2c3
Ny5vcmcwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAK78N9OZ58meYVWABeKN
E4gNT8Nl7t1FftOpp4qWQm63XVoMhOvioPJfrXwpjIeVlHHluFX3bmd7+QcrgLhe
gxEuffBv+FTS1VSqWr3EZArpk5d70l5ueUjLJGihG9gAZw/e23QJQcyT5kDr8aaZ
ZzdzPUd+97URBKKIXBDuhcUtAgMBAAGjgd8wgdwwCQYDVR0TBAIwADAsBglghkgB
hvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYE
FLHG6t5N4zDcaUlo1fmUYOuHbEarMIGBBgNVHSMEejB4gBTAAn0nbntcY51kBaAg
oDpdptYzUqFdpFswWTELMAkGA1UEBhMCRlIxCzAJBgNVBAgTAjc3MQ4wDAYDVQQH
EwVNZWx1bjENMAsGA1UEChMEQ0c3NzEeMBwGA1UEAxMVYWN0MjAwMC5kZW1vLWNn
Nzcub3JnggEAMA0GCSqGSIb3DQEBBAUAA4GBAAOdM1OPLCEVpGLJjz8czhPVg42y
QNUiQYvTmSmG8868GjvKl2iPBmSp9ZEVNv2xVyUHb6E0VTwwWih1cujYLbWw9ixM
MhgENCSyrVHT59Y7m0P7vH1FRZMhfko04FiVHP7HWtDGL3B9wxK/M4SIPyRzE0Cr
i83N1Dd5i1Ecew9a
-----END CERTIFICATE-----
---
Server certificate
subject=/C=FR/ST=77/L=Melun/O=CG77/CN=act2000.demo-cg77.org
issuer=/C=FR/ST=77/L=Melun/O=CG77/CN=act2000.demo-cg77.org
---
Acceptable client certificate CA names
/C=US/O=VeriSign, Inc./OU=Class 1 Public Primary Certification Authority - G2/OU=(c) 1998 VeriSign, Inc. - For authorized use only/OU=VeriSign Trust Network
/C=US/O=VeriSign, Inc./OU=Class 4 Public Primary Certification Authority - G2/OU=(c) 1998 VeriSign, Inc. - For authorized use only/OU=VeriSign Trust Network
/C=ZA/ST=Western Cape/L=Cape Town/O=Thawte Consulting/OU=Certification Services
Division/CN=Thawte Personal Freemail CA/emailAddress=personal-freemail@thawte.com
/C=ZA/ST=Western Cape/L=Cape Town/O=Thawte Consulting/OU=Certification Services
Division/CN=Thawte Personal Premium CA/emailAddress=personal-premium@thawte.com
/C=US/O=First Data Digital Certificates Inc./CN=First Data Digital Certificates
Inc. Certification Authority
/C=ZA/ST=Western Cape/L=Cape Town/O=Thawte Consulting/OU=Certification Services
Division/CN=Thawte Personal Basic CA/emailAddress=personal-basic@thawte.com
/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority
/C=US/O=VeriSign, Inc./OU=Class 2 Public Primary Certification Authority
/C=US/O=VeriSign, Inc./OU=Class 1 Public Primary Certification Authority
/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority - G2/OU=(c) 1998 VeriSign, Inc. - For authorized use only/OU=VeriSign Trust Network
/C=HU/L=Budapest/O=NetLock Halozatbiztonsagi Kft./OU=Tanusitvanykiadok/CN=NetLock Uzleti (Class B) Tanusitvanykiado
/C=US/O=GTE Corporation/CN=GTE CyberTrust Root
/C=US/O=GTE Corporation/OU=GTE CyberTrust Solutions, Inc./CN=GTE CyberTrust Global Root
/C=US/O=Entrust.net/OU=www.entrust.net/CPS incorp. by ref. (limits liab.)/OU=(c) 1999 Entrust.net Limited/CN=Entrust.net Secure Server Certification Authority
/C=HU/ST=Hungary/L=Budapest/O=NetLock Halozatbiztonsagi Kft./OU=Tanusitvanykiadok/CN=NetLock Kozjegyzoi (Class A) Tanusitvanykiado
/C=US/O=VeriSign, Inc./OU=Class 2 Public Primary Certification Authority - G2/OU=(c) 1998 VeriSign, Inc. - For authorized use only/OU=VeriSign Trust Network
/C=US/O=GTE Corporation/OU=GTE CyberTrust Solutions, Inc./CN=GTE CyberTrust Root/C=HU/L=Budapest/O=NetLock Halozatbiztonsagi Kft./OU=Tanusitvanykiadok/CN=NetLock Expressz (Class C) Tanusitvanykiado
/OU=Copyright (c) 1997 Microsoft Corp./OU=Microsoft Corporation/CN=Microsoft Root Authority
/DC=com/DC=microsoft/CN=Microsoft Root Certificate Authority
/C=FR/ST=77/L=Melun/O=CG77/CN=act2000.demo-cg77.org
---
SSL handshake has read 4098 bytes and written 336 bytes
---
New, TLSv1/SSLv3, Cipher is RC4-MD5
Server public key is 1024 bit
SSL-Session:
Protocol : TLSv1
Cipher : RC4-MD5
Session-ID: DB17000043304AC576E0586E82B6139839D1D812DA0C3C707CD1CABF390A1965 Session-ID-ctx:
Master-Key: 149A4A63893D34003E4D5AC2C9223040D68CAA2714AE7709193C64E7C2BE4B49AB7EA0B619DD8146F147FD0EE76DE1C3
Key-Arg : None
Krb5 Principal: None
Start Time: 1077894853
Timeout : 300 (sec)
Verify return code: 0 (ok)
---
(le programme ne rend pas la main, il faut l'interrompre par Ctrl-c)
Si par contre il y a un problème, le programme rendra la main après avoir
affiché la cause de l'erreur, et il faudra essayer de comprendre pourquoi
ça ne marche pas...
Une fois que tout ceci fonctionne, on peut enfin accéder à Active Directory au moyen d'une connexion LDAP sécurisée par SSL/TLS, ce qui permet entre
autres de changer le mot de passe d'un utilisateur (voir 4.4.1).
5.3 SSL avec Squid
Maintenant que les annuaires fonctionnent correctement avec SSL, on peut passer
à la configuration de Squid .
A priori, la seule chose à faire pour que Squid utilise SSL pour communiquer
avec les serveurs LDAP est de rajouter ldaps:// en tête de l'adresse du
serveur dans les appels de squid_ldap_auth et squid_ldap_group .
Cependant, il y avait un bug dans le code source de ces 2 helpers
(le bug #887 de Squid , cf http://www.squid-cache.org/bugs/show_bug.cgi?id=887 ), qui empêchait d'utiliser
correctement SSL/TLS, mais ce bug a été corrigé le 05/01/2004.
Il faut donc patcher les sources de la version utilisée de Squid ,
ou récupérer la dernière version de Squid (la version 2.5STABLE5 est sortie le 01/03/2004),
et la recompiler avec support SSL
(paramètre --enable-ssl de configure).
Si on veut utiliser cette dernière version de Squid , il faut la compiler
avec toutes les options adaptées, par exemple :
$ ./configure --prefix=/usr/local/squid
--enable-default-err-language=French
--enable-err-languages="English French"
--enable-basic-auth-helpers="LDAP NCSA"
--enable-external-acl-helpers="ldap_group"
--enable-ssl
$ make
$ su -c "make install"
Par contre, on peut ne récupérer que les dernières versions de squid_ldap_auth et squid_ldap_group , dans ce cas on ne fait pas de make install,
mais après le make on récupère les fichiers
helpers/basic_auth/LDAP/squid_ldap_auth et
helpers/external_acl/ldap_group/squid_ldap_group,
et on les place par exemple à l'endroit où se trouvaient les vieilles
versions de ces fichiers (qu'on aura sauvegardés avant au cas où).
Remarque
Lors de la compilation de Squid , en fait lors de la compilation de
squid_ldap_auth et squid_ldap_group , j'ai été confronté à une erreur,
et il a fallu que je rajoute -L/usr/local/lib
à la ligne LDADD=... des Makefile correspondants.
Ensuite, il suffit effectivement de modifier les 2 lignes de squid.conf
qui appellent squid_ldap_auth et squid_ldap_group , afin d'indiquer le nouveau
chemin de ces 2 programmes si celui-ci a changé, et de rajouter ldaps://
en tête de l'adresse du serveur LDAP.
Il ne reste plus qu'à relancer le serveur Squid , et maintenant
l'authentification par groupes s'effectue de manière cryptée par SSL/TLS.
(On peut le vérifier avec Ethereal : aucun mot de passe ne circule plus en
clair)
Ce document a été traduit de LATEX par
HEVEA.