Posts on this page:
Примечание: данный материал публикуется как обязательный для знания IT-специалистами, которые занимаются или только собираются заниматься темой PKI (Public Key Infrastructure).
Мне иногда задают вопрос про сущность этой опции Enable private strong protection, а так же встречаются любители обезопасить свои ключи данной опцией. Итак, что это такое? Private key strong protection позволяет вам шифровать ваш закрытый ключ отдельным паролем и является некоторым подобием поведения, когда сертификат находится на смарт-карте. Включить данную опцию вы можете при энроллменте или импорте сертификата. При энроллменте выберите нужный вам шаблон сертификата, нажмите Properties, перейдите на вкладку Private key, раскройте Key options и поставьте галочку на Strong private key protection:
после нажатия Ok, вылезет окошко, которое потребует у вас указать степень защиты и пароль (если выбран High):
Я выбрал уровень High и следующим окном меня попросили ввести пароль. Этот пароль не обязательно должен быть такой же как и пароль от учётной записи. Поэтому пароль можно указывать любой. И когда вы захотите использовать закрытый ключ от этого сертификата (например, подписать почтовое сообщение или аутентифицироваться по сертификату на веб-узле), то появится запрос для подтверждения использования закрытого ключа:
Вот так оно и работает. Кажется, что это очень действенный способ для защиты закрытых ключей в софтовом хранилище (когда ключи хранятся на жёстком диске), однако тут можно очень легко нарваться на проблемы, что вы больше никогда не получите доступ к закрытому ключу. Поэтому данную опцию категорически нельзя использовать для:
все сертификаты (например, SSL, IPsec), которые хранятся в компьютерном хранилище используются только учётной записью компьютера и диалоговое окошко с требованием подтвердить доступ к ключу появится у учётной записи LocalSystem, а вы не увидите этого запроса, в следствии чего сертификат невозможно будет использовать.
здесь кроется похожая засада. Дело в том, что шифрование и расшифровка файла (во всяком случае в Vista и выше) не происходит в окружении пользователя. При шифровании файла сертификатом EFS могло бы происходить примерно такой процесс:
Здесь как бы особого криминала нет, поскольку на данном этапе LSA ничего не знает про закрытый ключ, но при попытке расшифровать файл получается такая картина:
Поэтому окошка вы никакого не видите и, следовательно, доступ к данным сразу же теряете. Чтобы избежать этого было сделано хорошее решение — не шифровать файлы вообще, если сертификат EFS защищён отдельным паролем и запросить/сгенерировать новый сертификат не представляется возможным. Т.е. на стадии 1 LSA попутно проверяет статус закрытого ключа. И если он защищён, то пробует запросить новый сертификат EFS для пользователя. Если CA недоступен или нет шаблона Basic EFS, то пытается сгенерировать самоподписанный. Если политиками запрещено использовать самоподписанные сертификаты EFS, то получаете ошибку и никакого шифрования не производится.
Нужен ли этот Strong protection в реальной жизни? В реальной жизни есть смысл использовать смарт-карты, тем более сейчас всё больше приложений поддерживают их. И EFS в том числе. Тогда strong protection можно отключить на уровне политик:
Computer Configuration –> Policies –> Windows Settings Security Options –> System Cryptography: Force strong key protection for user keys stored on the computer
Если не уверены, что оно вам надо, то лучше отключить эту возможность на уровне домена. Включать эту политику не рекомендуется, поскольку она может привести к катастрофическим последствиям, что сертификаты у вас просто перестанут работать.
Продолжаем серию постов, которые посвящены базовому управлению объектами PKI в Active Directory. На данный момент мы рассмотрели сценарии публикации и просмотра сертификатов в Active Directory:
На данном этапе нам осталось последнее — удаление сертификатов из AD. Логика здесь очень простая: командой Get-ADPKIObject мы получаем коллекцию объектов, которые представляют собой сертификаты и через конвейер командой Remove-ADPKIObject указываем ID объектов, которые необходимо удалить. Если кто-то уже разбирал код предыдущих скриптов, то ему будет совсем нетрудно понять логику скрипта удаления объектов. Вот он, вместе с комментариями:
function Remove-ADPKIObject { <# .Synopsis Deletes certificates from Active Directory containers .Description Deletes certificates from Active Directory containers by specifying particular ID or IDs .Parameter ID Specifies certificate ID to delete that was set in Get-ADPKIObject command. .EXAMPLE Get-ADPKIObject RootCA | Remove-ADPKIObject 2 deletes certificate with ID = 2 in certificate viewer .Outputs This command provide a resultant of operation. #> param([int[]]$ID = $(throw "you must specify number of the object to delete")) # объявляем массив для хранения сертификатов из контейнера NTAuthCertificates begin {$sum = @()} process { # проверяем тип контейнера входящего объекта if ($_.Container -ne "NTAuthCertificates") { # если это не NTAuthCertificates, то проверяем, что ID текущего объекта # совпадает с ID, который нужно удалить if (@($ID) -contains $_.Id) { # если совпал, то собираем LDAP-запрос $ldap = [ADSI]"LDAP://CN=$($_.Container),$script:ConfigContext" # и удаляем текущий объект из AD $retn = $ldap.Delete("certificationAuthority", "CN=$($_.Subject)") if ($?) { Write-Host "`'$($_.Subject)`' certificate was sucessfully deleted from `'$($_.Container)`' container"` -ForegroundColor Green } } # если контейнер текущего объекта является NTAuthCertificates, то собираем их все в массив } else {$sum += $_} } end { # проверяем, что массив непустой (т.е. надо что-то удалять из NTAuthCertificates) if ($sum) { # если массив непустой, то выбираем те элементы, которые нужно сохранить # т.е. ID которых не содержится в аргументах скрипта $sum = @($sum |?{$ID -notcontains $_.Id}) # делаем LDAP-запрос к этому контейнеру $ldap = [ADSI]"LDAP://CN=$($_.Container),$script:ConfigContext" # проверяем, что после фильтрации, хотя бы один сертификат нужно оставить if ($sum.count -ge 1) { # записываем первый сертификат. Это необходимо потому что ADSI не поддерживает запись # массива сертификатов в свойство cACertificate, а только один сертификат в виде byte[] $ldap.put("cACertificate", [byte[]]$sum[0].RawCertificate) # а вот простое добавление он поддерживает. Тогда ADSI сам пересоберёт объекты # в свойстве в нужный формат данных. На данном этапе я применил маленькую хитрость: # как видно, я первый сертификат записываю дважды - предыдущей строкой и в первой итерации # текущей строки. Но это не проблема, поскольку метод SetInfo() записывает только уникальные # объекты, а дублирующиеся просто отбросит. $sum | %{$ldap.cACertificate += ,[byte[]]$($_.RawCertificate)} $ldap.SetInfo() if ($?) { Write-Host "`'$($_.Subject)`' certificate was sucessfully deleted from `'$($_.Container)`' container"` -ForegroundColor Green } # а вот если после фильтрации объектов, у нас ничего не остаётся на запись, то это означает, что все # сертификаты из этого контейнера удаляются. Поэтому мы просто удаляем запись NTAuthCertificates. } else { ([ADSI]"LDAP://$script:ConfigContext").Delete("certificationAuthority", "CN=NTAuthCertificates") if ($?) {Write-Host "All certificates was sucessfully deleted from NTAuthCertificates entry ." -ForegroundColor Green Write-Warning "This was last certificate in contaner. NTAuthCertificates entry is removed from Active Directory" } } } } }
И теперь можно подвести краткие итоги. Мы смогли реализовать функционал certutil и других графических утилит (консоли MMC) в PowerShell значительно улучшив читабельность выходных объектов, адаптировали под работу из консоли (синтаксис стал значимо короче и более юзерфрендли) и шаг за шагом делаем из PowerShell единое консольное средство управления различными аспектами PKI.
Можно задать вопрос: а кто целевая аудитория всего этого? Целевая аудитория есть — администраторы PKI. Просто у вас не всегда будет возможность использовать графические консоли для решения этих задач (потому что их функционал далёк от идеального). Можно использовать certutil, который умеет много чего, но тоже имеет свои недостатки. Это и ужасный синтаксис, и вырвиглазный неуправляемый вывод результатов. Вобщем я надеюсь, что рано или поздно PowerShell сможет по-настоящему заменить certutil (который вообще-то ни в чём не виноват) и стать единой консолью всех Windows-администраторов. Вот не знаю на сколько это хорошо или плохо, потому что Microsoft всех насильно переводит на PowerShell (это очень показательно продемонстрировано в MS Exchange, где у вас по сути есть только PowerShell и всё). Обычно, насильно переводят на другой инструмент когда он является УГ и очень тяжело на него перевести людей посредством обычной рекламы. Но является ли PowerShell таким УГ? Я пока не готов ответить на этот вопрос. Моё мнение — PowerShell пока что особой революцией не стал. Даже не смотря на тонны рекламы, пеара и прочего, где восхваляют PowerShell, закидывают ногами CMD/WSH. Это обусловлено тем фактом, что не всегда PowerShell бывает удобней CMD/WSH, особенно в тривиальных задачах. Говорить, что синтаксис стал более простым и компактным тоже нельзя, потому что реально функционала из коробки хватает для решения процентов 10 задач. Всё остальное нужно скриптовать и программировать (да-да!) самому. Благо средств для этого в PowerShell хватает. Во что это обычно выливается? А в то, что в большинстве случаев результирующий объём кода будет не сильно меньше, чем в связке WSH + CMD. В любом случае преимущества PowerShell перед остальными очевидны, но они далеко не определяющие, ведь люди раньше решали свои задачи на WSH/CMD, пирожки продавались, бизнес шёл. С одной стороны Microsoft дал людям простор для творчества, т.е. делать в PowerShell всякие потрясающие штуки и всё такое. Но это не совсем то, что нужно было администраторам. Им нужна одна кнопка на весь экран с надписью «Сделать всё п**дато!». Пока что PowerShell и близко не готов стать такой кнопкой, а является «удочкой». Т.е. удочка у вас уже есть, а что касается конечной рыбы (результата), то дело осталось за малым — написать мега-скрипт. Мне вот интересно, что думают администраторы Exchange (поскольку пока что только они получили полноценную поддержку для своего продукта в PowerShell) — стало ли им жить легче с PowerShell или нет? Если да, то это может быть хорошим знаком, что однажды PowerShell станет такой кнопкой. И не будет более в системе certutil и всеми задачами будет рулить PowerShell (пока что это наиболее логичный сценарий развития событий). А вот если их жизнь не стала легче, то обещанной революции (которая по словам Microsoft уже наступила, как и вендекапец у луноходов) не будет, а будет просто какое-то логическое продолжение предыдущих инструментов для сценариев.
К чему я написал столько букв? К тому, что я ежедневно задаю себе один и тот же вопрос: а зачем я всё это делаю? А ответ найти очень непросто, потому что отмазы вида «проще, удобней, красивее» не годятся для серьёзного аргумента. На самом деле я не ищу ответ на него, а просто говорю себе «так надо» и делаю. Поэтому не надо меня использовать как пример «правильного пользователя PowerShell» и пытаться повторить что-то подобное астрономических масштабов на овер9000 строк — поверьте, оно не стоит того. Используйте его по мере сил. Если чего-то будет не хватать и его решение потребует значительных усилий — посмотрите на готовые утилиты, они наверняка будут уметь то, что вам надо.
Удачи!© One
В предыдущем посте мы ознакомились с основными контейнерами с объектами PKI в Active Directory и смогли изучить функциональный аналог ключа dspublish в утилите certutil. Если публикация сертификатов в AD задача простая даже для Certutil, то просмотр содержимого может быть весьма нетривиальным. Например, если вы хотите посмотреть содержимое записи NTAuthCertificates, то придётся выполнить вот такую команду:
certutil –viewstore "CN=NTAuthCertificates,CN=Public Key Services,CN=Services,CN=Configuration, ForestRootDomainDN"
такие вещи совершенно неприспособлены к командной строке, поскольку надо набирать много текста и ошибиться весьма просто. Одно хорошо, команда выводит графическое окошко, где мы можем посмотреть содержимое. Но тут есть несколько неудобных моментов: мы не можем посмотреть несколько контейнеров сразу, для каждого контейнера надо выполнять отдельную команду. В этом окошке мы можем только посмотреть на содержимое контейнера и всё. Ни добавить, ни удалить сертификат мы не можем. Для добавления сертификатов мы можем воспользоваться тем же certutil или моим скриптом, который был опубликован в предыдущем посте. Графика — хорошо и замечательно, но мы можем хотеть автоматизировать какие-то задачи или просто посмотреть информацию в консоли. Вы можете подумать, что это не нужно, но преимущество между консольным выводом и графическим диалоговым окном очевидное: из первого можно копировать информацию в буфер обмена. Есть ещё вариант — для просмотра и удаления сертификатов из AD, пользоваться консолью pkiview.msc. Но мы сразу же теряем главную нить — единое средство управления. Т.е. даже похожие операции мы должны выполнять в разных инструментах! Но с появлением PowerShell мы получили единый (хоть и консольный) инструмент, которым можно автоматизировать абсолютно всё! Даже сам PowerShell :-) Вот, собственно код, который в разы упрощает процесс просмотра содержимого контейнеров:
function Get-ADPKIObject { <# .Synopsis Displays certificates info from Active Directory containers .Description Displays info about certificates that are stored in AD PKI-related containers. .Parameter Container Optional parameter. Specifies particular container to view. May contain one or more value from following possible values: RootCA - retrieves certificates from Certification Authorities container SubCA - retrieves certificates from AIA container NTAuthCA - retrieves certificates from NTAuthCertificate directory entry. if no parameter is set, command will return all certificates from all applicable containers. .EXAMPLE Get-ADPKIObject RootCA Retrieves certificates from Certification Authorities container .EXAMPLE Get-ADPKIObject RootCA, AIA Retrieves certificates from Certification Authorities and AIA containers .Outputs Output AD PKI object collection #> [CmdletBinding()] param([string[]][ValidateSet("RootCA", "SubCA", "NTAuthCA", "")]$Container) # объявляем массив, который будет хранить выходные объекты $script:sum = @() # это весьма крутая штука будет. Каждый объект будет содержать свойство Id или просто # порядковый номер объекта. При дальнейших операциях с этими объектами вам достаточно # будет указать его Id вместо длинных и неудобных LDAP/Thumpbrint значений, как это делается # в certutil и подобных ему утилитах. Нумерацию начнём с единицы $script:n = 1 # итоговая функция, которая будет разбирать бинарные массивы и готовить выходные объекты function _formatter_ ($certs, $type, $name) { # поскольку у нас все объекты в AD находятся в бинарном формате, мы импортируем каждый из них # в X509Certificate2 объект. $certs | %{ $script:Cert.Import($_) # здесь мы создаём образец выходного объекта и обвязываем этот объект необходимыми свойстами и данными $current = "" | select @{n='Id';e={$script:n}}, Subject, @{n='Type';e={$type}}, @{n='Container';e={$name}}, @{n='Thumbprint';e={$script:Cert.Thumbprint}}, @{n='SerialNumber';e={$script:Cert.SerialNumber}}, @{n='ValidFrom';e={$script:Cert.NotBefore}}, @{n='ValidTo';e={$script:Cert.NotAfter}}, @{n='RawCertificate';e={$script:Cert.RawData}} # чтобы не писать полный DN поля Subject, мы будем показывать только первую его часть # (которая отображается в самом сертификате) [void]($script:Cert.Subject -match 'CN=([^,]+)') $current.Subject = $matches[1] # добавляем объект в массив выходных объектов $script:sum += $current # очищаем X509Certificate2 $script:Cert.Reset() # увеличиваем счётчик и обрабатываем следующий элемент $script:n++ } } # ещё одна суб-функция, которая выдёргивает сертификаты из AD в бинарном виде и отправляет # их в _formatter_, который уже сформирует итоговые объекты. function _switcher_ ($name) { # подключаемся к нужному контейнеру $ldap = [ADSI]("LDAP://CN=$name,$script:ConfigContext") # как мы знаем, NTAuthCertificates не является контейнером, поэтому для него код будет немного # отличаться. А отличие будет состоять в том, что мы не будем залезать в контейнер, а сразу читать # свойства объекта NTAuthCA if ($name -eq "NTAuthCertificates") { # убеждаемся, что длина первого элемента свойства cACertificate больше единицы, т.е. содержит ненулевое # значение. Так же проверяем свойство crossCertificatePair, которое содержит Cross-certificates # и если оно не нулевое, то отправляем и его на формирование вывода if ($ldap.cACertificate[0].count -gt 1) { $certs = @($ldap.cACertificate) _formatter_ $certs "CA Certificate" $name } if ($ldap.crossCertificatePair[0].count -gt 1) { $certs = @($ldap.cACertificate) _formatter_ $certs "Cross CA Certificate" $name } # и переходим к следующему контейнеру return } # если контейнер указан как Certification Authority и/или AIA, то заглядываем # внутрь контейнера $ldap.psbase.children | %{ # и заглядываем в каждую запись на исследование свойств cACetificate и crossCertificatePair $certs = @($_.cACertificate) $ccerts = @($_.crossCertificatePair) # проверяем, что свойство имеет ненулевое значение. Если так, то отправляем # содержимое этих свойств на формирование вывода if ($certs[0].count -gt 1) {_formatter_ $certs "CA Certificate" $name} if ($ccerts[0].count -gt 1) {_formatter_ $ccerts "Cross CA Certificate" $name} } } switch ($Container) { # конструкцией switch проверяем содержимое аргумента функции, чтобы определить какие именно # контейнеры надо обследовать. "RootCA" {_switcher_ "Certification Authorities"} "SubCA" {_switcher_ "AIA"} "NTAuthCA" {_switcher_ "NTAuthCertificates"} # если контейнер в аргументе не указан, то проверяем все контейнеры и записи "" { _switcher_ "Certification Authorities" _switcher_ "AIA" _switcher_ "NTAUthCertificates" } } # когда вывод будет полностью сформирован, выбрасываем все объекты в консоль $script:sum }
Примечание: данная функция является частью файла dspublish.ps1, т.к. использует глобально объявленные переменные.
и вывод у него вот такой красивый:
Id : 3 Subject : Contoso CA Type : CA Certificate Container : AIA Thumbprint : BA8FECE99165E68CE27C9F0AF5F0664FDA39F7A2 SerialNumber : 5DD87E4CFFE3B3BC43F608EB57C767F7 ValidFrom : 2009.02.15. 16:31:15 ValidTo : 2014.02.15. 16:40:11 RawCertificate : {48, 130, 4, 98...} Id : 4 Subject : sysadmins-LV-CA Type : Cross CA Certificate Container : AIA Thumbprint : 1A28B582E21803D2BFE0DAEEF4593DE372C8EC3C SerialNumber : 170AD11B0000000000A7 ValidFrom : 2009.11.24. 19:43:10 ValidTo : 2011.03.30. 17:06:53 RawCertificate : {48, 130, 7, 94...}
я считаю его достаточно информативным. Но если хотите посмотреть любой сертификат из этого списка, то можно и сделать просмотр. К сожалению я в программировании не шарю и как работать напрямую с библиотекой просмотрщика сертификатов, поэтому я реализовал просмотр обходным путём:
filter View-ADPKIObject { <# .Synopsis Displays certificates in certificate viewer .Description Displays certificates in certificate viewer by selecting necessary certificates ID. Must be placed after Get-ADPKIObject command only. .Parameter ID Specifies certificate ID that was set in Get-ADPKIObject command. .EXAMPLE Get-ADPKIObject RootCA | ViewADPKIObject 1, 3 displays certificate with ID = 2 in certificate viewer .Outputs Script doesn't generate any output except errors #> # судя по конструкции int[] мы можем указать несколько чисел, тогда все выбранные # сертификаты будут отображены. Номер указывать обязательно. param([int[]]$ID = $(throw "you must specify number of the object to display")) # и проверяем входные объекты с конвейера на предмет их ID. Если ID совпадает с # одним из ID в аргументах, обрабатываем его. Если ID не совпадает, ничего не делаем. if (@($ID) -contains $_.Id) { # генерируем в пользовательской папке Temp временный файл с рандомным расширением $TempFile = [System.IO.Path]::GetTempFileName() + ".cer" # записываем бинарный массив сертификата в файл в виде DER кодировки [System.IO.File]::WriteAllBytes($TempFile, $_.RawCertificate) # запускаем файл (просмоторщик сертификатов) & $TempFile # в санитарных целях ждём пол секунды Start-Sleep 0.5 # и удаляем этот файл, чтобы не копился мусор del $TempFile -Force } }
Как вы видите, ничего сверх-космического или магического в этом коде нет, самое трудное здесь — придумать логику работы. А остальное — накидать несколько строк кода и у нас PowerShell в лёгкую может соперничать с certutil за право называться единой утилитой управления PKI :-)
Чтобы подкрутить рейтинг PowerShell в этой конкуренции, в следующий раз я покажу как мы можем легко и просто удалять сертификаты из контейнеров AD с использованием PowerShell :-)
Подоспела ещё одна задачка для PowerShell'а — управление объектами PKI в Active Directory. Active Directory содержит целый раздел посвящённый PKI и вот из чего он состоит:
Вот о них мы сегодня и поговорим. В AD есть ещё несколько контейнеров, которые связаны с PKI, но они сегодня интереса представлять не будут. Как мы уже знаем, в:
Update 04.01.2010: исправлена неточность в тексте. CRL'ы из CDP контейнера AD не копируются на клиентские компьютеры.
В предыдущей статье: Обсуждение схем иерархии Certification Authority мы обсудили наиболее часто встречающиеся ошибки при дизайне иерархии CA. Если кто-то захочет перевести как минимум корневые Enterprise CA на Standalone CA и сделать их Offline, то в этом посте вы узнаете как это делается пошагово.
Изначальные условия:
Перед переносом текущего корневого и/или Policy CA следует заранее спланировать периодичность публикации CRL. Если Enterprise CA, как правило, публикует Base CRL каждые 7 дней и Delta CRL — каждые 24 часа. Для Offline CA такая конфигурация будет неработоспособна. Поэтому мы должны переконфигурировать следующие параметры:
Для этого мы можем применить вот такой Reg файл:
Примечание: Статья содержит сведения о внесении изменений в системный реестр. Перед внесением изменений в системный реестр рекомендуется создать резервную копию системного реестра и изучить процедуру его восстановления. Дополнительные сведения о создании резервной копии, восстановлении и изменении реестра см. в статье базы знаний Microsoft: http://support.microsoft.com/kb/256986/.
Windows Registry Editor Version 5.00 Root CA] "CRLPeriod"="months" "CRLPeriodUnits"=dword:00000003 "CRLOverlapPeriod"="weeks" "CRLOverlapUnits"=dword:00000001 "CRLDeltaPeriod"="Days" "CRLDeltaPeriodUnits"=dword:00000000 "CRLDeltaOverlapPeriod"="hours" "CRLDeltaOverlapUnits"=dword:00000000 "CAXchgValidityPeriod"="Weeks" "CAXchgValidityPeriodUnits"=dword:00000000 "CAXchgOverlapPeriod"="Days" "CAXchgOverlapPeriodUnits"=dword:00000000 "ValidityPeriod"="Years" "ValidityPeriodUnits"=dword:00000005
Этим файлом мы задаём срок действия Base CRL в 3 месяца (но этот период может быть и другой, в зависимости от местных условий) с overlap равным 1 неделя. Так же отключили использование Delta CRL и CA Exchange, который используется для архивирования ключей в базе CA. А так же установили срок действия конечных сертификатов в 5 лет. Если под этим CA будет выделенный Offline Policy CA, то это значение может быть изменено на 10 лет. После импорта этого файла, вы должны перезапустить службу Certificates Services:
net stop certsvc && net start certsvc
Теперь нужно опубликовать новый CRL с новыми настройками:
certutil –CRL
Из предварительных приготовлений это всё, что нам потребуется. Пора приступать к бэкапу.
Бэкапу будут подлежать следующие вещи:
Примечание: на данном этапе пользователи и компьютеры уже не смогут отправлять запросы на этот CA. Но могут продолжать использовать CRL'ы для валидации сертификатов.
Первым делом нужно сделать бэкап самой базы CA. Для этого в командной строке выполните:
certutil –backup c:\RootCA_%date%
Для удаления ключевой пары запустите консоль MMC и добавьте в ней оснастку Certificates с указанным контекстом Computer Account. В оснастке раскройте секцию: Personal –> Certificates и найдите текущий сертификат CA. Далее, Action –> All Tasks –> Export. На странице Export Private Key мастера экспорта сертификатов переставьте переключатель в Yes, export private key. На странице Export file format поставьте галочки напротив Delete the private key if the export is successful и Export extended properties. Этим самым мы удаляем закрытый ключ CA с данного сервера, поскольку он больше не нужен и для предотвращения несанкционированного доступа к ключу. Установите пароль на PFX файл и сохраните в него экспортируемый сертификат. После экспорта удалите этот PFX файл.
Примечание: экспорт сертификата в PFX нужен только для удаления с сервера закрытого ключа CA. Сам ключ был сохранён во время бэкапа базы CA.
Теперь у нас в корне диска C: будет храниться полный бэкап базы CA и его ключевая пара. Нам осталось выполнить бэкап конфигурации CA. Для этого откройте редактор реестра и установите курсор на ключе:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\CertSvc\Configuration\Adatum Root CA
Экспортируйте этот ключ в Reg файл и сохраните в папке, где расположен бэкап базы CA. После этого перенесите всю папку бэкапа на съёмный носитель и скопируйте в корень диска C: компьютера OfflineRCA.
Теперь мы готовы демонтировать наш Online Enterprise Root CA. Для этого запустите Server Manager (для 2008 и выше) или Add or Remove Programs –> Windows Components (для 2003) и удалите с сервера роль CA.
После демонтажа роли убедитесь, что данный CA больше не отображается в AD как Issuing CA. Для этого можете запустить оснастку ADSIEdit.msc в контексте Configuration. И пройдите по пути: Configuration –> Services –> Public Key Services –> Enrollment Services. Если демонтируемый CA отсутствует внутри этой папки, то можете закрыть консоль. Если всё ещё отображается, то удалите запись данного CA и закройте ADSI Editor.
Примечание: для удаления объектов PKI из AD вам потребуются права Enterprise Admins.
На данном этапе все манипуляции будут производиться на сервере OfflineRCA, который состоит в рабочей группе. Запустите Server Manager (или Add or Remove Programs –> Windows Components для 2003) и поставьте галочку на Active Directory Certificate Services (или Certification Authority для 2003). Я думаю, что мастер вам уже знаком, поэтому я только расскажу на каких страницах мастера нам потребуется сделать изменения. В принципе, можете двигаться Next->Next до страницы Private Key. На этой странице выберите Use existing private key и Select a certificate and use its associated private key. Нажмите Next и нажмите кнопку Import. Импортируйте закрытый ключ вместе с сертификатом из PFX файла, который находится в папке с бэкапом CA. На следующей странице можете задать папки хранения базы CA.
Примечание: вам не обязательно устанавливать Standalone CA на полный сервер, а лучше будет устанавливать в Server Core.
Когда роль CA установлена, мы должны восстановить базу CA и конфигурацию. В командной строке выполните:
certutil –restore c:\RootCA_%date% –f –config "OfflineRCA\Adatum Root CA"
и конфигурацию восстановить простым запуском Reg файла. Если ваш бывший корень публиковал сертификаты и CRL в LDAP, то теперь мы не сможем это делать напрямую. Чтобы исправить это, откройте оснастку CertSrv.msc, выберите свойства CA и перейдите на вкладку Extensions. В ней найдите и удалите все LDAP ссылки в CDP и AIA, которые связаны с вашим доменом.
Всё, теперь мы полностью перенесли Online Enterprise Root CA на Offline Standalone CA, который теперь может выключаться на очень большие промежутки времени. По сути это потребуется только для того, чтобы опубликовать новый CRL, издать новый сертификат подчинённому CA или обновить свой собственный сертификат. Ну и обновления на сервер ставить тоже надо невзирая на то, что сервер будет большую часть времени выключен.
Чтобы наш мигрированный CA распознавался в исходном домене/лесу adatum.com, нам нужно опубликовать его сертификаты в следующих контейнерах Active Directory:
Для импорта сертификата CA войдите в домен с правами Enterprise Admins, скопируйте открытую часть сертификата в C:\RootCA.cer, запустите командную строку и выполните:
certutil –dspublish –f c:\RootCA.cer RootCAcertutil –dspublish –f c:\RootCA.cer SubCAcertutil –dspublish –f c:\RootCA.cer NTAuthCA
После того, как пройдёт репликация в лесу, наш новый CA будет полностью распознаваться как доверенный в текущем лесу.
Теперь можно приступать к процессу установки Enterprise Subordinate CA, который уже будет обслуживать конечных потребителей. Единственная разница в установке будет в том, что в списке ролей CA вы должны выбрать Enterprise Subordinate CA.
Совет: при установке CA старайтесь избегать привязки к домену в distinguished name CA. Используйте только привязку к названию компании, например:
CN = Adatum Class 1 Public Primary Certification Authority
OU = DB management systems
O = Adatum Inc.
C = US
Сохраните запрос в файл и получите сертификат у вышестоящего Offline CA (корневого или policy). Этот вопрос выходит за рамки данного материала, поэтому рассматриваться не будет. Сконфигурируйте CA должным образом (точки распространения сертификатов, CRL, периодичность публикации CRL, шаблоны, etc.) и можете запускать его в работу.
В случае, если ваш Enterprise CA до миграции публиковал LDAP ссылки в сертификатах, то для избежания задержек при проверке сертификатов, вы в течении всей жизни текущего сертификата корневого и/или Policy CA должны поддерживать доступность CRL в этих точках. Поскольку наши Root и Policy CA теперь члены рабочей группы и не могут публиковать CRL прямо в AD, вам придётся заниматься этим вручную. Когда Offline CA опубликует новый CRL, вы должны его доставить (по сети, что не очень рекомендуется, или через съёмные носители) в точки, куда он публиковался раньше (чтобы обеспечить работоспособность расширений CDP/AIA сертификатов). Если с HTTP ссылками всё просто (положили файл на веб-сервер и всё), то с LDAP придётся делать чуточку иначе, а именно — публиковать его в AD в контейнер CDP:
certutil –dspublish –f C:\RootCA.crl "Adatum Root CA"
Ещё раз обращаю ваше внимание на то, что эта операция требует права Enterprise Admins.
Кажется ничего не забыл. Но если что-то забыл — напомните.