Depuis Exchange Server 2010 SP1, il est hautement recommandé d'activer Kerberos pour les accès clients. Cela se faisait au travers d'un ensemble de manipulations visant à créer un objet de sécurité dans l'Active Directory, puis de définir les Service Principal Names Kerberos sur cet objet.
Cet objet devait ensuite être défini sur la configuration des serveurs CAS comme le "Alternate Service Account", ce qui permettait alors au service "Microsoft Exchange Protected Service Host" de répondre en mode Negotiate à un challenge SPNEGO.
J'avais documenté le pas-à-pas dans un tutoriel Exchange 2010 SP1 >> ici << (à l'époque c'était sur la Beta du SP1 mais la procédure est toujours applicable).
Qu'en est-il d'Exchange Server 2013... ?
Plusieurs points:
- Exchange 2013 n'utilise plus le Mapi/Rpc (pour les accès clients), seulement le Mapi sur Http (autrement dit, le Rpc/Http)
- Exchange 2013 est configuré par défaut en mode Ntml, afin de conserver une compatibilité large et surtout parce que la configuration en Kerberos requiert des manipulations qui ne peuvent être faites automatiquement au moment du Setup
- La haute disponibilité d'Exchange 2013 s'effectue uniquement au niveau du protocole HTTP, il n'y a par conséquent plus besoin de définir une VIP pour le Mapi/Rpc.
Ce que cela implique:
- Au niveau de la haute-disponibilité: il devient possible de se passer de répartiteur de charge (load-balancer, HLB) et de ne faire que du DNS round-robin (DNS RR). Il s'agit avant tout d'une logique du client et donc ne fonctionnera pas dans 100% des cas (vous devrez avoir des clients dits "modernes") - il reste bien sûr (et je le recommande pour plein de raisons) la possibilité de faire de la répartition de charge classique, en mode 100% HTTP/HTTPS désormais. Cependant, point noir pour Exchange 2013 RTM: il n'y a pas de support du SSL Offloading. Pour l'avoir testé, cela ne fonctionne pas du tout et j'essayerai de vous faire un tutoriel sur le SSL Bridging, qui lui devrait (en théorie) fonctionner.
- Au niveau de la configuration: il faudra configurer Outlook Anywhere et les Web Services afin de faire référence à un nom générique (load-balancé donc, ou en DNS RR). Cela permettra donc aux clients d'utiliser des URI liées à des points de connexion uniques, et non comme cela est le cas, directement liées au nom complet qualifié (Fqdn) de chaque serveur.
Première partie: configuration des Web Services
La configuration des Web Services est simple et presque identique à ce que l'on avait l'habitude de faire sur Exchange 2010, à savoir:
- Définition d'une "InternalURL" pour les services suivants: OWA/ECP, Exchange Web Services, OAB, Exchange ActiveSync. La configuration du Web Service Autodiscover n'est désormais plus utile, mais il faudra conserver la partie de la configuration visant à changer le Service Connection Point HTTP pour la découverte automatique via l'Active Directory (pour rappel: en utilisant le cmdlet Set-ClientAccessServer). A cela viendra s'ajouter la configuration, maintenant O-BLI-GA-TOIRE d'Outlook Anywhere, activé par défaut et référençant le Fqdn de chaque serveur.
- Optionnellement, définition des "ExternalURL", si vous souhaitez supporter des clients externes (pour du vrai Outlook Anywhere, dans le sens originel du terme... :)). Nous verrons cela dans un prochain article.
Pour l'exemple, nous allons donc configurer en premier lieu les URLs Internes et monter comment un client se connecte par défaut (il sera en Rpc/HTTP _et_ en Ntlm).
Le nom générique dans mon Lab sera "ex.w15-lab.com". J'ai ici deux serveurs (SV-E15-1 et SV-15-2) exécutant les rôles CAS et MBX, nous ne devrons configurer que la partie CAS. Pour l'exemple, je vais découper les actions en mode pas-à-pas et serveur par serveur.
Configuration des Web Services:
Regardons d'abord l'état de mon premier serveur pour le VDir Outlook Web App:
- Get-OwaVirtualDirectory -Server SV-E15-1 -ADPropertiesOnly | fl *Url
Il est est de même pour les autres Web Services, nous allons donc les configurer individuellement (ici en Shell pour le premier):
- Get-OwaVirtualDirectory -Server SV-E15-1 -ADPropertiesOnly | Set-OwaVirtualdirectory -InternalUrl "https://ex.w15-lab.com/owa"
- Get-EcpVirtualDirectory -Server SV-E15-1 -ADPropertiesOnly | Set-EcpVirtualdirectory -InternalUrl "https://ex.w15-lab.com/ecp"
- Get-WebServicesVirtualDirectory -Server SV-E15-1 -ADPropertiesOnly | Set-WebServicesVirtualDirectory -InternalUrl "https://ex.w15-lab.com/EWS/Exchange.asmx"
- Get-OabVirtualDirectory -Server SV-E15-1 -ADPropertiesOnly | Set-OabVirtualDirectory -InternalUrl "https://ex.w15-lab.com/OAB"
- Get-ActiveSyncVirtualDirectory -Server SV-E15-1 -ADPropertiesOnly | Set-ActiveSyncVirtualDirectory -InternalUrl "https://ex.w15-lab.com/Microsoft-Server-ActiveSync"
Note: Attention à la casse sur les "/répertoire". Il y a des scripts disponibles sur la blogosphère permettant de soit-disant les configurer "facilement". Historiquement il y a eu des soucis si la casse d'origine n'était pas respectée: typiquement en mode Proxy-CAS sur l'Exchange Control Panel où l'InternalURL était en autre chose que "/ecp" (en minuscules) et "cassait" le cookie msExchCanary. Mon conseil: écrivez votre propre script et respectez exactement la même casse que celle originellement trouvée sur l'InternalURL. Pour les ExternalURL, utilisez la même nomenclature que l'InternalURL.
Nous voyons ici que nous n'avons pas utilisé la Cmdlet Set-AutodiscoverVirtualDirectory, contrairement à ce que nous aurions fait dans Exchange 2010 et Exchange 2007. Cependant ces actions n'avaient que très peu d’intérêt même dans les versions précédentes. Il semblerait donc que la directive dans Exchange 2013 est de ne même pas s'y attarder... :)
Par contre, nous devons absolument configurer le Service Connection Point de l'Autodiscover afin d'arriver sur notre URI générique. Cela ne peut se faire qu'en Shell. Notez que vous pouvez vous passer ce cette configuration si vous voulez disposer un certificat sur vos CAS ayant chaque Fqdn de chaque CAS dans le Subject Alternate Name. La meilleure méthode reste cela dit de définir une URI générique, comme pour tous les autres Web Services...
Nous y sommes presque ! Reste donc la partie Rpc/Http, autrement dit, Outlook Anywhere !
La grosse nouveauté ici est qu'il existe désormais un "InternalHostname" à Outlook Anywhere. Rappelez vous que pour Exchange 2007 et Exchange 2010, il n'était possible que de définir un "ExternalHostName"... Vous l'aurez sans doute compris, le "InternalHostname" va être le point de connexion de vos clients et va complètement supprimer la notion de "Client Access Array" (NDLR: vous ne trouverez plus de Cmdlet New-ClientAccessArray, c'est donc normal :)).
Nous allons donc configurer l'InternalHostname afin qu'il pointe aussi sur notre nom générique. Cela s'effectue au travers de la Cmdlet Set-OutlookAnywhere:
- Get-OutlookAnywhere -Server SV-E15-1 -ADPropertiesOnly | Set-OutlookAnywhere -InternalHostName "ex.w15-lab.com" -InternalClientsRequireSsl:$true
Vous pouvez vérifier la bonne application du changement en utilisant la Cmdlet Get-OutlookAnywhere:
- Get-OutlookAnywhere -Server SV-E15-1 -ADPropertiesOnly | fl *Internal*
Dès lors, vous pouvez reproduire la même configuration pour vos autres serveurs CAS. Vous pouvez utiliser l'Exchange Administration Center (https://serveur.domaine.com/ecp en vous authentifiant avec un compte appartenant au(x) bon(s) Role Group(s)) et en allant dans les sections suivantes:
- Servers ==> Virtual directories pour les Web Services classiques (OWA/ECP, EWS, EAS, OAB)
- Servers ==> Servers ==> double-click puis section "Outlook Anywhere" pour la configuration du "InternalHostName" Outlook Anywhere.
Rappelez vous qu'il faudra quand même configurer l'AutodiscoverServiceInternalUri en Shell, l'EAC ne proposant pas la modification du champ.
Avant de tester la connexion avec un client Outlook, vous devrez attendre que les changements soient effectifs/commités dans la base IIS et la configuration Exchange de tous vos serveurs. Pour cela, cherchez dans l'eventlog Application une écriture au journal de l'évènement ID3025 de la source "MSExchange RPC Over HTTP Autoconfig".
En attendant que cela soit le cas, vous devez faire les actions suivantes:
- Créer un certificat à base d'un modèle "Web Server" ou d'un dérivé, et l'assigner à IIS. Pour ma part j'utilise un certificat "Wildcard" généré par un script, et ayant le InternalHostName et optionnellement (nous y viendrons plus tard) le ExternalHostName dans l'attribut SAN. Mon certificat n'a pas les Fqd des serveurs CAS dans le SAN, c'est mon côté puriste même si je comprends que certains préfèrent les avoir.
- Créer le ou les enregistrements DNS correspondant(s) au nom générique de connexion
- Pour du DNS round-robin, créez 'n' enregistrement de type A ayant le même nom. Dans mon cas, cela fait 2 enregistrements DNS dans ma zone DNS "w15-lab.com"
- Pour du load-balancing classique, il suffit de faire pointer l'enregistrement A sur la VIP créée à cet effet.
Faites ensuite un redémarrage d'IIS sur chacun des CAS (iisreset /noforce). Cette étape n'est normalement pas requise mais j'ai eu des comportements bizarres sur les URL retournées lors de l'Autodiscover.
Une fois toutes ces actions effectuées, vous pouvez démarrer votre client Outlook (testé avec Outlook 2010 ici).
Configuration Serveur Exchange et Exchange Rpc/HTTP Proxy
Etat des connexions:
On notera en particulier les points suivants:
- Le nom du serveur Exchange (ou anciennement du CAS Array) n'a plus lieu d'être est est remplacé par un GUID (GUID@forest.com)
- La configuration du Rpc/HTTP s'est fait automatiquement, comme pour les versions précédentes mais avec la subtilité d'avoir détecté une connectivité "interne" et donc une configuration du Rpc/HTTP Proxy faisant référence à l'InternalHostName configuré précédemment.
- On remarquera aussi que les deux options visant à forcer l'utilisation du Rpc/HTTP sont forcées, et ceci sans configurer l'OutlookProvider EXPR.
- On voit aussi clairement que la configuration par défaut se fait en Ntlm (auto-configuré ainsi) et en SSL (par défaut aussi).
Nous sommes maintenant connectés, passons donc à la seconde partie: le Kerberos !
Seconde partie: configuration du Kerberos
La configuration du Kerberos pour Exchange 2013 est dans la continuité d'Exchange 2010. Nous devons procéder ainsi:
- Créer un objet pour l'Alternate Service Account
- Lui assigner les Service Pincipal Names qui nous intéressent
- Le configurer sur chaque serveur CAS
- Reconfigurer le mode d'authentification
Création de l'Alternate Service Account:
J'utilise un objet de type "Computer", nommé ici EXCHANGE-MAIN$. La subtilité ici est qu'un compte d'ordinateur n'a pas de mot de passe positionné lorsqu'il est ajouté au domaine via la pré-création d'un objet. Puisqu'il n'y a pas à proprement parler de serveur à joindre au domaine, nous allons devoir positionner un mot de passe.
Pour ma part, j'utilise un script pour générer un mot de passe très long et très aléatoire puis un autre script pour faire une réinitialisation du mot de passe du compte ordinateur.
Lorsque l'objet est créé, il ne dispose d'aucun nom de service associé. Nous allons donc les créer à l'aide de la commande SETSPN.
- setspn.exe -A HTTP/ex.w15-lab.com WFLAB\EXCHANGE-MAIN$
Assignation de l'Alternate Service Account:
Vous devrez procéder en mettant les Credentials de l'objet dans une variable, ici $ASA. L’assignation s'effectue au travers de la Cmdlet Set-ClientAccessServer, comme dans Exchange 2010:
- $ASA = Get-Credential -Credential "WFLAB\EXCHANGE-MAIN$"
- Set-ClientAccessServer -Identity SV-E15-1 -AlternateServiceAccountCredential $ASA
Répétez l'opération pour chaque serveur CAS partageant le même pool. Rappelez vous que l'Alternate Service Account ne peut être manipulé à distance (même en utilisant un Connect-ExchangeServer -Fqdn . Le plus simple est donc de se connecter en RDP à chaque serveur ou d'utiliser le script RollAlternateServiceAccountPassword.ps1 (qui - fait rigolo - affiche fièrement ne pas avoir été testé avec cette version d'Exchange :)).
Par exemple:
- .\RollAlternateServiceAccountPassword.ps1 -CopyFrom SV-E15-1 -ToSpecificServers SV-E15-2
Reconfiguration du mode d'authentification
Comme nous l'avons vu précédemment, Outlook Anywhere est donc configuré par défaut en Ntlm. Nous devons donc reconfigurer chaque serveur CAS afin de bascule l'authentification en mode Negotiate afin de faire du Kerberos (avec fail-back en Ntlm potentiel). Nous le verrons plus tard, mais il existe d'autres modes d'authentification, comme le Nego2 mais qui n'est semble-t-il pas supporté sur Windows XP, même avec Outlook 2010. A terme, l'idée serait peut-être même de forcer le Kerberos, ce qui est totalement possible avec Exchange 2013 (à tester !).
Nous utiliserons la Cmdlet Set-OutlookAnywhere afin de reconfigurer l'authentification, l'Exchange Administration Center ne permettant que de modifier la méthode d'authentification externe (NDLR: Microsoft a encore pas mal de boulot pour finaliser l'EAC, trop léger à mon goût...).
- Get-OutlookAnywhere -Server SV-E15-1 -ADPropertiesOnly | Set-OutlookAnywhere -InternalClientAuthenticationMethod Negotiate -IISAuthenticationMethods Negotiate,Ntlm
- Get-OutlookAnywhere -Server SV-E15-2 -ADPropertiesOnly | Set-OutlookAnywhere -InternalClientAuthenticationMethod Negotiate -IISAuthenticationMethods Negotiate,Ntlm
Encore une fois, vous devrez surveiller l'eventlog Application afin de vérifier que la configuration Outlook Anywhere a bien été prise en compte et la configuration IIS alignée en conséquence (event ID 3025). Rappel: L'attente peut durer jusqu'à 15 minutes.
Vous pouvez aussi vérifier les Authentication Providers dans IIS sur l'application /Rpc et assurez-vous d'avoir (dans cet ordre: Negotiate et NTLM). Cette partie est normalement gérée par Exchange mais il semblerait que la synchronisation AD - Exchange - IIS ne fonctionne pas toujours très bien lors de modifications successives trop fréquentes... MEF !
Dès lors, vous pouvez redémarrer votre client Outlook. Celui-ci va se reconnecter en Ntlm puisque telle est la configuration actuellement en place coté client. L'avantage du mode Negotiate est donc de supporter une transition vers le Kerberos s'il est disponible, sans pour autant perturber le fonctionnement des clients déjà configurés.
Si vous ne voulez pas attendre une reconfiguration automatique de votre client (ce qui peut prendre jusqu'à 2 heures), effectuez une réparation de votre service Exchange, ce qui a pour effet de refaire appel au Web Service Autodiscover.
On voit bien d'ailleurs lorsque l'on fait un Test d'AutoConfiguration que l'on est configuré sur un autre mode d'authentification (ici, Nego2).
Et voici donc le résultat en se reconnectant et après une purge des tickets Kerberos (klist purge):
Promotion en Kerberos complet
Maintenant que nous avons vu comment configurer le mode Negotiate (le plus compatible), nous pouvons pousser l'exercice plus loin et forcer l'utilisation de Kerberos. N'appliquez pas cette procédure sur un environnement de production sans l'avoir testée dans un environnement de pré-production fonctionnellement similaire à la production.
La reconfiguration se fait de la même manière que précédemment, en utilisant la Cmdlet Set-OutlookAnywhere:
- Get-OutlookAnywhere -Server SV-E15-1 -ADPropertiesOnly | Set-OutlookAnywhere -InternalClientAuthenticationMethod NegoEx -IISAuthenticationMethods Kerberos
- Get-OutlookAnywhere -Server SV-E15-2 -ADPropertiesOnly | Set-OutlookAnywhere -InternalClientAuthenticationMethod NegoEx -IISAuthenticationMethods Kerberos
Note: vous pouvez utiliser "NegoEx" ou "Negotiate" pour l'InternalClientAuthenticationMethod.
D'un point de vue client, rien de change, on reste en Negotiate mais ce qui change est surtout côté serveur et des Authentication Providers, où l'on passe de "Negotiate" et "NTLM" à "Negotiate:Kerberos".
Notez que forcer le Kerberos sur cette partie d'IIS va impacter vos connexions externe, puisque un client hors Active Directory ne pourra utiliser Kerberos. Cela dépendra donc de la capacité de fournir une authentification externe en Negotiate et d'effectuer ou non de la délégation Kerberos via le Reverse Proxy, type ISA/TMG.