IIS: Управление несколькими сертификатами на нескольких веб-серверах

OSzone.net » Microsoft » PowerShell » IIS: Управление несколькими сертификатами на нескольких веб-серверах
Автор: Джейсон Хелмик
Иcточник: TechNetMagazine
Опубликована: 12.03.2013

Управление сертификатами в крупномасштабных веб-средах — крупномасштабная проблема. У вас могут быть сотни серверов, служащих хостами для сотен веб-сайтов с поддержкой SSL, имеющих уникальные сертификаты. Если вы используете GUI IIS Manager, установка и обслуживание сертификатов в таком масштабе отнимет массу времени.

Не бойтесь — имеется лучший подход. Независимо от того, сколько у вас веб-серверов — два или 200, Windows PowerShell превратит дни, недели или месяцы потраченного вами времени в несколько минут. В процессе развертывания, установки и настройки сертификатов и SSL ваших веб-сайтов, можно применить несколько приемов, которые позволят найти сертификаты, которые вскоре устареют, и заменить их.

Принципы просты. Это работает в IIS 7.5 и IIS 8, но необходимо задействовать удаленный доступ через Windows PowerShell. В нашем примере будет два веб-сервера, работающих в конфигурации с балансированием нагрузки, и имеющих свои собственные IP-адреса кластера. На каждом сервере функционирует три веб-сайта, которым нужны SSL-сертификаты и привязки. Я изменил IP-адреса кластера на внутренние, чтобы скрыть настоящие веб-сайты, но идея должна быть вам понятна. Я приобрел сертификаты, и имею .pfx-файлы, готовые к развертыванию. Вот список моих веб-сайтов:

Давайте приступим к развертыванию и установке сертификатов на веб-серверах с балансированием нагрузки.

Развертывание и установка

Для начала нам нужны две вещи — переменная, содержащая список имен компьютеров, являющихся веб-серверами, и удаленный сеанс соединения с каждым из этих серверов через Windows PowerShell. Имена компьютеров берутся из текстового файла с моего компьютера, но можно брать их и из Active Directory, если веб-серверы являются членами домена:

PS> $servers = Get-Content c:\webservers.txt
PS> $session = New-PsSession –ComputerName $servers

Скопируйте сертификаты на удаленные серверы, чтобы можно было без усилий установить их. Не опасайтесь, что кто-то украдет ваши .pfx-файлы. Вы удалите их в процессе выполнения операций, описанных в этом разделе. В нашем примере .pfx-файлы находятся на моем клиентском компьютере в каталоге c:\sites\certpfx:

PS> $servers | foreach-Object{
copy-item -Path c:\sites\certpfx\*.* -Destination "\\$_\c$"}

CertUtil.exe — отличное средство установки сертификатов из сеансов удаленного доступа через Windows PowerShell. В следующих однострочных командах осуществляется установка сертификатов на каждый веб-сервер. Нам нужно установить три сертификата (по одному для каждого веб-сайта), поэтому команда повторяется:

PS> Invoke-command -Session $session {
certutil -p P@ssw0rd -importpfx c:\shop.company.com.pfx}

PS> Invoke-command -Session $session {
certutil -p P@ssw0rd -importpfx c:\update.company.com.pfx}

PS> Invoke-command -Session $session {
certutil -p P@ssw0rd -importpfx c:\register.company.com.pfx}

При использовании CertUtil.exe потребуется указать пароли для .pfx. Поскольку я выполняю команды в реальном времени, я просто набираю пароли. Если вы собираетесь написать сценарий, я бы рекомендовал заменить пароли переменной для ввода пароля из приглашения, например:

PS> $Cred = (Get-Credential).password

Не забудьте удалить .pfx-файлы с удаленных веб-серверов, чтобы предотвратить потенциальное похищение сертификатов:

PS> $servers | foreach-object {Remove-Item -Path "\\$_\c$\*.pfx"}

Следующий шаг после установки сертификатов на удаленные серверы — создание HTTPS-привязок для веб-сайтов.

Создание привязок веб-сайтов

Каждый веб-сайт на каждом сервере в конфигурации с балансированием нагрузки должен иметь HTTPS-привязку. Воспользуйтесь командлетом New-WebBinding из модуля WebAdministration, и все будет проще простого. В параметрах командлета указывают имя сайта, протокол, порт и IP-адрес кластера для сайта. Параметр SSLFlags определяет местонахождение сертификата, который будет использоваться при привязке:

PS> Invoke-Command -session $session {Import-Module WebAdministration}

PS> Invoke-command -Session $session {
New-WebBinding -name shop -Protocol https -Port 443 -IPAddress 192.168.3.201 -SslFlags 0}

PS> Invoke-command -Session $session {
New-WebBinding -name update -Protocol https -Port 443 -IPAddress 192.168.3.202 -SslFlags 0}

PS> Invoke-command -Session $session {
New-WebBinding -name register -Protocol https -Port 443 -IPAddress 192.168.3.203 -SslFlags 0}

Мы только что установили сертификаты в хранилище сертификатов Windows. В нашем распоряжении были следующие варианты:

Остался последний шаг, который часто упускают из виду и забывают: связывание сертификатов с новыми привязками веб-сайтов.

Привязка сертификатов

На этом последнем шаге возможна путаница. Графический IIS Manager скрывает эту часть процесса, но мы не можем от нее отказаться, если хотим, чтобы наши сайты работали с SSL. Мы должны связать сертификаты с привязками веб-сайтов.

Это двухэтапный процесс. Во-первых, надо получить отпечаток (thumbprint) сертификата каждого веб-сайта, чтобы можно было создать соответствующую SSL-привязку. Вспомните: в нашем примере обслуживаются три веб-сайта. Мне нужен отпечаток каждого уникального сертификата. Я решил хранить отпечатки в трех различных переменных, чтобы не запутаться при их связывании с веб-сайтами:

PS> Invoke-Command -session $session {
$CertShop=Get-ChildItem -Path Cert:\LocalMachine\My |
where-Object {$_.subject -like "*shop*"} |
Select-Object -ExpandProperty Thumbprint}

PS> Invoke-Command -session $session {
$CertUpdate=Get-ChildItem -Path Cert:\LocalMachine\My |
where-Object {$_.subject -like "*update*"} |
Select-Object -ExpandProperty Thumbprint}

PS> Invoke-Command -session $session {
$CertRegister=Get-ChildItem -Path Cert:\LocalMachine\My |
where-Object {$_.subject -like "*register*"} |
Select-Object -ExpandProperty Thumbprint}

Теперь пора получить по отпечаткам сами сертификаты и указать их в SSL-привязках для каждого веб-сайта. Следующая команда использует Get-Item для получения сертификата, а затем New-Item для создания SSL-привязки; IIS-провайдер IIS:\SSLBindings создает SSL-привязки вместе с информацией о связывании:

PS> Invoke-Command -Session $session {
get-item -Path "cert:\localmachine\my\$certShop" |
new-item -path IIS:\SslBindings\192.168.3.201!443}

PS> Invoke-Command -Session $session {
get-item -Path "cert:\localmachine\my\$certUpdate" |
new-item -path IIS:\SslBindings\192.168.3.202!443}

PS> Invoke-Command -Session $session {
get-item -Path "cert:\localmachine\my\$certRegister" |
new-item -path IIS:\SslBindings\192.168.3.203!443}

В IIS информация о связывании обычно показывается как IP-адрес:порт:имя хоста (*:80:*). Однако Windows PowerShell интерпретирует двоеточие (:) как признак пути. Поэтому при использовании Windows PowerShell для задания информации о связывании вместо двоеточия используют восклицательный знак (!).

Теперь привязки сформированы, и можно обратиться к веб-сайтам по протоколу HTTPS:

PS> start iexplore https://shop.company.com
PS> start iexplore https://update.company.com
PS> start iexplore https://register.company.com

Проверка истечения

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

При управлении сертификатами приходится определять, не подходит ли к концу срок действия некоторых из них и не пора ли их заменить. К этой задаче применимы принципы и приемы, которые я описал выше. Но одной строкой здесь не обойдешься. И снова нужно открыть сеанс удаленного доступа через Windows PowerShell к веб-серверам, на которых вы собираетесь проверять срок действия сертификатов.

В следующем примере сканируются все сертификаты в хранилище сертификатов локального компьютера. Команда сравнивает свойство notafter, содержащее дату истечения сертификата, с текущей датой, и выводит результат в собственный столбец, названный мной ExpireInDays. Фильтр (Where-Object) служит для отбора сертификатов, до истечения которых осталось менее 90 дней. Команда выводит имена серверов и сертификаты, которые скоро устареют:

PS> Invoke-Command -Session $session {
Get-ChildItem -Path Cert:\LocalMachine\My |
Select-Object -Property PSComputerName, Subject, @{
n='ExpireInDays';e={($_.notafter - (Get-Date)).Days}} |
Where-Object {$_.ExpireInDays -lt 90}}

Используя усвоенные сегодня знания, вы сможете быстро и успешно заменить все такие сертификаты с помощью Windows PowerShell, даже в крупномасштабных конфигурациях.


Ссылка: http://www.oszone.net/20313/IIS