Dans la Partie 1, j’ai raconté comment mon monde Linux/appliances était passé d’une CA OpenSSL gérée à la main à une step-ca en intermédiaire, avec des certificats courts renouvelés automatiquement. Ce deuxième volet couvre l’autre moitié de mon infra perso : le monde Microsoft, avec sa propre autorité de certification AD CS, et le chantier qui m’a occupé ces dernièrs jours — sécuriser l’authentification RDP sur deux domaines Active Directory via des certificats machine émis et renouvelés automatiquement.
Deux PKI dans une même infra, ça peut sembler être une redondance à corriger. Ce n’est pas ce que j’ai fait, et j’explique pourquoi.
Pourquoi deux PKI plutôt qu’une seule
Quand j’ai commencé le chantier step-ca décrit dans la Partie 1, une autorité de certification Microsoft (AD CS, Enterprise Root, installée sur un contrôleur de domaine additionnel de mon domaine racine de forêt) tournait déjà depuis longtemps. Elle n’avait rien à voir avec le besoin qui a déclenché la Partie 1 : elle existe uniquement parce qu’Active Directory s’appuie dessus nativement — distribution du certificat racine comme approuvé sur tous les postes du domaine via GPO, émission de certificats machine pour LDAPS, et — le sujet de cet article — authentification RDP.
La question s’est posée en toute logique une fois step-ca opérationnelle : est-ce que je fusionne les deux mondes sous une seule autorité ? J’ai tranché pour non, et je documente ce choix ici parce que c’est le genre de décision qu’on regrette si elle n’est pas écrite noir sur blanc quelque part.
Trois raisons ont pesé :
- Le fonctionnement natif d’AD CS avec Active Directory n’a pas d’équivalent simple côté step-ca. L’autoenrollment de machine, la distribution automatique du certificat racine via GPO, l’intégration avec les templates de certificats et leurs ACL granulaires sont des mécanismes profondément intégrés à AD. Les reproduire avec step-ca aurait demandé de l’outillage sur mesure, pour un bénéfice pas franchement supérieur à celui de laisser AD CS faire ce qu’il sait déjà faire.
- Les besoins ne se recouvrent pas vraiment. Step-ca sert des services Linux et des appliances avec des cycles de vie courts (certificats à 90 jours, renouvellement automatisé par playbook). AD CS sert des besoins internes à Active Directory avec des cycles de vie longs et une logique de confiance différente (la confiance vient de l’appartenance au domaine, pas d’un enrôlement applicatif).
- Séparer les deux limite le rayon d’explosion. Si l’une des deux autorités est compromise ou mal configurée, l’autre continue de fonctionner indépendamment. Une fusion aurait créé un point de défaillance unique pour deux écosystèmes qui n’ont, en pratique, presque aucune raison de se faire confiance mutuellement.
Le compromis assumé : deux PKI à maintenir, deux logiques de renouvellement à connaître, deux endroits où vérifier “est-ce que ce certificat est encore valide”. C’est un coût réel, mais je préfère payer ce coût plutôt que de complexifier une intégration AD qui fonctionne bien telle quelle.
Le chantier : authentification RDP par certificat sur deux domaines
Mon infra AD n’est pas un domaine unique : c’est une forêt avec un domaine racine et un domaine enfant. Les deux hébergent des postes de travail et des serveurs sur lesquels je me connecte régulièrement en RDP. Jusqu’ici, ces connexions s’appuyaient sur le certificat auto-signé que Windows génère par défaut pour le service Bureau à distance — fonctionnel, mais générateur d’un avertissement de confiance à chaque connexion, et sans lien avec mon autorité de certification interne pourtant déjà en place et déjà approuvée par tous les postes du domaine.
L’objectif du chantier : que chaque poste de travail, serveur et contrôleur de domaine des deux domaines présente automatiquement un certificat d’authentification RDP émis par mon AD CS interne, renouvelé sans intervention manuelle, sur toute la durée de vie de la machine.
Le template de certificat
Le certificat recherché par le service Bureau à distance n’est pas un certificat “Authentification de serveur” générique (OID 1.3.6.1.5.5.7.3.1) : Windows privilégie un usage étendu (EKU) spécifique, Authentification Bureau à distance, dont l’OID est 1.3.6.1.4.1.311.54.1.2. Ce n’est pas un template fourni par défaut dans AD CS — il faut le créer.
J’ai dupliqué un template de type Ordinateur existant (jamais un template Utilisateur, voir plus loin le piège que ça m’a coûté sur un autre chantier), puis configuré :
- l’EKU Authentification Bureau à distance (
1.3.6.1.4.1.311.54.1.2) comme stratégie d’application ; - le nom du sujet basé sur le nom DNS de la machine (cohérent avec ce que le service Bureau à distance va chercher à faire correspondre) ;
- un fournisseur de stockage de clés (KSP) moderne, clé RSA 3072 bits, SHA-256 ;
- surtout : le nom d’affichage du template identique au nom du template — un détail qui a l’air anodin et qui ne l’est pas du tout (voir plus bas).
L’EKU Authentification Bureau à distance n’existe pas nativement dans la liste des stratégies d’application proposées par la console : il faut la créer à la main, en donnant son nom et son OID exact.
Comme mon AD est une forêt à deux domaines, j’ai dupliqué ce template une fois par domaine plutôt que de tenter de le faire fonctionner en cross-domaine — cohérent avec ma préférence générale d’éviter les dépendances cross-domaine quand une solution native et cloisonnée par domaine existe. Les templates de certificats sont stockés dans la partition Configuration de la forêt (donc visibles par tous les domaines), mais rien n’empêche d’en dupliquer un par domaine pour cloisonner les ACL — ce que confirme un coup d’œil dans ADSI Edit : chaque domaine a bien son propre template.
Côté ACL du template, seuls les groupes d’ordinateurs concernés (postes de travail et serveurs des deux domaines) ont reçu le droit Inscription. Pas Autoenroll — et c’est le point le plus important de cet article.
Une fois le template configuré, il reste une étape facile à oublier : l’activer explicitement sur l’autorité de certification (Modèles de certificat à délivrer dans certsrv.msc) avant qu’il n’apparaisse comme disponible à l’inscription.
Le service SessionEnv, pas l’autoenrollment générique
C’est là que ça devient contre-intuitif si on vient du réflexe “template de certificat = autoenrollment classique”. L’inscription du certificat d’authentification RDP n’est pas pilotée par le mécanisme générique d’autoenrollment de machine (Certificate Services Client - Auto-Enrollment, celui qu’on active habituellement dans Configuration ordinateur → Stratégies → Paramètres Windows → Paramètres de sécurité → Stratégies de clé publique). Elle est pilotée par un mécanisme dédié, propre au service SessionEnv (le service “Configuration Bureau à distance”), avec son propre cycle d’inscription et de renouvellement.
Pour bien marquer la distinction, voici à quoi ressemble le GPO d’autoenrollment générique — celui qu’on laisse volontairement de côté pour ce template :
Le GPO à configurer se trouve dans :
Configuration ordinateur → Stratégies → Modèles d'administration →
Composants Windows → Services Bureau à distance →
Hôte de la session Bureau à distance → Sécurité →
Modèle de certificat d'authentification serveur
On y renseigne le nom du template (qui doit donc être identique au nom d’affichage — d’où l’exigence plus haut). Une fois ce GPO appliqué et le service SessionEnv redémarré, celui-ci consulte périodiquement le magasin de certificats de l’ordinateur, recherche un certificat valide portant l’EKU attendu et émis depuis le template désigné ; s’il n’en trouve pas, il déclenche lui-même une demande d’inscription — sans passer par le pipeline d’autoenrollment générique.
Documentation à l’appui, plusieurs sources indépendantes convergent sur un point que je n’avais pas anticipé au départ : il ne faut pas activer l’autoenrollment générique sur ce template. La raison concrète, documentée par Microsoft et par des consultants PKI spécialisés : le cycle d’autoenrollment générique archive l’ancien certificat au moment du renouvellement, ce que SessionEnv ne gère pas de la même façon — le service perd la référence au certificat qu’il utilisait, et le service Bureau à distance peut se retrouver incapable de présenter un certificat valide, avec à la clé des échecs de connexion TLS. Le comportement attendu et documenté est : droit Inscription simple sur le template, laisser le GPO ci-dessus et le service SessionEnv gérer tout le cycle de vie — première émission comme renouvellement.
Les deux pièges qui m’ont fait perdre du temps
Nom d’affichage ≠ nom du template
Le premier symptôme a été déroutant : un certificat parfaitement valide, correctement émis, réémis à chaque redémarrage du service SessionEnv — pas à l’approche de son expiration, à chaque redémarrage. Un comportement qui, sur un poste rebooté régulièrement, se traduisait par une accumulation de certificats quasi identiques dans le magasin machine.
La cause : le GPO référence le template par son nom (Template name, la chaîne technique sans espaces), mais dans certaines conditions la correspondance utilisée en interne s’appuie aussi sur le nom d’affichage (Template display name, celui visible dans la console). Si les deux ne sont pas strictement identiques, SessionEnv ne reconnaît pas de façon fiable le certificat existant comme correspondant au template attendu, et en redemande un nouveau à chaque redémarrage plutôt que de réutiliser celui déjà en place. Une fois le nom d’affichage aligné sur le nom technique du template, le comportement s’est stabilisé : un seul certificat, réutilisé jusqu’à échéance.
gpupdate /force ne suffit pas
Deuxième piège, plus simple mais tout aussi trompeur au moment du diagnostic : après avoir corrigé une valeur du GPO (nom du template, par exemple), un gpupdate /force seul ne provoque aucune réaction visible. Le nouveau paramètre atterrit bien dans le registre local (HKLM\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services), mais le service SessionEnv ne le relit pas à chaud : il faut redémarrer le service (Restart-Service SessionEnv) — pas nécessairement redémarrer toute la machine — pour qu’il prenne en compte le changement et réévalue le certificat en place. Une fois qu’on le sait, le cycle de test devient beaucoup plus rapide : modifier le GPO, gpupdate /force, redémarrer le service, vérifier.
Cycle de test et déploiement
Avant tout déploiement à l’échelle, j’ai validé le mécanisme sur un poste et un serveur pilotes, un par domaine :
- GPO appliqué sur une OU de test contenant les deux machines pilotes.
gpupdate /forcepuis redémarrage du service SessionEnv.- Vérification dans
certlm.msc(magasin Personnel de l’ordinateur) qu’un certificat correspondant au bon template et portant l’EKU Authentification Bureau à distance a bien été émis.
- Connexion RDP vers la machine pilote — vérification côté client que le certificat présenté est bien celui émis par mon AD CS interne (et non plus l’auto-signé), et qu’aucun avertissement de confiance n’apparaît puisque le certificat racine de l’AD CS est déjà distribué comme approuvé sur tous les postes du domaine. J’ai aussi testé en tapant l’adresse IP brute plutôt que le nom DNS : le certificat reste bien présenté (avec, logiquement, une alerte de nom puisque le certificat porte le nom DNS et non l’IP) — la preuve que c’est bien un certificat émis par mon AD CS interne, et pas un repli sur l’auto-signé.
- Test de repli : en cas d’échec d’inscription (simulé en coupant temporairement l’accès à l’autorité), le service continue de présenter l’ancien certificat encore valide plutôt que de basculer sur l’auto-signé — comportement attendu et confirmé.
J’ai gardé les GPO Serveurs et Postes de travail séparés pour le déploiement, ce qui permet de faire avancer les deux vagues indépendamment :
Une fois ce cycle validé sur les deux pilotes, le déploiement du GPO a été étendu progressivement : postes de travail des deux domaines, puis serveurs, puis contrôleurs de domaine en dernier (par prudence, bien que rien dans le mécanisme ne les distingue des autres machines). Chaque vague a été suivie d’un contrôle par sondage dans certlm.msc sur un échantillon de machines plutôt que sur l’ensemble du parc — suffisant pour repérer rapidement une anomalie de propagation GPO sans avoir à vérifier les ~vingt-cinq machines une par une.
Ce que je retiens
- Faire coexister deux PKI n’est pas un défaut à corriger quand les deux répondent à des besoins qui ne se recouvrent pas — la fusion aurait coûté plus cher en complexité qu’elle n’aurait rapporté.
- L’authentification RDP par certificat sur AD CS suit un mécanisme dédié (service SessionEnv, GPO spécifique) totalement distinct de l’autoenrollment générique — les mélanger casse le renouvellement plutôt que de le simplifier.
- Le nom d’affichage d’un template de certificat n’est pas cosmétique : une divergence avec le nom technique peut provoquer une réémission silencieuse à chaque redémarrage de service.
gpupdate /forcedéploie la stratégie, mais ne réveille pas forcément le service qui doit la consommer — un réflexe à corriger si le résultat attendu ne se produit pas.
Ce chantier RDP a eu un deuxième volet, plus inattendu : signer numériquement les fichiers .rdp eux-mêmes pour éviter l’avertissement “éditeur inconnu” introduit par un durcissement de sécurité Windows récent. C’est un sujet suffisamment différent (JEA, PowerShell Remoting, automatisation côté client) pour mériter son propre article — ce sera l’objet d’une Partie 3.
Sources et références
Documentation et mécanisme SessionEnv / GPO :
- Remote Desktop Services enrolling for TLS certificate from an Enterprise CA — description du service SessionEnv, du GPO “Server authentication certificate template” et de l’avertissement explicite contre l’autoenrollment générique sur ce template
- Configuring a certificate template for Remote Desktop (RDP) certificates — Uwe Gradenegger — configuration du template et recommandations de permissions
- Creating RDP Certificates — PKI Solutions — OID de l’EKU Authentification Bureau à distance et mise en garde sur l’autoenrollment
- Using Group Policy to configure RDP cert — NCSU — chemin exact du GPO côté Hôte de la session Bureau à distance
- Remote Desktop Session Host Configuration — Microsoft Learn (archive) — logique de sélection automatique du certificat et exigence Display Name = Template Name