2013-01-31

Сертификаты RDP

Успешно решил намедни проблемку с терминалами. Может кому ещё пригодится, да и мне в случае, например, амнезии будет полезно вспомнить :)
Не удается проверить подлинность удаленного компьютера. Сертификат выдан не имеющим доверия центром сертификации.
Суть проблемки в следующем. Имеются сервера терминалов на windows 7 (а теперь уже и win8 попадаются - а может даже это же решение и для серверных версий подойдёт).
То есть соединения по протоколу Remote Desktop Protocol (RDP) версий 7 и 8 (бинарник версий 6.1 и 6.2 соответственно) к службе "Удалённый рабочий стол" (remote desktop services).
Теперь соединение с ними требует наличия сертификата у сервера и его проверка у клиента.
Сервер автоматически создаёт самоподписанный сертификат при подключении к нему (или если его "нечаянно" удалить).
Но при этом у клиентов в момент подключения выдаётся предупреждение "Не удается проверить подлинность удаленного компьютера: Сертификат выдан не имеющим доверия центром сертификации" - благо пока отключаемое. У серверов на Windows XP такой проблемы нет - но клиенты в XP уже ругается.
Не то, чтобы это была такая уж Проблема - так - мелкое неудобство. Но особо комфортной Ежедневную Работу не делает. Особенно администратору - который по несколько раз в день да к разным машинам цепляется..

Итак. Нужно заменить сертификаты у "серверов" на "правильные".
Как сделать "правильные" сертификаты - отдельная песня - отдельным постом.
Делал через openssl + EasyRSA (1.0 - или 2.0 что идёт в комплекте с openvpn - но пришлось слегка допиливать - но главное разобраться с конфигами - хех).
Вполне вероятно, что средствами MS (тем же certutil или GUI каким) можно было бы получить ключики куда проще, но зато слегка копнул эту x509 - теперь чуть лучше понимаю цели танцев с бубном ключами для openvpn.. Одних CA не считая промежуточных центров сертификатов пока с ними разобрался сколько понаделал :)
Можно (и желательно) получать сертификаты от доверенных сторонних центров сертификации - но они и за денюжку - и по-учиться на сертификатах не дадут.

Продолжим. В процессе кейгенеза должны получить следующие вещи:
  1. Сертификат самопального CA в формате x509/CER/base64 - пусть им будет файлик ca.crt.

  2. pkcs12/pfx ключик сервера с EKU "remote desktop connection" или "TLS server" подписанный сертификатом, который проверяется через вышеупомянутый CA - им будет файлик test.p12 с паролем "qwe" - хеш ключа - 01:23:..:cd:ef.

  3. HTTP сервер, отдающий промежуточные, корневые сертификаты и отзывы на них (crl).
    Без этого пункта работать RDP без ругани не получилось заставить - так что заранее планируйте; благо хватит какого-нибудь mangoose - ибо нашему CA требуется пока лишь отдавать мелкие статичные файлы и достаточно редко.
Это были пока лишь предварительные требования - и вот теперь, наконец, приступаем к решении задачи - как же заставить сервер(ы) использовать нашу структуру ключей.

Всё последующее требует административной консоли (с повышенными правами) на подопытном сервере.
  1. Засовываем корневой сертификат в хранилище доверенных корневых сертификатов. Это просто - используем штатную системную утилиту:
    certutil -addstore root ca.crt
  2. Засовываем ключ сервера в персональное хранилище (но "локального компьютера").
    Тут есть нюанс. При простом импорте ключа - он может поместиться в личное хранилище пользователя - да ещё и с неправильными правами. При продвинутом импорте - через mmc и оснастку "Сертификаты/Локальный компьютер" - потребуется давать права на доступ к закрытому ключу для Network Service - от имени которого работает termserv - опять же много буков и картинок потребуется, чтобы это всё описать. Самое простое найденное решение - через утилитку WinHttpCertCfg.exe - из состава Windows Server 2003 Resource Kit Tools.
    WinHttpCertCfg -a NetworkService -c LOCAL_MACHINE\MY -i test.p12 -p qwe
    Да, если ключик таки уже импортировали как-то по-другому, можно дать правильные права командой:
    WinHttpCertCfg.exe -a NetworkService -c LOCAL_MACHINE\MY -g -s SUBJ
    где SUBJ
     это сабжект ключа - чтобы утилита его смогла найти - и скорее всего он будет совпадать с именем компьютера - достаточно указать %COMPUTERNAME% .
  3. Заставляем терминал сервер отдавать наш ключ, вместо самоподписанного. Просто нужно указать хеш нужного ключа в реестре. Перезапуска сервиса а тем более компьютера не потребуется.
    reg add "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" /v SSLCertificateSHA1Hash /t REG_BINARY /d 0123456789..DEF



Вот такое свойство соединения..Ну Вот, собственно, и Всё. При следующем подключении - клиент не получит уведомления о неправильном сертификате сервера. Можно снова включать уведомления об этом кошмаре или даже запрещать соединяться с такими серверами.
Не правда ли, Всё очень просто?