как подписать скрипт powershell
Как подписать скрипт powershell
Как известно практически всем пользователям 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 и синтаксис его такой:
здесь мы явно указываем, что нам нужен сертификат, у которого в EKU (Enchanced Key Usage) указан Code Sgining. В нашем случае он будет всего 1. Но если их окажется несколько, то мы выберем самый первый. Вот как это будет выглядеть на практике:
Я наглядно показал, как это работает. Мы сначала перевели политику исполнения скриптов в AllSigned и убедились, что неподписанный скрипт не исполняется. После чего я подписал этот скрипт и попробовал снова. Как видите, скрипт теперь исполнился.
Если не будет выполнено условие распространения сертификата посредством политики SRP в контейнер Trusted Publishers, то вы получите вот такое сообщение:
Вот таким образом мы решаем задачу исполнения только проверенного набора скриптов. В этом смысле PowerShell 1.0 менее безопасный и удобный, поскольку мы не можем политикой SRP блокировать исполнение PS1 файлов как класс и имеем только один выход – принудительное подписывание скриптов. В версии V2 политика исполнения скриптов удобно интегрируется с SRP. Удобство интегрирования в том, что SRP помимо распространения сертификата в пределах домена так же на основе этого правила разрешает исполнять эти скрипты в обход общего ограничения на PS1 файлы.
В следующем посте я расскажу, как можно упростить процесс подписывания скриптов. Так что не отключаемся 🙂
Как подписать свой первый скрипт за 48 часов
Проблема
Выход есть всегда. Логично, что готовый скрипт для исполнения нужно подписать. Процесс организации механизма подписи достаточно протяжён и тернист, но послужил хорошей почвой для этого поста.
После двух суток мучений дома и в офисе, представляю на суд общественности краткий мануал по подписи скриптов для PowerShell.
Решение
По умолчанию, исполнение любых скриптов запрещено. Для начала, необходимо разрешить выполнение только подписанных скриптов от доверенных издателей с доверенным корневым сертификатом. В рамках сеанса администратора Powershell:
Дальнейшие танцы с бубном касаются утилиты по созданию корневого и персонального сертификатов.
Все сертификаты, согласно «инструкции» по подписыванию скриптов
создаются с использованием утилиты makecert.exe, находящейся в %Program Files%\Microsoft SDKs\Windows\v7.0A\bin\makecert
Следующие два действия выполняются в рамках обычного сеанса командной строки:
Первая строка создает корневой сертификат, используя в качестве удостоверяющего центра локальную машину. Наиболее популярный «бесплатный» способ получения сертификата.
Вторая строка создает персональный сертификат пользователя PowerShell, которым будут подписываться скрипты, заверяя его корневым сертификатом. Если всё прошло успешно, обе строки должны показать результат Succeeded.
Приведенные выше манипуляции можно и не выполнять, если персональный сертификат X509 уже есть.
После этого, на всякий случай, можно проверить, что ОС в курсе насчет только что созданного сертификата. PowerShell:
Подписывать скрипты уже можно, но, в таком случае, на подпись скрипта каждый раз будет уходить такая строка Powershell:
Было бы логичным создать скрипт, который будет подписывать другие скрипты. Скрипт нужно создавать в любом текстовом редакторе, кроме PowerShell ISE. Для скриптов, созданных внутри этой среды, возникнут проблемы с подписыванием в виде Unknown Error. Решение взято здесь.
О грустном
Не претендует на роль единственно верного решения, но результаты исследований показывают, что пока это более или менее нормальный способ. Прошу знающих помочь прояснить ситуацию и ткнуть ссылкой, по возможности.
Как подписать файл PowerShell скрипта (ps1) с помощью сертификата?
Наличие цифровой подписи у скрипта или исполняемого файла позволяет пользователю удостовериться, что файл является оригинальным и его код не был изменен третьими лицами. В современных версиях PowerShell есть встроенные средства для подписывания кода файла скриптов *.ps1 с помощью цифровых сертификатов.
Для подписывания скриптов PowerShell нужно использовать специальный сертификат типа Code Signing. Этот сертификат может быть получен от внешнего коммерческого центра сертификации, внутреннего корпоративного Certificate Authority (CA) или можно даже самоподписанный сертификат.
Если вы запросили сертификат вручную, у вас должен получится файл сертификат x509 в виде файла с расширением .cer. Данный сертификат нужно установить в локальное хранилище сертификатов вашего компьютера.
Для добавления сертификата в доверенные корневые сертификаты компьютера можно использовать следующие команды PowerShell:
Если вы хотите использовать самоподписанный сертификат, то вы можете использовать командлета New-SelfSignedCertificate чтобы создать сертификат типа CodeSigning c DNS именем test1:
После генерации сертификата, его нужно будет в консоли управления хранилищем сертификатов ( certmgr.msc ) перенести из контейнера Intermediate в Trusted Root.
После того, как сертификат получен, можно настроить политику исполнения скриптов PowerShell, разрешив запуск только подписанных скриптов. По умолчанию PowerShell Execution политика в Windows 10/Windows Server 2016 установлена в значение Restricted. Это режим блокирует запуск любых PowerShell скриптов:
Чтобы разрешить запуск только подписанных PS1 скриптов, можно изменить настройку политики исполнения скриптов на AllSigned или RemoteSigned (разница между ними в том, что RemoteSigned требует наличие подписи только для скриптов, полученных из интернета):
Set-ExecutionPolicy AllSigned –Force
В этом режиме при запуске неподписанных PowerShell скриптов появляется ошибка:
Теперь перейдем к подписыванию файла со скриптом PowerShell. В первую очередь вам нужно получить сертификат типа CodeSign из локального хранилища сертификатов текущего пользователя. Сначала выведем список всех сертификатов, которые можно использовать для подписывания кода:
Get-ChildItem cert:\CurrentUser\my –CodeSigningCert
$cert = (Get-ChildItem cert:\CurrentUser\my –CodeSigningCert)[0]
Затем можно использовать данный сертификат, чтобы подписать файл PS1 с вашим скриптом PowerShell:
Также можно использовать такую команду (в данном случае мы вибираем самоподписанный сертификат созданный ранее по DnsName):
Если вы попытаетесь использовать обычный сертификат для подписывания скрипта, появится ошибка:
Теперь можно проверить, что скрипт подписан. Можно использовать командлет Get-AuthenticodeSignature или открыть свойства PS1 файла и перейдти на вкладку Digital Signatures.
Если при выполнении команды Set-AuthenticodeSignature появится предупреждение UnknownError, значит этот сертификат недоверенный, т.к. находится в персональном хранилище сертификатов пользователя.
Теперь при проверке подписи PS1 файла должен возвращаться статус Valid.
При подписывании файла PowerShell скрипта, командлет Set-AuthenticodeSignature добавляет в конец текстового файла PS1 блок сигнатуры цифровой подписи, обрамленный специальными метками:
Блок сигнатуры содержит хэш скрипта, который зашифрован с помощью закрытого ключа.
При первой попытке запустить скрипт появится предупреждение:
Если выбрать [A] Always run, то при запуске любых PowerShell скриптов, подписанных этим сертификатом, предупреждение появляться больше не будет.
Теперь подписанный PowerShell скрипт будет запускаться без уведомления об untrusted publisher.
Если корневой сертификат недоверенный, то при запуске скрипта PowerShell будет появляться ошибка:
Что произойдет, если изменить код подписанного файла со скриптом PowerShell? Его запуск будет заблокирован, с ошибкой, что содержимое скрипта было изменено:
Таким образом, после любой модификации кода подписанного PS1 скрипта его нужно заново переподписать.
Личные IT заметки
четверг, 10 сентября 2015 г.
GPO AD: Computer Startup scripts and Powershell (часть 2: Созданиесвоего сертификата. Подпись скриптов)
Это продолжение этой статьи о том, как запустить свои скрипты в GPO. И в текущей, второй части, мы рассмотрим вариант собственной подписи скрипта созданным сертификатом.
Подразумевается, что у вас имеется установленная роль AD CS. Если у вас нет такой роли, то рекомендую поискать статьи в интернете, по поводу установки и настройке. Или, например, обратиться к этой статье.
В первую очередь, нам необходимо создать сертификат, которым мы будем подписывать наши скрипты. Все действия мы будем выполнять из под учетной записи Администратора Домена.
Открываем оснастку Certification Authority (выполнив команду certsrv.msc) и переходим в раздел Certificate Templates.
Нажимаем правой кнопкой по Certificate Templates и выбираем Manage. В открывшемся окне редактора шаблонов находим шаблон Code Signing и жмем на нем правой кнопкой, выбираем Properties. Переходим на вкладку Security и убеждаемся, что группа Domain Admins имеет права Read, Write, Enroll.
Теперь, в списке шаблонов у вас появился Code Signing.
Далее, нам необходимо вызвать менеджер сертификатов. Сделать это можно выполнив команду certmgr.msc
Откроется мастер запроса сертификата. В первом окне просто жмем Next, во втором ничего не меняя и не выбирая так же жмем Next
На следующем этапе выбираем наш шаблон Code Signing и жмем Enroll.
Откроется окно экспорта. Жмем Next. Во втором окне доступен лишь один пункт (Не экспортировать приватный содержимое), поэтому жмем Next
Далее оставляем выбор открытой части сертификата x509
Затем указываем путь и имя файла сертификата и жмем Finish.
На выходе у нас будет файл сертификата, который нам необходимо распространить по нашей сети, средствами GPO.
Если у вас еще нет ни одной политики безопасности программного обеспечения, то необходимо нажать правой кнопкой по Software Restriction Policy и выбрать New Sofware Restriction Policy. Политика будет создана моментально.
Переходим в папку Additional Rules. Жмем правой кнопкой в пустом месте и выбираем New Certificate Rule
У нас все готово, для того, чтобы начать подписывать наши скрипты. Важно, чтобы ваш сертификат находился в Personal Sertificate на той машине, с которой вы планируете подписывать.
Т.к. сертификат, распространенный через GPO будет лежать в Доверенных издателях. Тем самым не позволит выполнить нам подпись.
Если проще сказать: я выполняю подпись на том же сервере, где я запрашивал сертификат и где у меня установлен AD CA
Для удобства: создайте в корне диска папку для скриптов, которые необходимо будет подписать и сложите туда файлы скриптов.
$cert
Для этого выполняем команду:
Все готово! Скрипт подписан и об этом сообщает результат выполнения команды:
Статус валидной подписи можно узнать несколькими способами. В т.ч. и запросив статус из PS командой: Get-AuthenticodeSignature C:\Main.ps1
Теперь нам осталось лишь заменить в папках GPO наши файлы-скриптов уже подписанными файлами-скриптами путем банального копирования-замещения 🙂
about_Signing
Краткое описание
Описывает, как подписывать сценарии, чтобы они соответствовали политикам выполнения PowerShell.
Подробное описание
Политика ограниченного выполнения не позволяет запускать скрипты. Политики выполнения AllSigned и RemoteSigned запрещают PowerShell выполнять сценарии, не имеющие цифровой подписи.
В этом разделе объясняется, как выполнить выбранные сценарии, которые не подписаны, даже если политика выполнения RemoteSigned и как подписывать сценарии для собственного использования.
Дополнительные сведения о политиках выполнения PowerShell см. в разделе about_Execution_Policies.
Разрешение выполнения подписанных сценариев
При первом запуске PowerShell на компьютере, скорее всего, действует политика ограниченного выполнения (по умолчанию).
Политика с ограниченным доступом не позволяет запускать скрипты.
Чтобы найти действующую политику выполнения на компьютере, введите:
Чтобы запустить неподписанные скрипты, написанные на локальном компьютере и подписанные скрипты от других пользователей, запустите PowerShell с параметром Запуск от имени администратора, а затем используйте следующую команду, чтобы изменить политику выполнения на компьютере на RemoteSigned:
Дополнительные сведения см. в разделе справки по Set-ExecutionPolicy командлету.
Выполнение неподписанных скриптов с помощью политики выполнения RemoteSigned
Если политика выполнения PowerShell — RemoteSigned, PowerShell не будет запускать неподписанные сценарии, которые будут скачаны из Интернета, в том числе неподписанные сценарии, получаемые через электронную почту и программы обмена мгновенными сообщениями.
При попытке запустить скачанный скрипт PowerShell выводит следующее сообщение об ошибке:
Перед выполнением скрипта проверьте код, чтобы убедиться, что он является доверенным. Сценарии имеют тот же результат, что и любая исполняемая программа.
Чтобы выполнить неподписанный скрипт, используйте командлет Unblock-File или выполните следующую процедуру.
Если сценарий, скачанный из Интернета, имеет цифровую подпись, но вы еще не выбрали доверие к издателю, PowerShell выводит следующее сообщение:
Если вы доверяете издателю, выберите «запустить один раз» или «всегда запускать». Если вы не доверяете издателю, выберите параметр «никогда не запускать» или «не запускать». Если выбрать параметр «никогда не запускать» или «всегда запускать», PowerShell не будет выводить запрос для этого издателя снова.
Методы подписания скриптов
Вы можете подписывать скрипты, которые вы пишете, и скрипты, получаемые из других источников. Перед тем как подписать любой сценарий, проверьте каждую команду, чтобы убедиться в том, что он является надежным для выполнения.
Рекомендации по подписывания кода см. в статье рекомендации по подписываниякода.
Дополнительные сведения о том, как подписать файл скрипта, см. в разделе Set-AuthenticodeSignature.
New-SelfSignedCertificate Командлет, представленный в модуле PKI в PowerShell 3,0, создает самозаверяющий сертификат, подходящий для тестирования. Дополнительные сведения см. в разделе справки по командлету New-SelfSignedCertificate.
Чтобы добавить цифровую подпись в скрипт, необходимо подписать его с помощью сертификата подписи кода. Для подписи файла скрипта подходят два типа сертификатов:
Сертификаты, созданные центром сертификации. для платной платы общедоступный центр сертификации проверяет ваше удостоверение и предоставляет сертификат подписи кода. при приобретении сертификата от известного центра сертификации можно предоставить общий доступ к сценарию пользователям на других компьютерах, на которых выполняется Windows, так как эти компьютеры доверяют центру сертификации.
Создаваемые сертификаты: можно создать самозаверяющий сертификат, для которого компьютер является центром сертификации, который создает сертификат. Этот сертификат предоставляется бесплатно и позволяет писать, подписывать и выполнять сценарии на компьютере. Однако сценарий, подписанный самозаверяющим сертификатом, не будет выполняться на других компьютерах.
Как правило, самозаверяющий сертификат используется только для подписывания сценариев, написанных для собственного использования, и для подписывания сценариев, получаемых из других источников, которые были проверены как надежные. Он не подходит для сценариев, которые будут совместно использоваться даже в рамках предприятия.
При создании самозаверяющего сертификата обязательно включите усиленную защиту закрытого ключа в сертификате. Это не позволит вредоносным программам подписывать сценарии от вашего имени. Инструкции включены в конце этого раздела.
Создание самозаверяющего сертификата.
Чтобы создать самозаверяющий сертификат, используйте командлет New-SelfSignedCertificate в модуле PKI. этот модуль появился в PowerShell 3,0 и входит в Windows 8 и Windows Server 2012. Дополнительные сведения см. в разделе справки по New-SelfSignedCertificate командлету.
Использование Makecert.exe
Дополнительные сведения о синтаксисе и описаниях параметров MakeCert.exe средства см. в разделе средство создания сертификатов (MakeCert.exe).
Чтобы использовать MakeCert.exe средство для создания сертификата, выполните следующие команды в окне командной строки пакета SDK.
Первая команда создает локальный центр сертификации для компьютера. Вторая команда создает личный сертификат из центра сертификации. Вы можете скопировать или ввести команды в том виде, в каком они отображаются. Подстановки не требуются, хотя имя сертификата можно изменить.
MakeCert.exe Средство предложит ввести пароль закрытого ключа. Пароль гарантирует, что никто не сможет использовать сертификат или получить к нему доступ без вашего согласия. Создайте и введите пароль, который вы можете запомнить. Этот пароль будет использоваться позже для получения сертификата.
Чтобы убедиться, что сертификат создан правильно, выполните следующую команду, чтобы получить сертификат в хранилище сертификатов на компьютере. Файл сертификата не будет найден в каталоге файловой системы.
В командной строке PowerShell введите следующее:
Эта команда использует поставщик сертификата PowerShell для просмотра сведений о сертификате.
Подписать сценарий
Следующий пример скрипта Add-Signature.ps1 подписывает скрипт. Однако при использовании политики выполнения AllSigned необходимо подписать Add-Signature.ps1 сценарий перед запуском.
Скрипт должен быть сохранен с использованием кодировки ASCII или UTF8NoBOM. Вы можете подписать файл сценария, который использует другую кодировку. Но сценарий не запускается, или модуль, содержащий скрипт, не удается импортировать.
Чтобы подписать Add-Signature.ps1 файл скрипта, введите в командной строке PowerShell следующие команды:
После подписания скрипта его можно запустить на локальном компьютере. Однако сценарий не будет выполняться на компьютерах, на которых политика выполнения PowerShell требует наличия цифровой подписи от доверенного центра сертификации. При попытке PowerShell отобразится следующее сообщение об ошибке:
Если PowerShell отображает это сообщение при выполнении скрипта, который не был написан, обработайте файл так, как если бы вы ни использовали любой неподписанный сценарий. Проверьте код, чтобы определить, можно ли доверять сценарию.
Включение усиленной защиты закрытого ключа для сертификата
При наличии частного сертификата на компьютере вредоносные программы могут подписывать сценарии от вашего имени, что позволяет PowerShell выполнять их.
Чтобы экспортировать сертификат, выполните следующие действия.
Чтобы повторно импортировать сертификат, выполните следующие действия.
Запрет истечения срока действия подписи
Цифровая подпись в скрипте действительна до истечения срока действия сертификата подписи или до тех пор, пока сервер отметок времени не сможет проверить, подписан ли сценарий, пока сертификат для подписи был действителен.
Так как большинство сертификатов подписи действительны только в течение одного года, использование сервера отметок времени гарантирует, что пользователи смогут использовать ваш сценарий в течение многих лет.