Симптом

При попытке подключения по RDP (порт 3389) появляется окно:

plaintextНе удаётся подключиться к удалённому компьютеру.
Код ошибки: 0x904
Расширенный код ошибки: 0x7

Сеть, проброс порта и файрвол при этом в порядке — служба Remote Desktop Services локально слушает порт (netstat -ano | findstr :3389 показывает LISTENING).

Диагностика

Журнал «Безопасность»

Просмотр событий → Журналы Windows → Безопасность, событие 5061 с источником Microsoft Windows security auditing (подкатегория аудита «Аудит целостности системы»).

В деталях события:

plaintextОперация шифрования.
Имя ключа: TSSecKeySet1
Тип ключа: Ключ компьютера
Операция: Открыть ключ
Код возврата: 0x80090016

Код 0x80090016 (NTE_BAD_KEYSET) означает, что служба TermService не может открыть приватный ключ сертификата RDP (TSSecKeySet1) — ключ повреждён, отсутствует или недоступен для учётной записи NETWORK SERVICE.

Журналы служб терминалов

Дополнительно стоит посмотреть Журналы приложений и служб → Microsoft → Windows → TerminalServices-RemoteConnectionManager — там видно, что менеджер подключений не смог инициализировать сертификат.

Решение

Выполняйте это локально или через IPMI / KVM / консоль гипервизора. Остановка TermService разрывает RDP-сессию — если вы всё-таки подключились, доступ к машине потеряется на середине процедуры.

Все команды — от имени администратора, в PowerShell.

1. Остановить службу удалённых рабочих столов

Сначала зависимая служба, потом основная:

powershellnet stop umrdpservice
net stop termservice

Если TermService не останавливается («служба не может быть остановлена»), пропустите шаг — в этом случае процедура всё равно сработает, просто изменения применятся после перезагрузки на шаге 6.

2. Проверить и удалить повреждённый ключ

Ключ TSSecKeySet1 — машинный, поэтому просмотр без указания провайдера ничего не покажет:

powershellcertutil -csp "Microsoft Software Key Storage Provider" -key

Если TSSecKeySet1 виден в списке — удалить:

powershellcertutil -delkey -csp "Microsoft Software Key Storage Provider" "TSSecKeySet1"

Если -delkey возвращает 0x80090016 (NTE_BAD_KEYSET) / «Набор ключей не существует» — записи о ключе нет, но повреждённые файлы могут оставаться в хранилище на диске. Переходите к следующим шагам: сброс прав решает проблему и без явного удаления ключа.

3. Удалить старый самоподписанный сертификат RDP

powershellGet-ChildItem "Cert:\LocalMachine\Remote Desktop" | Remove-Item

4. Сбросить права на хранилище ключей MachineKeys

Это ключевой шаг, который фактически устраняет ошибку.

Осторожно. icacls /reset заменяет права на унаследованные от родительской папки, а у MachineKeys по умолчанию собственный набор разрешений, и у отдельных файлов ключей бывают индивидуальные ACL. После сброса могут потерять доступ к своим сертификатам IIS, SQL Server и другие службы. Сначала сохраните текущие права:

powershellicacls "C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys" /save "$env:USERPROFILE\machinekeys_acl.txt" /t

Восстановить при необходимости:

powershellicacls "C:\ProgramData\Microsoft\Crypto\RSA" /restore "$env:USERPROFILE\machinekeys_acl.txt"

Сам сброс:

powershellicacls "C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys" /reset /t /c

NETWORK SERVICE и SYSTEM должны иметь доступ к этой папке — сброс прав восстанавливает его, из-за отсутствия которого TermService не мог открыть ключ.

5. Запустить службу заново

powershellnet start termservice
net start umrdpservice

6. Перезагрузить компьютер

powershellshutdown /r /t 0

При следующем запуске Windows автоматически сгенерирует новый рабочий сертификат и ключ для RDP.

7. Проверить результат

После перезагрузки в хранилище должен появиться новый самоподписанный сертификат со свежей датой:

powershellGet-ChildItem "Cert:\LocalMachine\Remote Desktop" | Select-Object Subject, NotBefore, Thumbprint

Результат

Подключение по RDP проходит успешно, ошибка 0x904 / 0x7 не воспроизводится.

Итог по первопричине

Компонент Статус
Сеть / проброс порта / файрвол ОК, не являлись причиной
Служба TermService (локально) Слушала порт нормально
Ключ сертификата RDP (TSSecKeySet1) Повреждён / недоступен → корень проблемы
Права на MachineKeys Сброшены → проблема устранена