- Генерация сторонних сертификатов для терминального сервера
- Двухуровневый tls
- Защита по гостам
- Конфигурирование автоматического выпуска сертификатов
- Проверка работоспособности
- Создание групповой политики для rdp подключений
- Создание шаблона сертификата rdp в adcs
- Установка сертификата на виртуальные машины
- Шаг второй. и снова вопросы доверия
- Шаг нулевой. подготовка и вопросы доверия
- Шаг первый. размашисто подписываем файл
Генерация сторонних сертификатов для терминального сервера
Для пущей отказоустойчивости (возможно – мнимой) вожу юзеров на терминальный сервер по ip.
Задалбывает сообщение при подключении о том, что сертификат не соответсвует серверу.
Учить пользователей игнорировать – несколько неправильно.
Кроме того, на двух терминальных серверах развернут корпоративный сайт, который для пущей устойчивости раздается DNS round robin (т.е. то на тот, то на другой).
Т.е. на один и тот же компьютер могут придти как на:
А сертификат в AD выдают только SQL2.domain.domain.
Наверное, можно обойти штатными средствами, но я ниасилил.
1. Генерируем через openssl паралелную двухуровневую структуру сертификатов.
Наверху – заказной CA, ниже – подписанные им сертификаты серверов.
2. Сертификат заказного CA раздаем через политики AD и, для “вольных стрелков”, выкладываем на корпоративный сервак. Типа или вы нам доверяете, или нет.
3. Подписанные заказным СА сертификаты (с ключами) ставим на сервера.
Немного подробнее
1.1.Множественные имена в конфигурационном файле генерации пары ключ-сертификат сервера:
SQL2.cnf
[ req_distinguished_name ]
0.commonName = Common Name (eg, YOUR name)
0.commonName_default = sql2
0.commonName_max = 64
1.commonName = Common Name (eg, YOUR name)
1.commonName_default = sql2.domain.domain
1.commonName_max = 64
2.commonName = Common Name (eg, YOUR name)
2.commonName_default = 192.168.15.247
2.commonName_max =64
3.commonName = Common Name (eg, YOUR name)
3.commonName_default = 192.168.17.247
3.commonName_max = 64
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
# Multiple_Names
subjectAltName = @alt_names
crlDistributionPoints=URI:http://www.domain.domain/ca/ca-crl.crl
[alt_names]
DNS.1 = sql2
DNS.2 = sql2.domain.domain
DNS.3 = www
DNS.4 = www.domain.domain
DNS.5 = 192.168.15.247
DNS.6 = 192.168.17.247
crlDistributionPoints – тоже важный пунктик – без него ругается на невозможность проверить список отзыва. Список надо регулярно перегенерировать и выкладывать на сервер (отключить бы вообще фишку проверки отзыва, но пока не нашел).
Переодически (раз в неколько дней) прогоняем
openssl ca -keyfile $ROOT_KEY -cert $ROOT_CER -gencrl -out $CRL_PEM -config $CFG_NAME
и $CRL_PEM (это текущий список отзыва) выкладываем как http://www.domain.domain/ca/ca-crl.crl
(думаю автоматизировать)
1.2. Скрипт генерации пары ключ-сертификат для сервера:
CFG_NAME=”/etc/_SCRIPT/ISP/RDP2.cnf”
CER_NAME=”/etc/_SCRIPT/ISP/Keys/SQL2.cer”
KEY_NAME=”/etc/_SCRIPT/ISP/Keys/SQL2.key”
PFX_NAME=”/etc/_SCRIPT/ISP/Keys/SQL2.pfx”
REQ_NAME=”SQL2.req”
ROOT_CER=”/etc/_SCRIPT/ISP/Keys/ca-lnx.crt”
ROOT_KEY=”/etc/_SCRIPT/ISP/Keys/ca-lnx.key”
echo Generate Server key
openssl req -new -days 720 -nodes -out $REQ_NAME -keyout $KEY_NAME -config $CFG_NAME
openssl x509 -req -in $REQ_NAME -CAcreateserial
-extfile $CFG_NAME -extensions v3_req -days 720
-CAkey $ROOT_KEY -CA $ROOT_CER
-out $CER_NAME
# integrate key & cer
openssl pkcs12 -inkey $KEY_NAME -in $CER_NAME -export -out $PFX_NAME
Важно – ссылка на конфиг (-extfile) и раздел из него (v3_req, с мультиименами и ссылкой на точку раздачи списков отзыва -см 1.1).
2.1. Раздача корневого сертификата через политики:
Несем ca-lnx.crt (сертификат заказного CA) на сервер AD.
gpmc.msc, выбираем политику (у меня собственная политика доменных рабочих станций, но можно любую стандартную – главное что бы она применялась к целевым компьютерам), правая кнопка мыши, редактировать,
Computer Configuration-Windows Settings-Security Settings-Public Key Policies-Trusted Root Certification Authorities, импорт, добавить ca-lnx.crt.
Активируется после перезагрузки рабочей станции (gpupdate /force, похоже, не помогает).
3.1. Установка ключа сертификата на сервер.
Несем $PFX_NAME (файл с расширением .pfx, содержащий и сертификат, и ключ) на терминальный сервер/IIS.
mmc.msc,
Консоль – добавить или удалить оснастку (Ctrl – M) – Сертификаты – Учетной записи компьютера – Локальный компьютер – Ок
Заходим – Сертификаты (локальный компьютер) – Личное – Сертификаты
Действие – все задачи – импорт (или ПКМ – все задачи – импорт)
В мастере импорта – далее, Обзор, выбрать внизу Personal Information Exchange (.pfx, .p12) вместо x509, выбрать свой .pfx, далее-далее-далее-готово.
3.2. Настройка RDP на использование ключа/сертификата –
tsconfig.msc
В “подключения” выбираем свое подключение, ПКМ-свойства, вкладка общие, внизу строка “Сертификат” и кнопка “Выбрать”. Выбираем, применяем, выходим.
Вот, примерно так.
Конфиги полностью не выкладываю – анонимизировать лень, но основные грабли вроде обозначил.
Двухуровневый tls
В случае аутентификации пользователей об Active Directory по сертификатам RSA я предлагаю использовать обычный TLS c хранением клиентского ключа аутентификации RSA на Рутокен ЭЦП, но ходить через sTunnel. В этом случае TLS по RSA будет передаваться внутри канала TLS c ГОСТ.
Возможны две схемы. В первой TLS с RSA организует непосредственно клиент RDP. При этом на токене хранятся два ключа — ГОСТовый (аутентификация «свой-чужой», чтобы авторизоваться на сервере sTunnel)и RSA (если пользователь смог пройти первый барьер, то этот ключ используется для аутентификации об AD, пользователь сразу попадает в свою учетную запись на RDP-сервере).
Для доступа к ключу/сертификату RSA, хранящимся на Рутокен ЭЦП, и аппаратной реализации RSA на «борту» Рутокен ЭЦП используется на Windows Рутокен CSP (входит в дистрибутив драйверов Рутокен), на Linux приложение rdesktop работает через PC/SC.
Во второй схеме TLS по RSA и по ГОСТ обеспечивается самим sTunnel. Сразу предупреждаю, что эту вторую схему я не пробовал.
Для доступа к ключу RSA и аппаратной реализации RSA «на борту» Рутокен ЭЦП используется engine pkcs11 из проекта OpenSC www.opensc-project.org/engine_pkcs11.
Соответственно, в конфиге клиента sTunnel будут две секции:
[RDP-TLS-GOST]
engineNum=1
key=100
cert=client_gost.crt
accept = 127.0.0.1:8088
connect = x.x.x.x:1494
ciphers = GOST2001-GOST89-GOST89
TIMEOUTclose = 1
[RDP-TLS-RSA]
engineNum=2
key=101
cert=client_rsa.crt
accept = 127.0.0.1:8087
connect = 127.0.0.1:8088
TIMEOUTclose = 1
А ходить клиентом RDP надо на 127.0.0.1:8087.
Защита по гостам
Базовая схема представлена на рисунке.
Конфигурирование автоматического выпуска сертификатов
Переходим в Computer Configuration -> Policies -> Windows Settings -> Security Settings -> Public Key Policies и выбираем Certificate Services Client — Auto-Enrollment Включаем автоматический выпуск сертификатов а так же настройки по их автоматическому обновлению:

Проверка работоспособности
После применения групповой политики Windows клиенты должны в автоматическом порядке получить сертификат. Если этого не произошло, стоит обратить внимание на:
- Отсутствие в правильной группе безопасности, которая указана в шаблоне;
- Отсутствие к ЦС необходимых сетевых портов от клиента. Напомню, это tcp/135 (RPC) и динамические порты tcp/49152—65535.
Проверить что сертификат был успешно выпущен можно в консоли ADCS:

При следующем RDP подключении, стоит обратить внимание на наличие «замка» в верхнем меню RDP подключения. Нажав на этот «замок» можно удостоверится что используется нужный сертификат.

Создание групповой политики для rdp подключений
Непосредственно сама конфигурация Windows машин будет централизовано выполнятся с помощью групповой политики. Я рекомендую создать отдельный экземпляр политики, в котором будет следующее:
- Задание имени шаблона сертификата для использования в RDP подключениях;
- Задание типа шифрования RDP подключений;
- Конфигурирование автоматического выпуска сертификатов.
Создание шаблона сертификата rdp в adcs
Первый шаг состоит в создании шаблона сертификата, с помощью которого Windows клиенты будут автоматически генерировать сертификаты используемые в RDP подключениях. Для этого в оснастке ADCS переходим к управлению шаблонами сертификатов:

Дублируем сертификат Computer

Задаем имя будущего шаблона:

Указываем настройки совместимости:

В Extensions, необходимо задать правильные Application Policies для поддержки TLS в RDP протоколе

Для этого удаляем Client Authentication и Server Authentication и добавляем Remote Desktop Authentication с OID 1.3.6.1.4.1.311.54.1.2, как показано на скриншоте:

Далее, необходимо задать группу безопасности, члены которой должны автоматически сгенерировать сертификат по этому шаблону. Для этого добавляем нужную группу безопасности в DACL и назначаем соответствующие права:

Завершающим шагом будет его выпуск на выдающем корпоративном ЦС:

Установка сертификата на виртуальные машины
Для использования белого сертификата на виртуальных машинах необходимо:
Создадим новую групповую политику на уровне Organizational Unit, выделенного для компьютерных аккаунтов виртуальных машин фермы VDI.
Данная политика должна выполнить Startup Script ExportVDICert.bat на виртуальных машинах.
В указанном скрипте используются утилиты certutil и FindPrivateKey от Microsoft. Certutil является встроенной утилитой, FindPrivateKey предоставляется в качестве Samle tool для разработчиков и может быль скомпилирован самостоятельно. Скрипт необходимо расположить внутри политики.
Сертификат и утилиту FindPrivateKey необходимо разместить в сетевой папке, откуда скрипт будет забирать файлы для установки. Текст скрипта:
certutil -f -p "<certificate password>" -importpfx "<Path to pfx>" NoExport
c:
mkdir "c:TempCertSecurity"
cd "c:TempCertSecurity"
xcopy "<Path to FindPrivateKey.exe>" "c:TempCertSecurity"
FindPrivateKey.exe My LocalMachine -t "<thumbprint of certificate>" -a > tmp.txt
set /p myvar= < tmp.txt
del tmp.txt
del FindPrivateKey.exe
cd
rd "c:TempCertSecurity"
cacls.exe %myvar% /E /G "NETWORK SERVICE":R"
При помощи данного скрипта после перезагрузки виртуальной машины будет установлен новый сертификат и для него будут настроены права.
Следующая часть политики касается установки параметра SSLCertificateSHA1Hash. Необходимый ключ настраивается через Preferences Windows Settings Registry
Шаг второй. и снова вопросы доверия
Для избавления от этого сообщения нам снова понадобится групповая политика. На этот раз дорога лежит в раздел Конфигурация компьютера — Политики — Административные шаблоны — Компоненты Windows — Службы удаленных рабочих столов — Клиент подключения к удаленному рабочему столу — Указать отпечатки SHA1 сертификатов, представляющих доверенных издателей RDP.
Нужная нам политика.
В политике достаточно добавить уже знакомый нам отпечаток с предыдущего шага.
Стоит отметить, что эта политика перекрывает политику «Разрешать RDP-файлы от допустимых издателей и пользовательские параметры RDP, заданные по умолчанию».
Настроенная политика.
Шаг нулевой. подготовка и вопросы доверия
Итак, наш пользователь тыкает на сохраненный файл с расширением .rdp и получает такой вот запрос:
«Зловредное» подключение.
Для избавления от этого окна используется специальная утилита под названием RDPSign.exe. Полная документация доступна, как обычно, на официальном сайте, а мы разберем пример использования.
Для начала нам нужно взять сертификат для подписывания файла. Он может быть:
Самое главное, чтобы сертификат имел возможность подписывать (да, можно отобратьу бухгалтеров ЭЦП), а клиентские ПК ему доверяли. Здесь я буду использовать самоподписанный сертификат.
Напомню, что доверие самоподписанному сертификату можно организовать при помощи групповых политик. Чуть больше подробностей — под спойлером.
Если проблемы с доверием решены, переходим непосредственно к вопросу подписи.
Шаг первый. размашисто подписываем файл
Сертификат есть, теперь нужно узнать его отпечаток. Просто откроем его в оснастке «Сертификаты» и скопируем на вкладке «Состав».
Нужный нам отпечаток.
Лучше сразу его привести к должному виду — только большие буквы и без пробелов, если они есть. Это удобно сделать в консоли PowerShell командой:
("6b142d74ca7eb9f3d34a2fe16d1b949839dba8fa").ToUpper().Replace(" ","")
Получив отпечаток в нужном формате, можно смело подписывать файл rdp:
rdpsign.exe /sha256 6B142D74CA7EB9F3D34A2FE16D1B949839DBA8FA .contoso.rdp
Где .contoso.rdp — абсолютный или относительный путь к нашему файлу.
После того как файл подписан, уже не получится изменить часть параметров через графический интерфейс вроде имени сервера (действительно, иначе смысл подписывать?) А если поменять настройки текстовым редактором, то подпись «слетает».
Теперь при двойном клике по ярлыку сообщение будет другим:
Новое сообщение. Цвет менее опасный, уже прогресс.
Избавимся же и от него.
