¿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.
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íntoma | Causa probable | Cómo confirmarlo |
---|---|---|
Advertencia de identidad al abrir RDP | CN/SAN no coincide con el nombre de conexión | Botón “Mostrar certificado” en el cuadro de RDP y comprobar “Emitido para” |
Advertencia de confianza | CA raíz/intermedia no instalada en el cliente | Ver la pestaña “Ruta de certificación” en el certificado |
Fallo intermitente | Conexión por alias distinto al FQDN del certificado | Hacer nslookup al nombre que usas para conectarte |
Fallo continuo pese a importar en IIS | Certificado no asignado al listener RDP | Comprobar 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
ordp.empresa.com
, el SAN del certificado debe incluirserver.empresa.com
y/ordp.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
oterminal
deben agregarse como DNS adicionales en el SAN.
Sobre “CWRTABLEAU”
Solo será válido como CN/SAN si los clientes se conectan exactamente aCWRTABLEAU
(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
(OID1.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
- Abrir certlm.msc en el servidor.
- Navegar a Equipo local > Personal > Certificados.
- 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:
- En certlm.msc haz doble clic en el certificado > pestaña Detalles > Propiedades > botón Administrar claves privadas….
- 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:
- Abrir Server Manager > Remote Desktop Services > Overview.
- En Tasks > Edit Deployment Properties > Certificates, seleccionar Select existing certificate e importar el
.pfx
con su contraseña. - 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
Paso | Acción | Resultado esperado |
---|---|---|
Planificación de nombre | Elegir FQDN estable y alias | FQDN y SAN definidos |
Emisión | Solicitar certificado con EKU de servidor y SAN correctos | PFX con cadena completa |
Importación | Importar en Equipo local > Personal | Cert en almacén local |
Asignación | Vincular thumbprint al listener RDP | Hash aplicado en RDP-Tcp |
Permisos | Dar lectura a NETWORK SERVICE | Clave privada accesible |
Reinicio | Reiniciar TermService | Advertencia 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.