Corriger les erreurs de certificat RDS/RDP (SAN, RD Gateway, Connection Broker, Session Host) – Guide complet

Votre ferme RDS affiche des alertes de sécurité liées aux certificats ? Ce guide pas‑à‑pas explique pourquoi le message apparaît (SAN, redirections, auto‑signés), comment affecter et imposer le bon certificat à chaque rôle (Gateway, Web, Broker, Session Host) et comment valider la correction côté client et serveur.

Sommaire

Vue d’ensemble de la situation

Dans une ferme Remote Desktop Services (RDS) répartie sur trois serveurs, les clients reçoivent systématiquement un avertissement :

  • Un certificat auto‑signé est présenté, ou bien le nom déclaré par le certificat ne correspond pas au FQDN réellement utilisé.
  • Pourtant, le certificat importé contient plusieurs SAN : server1.contoso.com, *.contoso.com, *.subdomain.contoso.com, etc.
  • Malgré l’import du .pfx via Server Manager et dans le magasin Ordinateur local \ Personnel, les hôtes RDS continuent à présenter un certificat non valide.

La cause la plus fréquente : le bon certificat existe quelque part sur les serveurs, mais il n’est pas lié au bon rôle, pas séléctionné par RDP‑Tcp, ou bien le nom réellement composé par le client ne figure pas dans les SAN. À cela s’ajoutent des certificats auto‑signés résiduels que Windows choisit parfois “par défaut”.

Ce qui se passe réellement pendant une connexion RDP

Comprendre le cheminement aide à corriger rapidement :

  1. Un utilisateur lance mstsc vers farm.subdomain.contoso.com (ou clique un fichier .rdp).
  2. Le client contacte le RD Gateway (si configuré) en HTTPS :443 ; le nom appelé doit correspondre à un SAN du certificat Gateway.
  3. Le RD Connection Broker redirige alors la session vers un RD Session Host. Le client établit une seconde négociation TLS en RDP :3389 avec cet hôte et vérifie de nouveau le nom : s’il ne matche pas un SAN du certificat présenté par le Session Host, un avertissement s’affiche.

Conséquence : il ne suffit pas d’installer un PFX « quelque part ». Il faut lier le certificat à chaque rôle et forcer le Session Host à l’utiliser. Enfin, il faut que le FQDN que voit le client soit présent dans les SAN (ou couvert par un wildcard valide).

Plan de remédiation en 6 étapes (résumé opérationnel)

ÉtapeActionDétails pratiques
1. Affecter le certificat à chaque rôle RDSServer Manager → Remote Desktop Services → Overview → Deployment Properties → CertificatesImporter le même .pfx pour RD Connection Broker (Publishing + SSO), RD Web Access et RD Gateway, puis redémarrer les services concernés.
2. Forcer l’usage du certificat sur chaque Session Hosta) Importer le PFX dans Ordinateur\Personnel (avec clé privée) ;
b) Copier l’empreinte SHA‑1 (sans espaces, sans caractères invisibles) ;
c) Écrire l’empreinte dans RDP‑Tcp\SSLCertificateSHA1Hash ;
d) Redémarrer TermService (ou le serveur).
Empêche Windows de générer / présenter un auto‑signé.
3. Vérifier l’adéquation Nom ↔ CertificatLe FQDN réellement composé doit exister dans les SAN, ou être couvert par un wildcard.Ex. farm.subdomain.contoso.com doit correspondre à *.subdomain.contoso.com ou être listé explicitement.
4. Supprimer les auto‑signés résiduelscertlm.mscOrdinateur local \ Personnel et Remote Desktop → supprimer « RDP Self‑Signed … »Évite qu’un certificat interne soit choisi par erreur.
5. Propager automatiquement le certificatPowerShell RDS : Set‑RDCertificate ; GPO : Configuration ordinateur → Paramètres Windows → Paramètres de sécurité → Clés publiquesAssure la cohérence quand de nouveaux hôtes rejoignent la ferme.
6. Contrôles supplémentairesChaîne complète, EKU = Server Authentication, RSA ≥ 2048 / SHA‑256, clients RDP à jourCertains anciens clients gèrent mal les SAN multiples et les jokers.

Cartographie des rôles RDS et de leur certificat

RôlePort / protocoleOù est lié le certificat ?Noms attendus (SAN)
RD Gateway443 / TLS (HTTP.SYS)Assistant RDS (Deployment Properties) alimente la liaison HTTP.SYS. Vérifier avec netsh http show sslcert.Nom public d’accès (ex. rdgw.contoso.com)
RD Web Access443 / IISAssistant RDS ou Bindings IIS. Le même PFX peut être réutilisé.URL d’accès Web (ex. rdweb.contoso.com)
RD Connection Broker443 / service Broker (Publishing + SSO)Set‑RDCertificate -Role RDPublishing/RDRedirector cible le Broker.Nom d’équilibrage/HA (ex. rds.contoso.com)
RD Session Host3389 / TLS (RDP‑Tcp)Clé de registre SSLCertificateSHA1Hash (ou WMI) pour imposer le certificat à RDP‑Tcp.Nom vers lequel le client est redirigé (ex. rdsh01.contoso.com), ou un wildcard couvrant le niveau.

Étape 1 — Affecter le certificat aux rôles RDS via l’assistant (et vérifier)

Dans Server Manager → Remote Desktop Services → Overview → Deployment Properties → Certificates :

  1. Sélectionnez chaque rôle (RD Web Access, RD Gateway, RD Connection Broker – Publishing, RD Connection Broker – SSO).
  2. Choisissez « Select an existing certificate », importez le même .pfx (avec sa clé privée), entrez le mot de passe, cochez « Allow the certificate to be added to the certificate store ».
  3. Appliquez, puis redémarrez TS Gateway / IIS si demandé.

Équivalent PowerShell (utile pour l’automatisation et la répétabilité) :

Import-Module RemoteDesktop

# Paramètres

$PfxPath = 'C:\Secure\rds-unifie.pfx'
$PfxPwd  = Read-Host 'Mot de passe du PFX' -AsSecureString
$CB      = 'rdcb.contoso.com'  # FQDN du Broker (HA si applicable)

# RD Web Access

Set-RDCertificate -Role RDWebAccess -ImportPath $PfxPath -Password $PfxPwd -Force

# RD Gateway

Set-RDCertificate -Role RDGateway -ImportPath $PfxPath -Password $PfxPwd -Force

# RD Connection Broker (Publishing + Redirector)

Set-RDCertificate -Role RDPublishing -ConnectionBroker $CB -ImportPath $PfxPath -Password $PfxPwd -Force
Set-RDCertificate -Role RDRedirector -ConnectionBroker $CB -ImportPath $PfxPath -Password $PfxPwd -Force

# Vérification

Get-RDCertificate | Format-Table Role, Subject, Thumbprint, ExpirationDate 

Étape 2 — Imposer le certificat côté RD Session Host (éviter l’auto‑signé)

La liaison du certificat à RDP‑Tcp se fait au niveau de chaque hôte. Méthode recommandée (WMI) :

# 1) Récupérer l'empreinte du bon certificat (sans espaces)
$cert = Get-ChildItem Cert:\LocalMachine\My | Where-Object {
  $_.HasPrivateKey -and $_.FriendlyName -like '*RDS*'
} | Sort-Object NotAfter -Descending | Select-Object -First 1

$thumb = ($cert.Thumbprint).Replace(' ', '')

# 2) Appliquer à RDP-Tcp via WMI (évite les erreurs de type REG_BINARY)

$ts = Get-WmiObject -Namespace root\cimv2\TerminalServices -Class Win32_TSGeneralSetting -Filter "TerminalName='RDP-Tcp'"
$null = $ts.SetSSLCertificateSHA1Hash($thumb)

# 3) Redémarrer le service RDP (interrompt les connexions en cours)

Restart-Service TermService -Force 

Déploiement en masse sur tous les Session Hosts :

$Hosts = @('rdsh01.contoso.com','rdsh02.contoso.com','rdsh03.contoso.com')
Invoke-Command -ComputerName $Hosts -ScriptBlock {
  param($Thumb)
  $ts = Get-WmiObject -Namespace root\cimv2\TerminalServices -Class Win32_TSGeneralSetting -Filter "TerminalName='RDP-Tcp'"
  $null = $ts.SetSSLCertificateSHA1Hash($Thumb)
  Restart-Service TermService -Force
} -ArgumentList $thumb

Pièges courants : l’empreinte SHA‑1 copiée depuis la console contient parfois des caractères invisibles (LRM/RLM). Passez‑la dans $thumb.Replace(' ', '') et préférez la méthode WMI plutôt que la clé de registre manuelle SSLCertificateSHA1Hash pour éviter les erreurs binaires.

Étape 3 — Faire correspondre les noms (SAN) au FQDN réellement composé

  • Le client compare le nom demandé (ce qui est saisi, ou le full address:s: du .rdp) avec les SAN du certificat reçu.
  • Les wildcards ne couvrent qu’un niveau : *.contoso.com couvre host.contoso.com, mais pas farm.sub.contoso.com. Pour ce dernier, utiliser *.sub.contoso.com ou lister le FQDN exact.
  • En présence de Broker HA, le nom d’équilibrage (ex. rds.contoso.com) doit être dans les SAN, tout comme les FQDN vers lesquels le client est redirigé (ex. rdsh01.contoso.com), ou bien couverts par un wildcard approprié.

Exemple de SAN robuste :

rds.contoso.com
rdweb.contoso.com
rdgw.contoso.com
*.contoso.com
*.subdomain.contoso.com

Étape 4 — Éliminer les certificats auto‑signés résiduels

Retirez tous les « RDP Self‑Signed » des magasins Ordinateur\Personnel et Ordinateur\Remote Desktop ; sinon, RDP‑Tcp peut les privilégier.

# Supprimer les RDP Self-Signed dans les magasins pertinents
Get-ChildItem Cert:\LocalMachine\RemoteDesktop, Cert:\LocalMachine\My |
  Where-Object { $_.Issuer -eq $_.Subject -and $_.Subject -like '*RDP*' } |
  Remove-Item -Force

Vérifiez ensuite qu’il ne reste qu’un certificat « serveur » valide avec clé privée et l’empreinte attendue.

Étape 5 — Propager automatiquement (PowerShell & GPO)

Avec PowerShell (ferme existante et nouveaux hôtes)

Import-Module RemoteDesktop

# Variables

$PfxPath = '\files\PKI\rds-unifie.pfx'
$PfxPwd  = Read-Host 'Mot de passe du PFX' -AsSecureString
$CB      = 'rdcb.contoso.com'

# Appliquer aux rôles "contrôlés" par l'assistant

Set-RDCertificate -Role RDGateway     -ImportPath $PfxPath -Password $PfxPwd -Force
Set-RDCertificate -Role RDWebAccess   -ImportPath $PfxPath -Password $PfxPwd -Force
Set-RDCertificate -Role RDPublishing  -ConnectionBroker $CB -ImportPath $PfxPath -Password $PfxPwd -Force
Set-RDCertificate -Role RDRedirector  -ConnectionBroker $CB -ImportPath $PfxPath -Password $PfxPwd -Force

# Propager aux Session Hosts (liaison RDP-Tcp)

$thumb = ((Get-PfxCertificate $PfxPath).Thumbprint).Replace(' ','')
$RDSH  = (Get-RDServer -Role RDS-RD-SERVER).Server
Invoke-Command -ComputerName $RDSH -ScriptBlock {
param($Thumb)
$ts = Get-WmiObject -Namespace root\cimv2\TerminalServices -Class Win32_TSGeneralSetting -Filter "TerminalName='RDP-Tcp'"
$null = $ts.SetSSLCertificateSHA1Hash($Thumb)
Restart-Service TermService -Force
} -ArgumentList $thumb 

Avec GPO (PKI interne)

  • Activez l’auto‑inscription pour l’ordinateur : Configuration ordinateur → Stratégies → Paramètres Windows → Paramètres de sécurité → Stratégies de clés publiques → Client de services de certificats – Inscription automatique.
  • Distribuez la chaîne complète (racine + intermédiaire) dans Autorités de certification racines de confiance et Autorités de certification intermédiaires sur les clients et serveurs.
  • Option : script de démarrage GPO qui applique l’empreinte au RDP‑Tcp (méthode WMI ci‑dessus).

Étape 6 — Contrôles techniques indispensables

PropriétéPourquoiComment vérifier
Chaîne complète (serveur + intermédiaires + racine)Sans intermédiaire, certains clients “ne voient” pas la racine, d’où alerte.openssl s_client -connect rdgw.contoso.com:443 -showcerts ou certutil -verify
EKU = Server Authentication (OID 1.3.6.1.5.5.7.3.1)Un EKU inadapté peut faire rejeter le certificat par Schannel.Onglet « Détails » du certificat (ou Get-ChildItem Cert:\ -EKU)
Clé RSA ≥ 2048, signature SHA‑256Conformité moderne, élimine des avertissements sur anciens clients.openssl x509 -text -noout -in cert.cer
Clients RDP à jour (v10+)Vieilles versions gèrent mal SAN/jokers.Mettre à jour via Windows Update / client MSTSC récent.

Validation : voir et tester le certificat réellement présenté

Depuis un poste client

  • MSTSC : mstsc /v:farm.subdomain.contoso.com → à l’alerte, cliquer « Afficher le certificat » et vérifier Sujet, SAN, émetteur, validité.
  • OpenSSL : vérifier Session Host directement :
    openssl s_client -connect rdsh01.contoso.com:3389 -tls1_2 -servername rdsh01.contoso.com
  • RD Gateway : openssl s_client -connect rdgw.contoso.com:443 -tls1_2 -servername rdgw.contoso.com

Depuis le serveur

  • HTTP.SYS (Gateway / Web) : netsh http show sslcert → vérifier que le Hash correspond à l’empreinte attendue.
  • Événements Schannel : Observateur d’événements → Journaux Windows → Système → 36882/36885/36874 indiquent un problème de certificat ou de chaîne.
  • RDP‑Tcp (Session Host) : confirmer l’empreinte via WMI :
    Get-WmiObject -Namespace root\cimv2\TerminalServices -Class Win32_TSGeneralSetting -Filter "TerminalName='RDP-Tcp'" \| Select SSLCertificateSHA1Hash

Scénarios fréquents et corrections rapides

  • Nom d’équilibrage ≠ nom dans le RDP : Le fichier .rdp contient full address:s:server1.contoso.com alors que l’utilisateur se connecte à rds.contoso.com. Corriger le .rdp pour qu’il référence rds.contoso.com (ou ajouter ce FQDN dans les SAN).
  • Wildcard trop court : *.contoso.com ne couvre pas farm.eu.sub.contoso.com. Utiliser *.sub.contoso.com ou le FQDN explicite.
  • PFX sans clé privée : Apparent dans la console : “vous disposez d’une clé privée correspondant à ce certificat” absent. Régénérer l’export .pfx avec clé.
  • Chaîne incomplète côté client : Importez les certificats d’AC intermédiaires/racine dans les magasins « Autorités de certification » des clients.
  • Redirection vers FQDN non couvert : Le Broker envoie rdsh02.internal.local alors que le certificat couvre *.contoso.com. Uniformiser les suffixes DNS (ou élargir les SAN), et ajuster les Connection Broker settings.

Renouvellement sans interruption (roll‑over maîtrisé)

  1. T‑15 jours : Générer le nouveau certificat (nouvelle clé), PFX + chaîne complète.
  2. T‑14 : Importer le PFX sur tous les serveurs (magasin Ordinateur\Personnel). Ne pas supprimer l’ancien.
  3. T‑13 : Appliquer le nouveau PFX via Set‑RDCertificate (Gateway, Web, Broker). Vérifier netsh http show sslcert et Get‑RDCertificate.
  4. T‑12 : Lier l’empreinte sur chaque Session Host (WMI) et redémarrer TermService en dehors des heures de pointe.
  5. T‑11 : Tests clients (MSTSC/OpenSSL), double vérification des SAN.
  6. J‑0 : Supprimer l’ancien certificat une fois la bascule confirmée.

Script complet (idempotent) pour uniformiser la ferme

# Uniformisation du certificat RDS sur toute la ferme
param(
  [Parameter(Mandatory=$true)] [string]$PfxPath,
  [Parameter(Mandatory=$true)] [securestring]$PfxPassword,
  [Parameter(Mandatory=$true)] [string]$ConnectionBroker
)

Import-Module RemoteDesktop

# 1) Import local si nécessaire

if (-not (Get-PfxCertificate $PfxPath)) {
Import-PfxCertificate -FilePath $PfxPath -CertStoreLocation Cert:\LocalMachine\My -Password $PfxPassword | Out-Null
}

# 2) Affecter aux rôles Gateway/Web/Broker

Set-RDCertificate -Role RDGateway    -ImportPath $PfxPath -Password $PfxPassword -Force
Set-RDCertificate -Role RDWebAccess  -ImportPath $PfxPath -Password $PfxPassword -Force
Set-RDCertificate -Role RDPublishing -ConnectionBroker $ConnectionBroker -ImportPath $PfxPath -Password $PfxPassword -Force
Set-RDCertificate -Role RDRedirector -ConnectionBroker $ConnectionBroker -ImportPath $PfxPath -Password $PfxPassword -Force

# 3) Lier à RDP-Tcp sur tous les Session Hosts

$thumb = ((Get-PfxCertificate $PfxPath).Thumbprint).Replace(' ','')
$rdsh  = (Get-RDServer -Role RDS-RD-SERVER).Server
Invoke-Command -ComputerName $rdsh -ScriptBlock {
param($Thumb,$PfxPath,$PfxPassword)
if (-not (Get-PfxCertificate $PfxPath)) {
Import-PfxCertificate -FilePath $PfxPath -CertStoreLocation Cert:\LocalMachine\My -Password $PfxPassword | Out-Null
}
$ts = Get-WmiObject -Namespace root\cimv2\TerminalServices -Class Win32_TSGeneralSetting -Filter "TerminalName='RDP-Tcp'"
$null = $ts.SetSSLCertificateSHA1Hash($Thumb)
Restart-Service TermService -Force
} -ArgumentList $thumb,$PfxPath,$PfxPassword

# 4) Nettoyage des auto-signés (optionnel)

Get-ChildItem Cert:\LocalMachine\RemoteDesktop, Cert:\LocalMachine\My |
Where-Object { $*.Issuer -eq $*.Subject -and $_.Subject -like '*RDP*' } |
Remove-Item -Force 

FAQ express

Peut‑on utiliser un seul certificat pour toute la ferme ?
Oui, c’est la pratique la plus simple : un unique PFX dont les SAN couvrent tous les FQDN utilisés (nom d’accès Web, nom de Gateway, nom d’équilibrage Broker, et FQDN des Session Hosts ou wildcards par niveau).

Un wildcard suffit‑il ?
Un wildcard par niveau suffit souvent (*.contoso.com et *.subdomain.contoso.com). Il ne couvre pas les sous‑sous‑domaines.

Pourquoi vois‑je encore un auto‑signé ?
Parce qu’il reste dans un magasin (Remote Desktop ou Personnel) et que RDP‑Tcp le choisit par défaut si la valeur SSLCertificateSHA1Hash n’est pas définie. Imposer l’empreinte via WMI et supprimer les auto‑signés résiduels.

Let’s Encrypt convient‑il à RDS ?
Oui, tant que la chaîne est complète et que les SAN correspondent. Automatisez le renouvellement et le Set‑RDCertificate + la mise à jour RDP‑Tcp.

Faut‑il redémarrer le serveur ?
Pas pour Gateway / Web / Broker (un recyclage de service suffit). Pour la liaison RDP‑Tcp, le redémarrage de TermService interrompt les sessions actives ; planifiez le changement.

Informations complémentaires utiles

  1. Certificat unique par ferme — Sur Windows Server 2012/2016/2019/2022, un seul certificat couvrant tous les noms réellement utilisés (ou des wildcards restreints) évite les incohérences.
  2. DNS & Load Balancing — Le nom inscrit dans le fichier .rdp doit pointer vers l’équilibrage prévu (ou la Gateway). Un alias inattendu suffit à faire échouer la validation.
  3. Documentation Microsoft — Recherchez « Using certificates in Remote Desktop Services » sur Microsoft Learn pour la procédure avec l’assistant, les cmdlets PowerShell et la gestion du Broker en haute disponibilité.
  4. Dépannage rapidemstsc /v:<nom> puis « Afficher le certificat » ; ou interrogez le port 3389 :
    openssl s_client -connect <nom>:3389 -servername <nom>.

Checklist finale

  • Le même PFX (clé privée + chaîne complète) est présent sur tous les serveurs.
  • RD Gateway / RD Web / Broker : affectation confirmée par Set‑RDCertificate et Get‑RDCertificate.
  • Session Host : SSLCertificateSHA1Hash impose l’empreinte, TermService redémarré.
  • Nom appelé = nom dans SAN (ou wildcard adéquat, un seul niveau).
  • Plus aucun « RDP Self‑Signed » dans les magasins Remote Desktop et Personnel.
  • Chaîne complète déployée sur serveurs et clients (racine + intermédiaires).
  • Vérification pratique côté client (MSTSC / OpenSSL) et côté serveur (HTTP.SYS / Schannel).

Conclusion

En appliquant rigoureusement ces six étapes — affectation par rôle, binding explicite sur chaque Session Host, suppression des auto‑signés, propagation automatisée et contrôles de conformité — votre ferme RDS présentera systématiquement le bon certificat. Les avertissements disparaîtront pour de bon, et vos utilisateurs bénéficieront d’une expérience de connexion RDP propre, prévisible et sécurisée.

Sommaire