Error de certificado SSL en RDP en Windows Server 2019: CN, SAN, instalación y solución paso a paso

¿Ves el aviso “SSL Certificate Authentication / Remote Desktop cannot verify the identity…” al conectarte por RDP a Windows Server 2019? Aquí tienes la guía definitiva para elegir el CN/SAN correcto, emitir el certificado, instalarlo y asignarlo al listener de RDP sin depender de IIS ni ensayos a ciegas.

Índice

Entendiendo el aviso de identidad en RDP

El cliente de Escritorio remoto muestra una advertencia de identidad cuando no puede validar el certificado que presenta el servidor. Esto ocurre, típicamente, por tres motivos:

  • Certificado autofirmado o emitido por una entidad no confiable para el equipo cliente.
  • Nombre no coincidente: te conectas a un nombre o IP que no está en el CN/SAN del certificado.
  • Errores de validez: certificado caducado, cadena incompleta o EKU inadecuado.
SíntomaCausa probableCómo confirmarlo
Advertencia de identidad al abrir RDPCN/SAN no coincide con el nombre de conexiónBotón “Mostrar certificado” en el cuadro de RDP y comprobar “Emitido para”
Advertencia de confianzaCA raíz/intermedia no instalada en el clienteVer la pestaña “Ruta de certificación” en el certificado
Fallo intermitenteConexión por alias distinto al FQDN del certificadoHacer nslookup al nombre que usas para conectarte
Fallo continuo pese a importar en IISCertificado no asignado al listener RDPComprobar el valor SSLCertificateSHA1Hash del listener

CN y SAN correctos en el CSR

La regla de oro: usa exactamente el FQDN con el que los usuarios se conectan. Ese FQDN debe aparecer en el Subject Alternative Name (SAN) y, por compatibilidad, también como CN.

  • Ejemplo recomendado: si tus usuarios escriben server.empresa.com o rdp.empresa.com, el SAN del certificado debe incluir server.empresa.com y/o rdp.empresa.com.
  • Evita usar la IP en la conexión. Si es inevitable, el SAN debe incluir la IP (ip=10.0.0.10), algo que normalmente solo harás con una CA interna.
  • Alias habituales como rdp, remote o terminal deben agregarse como DNS adicionales en el SAN.

Sobre “CWRTABLEAU”
Solo será válido como CN/SAN si los clientes se conectan exactamente a CWRTABLEAU (sin dominio) y ese nombre resuelve por DNS en todos los equipos. Lo recomendable para RDP es emplear FQDN (por ejemplo, cwrtableau.empresa.com), y usarlo siempre como nombre de conexión.

Consideraciones sobre wildcard e intranet

  • Los wildcard (*.empresa.com) suelen ser aceptados por SChannel, pero para RDP es mejor un FQDN explícito. Evitas confusiones y facilitas auditoría.
  • En entornos únicamente internos, usa un FQDN que resuelva en tu DNS corporativo. Si expones RDP por Internet, deberías hacerlo a través de RD Gateway con su propio certificado público.

Requisitos del certificado para RDP

  • EKU: debe incluir Server Authentication (OID 1.3.6.1.5.5.7.3.1).
  • Clave: al menos 2048 bits RSA y firma SHA‑256 o superior.
  • Cadena de confianza completa: incluye intermedias y raíz confiable para los clientes.
  • Formato de importación: .pfx con clave privada. No basta el .cer.
  • Almacén: Equipo local > Personal (no en Usuario actual; no solo en IIS).

Servidor único sin roles de RDS

Si tu servidor solo expone el Escritorio remoto estándar (sin Connection Broker/Web/Gateway), sigue estos pasos:

Importar el certificado

  1. Abrir certlm.msc en el servidor.
  2. Navegar a Equipo local > Personal > Certificados.
  3. Importar el .pfx marcando “Marcar esta clave como exportable” si lo necesitas para futuras renovaciones.

Obtener el thumbprint y limpiarlo

El thumbprint se usa para enlazar el certificado al listener. Limpia espacios y caracteres ocultos.

PowerShell
Tomar el último certificado cuyo Subject contiene el FQDN
$Fqdn  = "rdp.empresa.com"
$cert  = Get-ChildItem -Path Cert:\LocalMachine\My |
         Where-Object { $_.Subject -like "$Fqdn" } |
         Sort-Object NotAfter -Descending | Select-Object -First 1

Thumbprint sin espacios ni caracteres no hexadecimales

\$thumb = (\$cert.Thumbprint -replace '\s','') -replace '\[^0-9A-Fa-f]',''
\$thumb 

Asignar el certificado al listener RDP

Usa cualquiera de los métodos oficiales. Con PowerShell vía WMI:

PowerShell
Get-WmiObject -Namespace root\cimv2\TerminalServices -Class Win32_TSGeneralSetting |
  Set-WmiInstance -Arguments @{ SSLCertificateSHA1Hash = $thumb }

Con línea de comandos:

cmd
wmic /namespace:\\root\cimv2\TerminalServices PATH Win32_TSGeneralSetting ^
  Set SSLCertificateSHA1Hash="<THUMBPRINTSINESPACIOS>"

Asignación por registro (avanzado):

Registro
Ruta: HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp
Valor: SSLCertificateSHA1Hash (REG_BINARY) = Thumbprint en bytes

Consejo: muchas veces se copia un carácter invisible en el thumbprint. El comando de PowerShell anterior lo elimina de forma segura.

Conceder lectura a la clave privada

El servicio de Escritorio remoto (TermService) se ejecuta como NETWORK SERVICE. Debe poder leer la clave privada del certificado:

  1. En certlm.msc haz doble clic en el certificado > pestaña Detalles > Propiedades > botón Administrar claves privadas….
  2. Añade NETWORK SERVICE con permiso de lectura.

Reiniciar el servicio

Para que el listener use el nuevo certificado:

PowerShell
Restart-Service -Name TermService -Force

Advertencia: reiniciar TermService corta sesiones RDP activas. Programa una ventana de mantenimiento o ejecuta el reinicio desde consola local.

Implementación con roles de RDS

Si usas Remote Desktop Services con Connection Broker, RD Web y/o RD Gateway, vincula certificados desde el Server Manager para que se propaguen a todos los roles:

  1. Abrir Server Manager > Remote Desktop Services > Overview.
  2. En Tasks > Edit Deployment Properties > Certificates, seleccionar Select existing certificate e importar el .pfx con su contraseña.
  3. Aplicar y confirmar que todos los roles quedan en estado OK.

También puedes usar PowerShell:

PowerShell
$pwd = ConvertTo-SecureString "P@ssw0rd!" -AsPlainText -Force
Set-RDCertificate -Role RDPublishing    -ImportPath "C:\certs\rdp.pfx" -Password $pwd
Set-RDCertificate -Role RDWebAccess     -ImportPath "C:\certs\rdp.pfx" -Password $pwd
Set-RDCertificate -Role RDGateway       -ImportPath "C:\certs\rdp.pfx" -Password $pwd
Set-RDCertificate -Role RDRedirector    -ImportPath "C:\certs\rdp.pfx" -Password $pwd

Nota: RD Gateway debe usar un FQDN público y un certificado confiable públicamente si será accesible desde Internet.

Verificaciones y pruebas

  • Nombre: conecta usando el mismo FQDN que declaraste en el SAN.
  • Listener: comprueba el hash activo.
PowerShell
Leer el hash actual del listener
Get-WmiObject -Namespace root\cimv2\TerminalServices -Class Win32_TSGeneralSetting |
  Select-Object -ExpandProperty SSLCertificateSHA1Hash
  • Cadena: en el cliente, abre el certificado y revisa la pestaña “Ruta de certificación” para confirmar que todas las intermedias y la raíz son de confianza.
  • DNS: verifica que el FQDN resuelve al servidor correcto.
cmd
nslookup rdp.empresa.com

Checklist operativo

PasoAcciónResultado esperado
Planificación de nombreElegir FQDN estable y aliasFQDN y SAN definidos
EmisiónSolicitar certificado con EKU de servidor y SAN correctosPFX con cadena completa
ImportaciónImportar en Equipo local > PersonalCert en almacén local
AsignaciónVincular thumbprint al listener RDPHash aplicado en RDP-Tcp
PermisosDar lectura a NETWORK SERVICEClave privada accesible
ReinicioReiniciar TermServiceAdvertencia desaparece

Script de PowerShell para automatizar la asignación

Este script importa un PFX en el almacén de equipo, toma su thumbprint saneado y lo asigna al listener RDP. Deja la concesión de lectura a NETWORK SERVICE como paso manual (por seguridad y porque varía según proveedor de clave RSA/CNG).

PowerShell
param(
  [Parameter(Mandatory=$true)] [string]$PfxPath,
  [Parameter(Mandatory=$true)] [string]$PfxPassword,
  [Parameter(Mandatory=$true)] [string]$Fqdn
)

Write-Host "Importando PFX en Equipo local > Personal..."
\$secure = ConvertTo-SecureString \$PfxPassword -AsPlainText -Force
\$certObj = Import-PfxCertificate -FilePath \$PfxPath -CertStoreLocation Cert:\LocalMachine\My -Password \$secure

if (-not \$certObj) { throw "No se pudo importar el PFX." }

Si hay varios, intenta elegir el que coincide con el FQDN

\$cert = \$certObj | Where-Object { \$.Subject -like "CN=\$Fqdn" -or \$.DnsNameList.Unicode -contains \$Fqdn } |
Sort-Object NotAfter -Descending | Select-Object -First 1
if (-not \$cert) {
\$cert = \$certObj | Sort-Object NotAfter -Descending | Select-Object -First 1
}

\$thumb = (\$cert.Thumbprint -replace '\s','') -replace '\[^0-9A-Fa-f]',''
Write-Host "Thumbprint seleccionado: \$thumb"

Write-Host "Asignando al listener RDP..."
Get-WmiObject -Namespace root\cimv2\TerminalServices -Class Win32\_TSGeneralSetting |
Set-WmiInstance -Arguments @{ SSLCertificateSHA1Hash = \$thumb } | Out-Null

Write-Host "Recuerda conceder lectura a NETWORK SERVICE en la clave privada del certificado."
Write-Host "Reiniciando servicio de Escritorio remoto..."
Restart-Service -Name TermService -Force

Write-Host "Completado. Prueba a conectar a \$Fqdn." 

Plantilla INF para generar el CSR con SAN

Si tu CA es interna o quieres un CSR exacto, usa esta plantilla. Sustituye el FQDN y alias según tu entorno.

Texto
; rdp.inf
[Version]
Signature="$Windows NT$"

\[NewRequest]
Subject = "CN=rdp.empresa.com"
Exportable = TRUE
KeyLength = 2048
KeySpec = 1
KeyUsage = 0xa0
MachineKeySet = TRUE
ProviderName = "Microsoft RSA SChannel Cryptographic Provider"
SMIME = FALSE
RequestType = PKCS10
HashAlgorithm = sha256

\[Extensions]
2.5.29.17 = "{text}"
continue = "dns=rdp.empresa.com&dns=server.empresa.com"

\[EnhancedKeyUsageExtension]
OID=1.3.6.1.5.5.7.3.1 

Comandos de emisión e instalación con certreq.exe:

cmd
certreq -new rdp.inf rdp.req
REM Envía rdp.req a tu CA y recibe rdp.cer (o un PFX desde la CA)
certreq -accept rdp.cer

Solución de problemas frecuente

  • Importé el certificado en IIS y el aviso sigue: vincular en IIS no afecta a RDP. Debes asignarlo al listener RDP como se detalla arriba.
  • Copié el thumbprint y no funciona: elimina espacios y caracteres ocultos. Usa la limpieza con PowerShell (-replace).
  • Cadena incompleta: importa las intermedias en el servidor y asegúrate de que los clientes confían en la CA raíz. En dominios, distribuye por directiva de grupo.
  • Conecto por IP: el aviso es esperado salvo que el SAN incluya esa IP. Cambia a FQDN o emite un certificado con la IP como SAN.
  • Certificado con EKU incorrecto: necesita Server Authentication. Plantillas “Web Server” o “Computer” de una CA interna suelen funcionar.
  • RDS en alta disponibilidad: usa un FQDN del Broker en el certificado y reparte ese mismo nombre a los clientes.
  • Clave privada inaccesible: concede lectura a NETWORK SERVICE desde “Administrar claves privadas…”.
  • Persisten advertencias: comprueba que el FQDN con el que te conectas exactamente está en el SAN; borra cachés DNS si cambiaste registros.

Buenas prácticas

  • Define y documenta un FQDN estable para RDP, idealmente un alias como rdp.empresa.com.
  • Automatiza renovaciones con tu CA interna o una herramienta ACME; planifica antes de la caducidad.
  • Para acceso externo, usa RD Gateway con MFA; evita exponer RDP directo a Internet.
  • Mantén TLS moderno habilitado y protocolos obsoletos deshabilitados según políticas de seguridad.

Resumen accionable

  • Elige el FQDN real de conexión y ponlo en el SAN del certificado.
  • Emite un PFX con cadena y EKU de Server Authentication.
  • Importa en Equipo local > Personal, asigna el thumbprint al listener RDP y otorga lectura a NETWORK SERVICE.
  • Reinicia TermService y conecta usando el mismo FQDN. El aviso debe desaparecer.

Índice