Note de déploiement pour Single Sign-On (SSO) Kerberos à l'aide du fournisseur d'identité Authentic2

# Avant-propos
Cette note d'installation se focalise sur le déploiement d'un SSO Kerberos depuis un poste client vers un fournisseur d'identité Authentic2.

Ce document présume que le lecteur est déjà familiarisé avec l'outil authentic, et omet ainsi certaines étapes de l'installation de ce fournisseur d'identité.
Toutefois, si des informations spécifiques concernant le déploiement de l'application authentic sont nécessaires, la documentation d'installation de cet outil est disponible directement dans les sources du projet, à l'adresse
`https://git.entrouvert.org/authentic.git/tree/README`

De même, la procédure d'installation du support Kerberos pour Authentic2 est consultable à l'adresse :
`https://git.entrouvert.org/authentic2-auth-kerberos.git/tree/README`

Les paquets Debian de ces deux briques logicielles sont aussi téléchargeables à l'adresse :
`https://deb.entrouvert.org/`

# Remarques concernant la typographie
Ce document contient plusieurs *listings* de commandes shell. Certaines de ces commandes sont effectuées sur le serveur Windows, et sont donc exécutées par PowerShell, tandis que d'autres sont exécutées par Bash, côté client ou côté fournisseur d'identités.
Par besoin de distinction entre ces deux types de commandes, ces dernières sont préfixées comme ci-dessous :

- les commandes préfixées par `> ` sont exécutées dans PowerShell

- les commandes préfixées par `$ ` sont exécutées dans Bash

# Descriptif de l'architecture

Le serveur d'annuaire est un Active Directory sur Windows Server 2012 R2 (ici virtualisé à l'aide de l'outil Oracle VirtualBox).

Dans le cadre du déploiement en local réalisé pour la rédaction de ce document, la machine Windows Server héberge aussi un DNS.

Le domaine géré par la machine est `entrouvert.local`.
Le *hostname* de la machine Windows Server est `WIN-4HOASL41N0M.entrouvert.local`.
La *locale* du serveur est `en_us`.

Le déploiement ayant lieu en réseau local (fonctionnalité *Host-only adapter* de VirtualBox), l'adresse IP du serveur est 192.168.56.101.
L'adresse IP du fournisseur d'identité Authentic2 est 192.168.56.1, il s'agit d'une machine Debian 9 testing.

# Configuration du serveur Active Directory

Dans le cadre du déploiement en local, le royaume (*realm*) Kerberos défini est `ENTROUVERT.LOCAL`.
Aussi, en supposant que la base d'utilisateurs est déjà présente dans l'AD, il tout de même créer un compte AD correspondant au fournisseur d'identité.

Cet ajout peut être effectué à l'aide de l'interface graphique *Serv Manager* sur la machine Windows :
*Tools* -> *AD Users and Computers* -> *Managed Service Accounts* -> Clic droit *New...* -> *User* -> *User logon name : a2idp* (avec le suffixe `@ENTROUVERT.LOCAL`)
Il faut ensuite définir un mot de passe pour le compte nouvellement créé (clic droit sur l'entrée AD du compte, puis *Reset password*).

Le mot de passe ne doit pas avoir de date d'expiration et ne doit pas non plus être modifiable par l'utilisateur.

# Configuration DNS
## Configuration du serveur de nom de domaine

Pour la rédaction de cette note documentaire, le DNS utilisé est directement celui de la machine Windows Server.

Afin que le SSO aboutisse, il est nécessaire d'ajouter un A-record correspondant au nom d'hôte (*hostname*) du fournisseur d'identité.
Le host utilisé ici est `phyhost.entrouvert.local`.

L'ajout du *A-record* s'effectue comme ci-dessous.
Toujours dans l'interface *Server Manager*, ici dans le cas du déploiement en local :
*Tools* -> *DNS* -> onglet `WIN-4HOASL41N0M.entrouvert.local` -> *Forward Lookup Zone* -> entrouvert.local -> Clic droit "*New Host (A or AAAA)...*" -> *Name : phyhost*, *IP Address : 192.168.56.1*

## Configuration du client
Côté client, la configuration pour le SSO consiste en la déclaration de l'IP du serveur DNS. Cette configuration est réalisable soit à l'aide de l'outil `nm-connexion-editor` (outil de gestion des connexions intégré dans NetworkManager) -- onglet *IPv4 settings* -> *DNS servers* ; soit directement dans `/etc/resolv.conf` par ajout d'une entrée `nameserver 192.168.56.101`.

# Configuration du KDC Kerberos

Dans l'invite de commande PowerShell, il faut définir un *service principal name* à l'aide de la commande `setspn` :
```
setspn -S HTTP/phyhost.entrouvert.local a2idp
```
(N.B : l'option -S remplace l'option -A obsolète, cette dernière ne vérifiant pas la présence d'éventuels doublons dans la liste des *service principals*).

Le *service principal* Kerberos `HTTP/phyhost.entrouvert.local` est alors associé au compte AD de service *a2idp2* créé plus haut.

L'étape suivante est la génération d'une *keytab* associée au *service principal*. Cette keytab contient les différentes bi-clés utilisées pour l'authentification Kerberos.
La création de la *keytab* est réalisée à l'aide de la commandei `ktpass` :
```
> ktpass -princ HTTP/phyhost.entrouvert.local@ENTROUVERT.LOCAL -mapuser a2idp@ENTROUVERT.LOCAL -crypto ALL -ptype KRB5_NT_PRINCIPAL -pass <mot de passe du compte de service a2idp> -out c:\idp.keytab
```

Explication des options :
 
* `princ` : nom du service principal Kerberos

* `user ` : nom du compte de service dans la base AD
 
* `crypto` : algos de chiffrements utilisés. L'option `ALL` autorise le chiffrement pour toutes les algos supportés par le serveur (DES-CBC-CRC, DES-CBC-MD5, RC4-HMAC-NT, AES256-SHA1 et AES128-SHA1)
 
* `ptype` : type de principal Kerberos pour lequel la *keytab* est générée.

* `out` : emplacement de la `keytab`

La keytab est alors générée pour les cinq méthodes de chiffrement supportées :
```
Targeting domain controller: WIN-4HOASL41N0M.entrouvert.local
Using legacy password setting method
Successfully mapped HTTP/192.168.56.1 to a2idp.
Key created.
Key created.
Key created.
Key created.
Key created.
Output keytab to c:\idp.keytab:
Keytab version: 0x502
keysize 61 HTTP/192.168.56.1@ENTROUVERT.LOCAL ptype 1 (KRB5_NT_PRINCIPAL) vno 3 etype 0x1 (DES-CBC-CRC) keylength 8 (0x3
d98dff7a701b0c4)
keysize 61 HTTP/192.168.56.1@ENTROUVERT.LOCAL ptype 1 (KRB5_NT_PRINCIPAL) vno 3 etype 0x3 (DES-CBC-MD5) keylength 8 (0x3
d98dff7a701b0c4)
keysize 69 HTTP/192.168.56.1@ENTROUVERT.LOCAL ptype 1 (KRB5_NT_PRINCIPAL) vno 3 etype 0x17 (RC4-HMAC) keylength 16 (0xaf
a5a93065041df2e1687d9d9ad1445d)
keysize 85 HTTP/192.168.56.1@ENTROUVERT.LOCAL ptype 1 (KRB5_NT_PRINCIPAL) vno 3 etype 0x12 (AES256-SHA1) keylength 32 (0
xeb6c5d4af02c76d6c4104cbc8ab117e04c5a18c865c39df30bec97d50defc72b)
keysize 69 HTTP/192.168.56.1@ENTROUVERT.LOCAL ptype 1 (KRB5_NT_PRINCIPAL) vno 3 etype 0x11 (AES128-SHA1) keylength 16 (0
x3902936547e7d0cd4706c38a4a4fc0fb)
```

Cette keytab devra par la suite être déposée sur la machine serveur Authentic2 pour le bon déroulement du SSO.

# Configuration du navigateur Web
Côté client, le navigateur doit être configuré pour accepter les challenges `WWW-Authenticate` en provenance de l'IDP.

La configuration est donnée ici pour un client Mozilla Firefox 45 :
`about:config` dans la barre de navigation -> `network.negotiate-auth.allow-non-fqdn` à `true` (en particulier dans le cas où le non de domaine n'est pas un FQDN), et `network.negotiate-auth.trusted-uris` à phyhost.entrouvert.local`

Le navigateur est alors capable d'envoyer les tickets Kerberos pour permettre l'authentification auprès de l'AD.

# Configuration Authentic2
Outre le code de base du fournisseur d'identité Authentic2, le support Kerberos dans cette brique logicielle est pris en charge par l'application authentic2-auth-kerberos.
Le paquet Debian authentic2-auth-kerberos est disponible sur deb.entrouvert.org, mais il est aussi possible de l'installer via les sources (cf git.entrouvert.org).

Il faut avant tout renseigner l'emplacement de la copie du keytab généré au préalable sur le serveur Windows, ainsi que le nom du royaume Kerberos par défaut.
Ces deux options doivent être définies dans la configuration à l'aide des variables KRB5_KTNAME, et KRB5_NT_PRINCIPAL.
Ainsi, les deux lignes ci-dessous illustrent les modifications nécessaires dans le fichier `settings.py` de l'application authentic :
```
KRB5_KTNAME = '/etc/krb5.keytab`
A2_AUTH_KERBEROS_REALM = 'ENTROUVERT.LOCAL'
```
Il est aussi possible de forcer l'ajout d'un utilisateur dans la base AD lors du SSO si celui-ci ne s'y trouve pas déjà, à l'aide de l'option booléenne :
```
A2_AUTH_KERBEROS_CREATE_USER = True
```

## Support d'un backend LDAP3 dans Authentic2
Le fournisseur d'identité Authentic2 peut prendre en charge un backend LDAP3 pour la constitution de la base d'utilisateurs.
Quelques modifications dans le fichier de configuration authentic `settings.py` sont alors nécessaires :
```
AUTHENTICATION_BACKENDS += ( 'django_auth_ldap.backend.LDAPBackend', )

LDAP_AUTH_SETTINGS = [{
    'url': 'ldap://tutu.entrouvert.lan',
    'binddn': 'cn=admin,dc=entrouvert,dc=lan',
    'bindpw': 'lemotdepasseadmin',
    'basedn': 'ou=People,dc=entrouvert,dc=lan',
    'use_tls': False,
}]


```

Il faut veiller à ce que l'option `'basedn'` corresponde à la branche contenant directement les entrées des comptes utilisateurs.

On peut alors forcer l'approvisionnement complet des comptes utilisateurs de l'annuaire dans la base authentic à l'aide de la commande :
```
authentic2-ctl sync-ldap-users
```

# Déroulement du Single Sign-on

Sous Debian, les utilitaires client MIT Kerberos 5 sont disponibles dans les dépôts apt, il suffit d'installer le paquet `krb5-user`.

Le SSO ne peut avoir lieu sans *Ticket-Granting Ticket* (TGT) obtenu au préalable, soit à la connexion de l'utilisateur au poste client dans la cas d'une infrastructure AD classique, soit par recoursaux utilitaires CLI de l'implémentation MIT Kerberos 5 :
```
$ kinit pmarillonnet@ENTROUVERT.LOCAL
Password for pmarillonnet@ENTROUVERT.LOCAL:
$ klist
Ticket cache: FILE:/tmp/krb5cc_1003
Default principal: pmarillonnet@ENTROUVERT.LOCAL

Valid starting       Expires              Service principal
05/22/2017 09:45:41  05/22/2017 19:45:41  krbtgt/ENTROUVERT.LOCAL@ENTROUVERT.LOCAL
    renew until 05/23/2017 09:45:37
```

Il est alors possible de se rendre sur l'IDP pour s'identifier à l'aide du TGT précedemment obtenu.
Cette identification est effectuée de façon transparente et automatique.

Cependant, si celle n'a pas lieu, il est possible de forcer la procédure de SSO en se rendant à l'URI `/accounts/kerberos/login`.

L'IDP ne demande pas le login/password de l'utilisateur mais utilise le TGT pour l'obtention d'un ticket auprès du *Key Distribution Center* (KDC).
La commande MIT Kerberos 5 `klist` permet de vérifier les tickets de service ont bien été obtenus :
```
$ klist
Ticket cache: FILE:/tmp/krb5cc_1003
Default principal: pmarillonnet@ENTROUVERT.LOCAL

Valid starting       Expires              Service principal
05/22/2017 09:45:41  05/22/2017 19:45:41  krbtgt/ENTROUVERT.LOCAL@ENTROUVERT.LOCAL
renew until 05/23/2017 09:45:37
05/22/2017 10:58:12  05/22/2017 19:45:41  HTTP/phyhost.entrouvert.local@
renew until 05/23/2017 09:45:37
05/22/2017 10:58:12  05/22/2017 19:45:41  HTTP/phyhost.entrouvert.local@ENTROUVERT.LOCAL
renew until 05/23/2017 09:45:37
```

On peut alors ajouter des fournisseurs de service pris en charge par authentic pour étendre la couverture du SSO (cf la documentation Authentic2).
