Translate

samedi 17 juillet 2010

FIX: Forefront TMG 2010 et Windows Server 2008 R2 = Lenteur abominable et plantage au Boot

Dans mes pérégrinations nocturnes, me voilà que me prend l'envie migrer mon ISA 2006 SP1 vers Forefront TMG 2010 (SP1 aussi). Comme a mon habitude avec les dernières générations de produits Microsoft, je prépare ma VM en Windows Server 2008 R2 (image sysprep).

Ta-da, l'exporte toute ma configuration ISA 2006 SP1 ainsi que la dizaine de certificats puis je l'éteins, pensant l'envoyer sans peine à la retraite !

Et bien, ce fut douloureux ! Outre l'installation de Forefront TMG 2010 qui a échoué m'expliquant gentillemment qu'ADAM n'a pu être installé alors qu'il venait de le faire 2 minutes avant :P), mon plus gros problème se retrouva dans l'incapacité de mon serveur TMG à rebooter sans pêter un câble.

Pour le 1er problème (ADAM), rien de bien dramatique. Il suffit de préparer les pré-requis (composants Windows installés par le Wizard d'installation TMG) puis de redémarrer le serveur. Après redémarrage, TMG s'installe sans soucis.

Le 2nd problème est plus délicat. Le serveur met plus de 16 minutes à démarrer (à atteindre donc le "Press Ctrl+Alt+Suppr to logon" :)) et encore, il démarre mais les 3/4 des services Forefront TMG sont plantés, prétextant qu'ils n'ont pu démarrer dans les délais impartis (non, sans blague... :)).

Bref, après moultes recherches, je me suis rendu compte que Ô Miracle, mon cas n'étais pas isolé. La plupart des gens ayant tenté divers installations de Forefront TMG ont recontré des problèmes similaires avec Windows Server 2008 R2 seulement. De plus, la plupart d'entre eux utilisent TMG + ForeFront for Exchange + Exchange 2010 Edge Transport sur la même machine, ce qui est supporté mais littéralement (dans mon petit esprit puriste) du suicide.

Bien que mon cas ne soit pas aussi dramatique que le leur, j'ai tenté diverses solutions en me basant sur les périgrinations d'autres malheureux qui, comme moi, pensaient que TMG 2010 n'était plus en BETA (cf blog ici: http://projectdream.org/wordpress/2010/04/27/tmg-2010-seems-to-be-still-in-beta/)

La solution qui a fonctionné dans mon lab consiste à modifier les dépendances sur les services HTTP (driver système) et ISACTRL (Forefront TM Control Service), ainsi que de passer ce dernier en "Automatic (Delayed)".

Une fois ces modifications effectuées, le démarrage du serveur montre en main (jusqu'à la mire de connexion) est inférieur à 3 minutes mais surtout tous les services Forefront TMG ont pu démarrer (ce qui n'est pas du luxe!!!).

Voici donc un petit script pour configurer les services:

fixTMG.cmd
@echo off

sc config HTTP depend= CRYPTSVC
sc config isactrl depend= RasMan/SSTPSVC/FwEng/ISASTG/bfe/mpssvc/HTTP
sc config isactrl start= delayed-auto

Le plus drôle (ou pas...) dans l'histoire est que Forefront TMG 2010 en est déjà à son Service Pack 1. Malgré cela, et malgré une interface correcte, le produit n'a toujours pas l'air fini.

Aller, histoire de rigoler, admirez la typo lorsque vous effectuer un Click-Droit sur la racine de la console puis "Finalize Enterprise".

En plus de ne servir à rien (?) si ce n'est faire "OK" (on aime le risque :)) - personne dans l'équipe de test/beta/RTM n'a remarqué cette faute de frappe grotesque... Honte à vous messieurs/dames de la DevTeam Forefront TMG !!!

Vive ISA 2006 SP1 !!!!! (et ses hotfixes salvateurs)
(et malgré ses défauts liés à son architecture vieillissante :P)

Je vais tout de même conserver TMG, histoire de 1) ne pas avoir galèré pour rien et 2) afin de voir ce qu'il a dans le ventre.

jeudi 15 juillet 2010

TUTORIEL: Exchange 2010 SP1 (Beta) - Activer Keberos pour un pool de serveurs CAS (Client Access Array)

Si vous avez implémenté Exchange Server 2010 en production avec un pool de serveurs d'Accès Client (CAS) mis en haute-disponibilité derrière un mécanisme de répartition de charge (HLB ou NLB), vous avez peut-être remarqué que l'accès à votre pool de CAS au travers du MAPI/RPC ou aux Web Services ne s'effectuait pas en Kerberos (pour observer cela, il suffit d'utiliser KerbTray, petit outil disponible dans le Resource Kit Windows Server 2003).

En effet, lorsque vous mettez des serveurs CAS en tolérance, vous créez un Client Access Arrary (CASArray). Ce CASArray devient le point de connexion de vos clients, et un nom d'hôte complet (FQDN) associé. Lorsque Outlook démarre, il ne se connecte donc pas sur le FQDN d'un CAS mais du CASArray (par exemple: CASArray.domaine.local), ce qui a pour effet de tenter de récupérer un jeton Kerberos pour les services suivants:
  • exchangeMDB/CASArray.domaine.local
  • exchangeRFR/CASArray.domaine.local
  • exchangeAB/CASArray.domaine.local
La négociation Kerberos ne fonctionne donc pas et Outlook se rabat donc sur le protocole NTLM, ce qui n'a pas d'effet négatif dans la grande majorité des cas, mais peut causer des ralentissements d'authentification en environnement multi-domaines, en particulier dans de grandes arborescences AD. Cela permet aussi une authentification plus efficace dans le cadre d'une relation bidirectionnelle de forêts s'exécutant en mode fonctionnel 2003 natif ou ultérieur (cas typique d'une Forêt de Ressources).

En mode 'Mono-Forêt/Multi-Domaines', une technique pour palier à l'inefficacité du NTLM est de créer des 'Shortcust Trusts' entre le(s) domaine(s) où se situent les serveurs Exchange et celui(ceux) où se situent les utilisateurs.

Mais le mieux et le plus performant (et le plus sexy) reste l'activation du Kerberos sur le Client Access Array :)~

ÉTAPE 1: Créer un compte d'abstraction Kerberos

Méthode 1:

Il suffit de créer un compte utilisateur activé et n'ayant aucun privilège. Cependant il est plus que conseillé de définir un mot de passe très complexe (ex: de 15 caractères ou +), voire même de restreindre l'ouverture de session sur les serveurs CAS seulement (non testé). Le plus simple à gérer est de définir ce mot de passe comme n'expirant jamais.

Pour l'exemple, ce compte s'appelle 'svcCASArray' dans mon lab, ce qui donne comme nom complet 'CORP\svcCASArrary' ('CORP' étant le nom Netbios de mon domaine).

Méthode 2:

L'alternative est d'utiliser un compte d'ordinateur créé à la main dans Active Directory. Il s'agit en fait de la méthode recommandée mais requiert un peu plus de travail pour sa mise en oeuvre et sa maintenance.

Par exemple, votre CAS Array a normalement un non défini, vous pouvez utilisez celui-ci, ou simplement la première partie de son FQDN ou son nom d'objet (pour l'exemple, le mien s'appelle 'MAPI-MAIN'). Le principe est similaire au principe d'avoir un compte d'ordinateur créé pour un serveur virtuel d'un cluster (tel que votre DAG par exemple).

Cela donnerait dans mon lab:

  • Création d'un objet 'Computer' dans l'Active Directory (ex: création de l'ordinateur 'MAPI-MAIN')
  • Définition d'un mot de passe pour l'objet 'CORP\MAPI-MAIN$'
  • Changement périodique du mot de passe pour l'objet 'CORP\MAPI-MAIN$'
Pour la configuration, le compte a utiliser ne sera donc plus 'CORP\svcCASArrary' mais 'CORP\MAPI-MAIN$'. Le hic dans ce mode est qu'il est préférable de changer régulièrement le mot de passe du compte d'ordinateur. A chaque changement, il faudra mettre à jour les 'credentials' mémorisés sur chaque CAS. Cela requiert 'us peu de scripting...' :)


Le gros avantage cependant est la sécurité. En effet, même si le mot de passe du compte d'ordinateur est 'piraté', il ne sera pas possible d'ouvrir une session interactive, et serait dans l'absolu moins facile à exploiter.

ÉTAPE 2: Attribuer les Service Principal Names (SPN) au compte de service pour le MAPI/RPC

Il s'agit ici d'associer au compte de service (ou compte d'ordinateur) les identifiants de service du CASArray.
Cela s'effectue sans peine avec la commande SetSPN.exe (disponible dans l'OS depuis Windows Server 2008):
  • setspn.exe -F -S "exchangeMDB/CASArray.domaine.local" "CORP\svcCASArray" (ou "CORP\MAPI-MAIN$")
  • setspn.exe -F -S "exchangeRFR/CASArray.domaine.local" "CORP\svcCASArray" (ou "CORP\MAPI-MAIN$")
  • setspn.exe -F -S "exchangeAB/CASArray.domaine.local" "CORP\svcCASArray" (ou "CORP\MAPI-MAIN$")
Bien sûr, il faut remplacer 'CASArray.domaine.local' par le FQDN de votre Client Access Array.

Notes:
  • SetSPN.exe -S permet d'ajouter un Service Principal Name (SPN) en vérifiant préalablement les doublons (avec le switch -F cherche les doubloins dans toute la forêt). Important car si un doublon existe, Kerberos échouera purement et simplement.
  • SetSPN.exe -C permet de vérfier si le SPN est déjà défini sur un objet 'User' ou 'Computer'. Avec l'option -F cela permet de rechercher dans toute la forêt et avec -P dans un ou plusieurs domaines (le switch -P peut être specifié plusieurs fois).
ÉTAPE 3: Attribuer les Service Principal Names (SPN) au compte de service pour les WebServices

L'idée est la même que ci-dessus, cependant ces SPNs seront de la forme "HTTP/WebService.domaine.local", où 'WebService' pourra être le même, ou différent pour chaque service Web. Dans un premier temps, ajoutez les noms d'hôte correspondant aux "Internal URL" de vos répertoires virtuels Exchange (Get-XXXXXVirtualDirectory). Il est inutile de tenter d'ajouter deux fois le même FQDN, donc si comme dans ma config vous n'avez qu'un FQDN pour tous les services Web, cela donnera quelque chose comme:
  • setspn.exe -F -S "HTTP/WebService.domaine.local" "CORP\svcCASArray" (ou "CORP\MAPI-MAIN$")
Note: il est tout à fait possible d'utiliser le même FQDN pour le MAPI/RPC et les Services Web.

ÉTAPE 4: Configurer le compte de service

Toute l'astuce est là. Il suffit de récupérer un objet de type 'PSCredential' en PowerShell et de l'assigner aux serveurs CAS participant au pool. Les commandes suivantes doivent être exécutées sur chaque serveur CAS, localement (NDLR: je n'ai pas essayé en PS Remoting, j'ai fait 'autrement' pour l'automatisation :)).

$cred = Get-Credential "CORP\svcCASArray" ==> vous serez invité à entrer le mot de passe du compte de service

Puis ensuite pour l'assigner:
Set-ClientAccessServer -Identity ServeurCAS -AlternateServiceAccountCredential $cred

Patientez une trentaines de secondes, puis vérifiez que la configuration ait été prise en compte avec:
Get-ClientAccessServer -Identity ServeurCAS -IncludeAlternateServiceAccountCredentialStatus et d'observer la propriété 'AlternateServiceAccountConfiguration'.
Petite astuce: Vous pouvez aussi utiliser le switch -IncludeAlternateServiceAccountCredentialPassword afin de récupérer aussi l'objet PSCredentials du compte d'abstraction. Ensuite, avec un peu d'astuce, il est possible de 'copier' ce compte avec son mot de passe sur d'autres serveurs CAS.

Enfin, effectuez un IISReset afin d'être sûr que les Web Applications soient complètement recyclées. Enfin, redémarrez les services suivants à l'aide de la cmdlet Restart-Service:
  • MSExchangeAB
  • MSExchangeRPC
ÉTAPE 5: Tester l'authentification Kerberos

Depuis un poste 'de base' avec KerbTray, purgez le tickets en cache. Puis lancez Outlook. Après le lancement d'Outlook, la première visualisation avec KerbTray donne les tickets exchangeMDB, exchangeRFR et exchangeAB récupérés et en cache.

Attendez quelques minutes ou effectuez toute opération faisant appel aux Web Services (tel qu'un Ctrl+Click droit sur l'icône Outlook dans le SysTray ==> Test E-mail Autoconfiguration). Le second visualisation montre qu'un ticket a été ajouté pour le(s) service(s) HTTP/WebService.domaine.local.
Vous pouvez aussi utiliser depuis un serveur Exchange (ou autre ordinateur ayant les outils d'administration installé) en Exchange Management Shell la commande Test-OutlookConnectivity:

$cred = Get-Credential 'DOMAIN\username'
Test-OutlookConnectivity -Identity MailboxIdentity -MailboxCredential $cred

Puis de vérifier avec KerbTray ou KList que le ticket existe.

Si cela ne fonctionne pas, vérifiez les points suivants:
  • Réplication AD (les SPNs sur le compte de service doivent avoir été répliqués)
  • Attribut 'servicePrincipalName' sur le compte d'abstraction Kerberos (ex: CORP\svcCASArrary)
  • Vérifiez qu'il n'existe aucun doublon de SPN dans l'AD (utilisez SetSPN.exe -F -Q Service/FQDN)
  • Assurez vous aussi que - pour les Web Services - le(s) FQDN(s) soient présents dans la zone "Local Intranet" dans les paramètres de configuration de sécurité dans Internet Explorer
CONFIGURATION 'DE MASSE'

L'activation du Kerberos peut-être fastidieuse, je vous laisse réfléchir au(x) moyen(s) d'effectuer en masse la configuration des serveurs CAS d'un même pool. Pour ma part, c'est déjà fait - j'ai utilisé une technique permettant de mettre en cache les credentials du compte de service afin de le rendre disponible sur tous mes serveurs d'un même CAS Arrary. La seule exception est lors de la 1ere configuration où je suis bien évidemment obligé de spécifier le mot de passe.

Au passage, si cela ne fonctionne pas et que vous voulez revenir en NTLM, utiliser la commande Set-ClientAccessServer -Identity ServeurCAS -RemoveAlternateServiceAccountCredentials puis supprimez le compte de service, ou moins drastiquement les SPNs qui y étaient associés (via SetSPN.exe ou en 'nettoyant' l'attribut servicePrincipalName du compte utilisateur).

POUR FINIR

Cette procédure n'est pas officiellement documentée par Microsoft et la rumeur dit que l'activation du Kerberos avec Exchange Server 2010 RTM ne serait pas supportée, mais le sera pleinement (ainsi que documentée) avec le SP1. Après vérification, la possibilité de configurer le compte d'abstraction a été implémentée dans l'Update Rollup 2 d'Exchange Server 2010 RTM mais ne sera pleinement supportée seulement dans le SP1. Elle ne sera d'ailleurs pleinement documentée (dans le principe et son implémentation) qu'au moment du SP1.

En parlant du SP1 justement, il apportera aussi de nouvelles possibilité avec l'authentification Kerberos puisqu'il supportera la configuration des mécanismes d'Extended Protection documentés ici: http://www.microsoft.com/technet/security/advisory/973811.mspx et là http://www.iis.net/ConfigReference/system.webServer/security/authentication/windowsAuthentication mais aussi ici:
http://support.microsoft.com/kb/973917

Ce mode permet entre autres de traverser des Proxy plus facilement, et globalement de durcir la securité lors de l'accès aux services en se protégeant un maximum des attaques du type "man in the middle" (ex: spoofing DNS, usurpation d'identité).

Note: l'Extended Protection est native dans Windows Server 2008 R2/Windows 7 mais requiert l'installation d'un correctif pour Windows Server 2008/Windows Vista. A l'heure actuelle, l'installation d'Exchange Server 2010 SP1 ne vérifie pas la présence de ce correctif puisqu'il n'est utile que pour activer ce mode (non obligatoire).

INFO: Exchange Server 2010 SP1 - Mais où sont passés les paramètres des fichiers 'config' ?

Dans Exchange Server 2010 RTM, il était possible de configurer la plupart des services Exchange au travers des fichiers '.config' situés au même endroit que l'exécutable. C'est une grande tradition .NET car facile à implémenter et à utiliser.

Cependant, depuis Exchange Server 2010 SP1 (Beta) un certain nombre de paramètres ont été déplacés à d'autres endroits. Nous l'avons vu précédemment, la configuration de l'intégration Outlook Web App et OCS a été sortie du fichier Web.config (qui pour le coup a été vampirisé complètement :)) au bénéfice de la configuration via la CmdLet Set-OWAVirtualDirectory.

Pour d'autres, cela est moins simple à trouver, ou somme toute plus inattendu.

Par exemple, afin d'utiliser mon "HLB fait maison" dans mon lab, j'ai du configurer l'accès RPC et l'accès à l'annuaire à l'aide de ports statiques.

Si la configuration du port pour l'accès RPC n'a pas changé (valeur dans le registre), la configuration du port TCP pour l'annuaire a été déplacé... dans la base de registre (à l'ancienne quoi =°). Un petit coup de ProcMon m'a permis de vite retrouver où...

HKLM:\SYSTEM\CurrentControlSet\Services\MSExchangeAB\Parameters
  • NspiHttpPort et RfrHttpPort ==> utilisés pour le RPC/HTTP et inutile de les changer
  • RpcTcpPort ==> ports du carnet d'adresses
Ces valeurs sont des REG_SZ (et oui, je m'attendait à des REG_DWORD) - en tout cas dans la Beta d'Exchange Server 2010 SP1. J'ose espérer que cela pourrait changer, non pas parce que ça m'amuse, mais utiliser un chaîne de caractère pour y stocker un n° de port TCP me semble juste une hérésie... :)

N'oubliez pas que lorsque vous mettrez à jour vos serveurs Exchange 2010 en SP1, il y a de forte chances que vous y perdiez quelques 'tweaks' au passage. Assurez-vous d'avoir testé au préalable toute mise à jour en condition réelle dans un lab ou une vraie préproduction (avec les mêmes 'tweaks'). Cela est d'autant plus vrai si vous utilisez Blackberry Enterprise Server et que vous avez configuré le MaxUserPerSession tel que recommandé par Research-In-Motion. Je n'ai pas encore trouvé (pas trop cherché) où celui-là a été déplacé, mais je sais qu'il est quelque part dans le Throttling Framework (donc plutôt côté des Throttling Policies :)).

Voici d'autres paramètres du registre en vrac, certains sont hérités des versions antérieures d'Exchange, d'autres méritent investigation:

MSExchangeIS\ParametersSystem

  • Rpc Compression Minimum Size
  • Rpc Compression Enabled
  • Rpc Packing Enabled
  • Rpc Context Pool Size
  • RPC Requests Threshold
  • Async Rpc Notify Enabled
  • OAB Bandwidth Threshold (kBps)
  • Log on Ptag set
  • Allow Order By Delivery Time On Sync
  • Force Order By Delivery Time On Sync
  • Force Batch Mode
  • Maximum Messages To Preread
  • Reread Logon Quotas Interval
  • Suppress Event Logs
  • Flush Call Traces
  • Flush Call Traces Periodically
  • ClientStatsIntervalMinutes
  • ClientStatsMinimumRpcAttempt
  • ClientStatsSuccessPercentageWarning
  • ClientStatsLatencySeconds
  • ClientStatsMaxWarning
  • ClientStatsMaxWarningIntervalSeconds
  • ClientMonitoringcMinAgeLimitMinutes
  • ClientMonitoringMaxLowBandwidth
  • ClientMonitoringEnableFlags
  • ClientMonitoringReportLevel
  • RemoteITP
  • Synch Mailbox/Check OOF Interval
  • Max FXGetBuffer Users
  • FXGetBuffer BackOff Constant
  • FXGetBuffer Retry Count
MSExchangeIS\ParametersSystem\Private-<GUID>
  • Maximum RPC Threads Per MDB
  • Mailbox LCID

MSExchangeRPC\ParametersSystem
  • ADUserDataCacheTimeout
  • ExecutionFlags
  • LoEveryConfigurationUpdate
  • TCP/IP Port
  • IdleConnectionCheckPeriod
  • ShareConnections
  • EnableExMonTestMode
  • Maximum Polling Frequency
  • RPC Retry Count
  • RPC Retry Delay
  • EnableWebServicesEndpoint
  • Max FXGetBuffer Users
  • FXGetBuffer BackOff Constant
  • FXGetBuffer Retry Count