Aller au contenu

Authentification Kerberos

L'authentification ssh de la plupart postes, serveurs ou machines virtuelles de l'ISIMA/LIMOS repose sur kerberos interfacé avec notre annuaire d'utilisateurs (Active Directory lui même synchronisé avec le LDAP UCA).

Authentification standard (login/mot de passe)

Pour se connecter à un serveur ssh kerbérisé il suffit d'ajouter <compte>@ devant le nom du serveur.

Par exemple

ssh vimazeno@vm-etu-vimazeno.local.isima.fr

Authentification par ticket Kerberos (en remplace de l'authentification par clés publiques / privées)

La génération d'un ticket Kerberos étant obligatoire à chaque connexion il n'est pas possible d'utiliser les clés ssh pour une connexion sans mot de passe

Toutefois il est possible de générer un keytab permettant d'obtenir un ticket kerberos sans taper de mot de passe.

serveurs kerberisés

  • perso
  • turing
  • ada
  • certaines VM étudiantes
  • bastion (double facteur d'authentification pour cette machine. Elle requiert également une clé SSH)

Linux

Pré requis

Préconfigurez l'installation du paquet krb5-config :

echo -e "krb5-config krb5-config/default_realm string LOCAL.ISIMA.FR" | sudo debconf-set-selections

ou

Taper le nom du Realm (ici: LOCAL.ISIMA.FR - En majuscules) quand il vous sera demandé lors de l'installatoin de krb5-config

sudo apt install krb5-user krb5-config

Authentification

kinit <compte-uca>
# ou
kinit <compte-uca>@LOCAL.ISIMA.FR # Si vous utilisez plusieurs realm Kerberos

Le Realm (LOCAL.ISIMA.FR) n'a pas besoin d'être renseigné, s'il est défini par défaut lors de l'installation des requirements

Il faut saisir le mot de passe

La commande klist liste les tickets de l'utilisateur

$ klist
Ticket cache: FILE:/tmp/krb5cc_1000
Default principal: <compte-uca>@LOCAL.ISIMA.FR

Valid starting     Expires            Service principal
08/24/20 10:10:37  08/24/20 20:10:37  krbtgt/LOCAL.ISIMA.FR@LOCAL.ISIMA.FR
        renew until 08/25/20 10:10:37

On comprend ici que l'utilisateur a obtenu son Ticket-Granting Ticket (TGT). Il lui permettra de s'authentifier auprès des serveurs de l'école et d'accéder à certains service de l'école (répertoire perso sur dirs, partages administratifs).

Ce ticket a une durée de vie limitée, il doit donc être redemandé lorsqu'il est périmé (avec kinit).

Vous pouvez désormais tester une connexion SSH en utilisant votre TGT. Vous pouvez aussi forcer le transfert du ticket kerberos sur votre session distante avec l'option -K. Cela est souvent nécessaire pour accéder à des ressources depuis la session que vous ouvrez sur le serveur (e.g. un accès à un partage NFS Kerberisé par exemple votre répertoire perso dans ~/shared).

Cette option peut être requise dans le cas où votre homedir est directement sur le partage NFS kerberisé. C'est le cas du serveur perso.local.isima.fr, turing.local.isima.fr ou de ada.local.isima.fr par exemple. Si vous faites pas suivre le TGT sur votre session distante, alors vous serez autorisé à vous connecter sur le serveur mais n'aurez pas le droit d'accéder à votre homedir.

ssh -K <compte-uca>@perso.local.isima.fr
# Ou
ssh -K <compte-uca>@turing.local.isima.fr
# Ou
ssh -K <compte-uca>@ada.local.isima.fr

kdestroy permet de détruire un ticket. À faire avant de continuer avec le keytab pour bien s'assurer qu'on récupère un ticket KRB5 avec le keytab sans saisie du mot de passe.

Création du keytab

La commande interactive ktutil permet de créer un fichier keytab.

$ 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.

ktutil:  addent -password -p <compte-uca>@LOCAL.ISIMA.FR -k 1 -e aes256-cts-hmac-sha1-96
Password for <compte-uca>@LOCAL.ISIMA.FR:
ktutil:  wkt my.keytab
ktutil:  exit

Un secret dérivé du mot de passe est généré dans le fichier ~/my.keytab

Bonne pratique

À l'image de vos clés SSH, il est prudent de mettre votre keytab (qui je le rappelle est un secret) dans un répertoire avec les droits 0700 (accès au propriétaire seulement).

mkdir ~/.krb5
chmod 0700 ~/.krb5
mv my.keytab ~/.krb5

Authentification avec KeyTab (sans mot de passe)

Remarques

Il n'est pas possible de demander à ssh de récupérer le ticket auprès du KDC/AD, seul la commande kinit le peut (ainsi que libpam-krb5). SSH ne peut utiliser que le ticket déjà présent sur la session. Il faut donc d'abord faire un kinit sur keytab, puis faire un ssh -K qui utilisera ton ticket pour s'authentifier sur un serveur SSH Kerberisé.

Ce keytab permet d'obtenir un ticket KDC/AD sans saisir ton mot de passe.

$ kinit -k -t ~/.krb5/my.keytab <compte-uca>@LOCAL.ISIMA.FR
$ klist
Ticket cache: FILE:/tmp/krb5cc_1000
Default principal: <compte-uca>@LOCAL.ISIMA.FR

Valid starting     Expires            Service principal
08/24/20 10:31:13  08/24/20 20:31:13  krbtgt/LOCAL.ISIMA.FR@LOCAL.ISIMA.FR
        renew until 08/25/20 10:31:13

vous pouvez tester la connexion en forçant l'envoie du ticket kerberos obtenu avec l'option -K

ssh -K <compte-uca>@perso.local.isima.fr
# Ou
ssh -K <compte-uca>@turing.local.isima.fr
# Ou
ssh -K <compte-uca>@ada.local.isima.fr

Il peut être intéressant de récupérer un ticket Kerberos via le kinit depuis votre .bashrc. Ainsi, vous avez un ticket Kerberos toujours disponible pour vous connecter aux serveurs de l'ISIMA/LIMOS.

Dans votre fichier ~/.bashrc ajoutez :

if timeout 0.4 ping -c1 192.168.100.75 > /dev/null 2>&1; then
  if ! klist -s; then
      kinit -k -t ~/.krb5/my.keytab <compte-uca>@LOCAL.ISIMA.FR 2> /dev/null
      true
  fi
fi

Si vous n'avez pas déjà un ticket KRB5, alors vous en réclamez un au controlleur de domaine. On ne veut pas afficher le message d'erreur de la commande kinit (2> /dev/null), car dans le cas où vous ne seriez pas à l'ISIMA, vous recevriez toujours une erreur lors de l'ouverture d'un terminal.

J'ai placé un timeout de 0,4 seconde sur la commande ping. Dans le cas où le controlleur de domaine ne serait pas joignable (vous n'êtes pas à l'ISIMA ni sur le VPN), alors la procédure ne ralentie que de peut l'ouverture d'un shell (ce timeout peut engendrer un echec du sondage avec la commande ping que j'ai evalué de 1 à 2 %, le cas échéant, le ticket est quand même récupérable par le lancement de la commande kinit comme décrit ci-dessus).

Windows

Mac

CI / Gitlab

exporter son keytab en hexadécimal

hexdump -v -e '1/1 "%02x"'  ~/.krb5/my.keytab > ~/.krb5/my.keytab.hex

récupérer le keytab à partir de sa version hexadécimal

À utiliser dans la CI/CD

sed 's/\([0-9A-F]\{2\}\)/\\\\\\x\1/gI'  ~/.krb5/my.keytab.hex | xargs printf

variable CI gitlab

Sur le gitlab, dans CI / CD > Variables [collapse] > créer l'entrée suivante:

  • key: KEYTAB
  • value: (le contenu du fichier ~/.krb5/my.keytab.hex)

Exemple de fichier .gitlab-ci.yml pour déployer du code sur un serveur distant avec rsync et un keytab Kerberos

Les stages de build et de test ne sont pas montré dans cet exemple, simplement le déploiement en utilisant Kerberos est mis en scène.

Vous pouvez ajoutez des stages utilisants d'autres images Docker pour build votre projet et utiliser le stage ci-dessous pour deployer le code sur le serveur distant.

stages:
  - deploy

production:
  stage: deploy
  image: instrumentisto/rsync-ssh:latest
  script:

    # Installation de Kerberos dans le docker et remplacement du client ssh par défaut par celui capable d'utiliser kerberos
    - apk update
    - apk del openssh-client-default
    - apk add krb5 openssh-client-krb5

    # Ne pas vérifier la hostkey des serveurs SSH
    - mkdir -p ~/.ssh
    - test -f /.dockerenv && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config

    # Récupération du KEYTAB en hexadécimal
    - echo "${KEYTAB}" > my.keytab.hex

    # Conversion du KEYTAB en binaire
    - sed 's/\([0-9A-F]\{2\}\)/\\\\\\x\1/gI' my.keytab.hex | xargs printf > my.keytab

    # Demande du ticket kerberos en utilisant le KEYTAB
    - kinit -k -t my.keytab ${USERNAME}@LOCAL.ISIMA.FR

    # Vérification de l'obtention du ticket Kerberos
    - klist 

    # Déploiement du code
    - rsync -az -e "ssh -K" ${DIRS_AND_FILES_TO_COPY} ${USERNAME}@${REMOTE_HOST_FQDN}:${REMOTE_LOCATION}