Vous êtes ici : index » informatique » reseau » ldap » auth_kerberos
Piste : auth_kerberos

Authentification Kerberos (SASL GSSAPI)

Authentification Kerberos (SASL GSSAPI)

Installation

On installe le paquet krb5-user pour avoir les commandes utiles :

apt-get install krb5-user

On crée ensuite le fichier /etc/krb5.conf :

[libdefaults]
default_realm = DOMAIN.TLD
dns_lookup_realm = false
dns_lookup_kdc = false
ticket_lifetime = 24h
renew_lifetime = 7d
forwardable = true
[realms]
DOMAIN.TLD = {
kdc = AD1.DOMAIN.TLD
admin_server = AD1.DOMAIN.TLD
}
[domain_realm]
.DOMAIN.TLD = DOMAIN.TLD
DOMAIN.TLD = DOMAIN.TLD
Le domaine doit être en majuscule partout pour que cela fonctionne.

On peut alors tenter une première authentification :

kinit myuser@DOMAIN.TLD

On vérifie ensuite le ticket obtenu :

klist

Pour la suite, on supprime le ticket obtenu :

kdestroy

Création d'un fichier keytab

Si le fichier keytab doit être utilisé par un utilisateur de service, celui-ci doit être créé et renouvelé en tant que cet utilisateur. Les commandes qui suivent doivent donc être lancées en tant que cet utilisateur (via sudo possiblement).

On crée le fichier keytab (par exemple /etc/myuser.keytab en lançant la commande ktutil (mode interactif) et on entre les commandes suivantes :

ktutil:  addent -password -p myuser@DOMAIN.TLD -k 1 -e RC4-HMAC
Password for myuser@DOMAIN.TLD:
ktutil:  wkt /etc/myuser.keytab
ktutil:  q

On récupère ensuite un ticket en utilisant le fichier keytab :

kinit myuser@DOMAIN.TLD -k -t /etc/myuser.keytab

On vérifie ticket obtenu :

klist

On peut maintenant utiliser ce ticket pour interroger l'annuaire LDAP :

On installe pour commencer les dépendances pour l'authentification SASL GSSAPI :

apt-get install sasl2-bin libsasl2-2 libsasl2-modules libsasl2-modules-gssapi-mit

On peut ensuite interroger l'annuaire LDAP avec ldapsearch :

ldapsearch -H ldaps://AD1.enscp.edu -Y GSSAPI -U 'myuser@DOMAIN.TLD' -b DC=enscp,DC=edu -s base dc
En cas de soucis d'authentification sur un AD via LDAPS (mais pas en LDAP), tenter d'ajouter la ligne suivante dans le fichier /etc/ldap/ldap.conf :
sasl_secprops minssf=0,maxssf=0

Source : https://bugs.launchpad.net/ubuntu/+source/cyrus-sasl2/+bug/1015819

Pour spécifier le fichier keytab à utiliser (dans un script par exemple), définissez la variable d'environnement KRB5CCNAME dans le contexte d'exécution des commandes ldapsearch, ldapmodify, etc :
export KRB5CCNAME=/path/to/file.keytab

Renouvellement automatique

En cas de besoin de renouvellement automatique (=token utilisé par un cron/service par exemple), un cron doit être mis en place :

  1. Créer le fichier /usr/local/bin/renew-keytab:
    #!/bin/bash
     
    DEBUG=0
    OWNER=
    KEYTAB=
    PRINCIPAL=
     
    usage() {
    	[[ "$#" -gt 0 ]] && echo "$*" >&2
    	echo "Usage: $(realname "$0") keytab principal -o owner [-d]"
    	echo "  [keytab]	Path of the keytab file (REQUIRED)"
    	echo "  [principal]	Principal of the user (REQUIRED)"
    	echo "  -o/--owner	Owner of the keytab file (defaut: the owner of the keytab file)"
    	echo "  -d/--debug	Enable debug log"
    	[[ "$#" -gt 0 ]] && exit 1
    	exit 0
    }
     
    idx=1
    while [[ $idx -le $# ]]; do
            opt=${!idx}
    	case "$opt" in
    		-d|--debug)
    			DEBUG=1
    			;;
    		-o|--owner)
    			((idx++))
    			OWNER="${!idx}"
    			;;
    		*)
    			if [[ -z "$KEYTAB" ]]; then
    				KEYTAB=$opt
    				[[ ! -f "$KEYTAB" ]] && usage "Keytab file (${KEYTAB}) not found"
    			elif [[ -z "$PRINCIPAL" ]]; then
    				PRINCIPAL=$opt
    			else
    				usage "Invalid argument '$opt'"
    			fi
    	esac
    	((idx++))
    done
     
    [[ -z "$KEYTAB" ]] && usage "Keytab file not specified"
    [[ -z "$PRINCIPAL" ]] && usage "Principal not specified"
    [[ -z "$OWNER" ]] && OWNER="$(stat -c %U "$KEYTAB")"
     
    debug() { [[ $DEBUG -eq 1 ]] && echo "[DEBUG] $*"; }
     
    if [[ "$( whoami )" != "$OWNER" ]]; then
            debug "This script must be run as $OWNER: rerun it as $OWNER"
            sudo -u "$OWNER" "$(realpath "$0")" "$@"
            exit $?
    fi
     
    if ! klist -k "$KEYTAB" | grep -q "$PRINCIPAL"; then
            if [[ -t 1 ]]; then
                    kinit -k -t "$KEYTAB" "$PRINCIPAL" || exit 1
            else
                    echo "No ticket found for $PRINCIPAL in $KEYTAB. You must init first authentification by running $(realpath "$0") manually."
                    exit 1
            fi
    else
            debug "Ticket found for $PRINCIPAL in $KEYTAB. Try to renew it..."
            if kinit -R -k -t "$KEYTAB" "$PRINCIPAL"; then
                    debug "Ticket renewed."
                    [[ $DEBUG -eq 1 ]] && klist
            elif [[ -t 1 ]]; then
                    debug "Failed to renew ticket, obtain new ticket interactively..."
                    kinit -k -t "$KEYTAB" "$PRINCIPAL" || exit 1
            else
                    echo "Failed to renew ticket for $PRINCIPAL. You must obtain a new ticket by running $(realpath "$0") manually."
                    exit 1
            fi
    fi
  2. rendez le exécutable :
    chmod 750 /usr/local/bin/renew-keytab

Exemple d'utilisation :

renew-keytab /etc/myuser.keytab myuser@DOMAIN.TLD
Si le fichier keytab est utilisé par un utilisateur de service, celui-ci doit être créé et renouvelé en tant que cet utilisateur. Assurez-vous de lancer le script via cron en tant que l'utilisateur de service ou spécifiez ce dernier via l'argument -o (ou –owner, par défaut : propriétaire actuel de fichier keytab). Si le script n'est pas lancé en tant que le propriétaire (spécifié ou auto-détecté), le script sera automatiquement relancé en tant que le propriétaire (en utilisant sudo).

Connexion en python (avec python-ldap)

import os
import ldap
 
os.environ['KRB5_CLIENT_KTNAME'] = '/etc/myuser.keytab'
ldap_conn = ldap.initialize('ldaps://AD1.domain.tld')
ldap_conn.sasl_non_interactive_bind_s('GSSAPI')
print(ldap_conn.whoami_s())

Connexion en PHP

<?php
$conn = ldap_connect("ldaps://AD1.domain.tld", 636) or die("Failed to connect to LDAP host");
ldap_set_option($conn, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($conn, LDAP_OPT_REFERRALS, 0);
putenv("KRB5_KTNAME=/path/to/file.keytab");
ldap_sasl_bind($conn, null, null, 'GSSAPI') or die("Kerberos auth failure: ".ldap_error($conn));