Настройка служебного принципала Azure: Руководство по неуполномоченному доступу

Когда вам нужно автоматизировать задачи в Azure с помощью сценариев и инструментов, вы рассмотрели бы использование служебных учетных записей или принципалов служб Azure? Не редко некоторые просто создают новую служебную учетную запись, назначают ей все необходимые административные роли и исключают из многофакторной аутентификации.

I know what you’re thinking – “that is a horrible idea”. Of course, it is! And for sure, your IT Sec will give you a lot of grief if you did all that.

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

В этой статье вы узнаете, что такое принципал служб Azure. Вы узнаете, как создавать принципалы служб с различными типами учетных данных, такими как пароли, секретные ключи и сертификаты.

Существует множество инструментов для создания принципалов служб Azure. Среди них можно выделить Портал Azure, Центр администратора Azure Active Directory, Azure AD PowerShell, Azure CLI и Azure PowerShell. Инструментом, которому будет уделено внимание в этой статье, является Azure PowerShell.

Все еще интересно? Продолжайте чтение и приступим!

Требования

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

Сервисный принципал Azure против Сервисной учетной записи

Инструменты и скрипты автоматизации часто требуют административного или привилегированного доступа. Например, предоставление учетных записей хранилища или запуск и остановка виртуальных машин по расписанию. И, вероятно, большинство администраторов используют полностью привилегированную учетную запись пользователя (называемую сервисной учетной записью) для настройки требований к учетным данным для скриптов.

A service account is essentially a privileged user account used to authenticate using a username and password. And, if used with automation, a service account is most likely excluded from any conditional access policies or multi-factor authentication.

С другой стороны, сервисный принципал Azure может быть настроен для использования имени пользователя и пароля или сертификата для аутентификации. Представьте его как идентификацию пользователя без самого пользователя, а скорее как идентификацию для приложения.

Сервисному принципалу Azure можно назначить доступ только к конкретному ресурсу Azure или даже к определенному одному Azure виртуальному компьютеру.на основе ролей доступа

Основные соображения при создании сервисных принципалов Azure

Перед созданием сервисного принципала Azure вам следует знать основные детали, на которые вам нужно обратить внимание. Эти детали могут показаться простыми, но они сделают процесс создания сервисного принципала Azure максимально эффективным и простым.

Отображаемое имя. Все начинается с имени, и у сервисного принципала Azure должно быть имя. Здесь нет никакого строгого правила, но у вашей организации может быть установлено предписанное соглашение об именовании.

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

Для сервисных принципалов имя пользователя и пароль более подходяще называются идентификатором приложения и секретным ключом.

  • Срок действия учетных данных. Независимо от того, назначаете ли вы пароль или сертификат, вы должны определить начальную и конечную дату их действительности. Как долго учетные данные будут действительны, обычно зависит от того, насколько часто вы готовы обновлять/переоформлять сертификаты и пароли.
  • Область доступа. Создаете ли вы сервисный принципал Azure, который будет иметь доступ к подписке, группе ресурсов или выбранным ресурсам?
  • Роль. Существует несколько доступных ролей, таких как Участник, Читатель и Владелец, чтобы назвать некоторые. Вам нужно определить, какая роль является “достаточной” для сервисного принципала.

Создание Azure Service Principal с автоматически назначаемым секретным ключом

Основа создания нового сервисного принципала в Azure – это командлет New-AzAdServicePrincipal. В этом примере будет создан новый сервисный принципал со следующими значениями:

Отображаемое имя: AzVM_Reader

Область применения: AzVM1 (виртуальная машина)

Роль: Читатель

Пароль: <автоматически назначено>

Срок действия учетных данных: 1 год

Получение ID целевой области (виртуальной машины)

Как видите, область этого нового сервисного принципала ограничена только для виртуальной машины с именем AzVM1. Однако параметр -Scope не принимает только имя, а требует весь идентификатор ресурса. Поэтому в этом примере сначала нужно получить идентификатор виртуальной машины AzVM1. Для этого используйте указанный ниже код.

Get-AzVM | Format-Table Name, ID

При выполнении указанного выше кода в PowerShell вы должны увидеть список имен и ID виртуальных машин, аналогичный скриншоту ниже.

Get the list of VM names and IDs

Создание Azure Service Principal с секретным ключом

Теперь, когда у вас есть ID целевой области, который представляет собой ID виртуальной машины AzVM1, вы можете использовать указанную ниже команду для создания нового сервисного принципала с ролью читателя. Свойства нового сервисного принципала будут сохранены в переменной $sp.

$sp = New-AzAdServicePrincipal `
	-DisplayName AzVM_Reader `
	-Scope '/subscriptions/5e252811-b376-4136-b8ae-d3b8abe2c9c3/resourceGroups/ATA/providers/Microsoft.Compute/virtualMachines/AzVM1'
	-Role 'Reader'

В результате выполнения указанной выше команды был создан сервисный принципал со следующими значениями.

The properties of the new service principal

Расшифровка секретного ключа

Теперь у вас есть ApplicationID и Secret, которые представляют собой имя пользователя и пароль служебного принципала. Однако значение Secret отображается как System.Security.SecureString. Вам нужно узнать, что представляет собой этот секрет. Для этого используйте следующую команду для преобразования секрета в обычный текст.

# Преобразование зашифрованного пароля в обычный текст
[System.Runtime.InteropServices.Marshal]::PtrToStringAuto(
    [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR(
        $sp.Secret
    )
)

Указанная выше команда преобразует зашифрованное значение SecureString переменной $sp.Secret в обычный текст. См. изображение ниже для справки.

Secure string password value converted to plain text

Проверка назначения роли служебному принципалу Azure

Как узнать, что это сработало? Вы можете проверить список управления доступом ресурса с использованием портала Azure. Например, на изображении ниже вы можете видеть, что служебный принципал AzVM_Reader теперь имеет доступ Reader к виртуальной машине AzVM1.

Azure resource access control

Также вы можете использовать команду Get-AzRoleAssignment -ObjectID $sp.id, чтобы получить назначенные роли служебному принципалу Azure. См. скриншот ниже в качестве примера.

Get the role assignment(s) of the service principal

Создание служебного принципала Azure с использованием пароля

Если вам нужно больше контроля над тем, какой пароль или секретный ключ присваивается вашему служебному принципалу Azure, используйте параметр -PasswordCredential при создании служебного принципала. Это особенно полезно, если пароль должен соответствовать определенным требованиям сложности.

В этом примере новый служебный принципал Azure будет создан со следующими значениями:

DisplayName: ATA_RG_Contributor

Scope: ATA (ResourceGroup)

Роль: Участник

Пароль: 20 символов с 6 не-алфавитными символами

Срок действия учетных данных: 5 лет

Получение идентификатора целевого объема (группы ресурсов)

Область применения этого нового служебного принципала охватывает всю группу ресурсов с именем ATA. Первое, что нужно получить, – это идентификатор группы ресурсов ATA. Для этого используйте приведенный ниже код, но убедитесь, что измените значение параметра -Name на имя вашей группы ресурсов.

# Получение значения ResourceId группы ресурсов
$Scope = (Get-AzResourceGroup -Name ATA).ResourceId
$Scope

Затем вы должны увидеть ResourceID группы ресурсов, который теперь сохранен в переменной $Scope.

Getting the Resource Group ID

Генерация строки пароля

Следующим шагом является генерация пароля, соответствующего сложности 20 символов с 6 не-алфавитными символами. Для этого можно использовать статический метод .NET GeneratePassword().

# Генерация случайного пароля с использованием статического метода GeneratePassword()
Add-Type -AssemblyName 'System.Web'
$password = [System.Web.Security.Membership]::GeneratePassword(20, 6)
$password

В приведенном выше коде GeneratePassword(20, 6), первое значение означает длину пароля, а второе значение – количество не-алфавитных символов для включения. Результат показан на скриншоте ниже.

Randomly generated password using the .NET GeneratePassword() static method

Создание объекта учетных данных для пароля

Теперь, когда у вас есть строка пароля, следующим шагом является создание объекта Microsoft.Azure.Commands.ActiveDirectory.PSADPasswordCredential. Этот объект будет содержать строку пароля, сохраненную в переменной $password, и срок действия в 5 лет. Скопируйте приведенный ниже код и выполните его в вашей сессии Azure PowerShell.

# Создание объекта учетных данных пароля
[Microsoft.Azure.Commands.ActiveDirectory.PSADPasswordCredential]`
    $PasswordCredential = @{
    StartDate = Get-Date;
    EndDate   = (Get-Date).AddYears(5);
    Password  = $password
}
$PasswordCredential

Запуск приведенного выше кода в PowerShell приведет к сохранению объекта учетных данных в переменной $PasswordCredential. Ожидаемый результат будет аналогичен показанному ниже.

Creating the new password credential object in Azure PowerShell

Создание главного сервисного объекта с паролем

Теперь у вас есть необходимые значения параметров для создания главного сервисного объекта Azure. Приведенный ниже код создаст главный сервисный объект с отображаемым именем ATA_RG_Contributor и используя пароль, сохраненный в переменной $PasswordCredential.

# Создание главного сервисного объекта с учетными данными пароля
$sp = New-AzAdServicePrincipal `
    -DisplayName 'ATA_RG_Contributor' `
    -PasswordCredential $PasswordCredential
$sp

После выполнения кода новый главный сервисный объект должен быть создан, и его свойства будут сохранены в переменной $sp. Смотрите пример результата ниже.

The new Azure service principal is created

Назначение роли и области

Главный сервисный объект Azure был создан в предыдущем разделе, но без Роли и Области. Это потому, что параметры -Role и -Scope не могут быть использованы вместе с параметром -PasswordCredential. Это означает, что требуется дополнительный шаг для назначения роли и области главному сервисному объекту.

Код ниже использует командлет New-AzRoleAssignment для назначения области и роли служебного принципала Azure.

# Назначить роль целевому ресурсу
New-AzRoleAssignment -$azSubscription = Get-AzSubscription -SubscriptionName VSE3
$Scope = "/subscriptions/$($azSubscription.ID)"
$TenantID = $azSubscription.TenantID$sp.ApplicationId `
    -Scope $Scope `
    -RoleDefinitionName 'Contributor'

На скриншоте ниже показан ожидаемый результат после назначения роли и области служебному принципалу Azure.

Assigning role and scope using Azure Powershell

Всегда убедитесь в сохранении пароля служебного принципала, потому что нет способа восстановить его, если вы не смогли сохранить или забыли его.

Подключение к Azure с использованием пароля служебного принципала

Теперь можно использовать служебного принципала. Вместо входа в Azure PowerShell от имени учетной записи пользователя, код ниже использует учетные данные служебного принципала.

# Получить служебный принципал с отображаемым именем ATA_RG_Contributor
$sp = Get-AzADServicePrincipal -DisplayName ATA_RG_Contributor

# Получить идентификатор арендатора
$TenantID = (Get-AzContext).Tenant.ID

# Получить имя первого служебного принципала
$user = $sp.ServicePrincipalNames[0]

# Преобразовать пароль в защищенную строку
$secPassword = $password | ConvertTo-SecureString -AsPlainText -Force

# Создать объект PSCredential
$credential = [PSCredential]::New($user,$secPassword)

# Подключиться к Azure
Connect-AzAccount -ServicePrincipal -Credential $credential -Tenant $TenantID
# Получить служебный принципал с отображаемым именем ATA_RG_Contributor
$sp = Get-AzADServicePrincipal -DisplayName ATA_RG_Contributor

# Получить идентификатор арендатора
$TenantID = (Get-AzContext).Tenant.ID

# Получить имя первого служебного принципала
$user = $sp.ServicePrincipalNames[0]

# Преобразовать пароль в защищенную строку
$secPassword = $password | ConvertTo-SecureString -AsPlainText -Force

# Создать объект PSCredential
$credential = [PSCredential]::New($user,$secPassword)

# Подключиться к Azure
Connect-AzAccount -ServicePrincipal -Credential $credential -Tenant $TenantID# Получить служебный принципал с отображаемым именем ATA_RG_Contributor
$sp = Get-AzADServicePrincipal -DisplayName ATA_RG_Contributor

# Получить идентификатор арендатора
$TenantID = (Get-AzContext).Tenant.ID

# Получить имя первого служебного принципала
$user = $sp.ServicePrincipalNames[0]

# Преобразовать пароль в защищенную строку
$secPassword = $password | ConvertTo-SecureString -AsPlainText -Force

# Создать объект PSCredential
$credential = [PSCredential]::New($user,$secPassword)

# Подключиться к Azure
Connect-AzAccount -ServicePrincipal -Credential $credential -Tenant $TenantID

После выполнения указанного выше кода вы должны войти в Azure PowerShell, используя учетную запись служебного принципала ATA_RG_Contributor и учетные данные пароля.

Connect to Azure using a Service Principal with Password Credential

Создание служебного принципала Azure с использованием сертификата

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

В этом примере новый служебный принципал Azure будет создан со следующими значениями:

Отображаемое имя: VSE3_SUB_OWNER

Область: VSE3 (подписка)

Роль: Владелец

Срок действия сертификата: 2 года

Получение идентификатора целевой области (подписка)

Область действия этого нового служебного принципала охватывает подписку Azure с именем VSE3. Первое, что нужно получить, – это идентификатор подписки VSE3. Для этого используйте указанный ниже код, но убедитесь, что измените значение параметра -SubscriptionName на имя вашей группы ресурсов.

# Получение идентификатора области подписки и идентификатора арендатора
$azSubscription = Get-AzSubscription -SubscriptionName VSE3
$Scope = "/subscriptions/$($azSubscription.ID)"
$TenantID = $azSubscription.TenantID

Затем укажите имя нового служебного принципала Azure и самоподписанного сертификата, которые следует создать.

# Имя нового служебного принципала Azure и самоподписанного сертификата
$DisplayName = 'VSE3_SUB_OWNER'

Создание самоподписанного сертификата

Код ниже создает самоподписанный пароль в хранилище персональных сертификатов с именем CN=VSE3_SUB_OWNER. Срок действия сертификата установлен в два года. Свойства сертификата сохраняются в переменной $cert.

# Создание самоподписанного сертификата
$cert = New-SelfSignedCertificate -CertStoreLocation "cert:\CurrentUser\My" `
    -Subject "CN=$($DisplayName)" `
    -KeySpec KeyExchange `
    -NotBefore ((Get-Date).AddDays(-1)) `
    -NotAfter ((Get-Date).AddYears(2))
$cert

На скриншоте ниже показано, что сертификат был создан.

The self-signed certificate is created in the personal certificate store

Если вы хотите увидеть новый сертификат в более привычном виде (графический интерфейс), вы можете найти его в консоли сертификатов (certmgr.mmc). Обратитесь к изображению ниже, показывающему сертификат.

Viewing the self-signed certificate

Далее необходимо получить закодированное значение самоподписанного сертификата в формате Base64 и сохранить его в переменной $keyValue.

# Получение значения base64 самоподписанного сертификата
$keyValue = [System.Convert]::ToBase64String($cert.GetRawCertData())

Создание служебного принципала с сертификатом

Теперь, когда сертификат создан, следующим шагом является создание нового служебного принципала Azure. Код ниже создаст служебного принципала Azure, который будет использовать самоподписанный сертификат в качестве учетных данных. Срок действия учетных данных совпадает с сроком действия сертификата.

$sp = New-AzADServicePrincipal -DisplayName $DisplayName `
    -CertValue $keyValue `
    -EndDate $cert.NotAfter `
    -StartDate $cert.NotBefore
$sp

Вы получите аналогичный вывод, как показано на изображении ниже.

The new Azure service principal with a certificate is created

Назначение роли и области

Служебный принципал Azure создан, но ему еще не назначены Роль и Область. Это означает, что требуется дополнительный шаг для назначения роли и области служебному принципалу.

Код ниже использует cmdlet New-AzRoleAssignment для назначения роли владельца подписки VSE3 для учетной записи службы.

# Назначение роли и области
New-AzRoleAssignment -ApplicationId $sp.ApplicationId `
    -Scope $Scope `
    -RoleDefinitionName 'Owner'

При выполнении кода ниже на скриншоте ниже показано подтверждение завершения назначения роли.

The service principal’s owner role is added to the subscription

Подключение к Azure с использованием учетной записи службы с сертификатом

Теперь вы создали учетную запись службы с учетными данными на основе сертификата. Это означает, что вы можете использовать ее для подключения к Azure без использования пароля. Вместо этого вы будете использовать сертификат, доступный на вашем компьютере, в качестве метода аутентификации.

В данном примере отображаемое имя службы принципала – VSE3_SUB_OWNER, а имя сертификата – CN=VSE3_SUB_OWNER. Код ниже получит отпечаток сертификата из личного хранилища сертификатов и использует его в качестве учетных данных для входа.

# Получить сертификат с темой CN=VSE3_SUB_OWNER
$cert = Get-ChildItem Cert:\CurrentUser\My\ | Where-Object { $_.Subject -eq 'CN=VSE3_SUB_OWNER' }

# Подключение к Azure
Connect-AzAccount -ServicePrincipal -CertificateThumbprint $cert.ThumbPrint -ApplicationID $sp.ApplicationID -Tenant $TenantID

На скриншоте ниже показано, что с использованием указанного выше кода вход в Azure PowerShell был успешным, используя только ApplicationID, Tenant и Certificate ThumbPrint.

Connecting to Azure using a Service Principal and Certificate

Заключение

Azure Service Principals – это принцип безопасности, который следует учитывать при создании учетных данных для задач автоматизации и инструментов, обращающихся к ресурсам Azure. Можно выбрать область и роль, которые будут применены, чтобы предоставить “точно такие” права доступа.

В этой статье вы узнали, как создавать принципалы служб Azure, используя только PowerShell. У принципалов служб Azure может быть пароль, секретный ключ или учетные данные на основе сертификата. У каждого из этих типов учетных данных есть свои преимущества и сценарии применения.

Принципалы служб с паролем или учетными данными на основе секретного ключа более переносимы, но считаются менее безопасными, потому что учетные данные можно передавать в виде обычного текста. С другой стороны, учетные данные на основе сертификата – более безопасный вариант, но требует немного больше усилий для поддержки.

Техники, которые вы изучили в этой статье, охватывают только основы, чтобы вы могли начать использовать принципалы служб Azure в своей автоматизации. Существует еще много способов настройки принципалов служб Azure, таких как добавление, удаление и сброс учетных данных. Это зависит от вас, как вы их откроете по мере продвижения.

Спасибо за чтение!

Дополнительные обучающие ресурсы

Вот несколько ресурсов, которые могут оказаться полезными в дополнение к этой статье.

Source:
https://adamtheautomator.com/azure-service-principal/