Как известно практически всем пользователям PowerShell, в целях безопасности была введена политика запуска скриптов. Которая имеет 4 режима:
В версии V2 (пока ещё CTP3) скрипты PowerShell приравняли к исполняемым файлам и эти файлы стали неотключаемо мониториться политикой Software Restriction Policies. Я об этом уже писал ранее: PowerShell V2 и Software Restriction Policies. Поначалу меня это сильно напрягало, но после пришёл к мнению, что это правильно. Неправильно только то, что мы этого не видим (ps1 расширение нигде не фигурирует). С этим бороться можно двумя методами – явно указывать пути, откуда разрешён запуск .ps1 файлов или подписать их все.
Если компьютеров в сети больше одного, то самое идеальное для решения задачи будет наличие домена Active Directory и, по возможности, Enterprise Certification Authity (CA). Наличие домена решит массу задач, как распространение политики SRP в пределах домена, распространение сертификата в пределах домена, контроль версии сертификата, которым подписаны скрипты.
Итак, для начала нам нужно получить сертификат, которым будут подписываться скрипты. В целях безопасности следует создать ограниченную учётную запись пользователя из под которой администратор (в большинстве случаев) будет подписывать скрипты. В книге PowerShell In Action для генерации сертификата предлагается использовать makecert.exe, который входит в состав Visual Studio SDK, но как мне кажется более правильным будет использование CA. В Windows Server CA для этих целей есть уже готовый шаблон, который называется Code Signing. Но принципиальной разницы нету, каким инструментом вы будете генерировать сертификат и я опишу процесс получения сертификата с использованием доменного CA.
Если CA у нас уже установлен, то открываем оснастку Certification Authority и переходим в раздел Certificate Templates. Нажимаем правой кнопкой и выбираем Manage. Откроется редактор шаблонов. Если у вас Enterprise или Datacenter редакции Windows Server, то вы можете создать свой настроенный шаблон. Но я не вижу в этом необходимости. На данном этапе нам необходимо разрешить ограниченному пользователю запрашивать сертификаты этого шаблона. Для этого в закладке Security шаблона Code Signing нужно разрешить чтение и запрос сертификата ограниченному пользователю. Когда эта процедура проделана, редактор шаблонов можно закрыть. После чего в оснастке Certification Authority снова нажать правой кнопкой на разделе Certificate Templates –> New –> Certificate Template to Issue и в списке выбрать шаблон Code Signing.
После чего нужно залогиниться этим пользователем, запустить оснастку Certificate Manager (Start –> Run… –> certmgr.msc) и выполнить запрос сертификата. В списке шаблонов должен быть и добавленный нами Code Signing. Когда сертификат будет запрошен не надо закрывать оснастку сертификатов. Далее нам потребуется экспортировать открытую часть сертификата в x509 файл (с расширением .cer). Экспорт открытой части нам потребуется для проверки подписи и организации доверия подписи в пределах домена. Экспортированный сертификат необходимо теперь доставить администратору(-ам), который отвечает за групповую политику.
В групповых политиках (чаще всего в доменной политике) необходимо создать новую политику Software Restriction Policies и в Additiona Rules добавить правило сертификата (Certificate Rule) и указать экспортированный сертификат. Это необходимо затем, что PowerShell для проверки доверия сертификата ищет его в контейнере Trusted Publishers и только Software Restriction Policies позволяет централизовано распространять сертификаты в этот контейнер.
Теперь можно приступать к подписыванию скриптов. Для этих целей используется командлет Set-AuthenticodeSignature и синтаксис его такой:
Set-AuthenticodeSignature $file $cert
Где $file – путь к скрипту и $cert – объект сертификата, который получается следующим образом:
$cert = @(dir cert:\CurrentUser\My -codesigning)[0]
здесь мы явно указываем, что нам нужен сертификат, у которого в EKU (Enchanced Key Usage) указан Code Sgining. В нашем случае он будет всего 1. Но если их окажется несколько, то мы выберем самый первый. Вот как это будет выглядеть на практике:
[Desktop] Set-ExecutionPolicy allsigned
[Desktop] Get-ExecutionPolicy
AllSigned
[Desktop] .\uptime.ps1
File C:\Documents and Settings\Signer\Desktop\uptime.ps1 cannot be loaded. The file C:\Documents and Settings\Signer
\Desktop\uptime.ps1 is not digitally signed. The script will not execute on the system. Please see "get-help
about_signing" for more details..
At line:1 char:13
+ .\uptime.ps1 < +="" categoryinfo="" :="" notspecified:="" (:)="" [],="" pssecurityexception="" +="" fullyqualifiederrorid="" :="">
[Desktop] $cert = @(dir cert:\currentuser\my -codesigning)[0]
[Desktop] $cert
Directory: Microsoft.PowerShell.Security\Certificate::currentuser\my
Thumbprint Subject
---------- -------
42E5B32A19885C6ADCF9683BDA1C871E0FE5E0DB CN=Signer, CN=Users, DC=contoso, DC=com
[Desktop] Set-AuthenticodeSignature uptime.ps1 $cert
Directory: C:\Documents and Settings\Signer\Desktop
SignerCertificate Status Path
----------------- ------ ----
42E5B32A19885C6ADCF9683BDA1C871E0FE5E0DB Valid uptime.ps1
[Desktop] .\uptime.ps1
System Uptime for DC1 is: 1 days 4 hours 19 minutes 20 seconds
[Desktop]
Я наглядно показал, как это работает. Мы сначала перевели политику исполнения скриптов в AllSigned и убедились, что неподписанный скрипт не исполняется. После чего я подписал этот скрипт и попробовал снова. Как видите, скрипт теперь исполнился.
Если не будет выполнено условие распространения сертификата посредством политики SRP в контейнер Trusted Publishers, то вы получите вот такое сообщение:
[Desktop] .\uptime.ps1
Do you want to run software from this untrusted publisher?
File C:\Documents and Settings\Signer\Desktop\uptime.ps1 is
published by CN=Signer, CN=Users, DC=contoso, DC=com and is not trusted
on your system. Only run scripts from trusted publishers.
[V] Never run [D] Do not run [R] Run once [A] Always run [?] Help
(default is "D"):d
File C:\Documents and Settings\Signer\Desktop\uptime.ps1 cannot be loaded because you have elected to no
t run this software now.
At line:1 char:12
+ .\uptime.ps1
[Desktop]
Вот таким образом мы решаем задачу исполнения только проверенного набора скриптов. В этом смысле PowerShell 1.0 менее безопасный и удобный, поскольку мы не можем политикой SRP блокировать исполнение PS1 файлов как класс и имеем только один выход – принудительное подписывание скриптов. В версии V2 политика исполнения скриптов удобно интегрируется с SRP. Удобство интегрирования в том, что SRP помимо распространения сертификата в пределах домена так же на основе этого правила разрешает исполнять эти скрипты в обход общего ограничения на PS1 файлы.
В следующем посте я расскажу, как можно упростить процесс подписывания скриптов. Так что не отключаемся :-)
Comments: