Faire en sorte que Squid s'authentifie avec Kerberos et Windows 2008/2003/7/XP

C’est quelque chose que j’ai configuré récemment et qui a été assez pénible. Mon environnement consistait à faire en sorte que Squid authentifie un client Windows 7 contre un serveur Windows 2008 de manière transparente. NTLM n’est pas vraiment une option, car son utilisation nécessite une modification du registre sur chaque client.

Microsoft recommande Kerberos depuis Windows 2000, il est donc enfin temps de se mettre à la page.

Un grand merci à Markus Moeller des listes de diffusion Squid pour avoir aidé à faire fonctionner tout cela.


Source : Server Fault.)

Cette configuration utilise Squid 3.0, a également été testée avec Squid 3.1 et devrait fonctionner avec Squid 2.7. Votre utilisateur Windows doit être membre du groupe SQUID_USERS dans Active Directory (pour ce cas en tout cas).

Côté Windows, Windows XP et Windows 2007 ont été testés contre Windows 2008, et Windows XP contre Windows 2003.

Notez que presque chaque étape nécessite que la précédente soit complétée pour continuer.

Si vous rencontrez un problème, le DNS est toujours le premier endroit où regarder. Les deux machines Windows doivent pouvoir effectuer un ping du serveur Linux par nom (et vice versa), et vous pourriez avoir besoin d’exécuter ipconfig /flushdns de temps en temps. Un redémarrage peut aussi aider, si vous voulez être vraiment sûr qu’il n’y a pas de résidus persistants.

Informations du domaine

  • Domaine Windows : dom.local

  • Serveur de domaine : server.dom.local, 172.17.3.11

  • Serveur Squid CentOS : centos.dom.local, 172.17.3.10

Configuration du serveur de domaine

  • Créez la zone inversée dom.local dans la configuration DNS.

  • Créez un enregistrement statique (‘A’) pour centos.dom.local pointant vers 172.17.3.10, sélectionnez Oui lorsqu’on vous demande si vous voulez configurer le PTR inversé également.

Windows 2008

Pour le serveur Windows 2008, vous devez installer le correctif 951191.

Configuration Linux

Paquets mineurs

Installez les paquets

$ yum install -y cyrus-sasl-gssapi cvs autoconf automake openldap openldap-devel krb5-workstation krb5-devel gcc-c++

Installez msktutil. Vous devez le patcher avant de le compiler.

$ wget http://download.systemimager.org/~finley/msktutil/msktutil_0.3.16.orig.tar.gz
$ wget http://download.systemimager.org/~finley/msktutil/msktutil_0.3.16-7.diff.gz
$ gunzip msktutil_0.3.16-7.diff.gz
$ tar zxf msktutil_0.3.16.orig.tar.gz
$ cd msktutil-0.3.16
$ patch < ../msktutil_0.3.16-7.diff
$ ./configure && make && make install

Compilez la dernière version de squid_kerb_ldap.

$ cvs -z3 -d:pserver:[email protected]:/cvsroot/squidkerbauth co -P squid_kerb_ldap
$ cd squid_kerb_ldap
$ ./configure && make

DNS

Utilisez system-config-network pour configurer le DNS pointant vers le contrôleur de domaine, définissez le nom d’hôte sur centos.dom.local.

Redémarrez

Vérifiez que le DNS inversé fonctionne :
$ dig -x 172.17.3.10

Vous devriez obtenir centos.dom.local dans la section réponse. Si ce n’est pas le cas, il est inutile de continuer. L’authentification Kerberos ne fonctionnera pas sans un DNS correctement configuré.

Kerberos

Votre krb.conf devrait ressembler à quelque chose comme ceci :

[logging]
 default = FILE:/var/log/krb5libs.log
 kdc = FILE:/var/log/krb5kdc.log
 admin_server = FILE:/var/log/kadmind.log

[libdefaults]
 default_realm = DOM.LOCAL
 dns_lookup_realm = false
 dns_lookup_kdc = false
 ticket_lifetime = 24h

# Pour Windows XP :
 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

# Pour Windows 2007 :
# 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
 forwardable = yes

[realms]
 DOM.LOCAL = {
  kdc = 172.17.3.11:88
  admin_server = 172.17.3.11:7491
  default_domain = dom.local
 }

[domain_realm]
 .dom.local = DOM.LOCAL
 dom.local = DOM.LOCAL

[appdefaults]
 pam = {
   debug = false
   ticket_lifetime = 36000
   renew_lifetime = 36000
   forwardable = true
   krb4_convert = false
}

Créez le keytab :

$ kinit administrator
$ msktutil -c -b "CN=COMPUTERS" -s HTTP/centos.dom.local -h centos.dom.local -k /etc/HTTP.keytab --computer-name centos-http --upn HTTP/centos.dom.local --server server.dom.local --verbose

Pour Windows 2008, vous devez ajouter --enctypes 28 à la commande msktutil.

Squid

Installez Squid :

$ wget http://www.squid-cache.org/Versions/v3/3.0/squid-3.0.STABLE18.tar.gz
$ tar zxvf squid-3.0.STABLE18.tar.gz
$ cd squid-3.0.STABLE18
$ ./configure --enable-negotiate-auth-helpers=squid_kerb_auth --enable-stacktraces --prefix=/opt/squid-3.0
$ make
$ make install
$ cp helpers/negotiate_auth/squid_kerb_auth/squid_kerb_auth /opt/squid-3.0/sbin/
$ cp ~/squid_kerb_ldap/squid_kerb_ldap /opt/squid-3.0/sbin/
$ cd /opt/squid-3.0/
$ mv etc/squid.conf etc/squid.conf.ORIG

Configurez les paramètres appropriés dans squid.conf :

auth_param negotiate program /opt/squid-3.0/sbin/squid_kerb_auth -d -s HTTP/centos.dom.local
auth_param negotiate children 10
auth_param negotiate keep_alive o

external_acl_type SQUID_KERB_LDAP ttl=3600  negative_ttl=3600  %LOGIN /opt/squid-3.0/sbin/squid_kerb_ldap -d -g SQUID_USERS
acl AUTHENTICATED proxy_auth REQUIRED
acl LDAP_GROUP_CHECK external SQUID_KERB_LDAP
acl localnet src 172.17.3.0/24        # RFC1918 possible internal network

#http_access allow localnet
#http_access allow AUTHENTICATED
http_access allow LDAP_GROUP_CHECK

cache_dir ufs /var/cache/squid-3.0 100 16 256
access_log /var/log/squid-3.0/access.log squid
cache_log /var/log/squid-3.0/cache.log
cache_store_log /var/log/squid-3.0/store.log
pid_filename /var/run/squid-3.0.pid
cache_effective_user squid
cache_effective_group squid
coredump_dir /var/cache/squid-3.0

Configurez l’utilisateur et les répertoires :

$ chown -R squid:squid /opt/squid-3.0/
$ mkdir /var/cache/squid-3.0
$ chown -R squid:squid /var/cache/
$ mkdir /var/log/squid-3.0
$ chown -R squid:squid /var/log/squid-3.0/
$ chown squid:squid /etc/HTTP.keytab

Créez les caches :

$ /opt/squid-3.0/sbin/squid -z

Script d’initialisation

Ceci est important : Squid a besoin de certaines variables d’environnement configurées pour fonctionner correctement. La meilleure façon de le faire est d’utiliser un script d’initialisation. Voici une version CentOS légèrement modifiée :

#!/bin/bash
# squid     This shell script takes care of starting and stopping
#       Squid Internet Object Cache
#
# chkconfig: - 90 25
# description: Squid - Internet Object Cache. Internet object caching is \
#   a way to store requested Internet objects (i.e., data available \
#   via the HTTP, FTP, and gopher protocols) on a system closer to the \
#   requesting site than to the source. Web browsers can then use the \
#   local Squid cache as a proxy HTTP server, reducing access time as \
#   well as bandwidth consumption.
# pidfile: /var/run/squid-3.0.pid
# config: /opt/squid-3.0/etc/squid.conf

PATH=/usr/bin:/sbin:/bin:/usr/sbin
export PATH

# Source function library.
. /etc/rc.d/init.d/functions

# Source networking configuration.
. /etc/sysconfig/network

# don't raise an error if the config file is incomplete
# set defaults instead:
SQUID_OPTS=${SQUID_OPTS:-"-D"}
SQUID_PIDFILE_TIMEOUT=${SQUID_PIDFILE_TIMEOUT:-20}
SQUID_SHUTDOWN_TIMEOUT=${SQUID_SHUTDOWN_TIMEOUT:-100}

KRB5_KTNAME=/etc/HTTP.keytab
export KRB5_KTNAME

# determine the name of the squid binary
[ -f /opt/squid-3.0/sbin/squid ] && SQUID=/opt/squid-3.0/sbin/squid

prog="$SQUID"

# determine which one is the cache_swap directory
CACHE_SWAP=`sed -e 's/#.*//g' /opt/squid-3.0/etc/squid.conf | \
    grep cache_dir |  awk '{ print $3 }'`
[ -z "$CACHE_SWAP" ] && CACHE_SWAP=/var/spool/squid-3.0

RETVAL=0

start() {

        #check if the squid conf file is present
        if [ ! -f /opt/squid-3.0/etc/squid.conf ]; then
            echo "Configuration file /opt/squid-3.0/etc/squid.conf missing" 1>&2
            exit 6
        fi
        . /etc/sysconfig/squid

        # don't raise an error if the config file is incomplete.
        # set defaults instead:
        SQUID_OPTS=${SQUID_OPTS:-"-D"}
        SQUID_PIDFILE_TIMEOUT=${SQUID_PIDFILE_TIMEOUT:-20}
        SQUID_SHUTDOWN_TIMEOUT=${SQUID_SHUTDOWN_TIMEOUT:-100}

        if [ -z "$SQUID" ]; then
                echo "Insufficient privilege" 1>&2
                exit 4
        fi

        for adir in $CACHE_SWAP; do
        if [ ! -d $adir/00 ]; then
         echo -n "init_cache_dir $adir... "
         $SQUID -z -F -D >> /var/log/squid-3.0/squid.out 2>&1
    fi
    done
    echo -n $"Starting $prog: "
    $SQUID $SQUID_OPTS >> /var/log/squid-3.0/squid.out 2>&1
    RETVAL=$?
    if [ $RETVAL -eq 0 ]; then
       timeout=0;
       while : ; do
          [ ! -f /var/run/squid-3.0.pid ] || break
      if [ $timeout -ge $SQUID_PIDFILE_TIMEOUT ]; then
         RETVAL=1
         break
      fi
      sleep 1 && echo -n "."
      timeout=$((timeout+1))
       done
    fi
    [ $RETVAL -eq 0 ] && touch /var/lock/subsys/squid-3.0
    [ $RETVAL -eq 0 ] && echo_success
    [ $RETVAL -ne 0 ] && echo_failure
    echo
    return $RETVAL
}

stop() {
    . /etc/sysconfig/squid

    # don't raise an error if the config file is incomplete.
    # set defaults instead:
    SQUID_SHUTDOWN_TIMEOUT=${SQUID_SHUTDOWN_TIMEOUT:-100}

    echo -n  $"Stopping $prog: "
    $SQUID -k check >> /var/log/squid-3.0/squid.out 2>&1
    RETVAL=$?
    if [ $RETVAL -eq 0 ] ; then
        $SQUID -k shutdown &
        rm -f /var/lock/subsys/squid-3.0
    timeout=0
    while : ; do
        [ -f /var/run/squid-3.0.pid ] || break
        if [ $timeout -ge $SQUID_SHUTDOWN_TIMEOUT ]; then
            echo
            return 1
        fi
        sleep 2 && echo -n "."
        timeout=$((timeout+2))
        done
    echo_success
    echo
    else
        echo_failure
    echo
    fi
    return $RETVAL
}

reload() {
    . /etc/sysconfig/squid
    # don't raise an error if the config file is incomplete.
    # set defaults instead:
    SQUID_OPTS=${SQUID_OPTS:-"-D"}

    $SQUID $SQUID_OPTS -k reconfigure
}

restart() {
    stop
    start
}

condrestart() {
    [ -e /var/lock/subsys/squid-3.0 ] && restart || :
}

rhstatus() {
    status $SQUID && $SQUID -k check
}

probe() {
    return 0
}

case "$1" in
start)
    start
    ;;

stop)
    stop
    ;;

reload)
    reload
    ;;

restart)
    restart
    ;;

condrestart)
    condrestart
    ;;

status)
    rhstatus
    ;;

probe)
    exit 0
    ;;

*)
    echo $"Usage: $0 {start|stop|status|reload|restart|condrestart}"
    exit 2
esac

exit $?

Voici les lignes importantes :

KRB5_KTNAME=/etc/HTTP.keytab
export KRB5_KTNAME

Machine cliente

Définissez votre proxy sur le serveur centos.dom.local en utilisant le port 3128. Il est important que vous utilisiez le nom de domaine pleinement qualifié et NON l’adresse IP.