# Kerberos

A backport of 2.0 new Kerberos authentication module has been done for 1.9.14. See Kerberos to see how to use it.

## Présentation

Cette documentation explique comment utiliser Active Directory comme serveur Kerberos, et fournir une authentification transparente aux utilisateurs du domaine AD à LL::NG.

On présente ici plusieurs architectures:

- Un seul serveur LL::NG lié à un seul domaine AD
- Un cluster LL::NG lié à un seul domaine AD
- Un cluster LL::NG lié à 2 domaines AD

## Pré-requis

### Valeurs d'exemple

Nous utilisons les valeurs suivantes dans nos exemples

- EXAMPLE.COM : premier domaine AD
- ACME.COM : second domaine AD
- auth.example.com : DNS du portail LL::NG
- authpwd.example.com : DNS du portail LL::NG (pour retomber sur un formulaire d'authentification)
- node1.example.com : DNS du second portail LL::NG (en mode cluster)
- node2.example.com : DNS du second portail LL::NG (en mode cluster)
- ad.example.com : DNS du premier Active Directory
- ad.acme.com : DNS du second Active Directory
- KERB_AUTH : compte AD pour générer la table de clefs du serveur LL::NG (en mode serveur seul)
- KERB_NODE1 : compte AD pour générer la table de clefs du premier serveur LL::NG (en mode cluster)
- KERB_NODE2 : compte AD pour générer la table de clef du second serveur LL::NG (en mode cluster)

### Horloge des serveurs

Il est impératif que les serveurs LL::NG et AD soient à la même heure. Il est recommandé d'utilisé NTP à cet effet.

### DNS

Tous les noms doivent être enregistrés dans le serveur DNS (qui est Active Directory). Il est préférable que le DNS inverse soit capable de résoudre tous les noms.

### Comptes AD

Il est recommandé de créer un compte AD pour chaque serveur LL::NG. Chaque compte tiendra le nom principal de service (SPN) du serveur LL::NG.

Il devrait être possible d'avoir le même compte pour tous les SPN, mais ça nécessite certaines manipulations de l'AD (commande setspn) non documentées ici.

### Configuration du navigateur web

#### Firefox

Aller à `about:config` dans un onglet et chercher `trusted`. Éditer la propriété `network.negotiate-auth.trusted-uris` et la mettre à la valeur `example.com`.

#### Internet Explorer

Ajouter `https://auth.example.com` comme site approuvé.

Vérifier dans les paramètres de sécurité que l'authentification Kerberos est autorisée.

### Installation du module Kerberos d'Apache

Sur CentOS/RHEL :

    yum install mod_auth_kerb

Sur Debian/Ubuntu :

    apt-get install libapache2-mod-auth-kerb

Ce module doit être chargé par Apache (directive LoadModule).

## Serveur LL::NG unique / Domaine AD unique

### Configuration du client Kerberos

Sur le serveur LL::NG, éditer `/etc/krb5.conf` :

    [libdefaults]
     default_realm = EXAMPLE.COM
     dns_lookup_kdc = false
     dns_lookup_realm = no
     ticket_lifetime = 24h
     forwardable = yes
     renewable = true

    [realms]
     EXAMPLE.COM = {
      kdc = ad.example.com
      admin_server = ad.example.com
     }

    [domain_realm]
     .example.com = EXAMPLE.COM
     example.com = EXAMPLE.COM

On peut vérifier que Kerberos fonctionne en essayant d'obtenir un ticket pour un utilisateur du domaine (par exemple coudot) :

    kinit coudot@EXAMPLE.COM

Un mot-de-passe peut être demandé. Lister ensuite les tickets :

    klist -e

On doit trouver un ticket krbtgt :

    Valid starting     Expires            Service principal
    06/04/15 15:43:24  06/05/15 01:43:29  krbtgt/EXAMPLE.COM@EXAMPLE.COM
            renew until 06/05/15 15:43:24, Etype (skey, tkt): aes256-cts-hmac-sha1-96, aes256-cts-hmac-sha1-96

On peut alors fermer la sessions Kerberos :

    kdestroy

### Obtenir un fichier table de clef

Il faut lancer cette commande dans Active Directory:

    ktpass -princ HTTP/auth.example.com@EXAMPLE.COM -mapuser KERB_AUTH@EXAMPLE.COM -crypto DES-CBC-MD5 -ptype KRB5_NT_PRINCIPAL -mapOp set -pass <PASSWORD> -out c:\auth.keytab

Les valeurs passées dans -crypto et -ptype dépendent de la version d'Active Directory et de celle des stations de travail. On peut par exemple utiliser RC4-HMAC-NT comme protocole de chiffrement si DES n'est pas supporté par les stations de travail (c'est le cas par défaut sur Window 8 par exemple).

Le fichier `auth.keytab` doit ensuite être copié (par un média sûr) sur le serveur Linux (par exemple dans `/etc/lemonldap-ng`).

Changer les droits sur le fichier keytab :

    chown apache /etc/lemonldap-ng/auth.keytab
    chmod 600 /etc/lemonldap-ng/auth.keytab

On peut vérifier la validité du fichier table de clefs en essayant de demander un ticket de service, et en le comparant au contenu de la table de clefs.

Ouvrir une session Kerberos (comme effectué dans l'étape précédente) :

    kinit coudot@example.com

Demander un ticket de service :

    kvno HTTP/auth.example.com@EXAMPLE.COM

Le résultat de la commande doit être :

    HTTP/auth.example.com@EXAMPLE.COM: kvno = 3

Lire le ticket de service :

    klist -e

On doit trouver un ticket de ce genre :

    06/04/15 16:28:49  06/05/15 02:28:11  HTTP/auth.example.com@EXAMPLE.COM
            renew until 06/05/15 16:28:07, Etype (skey, tkt): arcfour-hmac, arcfour-hmac

La session Kerberos peut être fermée :

    kdestroy

Comparer maintenant le résultat ci-dessus avec la même requête effectuée au travers de la table de clefs :

    klist -e -k -t /etc/lemonldap-ng/auth.keytab

Le résultat de la commande doit être :

    Keytab name: FILE:/etc/lemonldap-ng/auth.keytab
    KVNO Timestamp         Principal
    ---- ----------------- --------------------------------------------------------
       3 01/01/70 01:00:00 HTTP/auth.example.com@EXAMPLE.COM (arcfour-hmac)

Les points importants à vérifier sont :

- KVNO doit être identique
- Principal names doit identique
- Encryption types doit être identique

### Configuration de LemonLDAP::NG

Voir la configuration du module d'authentification Apache.

### Configuration de l'hôte virtuel du portail

Premièrement, copier l'actuelle définition de l'hôte virtuel du portail dans une nouvelle. Utiliser le nom de serveur `authpwd` pour cet hôte virtuel :

    <VirtualHost *>
        ServerName authpwd.example.com

        ...

    </VirtualHost>

Cet hôte virtuel sera utilisé par les clients qui ne réussiront pas à utiliser le protocole Kerberos.

Modifier ensuite l'hôte virtuel du portail principal pour charger le module d'authentification Kerberos d'Apache :

    <VirtualHost *>
      ServerName auth.example.com

      DocumentRoot /var/lib/lemonldap-ng/portal/

      <Directory /var/lib/lemonldap-ng/portal/>
        Order allow,deny
        Allow from all
        Options +ExecCGI +FollowSymLinks
      </Directory>

      ErrorDocument 401 /login.pl
      <LocationMatch ^/(?!login.pl)>
        <IfModule auth_kerb_module>
          AuthType Kerberos
          KrbMethodNegotiate On
          KrbMethodK5Passwd Off
          KrbAuthRealms EXAMPLE.COM
          Krb5KeyTab /etc/lemonldap-ng/auth.keytab
          KrbVerifyKDC Off
          KrbServiceName HTTP/auth.example.com
          require valid-user
        </IfModule>
      </LocationMatch>

    </VirtualHost>

### Script de redirection

Créer un script de redirection, appelé login.pl:

    vi /var/lib/lemonldap-ng/portal/login.pl

    #!/usr/bin/perl
    use CGI ':cgi-lib';
    use strict;
    use CGI::Carp 'fatalsToBrowser';
    my $uri = $ENV{"REQUEST_URI"};
    print CGI::header(-Refresh => '0; URL=https://authpwd.example.com'.$uri);
    exit(0);

Le script de redirection est nécessaire si l'authentification de secours est utilisée. If not, you can just keep a single virtual host (the authentication will fail if Kerberos negotiation do not succeed).

## Cluster LL::NG / domaine AD unique

### Configuration du client Kerberos

La configuration du client Kerberos est la même qie pour un serveur LL::NG unique.

### Obtenir un fichier table de clef

Il faut obtenir une table de clef pour chaque nœud LL::NG.

Les commandes sur Active Directory :

    ktpass -princ HTTP/node1.example.com@EXAMPLE.COM -mapuser KERB_NODE1@EXAMPLE.COM -crypto DES-CBC-MD5 -ptype KRB5_NT_PRINCIPAL -mapOp set -pass <PASSWORD> -out c:\authnode1.keytab
    ktpass -princ HTTP/node2.example.com@EXAMPLE.COM -mapuser KERB_NODE2@EXAMPLE.COM -crypto DES-CBC-MD5 -ptype KRB5_NT_PRINCIPAL -mapOp set -pass <PASSWORD> -out c:\authnode2.keytab

Copier les tables de clefs générés sur chaque nœud (en la renommant en auth.keytab pour avoir la même configuration Apache sur chaque nœud).

Changer les droits sur le fichier keytab :

    chown apache /etc/lemonldap-ng/auth.keytab
    chmod 600 /etc/lemonldap-ng/auth.keytab

On peut faire le même contrôle que pour un serveur LL::NG isolé. Utiliser simplement node1.example.com et node2.example.com au lieu de auth.example.com.

### Configuration de LemonLDAP::NG

La configuration est la même qie pour un serveur LL::NG unique.

### Configuration de l'hôte virtuel du portail

Le seul chagement dans la configuration d'Apache est le the `KrbServiceName` qui doit être mis à Any:

        KrbServiceName Any

## Cluster LL::NG / Deux domaines AD

### Configuration du client Kerberos

Les deux domaines doivent être définis dans `/etc/krb5.conf` :

    [libdefaults]
     default_realm = EXAMPLE.COM
     dns_lookup_kdc = false
     dns_lookup_realm = no
     ticket_lifetime = 24h
     forwardable = yes
     renewable = true

    [realms]
     EXAMPLE.COM = {
      kdc = ad.example.com
      admin_server = ad.example.com
      default_domain = EXAMPLE.COM
     }
     ACME.COM = {
      kdc = ad.acme.com
      admin_server = ad.acme.com
      }

    [domain_realm]
     .example.com = EXAMPLE.COM
     example.com = EXAMPLE.COM
     .acme.com = ACME.COM
     acme.com = ACME.COM

On doit pouvoir ouvrir une session Kerberos dans chaque domaine :

    kinit coudot@EXAMPLE.COM
    klist -e
    kdestroy

    kinit coudot@ACME.COM
    klist -e
    kdestroy

### Obtenir un fichier table de clef

Il faut obtenir une table de clefs pour chaque nœud dans chaque domaine. Ce qui signifie que la commande ktpass doit être lancée dans les deux AD.

On a donc 2 tables de clefs pour chaque nœud, par exemple :

- node1-example.keytab
- node1-acme.keytab

Il faut concaténer les 2 fichiers, merci à la commande `ktutil` :

    ktutil
    ktutil: read_kt node1-example.keytab
    ktutil: read_kt node1-acme.keytab
    ktutil: write_kt /etc/lemonldap-ng/auth.keytab
    ktutil: quit

On peut ensuite effacer les tables de clefs originales et protéger la table de clefs finale :

    chown apache /etc/lemonldap-ng/auth.keytab
    chmod 600 /etc/lemonldap-ng/auth.keytab

### Configuration de LemonLDAP::NG

La configuration est la même qie pour un serveur LL::NG unique.

### Configuration de l'hôte virtuel du portail

La configuration est la même que pour un domaine AD unique.

## Autres documents

Pour en savoir plus :

- http://modauthkerb.sourceforge.net/configure.html
- http://www.grolmsnet.de/kerbtut/