Ошибка 0x907 при подключении к RDP
Добрый день! Уважаемые читатели и гости IT блога Pyatilistnik.org. В прошлый раз мы с вами решили проблему "Произошла внутренняя ошибка RDP" при попытке входа на RDS ферму. Сегодня мы вновь столкнемся с трудностями авторизации на RDS ферме, ошибка звучит так "Код ошибки 0x907. Расширенный код ошибки 0x0". Ловить я ее начал буквально вчера 27 ноября, до этого все прекрасно работало. Из пострадавших, это операционные системы Windows 10 и Windows 11, а вот на Windows 8.1, все отрабатывало на ура. Давайте разбираться в чем дело.
Диагностика ошибки 0x907
Опишу немного инфраструктуру, есть большая RDS ферма из 50 хостов RDSH. Клиенты Windows 10/11, доменные и не доменные стали получать ошибки:
Такую ошибку мы ловили, и я объяснял, что чаще всего это было из-за того, что клиент RDP (mstsc) открывается с ключом /admin. Тут я точно запускал все без ключа. Обратите внимание, что вам показывают, что вы не можете попасть именно на определенную ноду, так как брокер подключений отработал нормально и вас перекинул.
Так как у меня были полные права на любую ноду, то я попытался войти на данную ноду напрямую. В итоге получил ошибку:
Ранее я встречал проблему с сертификатом, но не с кодом 0x907, тем более ничего не менялось в самой конфигурации.
Диагностика и устранение ошибки для Windows клиентов
Раз при подключении на прямую к хосту RDSH мы получаем ошибку сертификата, то дело вероятнее в нем. На своем клиентском месте, где вы пытаетесь подключаться, вы должны запустить реестр Windows. Вам нужно перейти в ветку:
Тут у вас будут папки с названиями всех серверов, к которым вы подключались по RDP. В каждой папке будет ключик CertHash, в котором будет отпечаток сертификата.
Далее когда ветка стала чистой, вновь попытайтесь напрямую подключиться к серверу куда вас не пускало, использую ключ /admin. В результате у меня после прохождения брокера высочило окно:
С вероятностью 99% мой RDSH хост использует самоподписный сертификат, но раньше этого хватало для подключений, давайте посмотрим сертификат. В сведениях о сертификате, видно, что наша операционная система ему не доверяет, так как нет такого корневого центра сертификации, кто его выпустил и был доверенным. Если у вас один такой хост, то можете просто установить данный сертификат, но если как и у меня их 50, то тут выкручиваться нужно иначе.
Для установки сертификата нажмите соответствующую кнопку. В мастере импорта я всегда советую корневые сертификаты устанавливать в расположение локального компьютера.
Выбираем пункт "Переместить все сертификаты в следующее хранилище" и указываем доверенные корневые центры сертификации.
Завершаем импорт корневого сертификата
Теперь если посмотреть состав вашего сертификата, то ваша система ему доверяет.
Теперь подключение к текущему хосту будет без ошибок
- 1️⃣Выпустить сертификаты на все RDSH хосты из вашего внутреннего Active Directory CA, если он есть, не все его устанавливают
- 2️⃣Заказать внешний Wildcard сертификат на домен от внешнего CA, что проще на мой взгляд
У меня уже есть такой сертификат в формате PFX. Задача у нас такая, нам нужно на всех участниках RDS фермы поменять самоподписный сертификат на новый. Алгоритм тут такой:
- 1️⃣Вы устанавливаете на нужные хосты PFX сертификат в локальное хранилище компьютера
- 2️⃣Проверяете текущий отпечаток сертификата, что используется для RDP сессий
- 3️⃣Подменяете сертификат на новый
- 4️⃣Проверяете, что теперь используется новый сертификат
Установка PFX архива дело тривиальное
В результате у вас в контейнере личное, будет ваш сертификат.
Чтобы массово установить сертификат на большое количество серверов, можете воспользоваться моим кодом:
# Задаем переменные
$sourceCert="\\TS102.pyatilistnik.org\Temp\new.pfx" #Тут лежит pfx сертификат
$certPassword=ConvertTo-SecureString "1234436" -AsPlainText -Force #Пароль для доступа к сертификату
$servers=Get-Content "c:\Temp\term.txt" #Файл со списком серверов
# Функция для копирования сертификата на удаленные серверы перед доступом к WinRM для их применения.
function copyCertsToServers{
$servers |%{Copy-Item $sourceCert -Destination "\\$_`\c$\Temp"} # Кладу в папку C:\Temp
}
copyCertsToServers;
# Установка сертификата на удаленных машинах
$servers | %{ Invoke-Command -ComputerName $_ -ScriptBlock {
param($x)
$env:computername;
Import-PfxCertificate -CertStoreLocation Cert:\LocalMachine\My -FilePath "C:\Temp\new.pfx" -Password $x;
} -ArgumentList $certPassword
}
Запустите теперь PowerShell ISE в режиме администратора. Введите команду, чтобы посмотреть текущие настройки сертификата для RDP.
Нас будет интересовать поле SSLCertificateSHA1Hash, тут будет отпечаток самоподписного сертификата.
Теперь выясните отпечаток вашего Wildcard сертификата. После этого выполните команду.
Set-WmiInstance -Path $path -argument @{SSLCertificateSHA1Hash="3a9ba2991ca000 779cdbac4333c3c4adcaf122c"}
Теперь у вас будет все отлично, с подключением по RDP к данному участнику RDS фермы и ошибка 0x907 пропадет.
Более продвинутый скрипт по массовой установке
#Создаем логи если их нет
function Date {Get-Date -Format "yyyy.MM.dd HH:mm:ss"}
$log_folder = "$PSScriptRoot\Logs\" + $($MyInvocation.MyCommand.Name -replace (".ps1", ""))
$log = "$log_folder\$(Get-Date -Format "yyyy_MM_dd_HH_mm_ss").txt"
if (! (Test-Path $log_folder -PathType Container -ErrorAction SilentlyContinue))
{
New-Item $log_folder -ItemType D -Force | Out-Null
}
"$(Date) Start Processing" | Tee-Object $log -Append
### Тут мы подгружаем файл со списком серверов
foreach ($server in (Get-Content "$PSScriptRoot\servers.txt"))
{
"$(Date) Trying to copy certificate file" | Tee-Object $log -Append
$Thumbprint = "3a9ba2991ca444779cdbac42126c3c4adcaf122c"
Copy-Item -Path "$PSScriptRoot\имя_сертификата.pfx" -Destination "\\$server\C$\Windows\Temp\имя_сертификата.pfx" -Force -Verbose
### Установка удаленной сессии
"$(Date) Trying to create PS session and install certificate file" | Tee-Object $log -Append
$session = New-PSSession -ComputerName $server
Invoke-Command -Session $session -ScriptBlock {
$password = ConvertTo-SecureString -String "12345678" -AsPlainText -Force
Import-PFXCertificate -CertStoreLocation "Cert:\LocalMachine\My" -FilePath "C:\windows\temp\имя_сертификата.pfx" -Password $password -Verbose
}
Remove-PSSession $session
###
"$(Date) Trying to assign certificate to terminal services" | Tee-Object $log -Append
try {
$path = Get-WmiObject -Class "Win32_TSGeneralSetting" -Namespace "root\cimv2\terminalservices" -ComputerName $server -Verbose -ErrorAction Stop
Set-WmiInstance -Path $path -Arguments @{SSLCertificateSHA1Hash = $Thumbprint} -Verbose -ErrorAction Stop
}
catch {
"$(Date) $($_.exception.message)" | Tee-Object $log -Append
}
}
###
"$(Date) End Processing" | Tee-Object $log -Append
Как проверить какой сертификат отвечает на RDP
1️⃣PowerShell скрипт получает список серверов из текстового файла и сохраняет их в переменной.
2️⃣Далее для каждого сервера выполняет команду Get-WmiObject "Win32_TSGeneralSetting" -Namespace root\cimv2\terminalservices -Filter "TerminalName='RDP-tcp'"
3️⃣Из вывода команды берет поле SSLCertificateSHA1Hash и его значение и выводит все это в виде таблицы
$serverList = Get-Content "C:\Servers.txt"
foreach ($server in $serverList) {
$tsGeneralSettings = Get-WmiObject "Win32_TSGeneralSetting" -ComputerName $server -Namespace root\cimv2\terminalservices -Filter "TerminalName='RDP-tcp'"
$sslCertificateHash = $tsGeneralSettings.SSLCertificateSHA1Hash
$output = New-Object -TypeName PSObject
$output | Add-Member -MemberType NoteProperty -Name "Server" -Value $server
$output | Add-Member -MemberType NoteProperty -Name "SSLCertificateSHA1Hash" -Value $sslCertificateHash
Write-Output $output | Format-Table
}
Смена клиента RDP в Windows
В качестве обходного варианта, если вы не хотите заморачиваться с сертификатами, вы можете просто выбрать другие RDP клиенты, например:
- Remote Desktop Connection Manager
- Подключение к удаленному рабочему столу Windows через магазинное приложение
Диагностика и устранение ошибки для MacOS клиентов
Пользователи Windows не одиноки, ошибку 0x907 вы можете встретить и в MacOS. После обновления RD Client до 10.3.0 так же стала отображаться ошибка 0x907, когда я хочу подключиться по RDP. На предыдущей версии RD Client все работало.
Как я и написал все началось с версии 10.3.0. Тут вы можете либо откатиться на предыдущую версию или поставить более свежую бетта версию. Я за второй вариант. Перейдите по ссылке:
Как видите уже есть версия Version 10.8.0 (2032). Установите ее и будет вам счастье.
На этом у меня все. Надеюсь, что вы смогли подключиться и продолжить работу. С вами был Иван Сёмин, автор и создатель IT портала Pyatilistnik.org.