Si vous posséder un serveur Active Directory, des utlisateurs dans cet AD, et une application Web, vous avez déjà surement trouvé ou essayé de trouver un moyen d'authentifier les utilisateurs de l'application web via l'AD. Pour ceux qui ont réussi, vous utilisez surement votre appli pour interroger la base LDAP de l'AD. De cette manière, les utilisateurs de votre domaine sont aussi ceux de votre application. C'est facile pour l'utilisateur, un seul mot de passe à retenir ! La ou Geco-iT vous propose d'aller plus loin, c'est que les utilisateurs n'aient même plus besoin de taper ce mot de passe… C'est possible en utilisant le Jeton Kerberos de la machine windows qui est récupéré à l'ouverture de session du user.
Si vous avez un site d'intranet qui tourne sur un server apache, bien souvent vous aurez un CMS, prenons l'exemple de typo3 car c'est un qu'on connait un peu a geco. En temps normal c'est typo3 qui gere l'authentification de vos utilisateurs. C'est à dire que apache laisse passer toutes les requetes, et c'est typo3 qui va se charger d'afficher une page de login, de récupérer les utilisateurs dans votre AD et ensuite d'afficher les pages une fois que le user a été validé ou pas.
Si on veut ne plus taper de mot de passe, on va déléguer l'authentification au serveur apache lui même. Apache va valider l'utilisateur et remplir la variable $REMOTE_USER de php. C'est à partir de cette variable que le CMS pourra connaitre l'utilisateur et afficher seulement les pages auxquelles il a droit.
Nous allons creer une page PHP très simple qui affiche simplement le contenu de la fameuse variable PHP $REMOTE_USER, et aussi quelque headers.
<?php echo "<h1>Geco it Kerberos test sample page</h1>"; if (isset($_SERVER['REMOTE_USER'])) { $token = $_SERVER['REMOTE_USER']; echo "<p style='color: green'>Kerberos auth succes, you token is : $token</p>"; } else { echo "<p style='color: red'>Kerberos auth failed or not sent</p>"; } echo "<h2>Here is some headers that may help</h2>"; $headers = apache_request_headers(); foreach ($headers as $header => $value) { echo "$header: $value <br />\n"; } ?>
Ensuite on va installer ce dont on a besoin sur notre serveur apache !
sudo apt update sudo apt install libapache2-mod-auth-gssapi krb5-user
On va remplir le fichier /etc/krb5.conf comme ceci :
[libdefaults] default_realm = LAN.GECO-IT.NET # The following krb5.conf variables are only for MIT Kerberos. kdc_timesync = 1 ccache_type = 4 forwardable = true proxiable = true fcc-mit-ticketflags = true [realms] LAN.GECO-IT.NET = { kdc = dc1.lan.geco-it.net admin_server = dc1.lan.geco-it.net } [domain_realm] .lan.geco-it.net = LAN.GECO-IT.NET [logging] kdc = SYSLOG:NOTICE admin_server = SYSLOG:NOTICE default = SYSLOG:NOTICE
Biensur dans votre cas il faudra remplacer le domaine par le votre et surtout remplacer “dc1” par le nom de votre controller de domaine. A partir de la, on peut essayer notre config !
#UN ping du controleur de domaine admin@apache2:~$ sudo ping dc1 PING dc1 (172.20.50.10): 56 data bytes 64 bytes from 172.20.50.10: seq=0 ttl=127 time=0.714 ms ^C --- dc1 ping statistics --- 1 packets transmitted, 1 packets received, 0% packet loss round-trip min/avg/max = 0.714/0.714/0.714 ms admin@apache2:~$ sudo ping dc1.lan.geco-it.net PING dc1.lan.geco-it.net (172.20.50.10): 56 data bytes 64 bytes from 172.20.50.10: seq=0 ttl=127 time=0.829 ms ^C --- dc1.lan.geco-it.net ping statistics --- 1 packets transmitted, 1 packets received, 0% packet loss round-trip min/avg/max = 0.829/0.829/0.829 ms #Et on essaye d'obtenir un ticket kerberos depuis notre AD, vous pouvez utiliser n'importe quel compte, donc je prend le mien, si tout va bien il demandera votre mot de passe admin@apache2:~$ sudo kinit h.campion@LAN.GECO-IT.NET Password for h.campion@LAN.GECO-IT.NET: #Si il n'y a aucun sortie apres la demande du pass c'est que tout va bien, si on fait un klist, on doit trouver notre ticket admin@apache2:~$ klist klist: No credentials cache found (filename: /tmp/krb5cc_1000) admin@apache2:~$ sudo klist Ticket cache: FILE:/tmp/krb5cc_0 Default principal: h.campion@LAN.GECO-IT.NET Valid starting Expires Service principal 05/05/2021 09:50:19 05/05/2021 19:50:19 krbtgt/LAN.GECO-IT.NET@LAN.GECO-IT.NET renew until 06/05/2021 09:50:16
Il va nous falloir maintenant creer un user sur l'AD pour mapper l'authentification kerberos dessus, c'est un user normal de l'AD sauf qu'il faut cocher les options suivantes et mettre un bon password !
Ensuite on va creer le keytab kerberos pour le serveur, donc en etant sur l'ad en powershell :
PS M:\> ktpass -princ HTTP/intranet.geco-it.net@LAN.GECO-IT.NET -mapuser kerb@LAN.GECO-IT.NET -crypto AES256-SHA1 -ptype KRB5_NT_PRINCIPAL -pass Azerty1234 -out C:\tmp\intranet.keytab Targeting domain controller: DC1.lan.geco-it.net Successfully mapped HTTP/intranet.geco-it.net to kerb. Password successfully set! Key created. Output keytab to C:\tmp\intranet.keytab: Keytab version: 0x502 keysize 92 HTTP/intranet.geco-it.net@LAN.GECO-IT.NET ptype 1 (KRB5_NT_PRINCIPAL) vno 6 etype 0x12 (AES256-SHA1) keylengt h 32 (0xfb589c884bdf6245b3f0bd84c2823d08a518ad26e83726fc3897375628197caa) PS M:\>
Les différents paramètres sont :
Il vous faut ensuite récupérer ce keytab et le mettre sur votre serveur apache dans /etc/apache2 et avec les droits www-data si vous etes sur debian, ou ceux du user qui fait tourner apache pour tout autre distrib :
admin@apache2:/etc/apache2$ sudo chown www-data:www-data intranet.keytab admin@apache2:/etc/apache2$ l total 16K drwxr-xr-x 3 root root 4,0K mai 5 11:29 . drwxr-xr-x 77 root root 4,0K mai 5 09:46 .. -rw-r--r-- 1 www-data www-data 98 mai 5 11:29 intranet.keytab drwxr-xr-x 2 root root 4,0K mai 5 09:38 mods-available
Une fois le keytab en place, on va pouvoir le tester :
#On recupère le KVNO pour le principal HTTP/intranet.geco-it.net sudo kvno HTTP/intranet.geco-it.net@LAN.GECO-IT.NET HTTP/intranet.geco-it.net@LAN.GECO-IT.NET: kvno = 6 admin@apache2:/etc/apache2$ sudo klist -e Ticket cache: FILE:/tmp/krb5cc_0 Default principal: h.campion@LAN.GECO-IT.NET Valid starting Expires Service principal 05/05/2021 09:50:19 05/05/2021 19:50:19 krbtgt/LAN.GECO-IT.NET@LAN.GECO-IT.NET renew until 06/05/2021 09:50:16, Etype (skey, tkt): aes256-cts-hmac-sha1-96, aes256-cts-hmac-sha1-96 05/05/2021 11:41:10 05/05/2021 19:50:19 HTTP/intranet.geco-it.net@LAN.GECO-IT.NET Etype (skey, tkt): aes256-cts-hmac-sha1-96, aes256-cts-hmac-sha1-96 admin@apache2:/etc/apache2$ klist -e -k -t /etc/apache2/intranet.keytab Keytab name: FILE:/etc/apache2/intranet.keytab KVNO Timestamp Principal ---- ------------------- ------------------------------------------------------ 6 01/01/1970 00:00:00 HTTP/intranet.geco-it.net@LAN.GECO-IT.NET (aes256-cts-hmac-sha1-96)
On va maintenant carrement essayer de s'authentiife au nom du service HTTP/intranet.geco-it.net avec notre keytab :
admin@apache2:/etc/apache2$ kinit -k -t /etc/apache2/intranet.keytab HTTP/intranet.geco-it.net admin@apache2:/etc/apache2$ klist Ticket cache: FILE:/tmp/krb5cc_1000 Default principal: HTTP/intranet.geco-it.net@LAN.GECO-IT.NET Valid starting Expires Service principal 05/05/2021 12:06:03 05/05/2021 22:06:03 krbtgt/LAN.GECO-IT.NET@LAN.GECO-IT.NET renew until 06/05/2021 12:06:03
Maintenant que la partie kerberos est vérifiée, nous allons la mettre en place sur le vhost apache2 :
vim /etc/apache2/sites-available/100-intranet.geco-it.net.conf <VirtualHost *:80> DocumentRoot /var/www/intranet.geco-it.net ServerName intranet.geco-it.net RemoteIPHeader X-Forwarded-For RemoteIPInternalProxy 172.20.44.1 <Directory /var/www/testsso.lan.imcheck.fr> Options +FollowSymLinks AllowOverride All </Directory> <Location /> AuthType GSSAPI AuthName "Intranet of Geco" GssapiCredStore keytab:/etc/apache2/intranet.keytab Require valid-user </Location> # mod_php enabled AddType application/x-httpd-php .php .php3 .php4 .php5 php_admin_value open_basedir none </VirtualHost> sudo a2enmod auth_gssapi sudo a2ensite 100-intranet.geco-it.net.conf sudo apache2ctl configtest Syntax OK sudo apache2ctl restart
SI vous essayez d'aller sur le site, vous tomberez sur une erreur forbidden, pour acceder au site, il faudra deja y acceder d'une machine de votre domaine, depuis une session utilisateur de votre domaine. Ensuite on va devoir indiquer à firefox d'envoyer la negociation kerberos pour l'url intranet.geco-it.net. Pour cela il faut taper about:config dans la barre d'addresse de firefox pour accéder aux options avancées. Tapez ensuite “trust” pour rechercher les deux options qui nous interessent :
Une fois que c'est correctement renseigné, un petit test vous confirmera le bon fonctionnement :
C'est bien mais demander a tout vos user d'aller dans about:config de firefox c'est pas recevable… heureusement la magie des gpo va venir à notre rescousse ! Si on resume les navigateurs les plus courants, on a :
Pour firefox il faudra ajouter les ADMX de firefox à votre AD et utiliser la version ESR de firefox pour pouvoir le piloter par GPO !
$ a2enmod ldap authnz_ldap $ cat /etc/apache2/sites-available/intranet2.conf <VirtualHost *:80> ServerAdmin admin@intranet2.lan.cereg.com ServerName intra2.cereg.com ServerAlias intranet.lan.cereg.com DocumentRoot /var/www/intra2 <Directory /var/www/intra2> AuthType Basic AuthName "LDAP Authentication" AuthBasicProvider ldap AuthLDAPURL "ldaps://dcmon.lan.cereg.com/OU=CEREG,DC=lan,DC=cereg,DC=com?sAMAccountName?sub?(objectClass=User)" AuthLDAPBindDN agilap AuthLDAPBindPassword SuperPasswd #Require valid-user AuthLDAPGroupAttributeIsDN On require ldap-group CN=ALLOW_INTRANET,OU=01-GLOBAL,OU=Groups,OU=CEREG,DC=lan,DC=cereg,DC=com </Directory> </VirtualHost> $ chgrp www-data /etc/apache2/sites-available/intranet2.conf $ chmod 640 /etc/apache2/sites-available/intranet2.conf