Puisque nous avons, bon gré, mal gré, un domaine Microsoft avec des contrôleurs de domaine Active Directory (Windows 2008), voyons un peu comment profiter du cerbère Microsoft. Nous allons voir ceci au travers de deux exemples :
C'est le moment maintenant de faire le rapprochement entre ce que nous avons vu avec le KDC du MIT et ce qu'il faut découvrir avec celui de MS Active Directory.
Cette partie est triviale. Le royaume kerberos existe et il a le même nom que le domaine Microsoft. Ce domaine privé (sans aucune relation avec l'internet) s'appelle ici eme.org
, si bien que le royaume sera EME.ORG.
Nous prenons un client GNU/Linux au hasard dans notre panoplie d'hôtes virtuels. Il s'agit en l'occurrence d'une Debian Lenny équipée de Gnome. Nous lui installons krb5-client
et nous créons un krb5.conf
de la forme :
[libdefaults] default_realm = EME.ORG dns_lookup_kdc = no dns_lookup_realm = no allow_weak_crypto = true default_keytab_name = /etc/krb5.keytab ; for Windows 2003 ; default_tgs_enctypes = rc4-hmac des-cbc-crc des-cbc-md5 ; default_tkt_enctypes = rc4-hmac des-cbc-crc des-cbc-md5 ; permitted_enctypes = rc4-hmac des-cbc-crc des-cbc-md5 ; for Windows 2008 with AES default_tgs_enctypes = aes256-cts-hmac-sha1-96 rc4-hmac des-cbc-crc des-cbc-md5 default_tkt_enctypes = aes256-cts-hmac-sha1-96 rc4-hmac des-cbc-crc des-cbc-md5 permitted_enctypes = aes256-cts-hmac-sha1-96 rc4-hmac des-cbc-crc des-cbc-md5 [realms] EME.ORG = { kdc = urnus.eme.org kdc = neptune.eme.org admin_server = uranus.eme.org admin_server = neptune.eme.org } [domain_realm] .eme.org = EME.ORG eme.org = EME.ORGUranus et Neptune sont les deux contrôleurs de domaine. La directive
allow_weak_crypto = true
est rendue nécessaire pour permettre aux outils kerberos du MIT d'utiliser les chiffrements DES
considérés actuellement comme trop peu sûrs (mais pas encore par Microsoft, qui n'a pas intégré le triple DES, semble-t-il).
Ceci devrait suffire pour obtenir un TGT. Nous avons sur AD un compte chris
, essayons avec :
chris@lennyvirt:~$ kinit -V chris Password for chris@EME.ORG: Authenticated to Kerberos v5 chris@lennyvirt:~$ klist Ticket cache: FILE:/tmp/krb5cc_1000 Default principal: chris@EME.ORG Valid starting Expires Service principal 03/02/10 11:44:27 03/02/10 21:44:34 krbtgt/EME.ORG@EME.ORG renew until 03/02/10 21:44:27 Kerberos 4 ticket cache: /tmp/tkt1000 klist: You have no tickets cached
Ça marche.
Il nous faut maintenant créer un serveur (GNU/Linux Squeeze) qui va héberger squid3 et aussi ssh, il va s'appeler proxy3.eme.org
. Il faudra enregistrer sur le TGS Microsoft cet hôte host/proxy3.eme.org@EME.ORG
, ainsi que le service HTTP/proxy3.eme.org@EME.ORG
. Sur le TGS du MIT, nous l'avons fait avec la commande kadmin
, qui ne donne rien de bon ici. Ce serait en effet trop beau sinon.
Il existe des outils qui devraient arriver au même résultat sur les serveurs Windows 2008, la solution qui me semble la plus simple est d'utiliser les services de samba qui sait dialoguer avec le kerberos Microsoft. Soyons clairs, samba ne sert à rien d'autre ici qu'à intégrer l'hôte proxy3
au domaine Microsoft, créant par là même le principal host/proxy3.eme.org@EME.ORG
et de permettre l'emploi du couteau suisse net
pour exporter le keytab.
Nous installons samba sur proxy3.eme.org
et le configurons comme ceci :
[global] netbios name = PROXY3 server string = Samba Server realm = EME.ORG workgroup = EME2K security = ADS password server = 172.16.254.8 kerberos method = dedicated keytab dedicated keytab file = /etc/krb5.keytab encrypt passwords = yes guest account = nobody log file = /var/log/samba/samba.log username map = /etc/samba/user.map socket options = TCP_NODELAY SO_RCVBUF=8192 SO_SNDBUF=8192Et encore, peut-être pouvons nous faire encore plus simple…
Le password-server
est l'un des contrôleurs AD, il est bien entendu possible de les spécifier tous. La directive kerberos method
est nécessaire pour la récupération du keytab. Notons que cette directive est nouvelle et n'existe sous cette forme que sur Samba version 3.4.5 (Nous utilisons Squeeze et non Lenny avec sa version 3.2.5, qui nécessiterait use kerberos keytab = True
).
Côté DNS Microsoft, il vaut mieux enregistrer manuellement notre nouvel hôte avant de l'intégrer au domaine, sans oublier de mettre également à jour la « zone de recherche inversée ». A ce jour, l'intégration d'un hôte via samba ne gère pas cet enregistrement DNS et produit un message d'erreur, sans gravité, mais désagréable. L'absence de l'enregistrement sur DNS, en revanche n'est pas acceptable, elle empêchera l'exportation du keytab. Il faut donc avoir le DNS Microsoft correctement documenté (kerberos aime DNS).
Une fois ceci fait, il faut joindre le domaine :
net ads join -U <un administrateur du domaine>
Le message doit clairement indiquer que la procédure a réussie :
proxy3:/etc/samba# net -d=1 ads join -U administrateur Enter administrateur's password: Using short domain name -- EME2K Joined 'PROXY3' to realm 'eme.org'
Le nom de l'hôte doit apparaitre dans le conteneur « Computers » du domaine eme.org
dans la mmc
« Utilisateurs et ordinateurs Active Directory ».
Il nous faut maintenant récupérer le keytab contenant les principaux de notre hôte :
proxy3:/etc/samba# net ads keytab create -U administrateur Enter administrateur's password:
Normalement, /etc/krb5.keytab
a été généré :
proxy3:/etc/samba# klist -e -k /etc/krb5.keytab Keytab name: WRFILE:/etc/krb5.keytab KVNO Principal ---- -------------------------------------------------------------------------- 2 host/proxy3.eme.org@EME.ORG (DES cbc mode with CRC-32) 2 host/proxy3.eme.org@EME.ORG (DES cbc mode with RSA-MD5) 2 host/proxy3.eme.org@EME.ORG (ArcFour with HMAC/md5) 2 host/proxy3@EME.ORG (DES cbc mode with CRC-32) 2 host/proxy3@EME.ORG (DES cbc mode with RSA-MD5) 2 host/proxy3@EME.ORG (ArcFour with HMAC/md5) 2 PROXY3$@EME.ORG (DES cbc mode with CRC-32) 2 PROXY3$@EME.ORG (DES cbc mode with RSA-MD5) 2 PROXY3$@EME.ORG (ArcFour with HMAC/md5)
Et voilà le travail. Notez l'absence du triple DES.
Puisque nous y sommes, nous allons générer les principaux pour le service HTTP :
net ads keytab add HTTP -U administrateur
Ceci doit avoir ajouté ce qu'il faut dans le keytab :
proxy3:/etc/samba# klist -e -k /etc/krb5.keytab Keytab name: WRFILE:/etc/krb5.keytab KVNO Principal ---- -------------------------------------------------------------------------- 2 host/proxy3.eme.org@EME.ORG (DES cbc mode with CRC-32) 2 host/proxy3.eme.org@EME.ORG (DES cbc mode with RSA-MD5) 2 host/proxy3.eme.org@EME.ORG (ArcFour with HMAC/md5) 2 host/proxy3@EME.ORG (DES cbc mode with CRC-32) 2 host/proxy3@EME.ORG (DES cbc mode with RSA-MD5) 2 host/proxy3@EME.ORG (ArcFour with HMAC/md5) 2 PROXY3$@EME.ORG (DES cbc mode with CRC-32) 2 PROXY3$@EME.ORG (DES cbc mode with RSA-MD5) 2 PROXY3$@EME.ORG (ArcFour with HMAC/md5) 2 HTTP/proxy3.eme.org@EME.ORG (DES cbc mode with CRC-32) 2 HTTP/proxy3.eme.org@EME.ORG (DES cbc mode with RSA-MD5) 2 HTTP/proxy3.eme.org@EME.ORG (ArcFour with HMAC/md5) 2 HTTP/proxy3@EME.ORG (DES cbc mode with CRC-32) 2 HTTP/proxy3@EME.ORG (DES cbc mode with RSA-MD5) 2 HTTP/proxy3@EME.ORG (ArcFour with HMAC/md5)
C'est vraiment du niveau « jardin d'enfant ».
Nous avons un bon gros tableau de clés, qu'il convient peut-être de découper en morceaux vu que ces clés vont servir à des services différents, qui vont tourner sous des identités différentes. L'outil ktutil
va faire la preuve qu'il est bien nommé. Il s'agit d'un « sous-shell » :
proxy3:/etc/samba# ktutil ktutil: ? Available ktutil requests: clear_list, clear Clear the current keylist. read_kt, rkt Read a krb5 keytab into the current keylist. read_st, rst Read a krb4 srvtab into the current keylist. write_kt, wkt Write the current keylist to a krb5 keytab. write_st, wst Write the current keylist to a krb4 srvtab. add_entry, addent Add an entry to the current keylist. delete_entry, delent Delete an entry from the current keylist. list, l List the current keylist. list_requests, lr, ? List available requests. quit, exit, q Exit program.
Nous lisons notre krb5.keytab
:
ktutil: rkt /etc/krb5.keytab
Nous listons son contenu :
ktutil: l slot KVNO Principal ---- ---- --------------------------------------------------------------------- 1 2 host/proxy3.eme.org@EME.ORG 2 2 host/proxy3.eme.org@EME.ORG 3 2 host/proxy3.eme.org@EME.ORG 4 2 host/proxy3@EME.ORG 5 2 host/proxy3@EME.ORG 6 2 host/proxy3@EME.ORG 7 2 PROXY3$@EME.ORG 8 2 PROXY3$@EME.ORG 9 2 PROXY3$@EME.ORG 10 2 HTTP/proxy3.eme.org@EME.ORG 11 2 HTTP/proxy3.eme.org@EME.ORG 12 2 HTTP/proxy3.eme.org@EME.ORG 13 2 HTTP/proxy3@EME.ORG 14 2 HTTP/proxy3@EME.ORG 15 2 HTTP/proxy3@EME.ORG
Puis nous n'y laissons que ce qui sera nécessaire à ssh, à savoir les principaux host
:
ktutil: delent 15 ktutil: delent 14 ktutil: delent 13 ktutil: delent 12 ktutil: delent 11 ktutil: delent 10 ktutil: delent 9 ktutil: delent 8 ktutil: delent 7 ktutil: l slot KVNO Principal ---- ---- --------------------------------------------------------------------- 1 2 host/proxy3.eme.org@EME.ORG 2 2 host/proxy3.eme.org@EME.ORG 3 2 host/proxy3.eme.org@EME.ORG 4 2 host/proxy3@EME.ORG 5 2 host/proxy3@EME.ORG 6 2 host/proxy3@EME.ORG
Enfin, nous sauvegardons le résultat dans un nouveau tableau :
ktutil: wkt /etc/ssh-krb5.keytab ktutil: q
Et nous pouvons vérifier le résultat :
proxy3:~# klist -e -k /etc/ssh-krb5.keytab Keytab name: WRFILE:/etc/ssh-krb5.keytab KVNO Principal ---- -------------------------------------------------------------------------- 2 host/proxy3.eme.org@EME.ORG (DES cbc mode with CRC-32) 2 host/proxy3.eme.org@EME.ORG (DES cbc mode with RSA-MD5) 2 host/proxy3.eme.org@EME.ORG (ArcFour with HMAC/md5) 2 host/proxy3@EME.ORG (DES cbc mode with CRC-32) 2 host/proxy3@EME.ORG (DES cbc mode with RSA-MD5) 2 host/proxy3@EME.ORG (ArcFour with HMAC/md5)
Le principe étant compris, nous faisons ceci maintenant pour le service HTTP dans un tableau http-krb5.keytab
et nous obtenons finalement :
proxy3:/etc/samba# klist -e -k /etc/http-krb5.keytab Keytab name: WRFILE:/etc/http-krb5.keytab KVNO Principal ---- -------------------------------------------------------------------------- 2 HTTP/proxy3.eme.org@EME.ORG (DES cbc mode with CRC-32) 2 HTTP/proxy3.eme.org@EME.ORG (DES cbc mode with RSA-MD5) 2 HTTP/proxy3.eme.org@EME.ORG (ArcFour with HMAC/md5) 2 HTTP/proxy3@EME.ORG (DES cbc mode with CRC-32) 2 HTTP/proxy3@EME.ORG (DES cbc mode with RSA-MD5) 2 HTTP/proxy3@EME.ORG (ArcFour with HMAC/md5)
Nous sommes proches de la sortie. Il ne reste plus qu'à kerbériser ssh et squid.
Juste pour le fun, voici un moyen d'ouvrir une session ssh en utilisant kerberos au travers de GSSAPI. Soit un utilisateur disposant de :
proxy3.eme.org
;
A la condition que l'hôte distant fasse partie du royaume, ce qui est le cas ici, et soit lui-même authentifié (clé partagée entre le KDC et l'hôte distant) ce qui est également le cas pour le principal host/proxy3.eme.org@EME.ORG
, alors cet utilisateur va pouvoir utiliser le SSO pour ouvrir sa session ssh sur l'hôte distant, sans saisie de mot de passe, et sans échange de clé publique.
Une démonstration rapide ?
Voici la configuration de sshd
sur proxy3
:
proxy3:/etc/ssh# cat sshd_config
Port 22
Protocol 2
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_dsa_key
UsePrivilegeSeparation yes
KeyRegenerationInterval 3600
ServerKeyBits 768
SyslogFacility AUTH
LogLevel INFO
LoginGraceTime 120
PermitRootLogin yes
StrictModes yes
RSAAuthentication yes
PubkeyAuthentication yes
IgnoreRhosts yes
RhostsRSAAuthentication no
HostbasedAuthentication no
PermitEmptyPasswords no
ChallengeResponseAuthentication no
GSSAPIAuthentication yes
GSSAPICleanupCredentials yes
X11Forwarding yes
X11DisplayOffset 10
PrintMotd no
PrintLastLog yes
TCPKeepAlive yes
AcceptEnv LANG LC_*
Subsystem sftp /usr/lib/openssh/sftp-server
UsePAM yes
Soit un utilisateur chris
qui dispose :
squid3.eme.org
; eme.org
(pas forcément avec le même mot de passe d'ailleurs, ni même avec les mêmes privilèges d'administration) ;
Soit une station de travail (Ubuntu Karmic Koala nommée karmicvirt
), disposant des outils kerberos krb5-user
. PAM a été configuré de manière à ce que le TGT soit automatiquement chargé à l'ouverture de session. Notre cobaye (chris) a ouvert une session sur ce poste de travail et souhaite accéder à proxy3.eme.org
:
chris@karmicvirt:~$ ssh -v proxy3.eme.org
OpenSSH_5.1p1 Debian-6ubuntu2, OpenSSL 0.9.8g 19 Oct 2007
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: Applying options for *
debug1: Connecting to proxy3.eme.org [192.168.0.137] port 22.
debug1: Connection established.
...
debug1: Authentications that can continue: publickey,gssapi-keyex,gssapi-with-mic,password
debug1: Next authentication method: gssapi-keyex
debug1: No valid Key exchange context
debug1: Next authentication method: gssapi-with-mic
debug1: Authentication succeeded (gssapi-with-mic).
debug1: channel 0: new [client-session]
debug1: Requesting no-more-sessions@openssh.com
debug1: Entering interactive session.
debug1: Sending environment.
debug1: Sending env LANG = fr_FR.UTF-8
Linux proxy3 2.6.32-trunk-686 #1 SMP Sun Jan 10 06:32:16 UTC 2010 i686
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Mon Mar 1 16:15:32 2010 from 192.168.0.68
chris@proxy3:~$
le SSO a fonctionné.
chris@karmicvirt:~$ klist Ticket cache: FILE:/tmp/krb5cc_1000_f9ItDE Default principal: chris@EME.ORG Valid starting Expires Service principal 03/01/10 22:27:43 03/02/10 05:07:43 krbtgt/EME.ORG@EME.ORG 03/01/10 22:29:49 03/02/10 05:07:43 host/proxy3.eme.org@ 03/01/10 22:29:49 03/02/10 05:07:43 host/proxy3.eme.org@EME.ORG
Bien sûr, si chris fait ceci :
chris@karmicvirt:~$ kdestroy chris@karmicvirt:~$ klist klist: No credentials cache found (ticket cache FILE:/tmp/krb5cc_1000_f9ItDE)
Aucun principal ni aucun ticket ne sont désormais présents dans le cache.
chris@karmicvirt:~$ ssh -v proxy3.eme.org
OpenSSH_5.1p1 Debian-6ubuntu2, OpenSSL 0.9.8g 19 Oct 2007
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: Applying options for *
debug1: Connecting to proxy3.eme.org [192.168.0.137] port 22.
debug1: Connection established.
...
debug1: Authentications that can continue: publickey,gssapi-keyex,gssapi-with-mic,password
debug1: Next authentication method: gssapi-keyex
debug1: No valid Key exchange context
debug1: Next authentication method: gssapi-with-mic
debug1: Unspecified GSS failure. Minor code may provide more information
Credentials cache file '/tmp/krb5cc_1000_f9ItDE' not found
debug1: Unspecified GSS failure. Minor code may provide more information
Credentials cache file '/tmp/krb5cc_1000_f9ItDE' not found
debug1: Unspecified GSS failure. Minor code may provide more information
debug1: Next authentication method: publickey
debug1: Trying private key: /home/chris/.ssh/identity
debug1: Trying private key: /home/chris/.ssh/id_rsa
debug1: Trying private key: /home/chris/.ssh/id_dsa
debug1: Next authentication method: password
chris@proxy3.eme.org's password:
Notre client n'a pas de clé publique à présenter, il n'a pas de ticket kerberos non plus, il va devoir utiliser le mot de passe de son compte chris
sur proxy3
.
Voici simplement la configuration de sshd
sur proxy3
:
proxy3:/etc/ssh# cat sshd_config
Port 22
Protocol 2
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_dsa_key
UsePrivilegeSeparation yes
KeyRegenerationInterval 3600
ServerKeyBits 768
SyslogFacility AUTH
LogLevel INFO
LoginGraceTime 120
PermitRootLogin yes
StrictModes yes
RSAAuthentication yes
PubkeyAuthentication yes
IgnoreRhosts yes
RhostsRSAAuthentication no
HostbasedAuthentication no
PermitEmptyPasswords no
ChallengeResponseAuthentication no
GSSAPIAuthentication yes
GSSAPICleanupCredentials yes
X11Forwarding yes
X11DisplayOffset 10
PrintMotd no
PrintLastLog yes
TCPKeepAlive yes
AcceptEnv LANG LC_*
Subsystem sftp /usr/lib/openssh/sftp-server
UsePAM yes
Nous avons déjà vu comment faire avec un cerbère du MIT, ici, ce sera exactement la même chose, le seule différence étant le royaume kerberos, mais ce n'est pas l'affaire du squid.
/etc/http-krb2.keytab
doit être en lecture seule, exclusivement par proxy
puisque c'est sous cette identité que fonctionne le poulpe :
chown proxy:proxy /etc/http-krb5.keytab chmod 400 /etc/http-krb5.keytab
Nous devons créer une variable d'environnement qui renseigne sur le nom du keytab à utiliser. Nous savons que c'est dans /etc/default/squid3
que ça se passe :
KRB5_KTNAME=/etc/http-krb5.keytab export KRB5_KTNAME
Pour rappel, car il n'y a rien de nouveau ici :
acl manager proto cache_object acl localhost src 127.0.0.1/32 acl to_localhost dst 127.0.0.0/8 0.0.0.0/32 acl localnet src 192.168.0.0/24 auth_param negotiate program /usr/lib/squid3/squid_kerb_auth -d auth_param negotiate children 10 auth_param negotiate keep_alive on acl auth proxy_auth REQUIRED acl SSL_ports port 443 acl Safe_ports port 80 # http acl Safe_ports port 21 # ftp acl Safe_ports port 443 # https acl Safe_ports port 70 # gopher acl Safe_ports port 210 # wais acl Safe_ports port 1025-65535 # unregistered ports acl Safe_ports port 280 # http-mgmt acl Safe_ports port 488 # gss-http acl Safe_ports port 591 # filemaker acl Safe_ports port 777 # multiling http acl CONNECT method CONNECT http_access allow manager localhost http_access deny manager http_access deny !Safe_ports http_access deny CONNECT !SSL_ports http_access allow localhost http_access allow localnet auth http_access deny all icp_access deny all htcp_access deny all http_port 3128 hierarchy_stoplist cgi-bin ? access_log /var/log/squid3/access.log squid refresh_pattern ^ftp: 1440 20% 10080 refresh_pattern ^gopher: 1440 0% 1440 refresh_pattern (cgi-bin|\?) 0 0% 0 refresh_pattern . 0 20% 4320 icp_port 3130 coredump_dir /var/spool/squid3
Un essai pour vérifier :
chris@lennyvirt:~ $kinit chris Password for chris@EME.ORG:
Et dans les logs du décapode :
1267547026.580 67 192.168.0.89 TCP_MISS/302 322 GET http://irp.nain-t.net/ chris@EME.ORG DIRECT/213.186.40.149 text/html 1267547026.791 209 192.168.0.89 TCP_MISS/200 12573 GET http://irp.nain-t.net/doku.php chris@EME.ORG DIRECT/213.186.40.149 text/html ...
Bien entendu :
chris@lennyvirt:~$ klist Ticket cache: FILE:/tmp/krb5cc_1000 Default principal: chris@EME.ORG Valid starting Expires Service principal 03/02/10 17:20:50 03/03/10 03:20:55 krbtgt/EME.ORG@EME.ORG renew until 03/03/10 03:20:50 03/02/10 17:21:13 03/03/10 03:20:55 HTTP/proxy3.eme.org@EME.ORG renew until 03/03/10 03:20:50
C'est devenu de la routine.
Tout l'intérêt de cette solution apparait pour les utilisateurs qui ont ouvert une session Windows (XP, Vista, Seven…) sur le domaine AD eme.org
. Ils disposent de leur TGT de façon implicite en ayant ouvert leur session, l'authentification sur le proxy se fait donc de manière parfaitement transparente et plus proprement qu'avec la méthode NTLM, vue dans Active Directory au chapitre Squid et SquidGuard.
La seule restriction supplémentaire est qu'un utilisateur qui a ouvert une session locale ne dispose pas du TGT et donc ne peut avoir accès au proxy.
Il n'est donc pas utopique de faire cohabiter des services Unix dans une architecture comportant un domaine Active Directory de façon propre. Windows 2008 intègre les « services pour Unix » qui permettent un peu plus d'interopérabilité, principalement en ajoutant dans l'annuaire LDAP des schémas supplémentaires. Il n'est pas interdit de penser que :
Mais LDAP est une autre affaire. Un jour peut-être…