Автоматическая выдача сертификатов пользователям через GPO

от автора

Введение

В корпоративной среде с ростом количества сотрудников, которым требуется доступ к системам с использованием ЭЦП, возникла необходимость автоматизировать процесс установки сертификатов.

Попытки применить стандартные средства — Import-PfxCertificatecertutil и другие — результата не дали: сертификаты не виделись рядом приложений, включая СБИС. Готовых рабочих решений тоже не нашлось. Пришлось разрабатывать собственный метод.

В этой статье описан механизм, применяемый для распространения сертификатов ИФНС. Методы экспорта ключей и сертификатов можно найти в сети, поэтому они здесь не рассматриваются. Вопросы безопасности при передаче приватных ключей также остаются за рамками — предполагается, что всё выполняется во внутреннем доверенном контуре.

За основу была взята статья «Перенос контейнеров закрытых ключей и сертификатов CryptoPro», где описан ручной процесс. Я доработал его и автоматизировал для централизованного распространения через GPO.


Проблема

При переносе сертификатов и ключей между машинами или профилями возникает одна и та же трудность: они «привязаны» к SID пользователя.

Если импортировать .reg напрямую, записи окажутся связаны с SID другого пользователя и работать не будут.

Поэтому при автоматическом распространении необходимо корректно подставлять текущий SID.


Решение

Я подготовил набор PowerShell-скриптов, которые выполняются от имени пользователя при логоне (через GPO Logon Script).

Сценарий работы такой:

  1. Шаблон реестра
    В исходном .reg файле хранится конфигурация с «старым» SID.

  2. Подмена SID
    Скрипт получает SID текущего пользователя

    [System.Security.Principal.WindowsIdentity]::GetCurrent().User.Value 

    и заменяет им статический идентификатор в файле.

  3. Импорт реестра
    Обновлённый .reg файл импортируется в HKCU.

  4. Копирование сертификатов
    Из сетевой папки (\\share\Cert\My) копируются нужные файлы в профиль пользователя:

    %APPDATA%\Microsoft\SystemCertificates\My

  5. Готово
    При следующем запуске приложений (Outlook, браузеры, CryptoPro) пользователь сразу получает доступ к сертификатам.


Пример кода

Запуск разных скриптов по группам

Этот пример показывает, как можно привязывать разные сценарии к членству пользователя в группах AD. Каждое группа соответствует отдельному сертификату.

# Задаем группы и соответствующие пути к скриптам для каждой группы $groupScriptMap = @{     "First Group" = "\\path\first_script.ps1"     "Second Group" = "\\path\second_script.ps1" }  # Получаем информацию о текущем пользователе $user = [System.Security.Principal.WindowsIdentity]::GetCurrent()  $userGroups = $user.Groups | ForEach-Object {      $_.Translate([System.Security.Principal.NTAccount]).Value.Split("\")[1] }  # Перебираем каждую группу из маппинга и проверяем, состоит ли в ней пользователь foreach ($group in $groupScriptMap.Keys) {     if ($userGroups -contains $group) {         Write-Output "Пользователь $($user.Name) принадлежит группе $group."                  # Получаем путь к скрипту для этой группы         $scriptPath = $groupScriptMap[$group]         Write-Output "Запускается скрипт для группы: $scriptPath"                  # Выполняем соответствующий скрипт         try {             #Start-Process -FilePath "powershell.exe" -ArgumentList "-ExecutionPolicy Bypass -File $scriptPath" -NoNewWindow -Wait             Start-Process -FilePath "powershell.exe" -ArgumentList "-ExecutionPolicy", "Bypass", "-File", "`"$scriptPath`"" -NoNewWindow -Wait          } catch {             Write-Output "Ошибка при выполнении скрипта для группы $[group]: $_"         }     } else {         Write-Output "Пользователь $($user.Name) не состоит в группе $group."     } }   

Данные скрипт производит основные действия по замене SID, импорте reg файла и копировании хранилища личных сертификатов пользователя

 # Указываем путь к файлу реестра (исходный шаблон .reg файл) $regFileSource = "\\path\first_file.reg"  # Определяем временную папку текущего пользователя $tempFolder = [System.IO.Path]::GetTempPath()  # Определяем SID текущего пользователя $userSID = (Get-WmiObject -Class Win32_UserAccount -Filter "Name='$env:USERNAME'").SID  # Определяем целевой файл во временной папке $regFileTemp = Join-Path $tempFolder "modified_registry.reg"  # Читаем содержимое исходного файла реестра $regContent = Get-Content -Path $regFileSource -Encoding Unicode  # Статический SID, который будем заменять $oldSID = "S-1-5-21-3734670798-76392145-1373982661-1117"  # Заменяем статический SID на SID текущего пользователя $updatedContent = $regContent -replace $oldSID, $userSID  # Записываем обновленный файл реестра во временную папку $updatedContent | Out-File -FilePath $regFileTemp -Encoding Unicode  # Импортируем обновленный файл реестра reg import $regFileTemp  # Указываем сетевую папку для копирования $networkFolder = "\\path\My"  # Папка пользователя, куда нужно скопировать сетевую папку $userFolder = "C:\Users\$env:USERNAME\AppData\Roaming\Microsoft\SystemCertificates"  # Копируем содержимое с заменой конфликтов Copy-Item -Path $networkFolder -Destination $userFolder -Recurse -Force  Write-Host "Файл реестра был успешно импортирован, и папка скопирована."   

Варианты использования

  • Распространение сертификатов ЭЦП среди сотрудников

  • Миграция рабочих мест и перенос профилей


Репозиторий

Исходный код доступен здесь. Там же постарался создать подробный и понятный README.
👉 GitHub — provision_of_certificates_GPO


Заключение

Предложенный метод позволяет автоматизировать раздачу сертификатов через GPO без ручных действий. Он прост в реализации.

При этом стоит помнить о недостатках:

  • нет централизованного контроля за сроком действия сертификатов;

  • приватные ключи передаются в файлах, что требует доверенной среды;

  • метод рассчитан именно на Windows-среду с CryptoPro.


ссылка на оригинал статьи https://habr.com/ru/articles/941198/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *