Configurar Azure Service Principal: Guía de acceso no supervisado

Cuando necesitas automatizar tareas en Azure con scripts y herramientas, ¿considerarías el uso de cuentas de servicio o principios de servicio de Azure? No es raro que algunos simplemente creen una nueva cuenta de servicio, le asignen todos los roles de administrador que deseen y la excluyan de la autenticación multifactor.

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.

Pero, ¿cuál es la alternativa? ¿Cómo puedes utilizar una credencial privilegiada con un alcance limitado que no tenga que ser excluida de autenticación multifactor? Tienes suerte, porque eso es lo que te enseñará este artículo.

En este artículo, aprenderás qué es un Principio de Servicio de Azure. Aprenderás cómo crear principios de servicio con diferentes tipos de credenciales, como contraseñas, claves secretas y certificados.

Hay muchas herramientas para crear Principios de Servicio de Azure. Estas incluyen el uso del Portal de Azure, Centro de administración de Azure Active Directory, Azure AD PowerShell, Azure CLI, y Azure PowerShell. La herramienta que será el foco de este artículo es Azure PowerShell.

¿Todavía interesado? ¡Sigue leyendo y comencemos!

Requisitos

Dado que este es un artículo de aprender haciendo, aquí hay algunos requisitos previos para que puedas seguir el hilo.

Principal de servicio de Azure vs. Cuenta de servicio

Las herramientas y scripts de automatización a menudo necesitan acceso de administrador o privilegiado. Como, por ejemplo, aprovisionar cuentas de almacenamiento o iniciar y detener máquinas virtuales según un horario. Y la mayoría de los administradores probablemente usan una cuenta de usuario totalmente privilegiada (llamada cuenta de servicio) para establecer los requisitos de credencial para los scripts.

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.

Por otro lado, un principal de servicio de Azure se puede configurar para usar un nombre de usuario y contraseña o un certificado para la autenticación. Piénsalo como una identidad de usuario sin un usuario, sino más bien una identidad para una aplicación.

Un principal de servicio de Azure puede tener acceso justo a lo necesario, tan poco como a un único recurso de Azure específico. Por ejemplo, puedes crear un principal de servicio de Azure que tenga acceso basado en roles a una suscripción entera o solo a una máquina virtual de Azure específica.

Consideraciones principales para la creación de Principales de Servicio en Azure

Antes de crear un principal de servicio en Azure, debes conocer los detalles básicos que necesitas planificar. Estos detalles pueden parecer simples, pero harán que la creación de un principal de servicio en Azure sea lo más eficiente y fácil posible.

El nombre para mostrar. Todo comienza con un nombre, y un principal de servicio en Azure debe tener un nombre. No hay una regla específica aquí, pero tu organización podría tener una convención de nomenclatura prescrita.

  • Tipo de credencial a utilizar. Puedes optar por crear un principal de servicio en Azure que utilice una contraseña o un certificado para la autenticación. Esto no significa que solo puedas elegir uno, puedes usar ambos.

Para los principales de servicio, el nombre de usuario y la contraseña se conocen más apropiadamente como ID de aplicación y clave secreta.

  • Periodo de validez de la(s) credencial(es). Ya sea que estés asignando una contraseña o una credencial de certificado, debes definir una fecha de inicio y fin para su validez. La duración de la validez de una credencial generalmente depende de la frecuencia con la que estés dispuesto a rotar o renovar certificados y contraseñas.
  • Ámbito de acceso. ¿Estás creando un principal de servicio en Azure que tendrá acceso a una suscripción, grupo de recursos o recursos seleccionados?
  • El rol. Hay varios roles disponibles, como Contributor, Reader y Owner, por nombrar algunos. Debes definir qué rol es “lo suficientemente adecuado” para el principal de servicio.

Creación de un Azure Service Principal con Clave Secreta Asignada Automáticamente

El corazón de la creación de un nuevo service principal en Azure es el cmdlet New-AzAdServicePrincipal. En este ejemplo, se creará un nuevo service principal con los siguientes valores:

DisplayName: AzVM_Reader

Scope: AzVM1 (Máquina Virtual)

Role: Reader

Password: <asignado automáticamente>

Validez de las Credenciales: 1 año

Obtención del ID del Ámbito Objetivo (Máquina Virtual)

Como se puede ver, el ámbito de este nuevo service principal es solo para la máquina virtual llamada AzVM1. Sin embargo, el parámetro -Scope no acepta solo el nombre, sino el ID completo del recurso. Entonces, en este ejemplo, lo primero que se obtiene es el ID de la máquina virtual AzVM1. Para hacerlo, usa el código a continuación.

Get-AzVM | Format-Table Name, ID

Cuando ejecutas el código anterior en PowerShell, deberías ver la lista de nombres e IDs de las VM, similar a la captura de pantalla a continuación.

Get the list of VM names and IDs

Creación del Azure Service Principal con Clave Secreta

Ahora que tienes el ID del ámbito objetivo, que es el ID de la máquina virtual AzVM1, puedes usar el comando a continuación para crear el nuevo service principal que tiene el rol de reader. Las propiedades del nuevo service principal se almacenarán en la variable $sp.

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

Como resultado del comando anterior, se creó el service principal con los siguientes valores.

The properties of the new service principal

Descifrado de la Clave Secreta

Ahora tienes el ApplicationID y el Secreto, que es el nombre de usuario y la contraseña del principal de servicio. Sin embargo, el valor del Secreto se muestra como System.Security.SecureString. Querrás saber cuál es el secreto. Para eso, utiliza el comando siguiente para convertir el secreto a texto plano.

# Convertir la contraseña encriptada a texto plano
[System.Runtime.InteropServices.Marshal]::PtrToStringAuto(
    [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR(
        $sp.Secret
    )
)

El comando anterior convierte el valor de cadena asegurado de $sp.Secret a texto plano. Mira la imagen debajo para referencia.

Secure string password value converted to plain text

Verificación de la Asignación de Rol del Principal de Servicio de Azure

¿Cómo sabes si funcionó? Puedes verificar la lista de control de acceso del recurso usando el Portal de Azure. Por ejemplo, en la imagen debajo, puedes ver que el principal de servicio AzVM_Reader ahora tiene acceso de Reader a la máquina virtual AzVM1.

Azure resource access control

También puedes utilizar el comando Get-AzRoleAssignment -ObjectID $sp.id para obtener las asignaciones de rol del principal de servicio de Azure. Mira la captura de pantalla debajo como ejemplo.

Get the role assignment(s) of the service principal

Creación de un Principal de Servicio de Azure con Contraseña

Si deseas tener más control sobre qué contraseña o clave secreta se asigna a tu principal de servicio de Azure, utiliza el parámetro -PasswordCredential durante la creación del principal de servicio. Esto es especialmente útil si la contraseña debe cumplir con un requisito de complejidad.

En este ejemplo, el nuevo principal de servicio de Azure se creará con estos valores:

Nombre de visualización: ATA_RG_Contributor

Alcance: ATA (Grupo de Recursos)

Papel: Colaborador

Contraseña: 20 caracteres de longitud con 6 caracteres no alfanuméricos

Validez de las credenciales: 5 años

Obtención del ID del alcance objetivo (Grupo de recursos)

El alcance de este nuevo principal de servicio abarca todo el grupo de recursos llamado ATA. Lo primero que se debe obtener es el ID del grupo de recursos ATA. Para hacerlo, utiliza el código a continuación pero asegúrate de cambiar el valor del parámetro -Name por el nombre de tu grupo de recursos.

# Obtener el valor ResourceId del grupo de recursos
$Scope = (Get-AzResourceGroup -Name ATA).ResourceId
$Scope

Luego, deberías ver el ResourceID del grupo de recursos que ahora está almacenado en la variable $Scope.

Getting the Resource Group ID

Generación de la cadena de contraseña

El siguiente paso es generar la contraseña que sigue la complejidad de 20 caracteres de longitud con 6 caracteres no alfanuméricos. Para eso, puedes utilizar el método estático de .NET GeneratePassword().

# Generar una contraseña aleatoria usando el método estático GeneratePassword()
Add-Type -AssemblyName 'System.Web'
$password = [System.Web.Security.Membership]::GeneratePassword(20, 6)
$password

En el código anterior GeneratePassword(20, 6), el primer valor significa la longitud de la contraseña y el segundo valor significa la cantidad de caracteres no alfanuméricos que se incluirán. El resultado se muestra en la captura de pantalla a continuación.

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

Creación del objeto de credencial de contraseña

Ahora que tienes la cadena de contraseña, el siguiente paso es crear el objeto Microsoft.Azure.Commands.ActiveDirectory.PSADPasswordCredential. Este objeto contendrá la cadena de contraseña almacenada en la variable $password y el período de validez de 5 años. Copia el código a continuación y ejecútalo en tu sesión de Azure PowerShell.

# Crear el Objeto de Credencial de Contraseña
[Microsoft.Azure.Commands.ActiveDirectory.PSADPasswordCredential]`
    $PasswordCredential = @{
    StartDate = Get-Date;
    EndDate   = (Get-Date).AddYears(5);
    Password  = $password
}
$PasswordCredential

Al ejecutar el código anterior en PowerShell, se almacenará el objeto de credencial en la variable $PasswordCredential. El resultado esperado sería similar al que se muestra a continuación.

Creating the new password credential object in Azure PowerShell

Creando el Principal de Servicio con Contraseña

Ahora tienes los valores de parámetros requeridos listos para crear el principal de servicio de Azure. El código a continuación creará el principal de servicio con el nombre de visualización ATA_RG_Contributor y usando la contraseña almacenada en la variable $PasswordCredential.

# Crear el Principal de Servicio con una Credencial de Contraseña
$sp = New-AzAdServicePrincipal `
    -DisplayName 'ATA_RG_Contributor' `
    -PasswordCredential $PasswordCredential
$sp

Después de ejecutar el código, el nuevo principal de servicio debería crearse y las propiedades se almacenarán en la variable $sp. Consulta el resultado del ejemplo a continuación.

The new Azure service principal is created

Asignación del Rol y el Alcance

El principal de servicio de Azure se ha creado en la sección anterior, pero sin Rol y Alcance. Esto se debe a que los parámetros -Role y -Scope no pueden utilizarse junto con el parámetro -PasswordCredential. Esto significa que se necesita un paso adicional para asignar el rol y el alcance al principal de servicio.

El código a continuación utiliza el cmdlet New-AzRoleAssignment para asignar el ámbito y el rol del principal de servicio de Azure.

# Asignar el rol al recurso objetivo
New-AzRoleAssignment -$azSubscription = Get-AzSubscription -SubscriptionName VSE3
$Scope = "/subscriptions/$($azSubscription.ID)"
$TenantID = $azSubscription.TenantID$sp.ApplicationId `
    -Scope $Scope `
    -RoleDefinitionName 'Contributor'

La captura de pantalla a continuación muestra el resultado esperado después de asignar el rol y el ámbito al principal de servicio de Azure.

Assigning role and scope using Azure Powershell

Siempre asegúrese de guardar la contraseña del principal de servicio, ya que no hay forma de recuperarla si no pudo guardarla o la ha olvidado.

Conexión a Azure con una Contraseña de Principal de Servicio

Ahora, para poner en uso al principal de servicio. En lugar de iniciar sesión en Azure PowerShell con una cuenta de usuario, el código a continuación utiliza las credenciales del principal de servicio.

# Obtén el principal de servicio con el nombre de visualización ATA_RG_Contributor
$sp = Get-AzADServicePrincipal -DisplayName ATA_RG_Contributor

# Obtén el ID del inquilino
$TenantID = (Get-AzContext).Tenant.ID

# Obtén el primer nombre del principal de servicio
$user = $sp.ServicePrincipalNames[0]

# Convierte la contraseña en una cadena segura
$secPassword = $password | ConvertTo-SecureString -AsPlainText -Force

# Crea el objeto PSCredential
$credential = [PSCredential]::New($user,$secPassword)

# Conéctate a Azure
Connect-AzAccount -ServicePrincipal -Credential $credential -Tenant $TenantID
# Obtén el principal de servicio con el nombre de visualización ATA_RG_Contributor
$sp = Get-AzADServicePrincipal -DisplayName ATA_RG_Contributor

# Obtén el ID del inquilino
$TenantID = (Get-AzContext).Tenant.ID

# Obtén el primer nombre del principal de servicio
$user = $sp.ServicePrincipalNames[0]

# Convierte la contraseña en una cadena segura
$secPassword = $password | ConvertTo-SecureString -AsPlainText -Force

# Crea el objeto PSCredential
$credential = [PSCredential]::New($user,$secPassword)

# Conéctate a Azure
Connect-AzAccount -ServicePrincipal -Credential $credential -Tenant $TenantID# Obtén el principal de servicio con el nombre de visualización ATA_RG_Contributor
$sp = Get-AzADServicePrincipal -DisplayName ATA_RG_Contributor

# Obtén el ID del inquilino
$TenantID = (Get-AzContext).Tenant.ID

# Obtén el primer nombre del principal de servicio
$user = $sp.ServicePrincipalNames[0]

# Convierte la contraseña en una cadena segura
$secPassword = $password | ConvertTo-SecureString -AsPlainText -Force

# Crea el objeto PSCredential
$credential = [PSCredential]::New($user,$secPassword)

# Conéctate a Azure
Connect-AzAccount -ServicePrincipal -Credential $credential -Tenant $TenantID

Después de ejecutar el código anterior, deberías iniciar sesión en Azure PowerShell usando el principal de servicio ATA_RG_Contributor y la credencial de contraseña.

Connect to Azure using a Service Principal with Password Credential

Crear un Principal de Servicio de Azure con Certificado

Aparte de las credenciales de contraseña, un principal de servicio de Azure también puede tener una credencial basada en certificado. El certificado asociado puede ser uno emitido por una autoridad de certificación o auto firmado.

En este ejemplo, el nuevo principal de servicio de Azure se creará con estos valores:

Nombre para Mostrar: VSE3_SUB_OWNER

Ámbito: VSE3 (Suscripción)

Rol: Propietario

Validez del Certificado: 2 años

Obtener el ID del Ámbito Objetivo (Suscripción)

El ámbito de este nuevo principal de servicio abarca la suscripción de Azure llamada VSE3. Lo primero que se debe obtener es el ID de la suscripción VSE3. Para hacerlo, utiliza el código a continuación pero asegúrate de cambiar el valor del parámetro -SubscriptionName al nombre de tu grupo de recursos.

 # Obtener el ID del ámbito de la suscripción y el ID de inquilino 
$azSubscription = Get-AzSubscription -SubscriptionName VSE3
$Scope = "/subscriptions/$($azSubscription.ID)"
$TenantID = $azSubscription.TenantID

A continuación, especifica el nombre del nuevo principal de servicio de Azure y el certificado auto firmado que se creará.

 # El nombre del nuevo principal de servicio de Azure y el certificado auto firmado 
$DisplayName = 'VSE3_SUB_OWNER'

Creando el Certificado Auto Firmado

El código a continuación crea el certificado autofirmado en el almacén de certificados personales con el nombre CN=VSE3_SUB_OWNER. La validez del certificado se establece en dos años. Las propiedades del certificado se guardan en la variable $cert.

# Generar un certificado autofirmado
$cert = New-SelfSignedCertificate -CertStoreLocation "cert:\CurrentUser\My" `
    -Subject "CN=$($DisplayName)" `
    -KeySpec KeyExchange `
    -NotBefore ((Get-Date).AddDays(-1)) `
    -NotAfter ((Get-Date).AddYears(2))
$cert

La captura de pantalla a continuación muestra que el certificado ha sido creado.

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

Si deseas ver el nuevo certificado en una vista más familiar (GUI), puedes encontrarlo en la consola de Certificados (certmgr.mmc). Consulta la imagen a continuación que muestra el certificado.

Viewing the self-signed certificate

El siguiente paso es obtener el valor codificado en Base64 del certificado autofirmado y guardarlo en la variable $keyValue.

# Obtener el valor base64 del certificado autofirmado
$keyValue = [System.Convert]::ToBase64String($cert.GetRawCertData())

Creando el Principal de Servicio con Certificado

Ahora que el certificado está creado, el siguiente paso es crear el nuevo principal de servicio de Azure. El código a continuación creará el principal de servicio de Azure que utilizará el certificado autofirmado como credencial. El período de validez de la credencial coincide con el período de validez del certificado.

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

Obtendrás una salida similar, como se muestra en la imagen a continuación.

The new Azure service principal with a certificate is created

Asignación de la Función y el Alcance

Se ha creado el principal de servicio de Azure, pero aún no se ha asignado Función y Alcance. Esto significa que se necesita un paso adicional para asignar la función y el alcance al principal de servicio.

El código a continuación utiliza el cmdlet New-AzRoleAssignment para asignar el rol de propietario a la suscripción VSE3 del principal de servicio.

# Asignar rol y ámbito
New-AzRoleAssignment -ApplicationId $sp.ApplicationId `
    -Scope $Scope `
    -RoleDefinitionName 'Owner'

Cuando se ejecuta el código, la siguiente captura de pantalla muestra la confirmación de que se ha realizado la asignación de roles.

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

Conexión a Azure con un certificado de principal de servicio

Ahora ha creado el principal de servicio con una credencial basada en certificado. Esto significa que puede usarlo para conectarse a Azure sin usar una contraseña. En su lugar, usará el certificado que está disponible en su computadora como método de autenticación.

En este ejemplo, el nombre de visualización del principal de servicio es VSE3_SUB_OWNER, y el nombre del certificado es CN=VSE3_SUB_OWNER. El código a continuación obtendrá la huella digital del certificado del almacén de certificados personales y la usará como credencial de inicio de sesión.

# Obtener el certificado con el sujeto CN=VSE3_SUB_OWNER
$cert = Get-ChildItem Cert:\CurrentUser\My\ | Where-Object { $_.Subject -eq 'CN=VSE3_SUB_OWNER' }

# Conectar a Azure
Connect-AzAccount -ServicePrincipal -CertificateThumbprint $cert.ThumbPrint -ApplicationID $sp.ApplicationID -Tenant $TenantID

La siguiente captura de pantalla muestra que utilizando el código anterior, el inicio de sesión en Azure PowerShell fue exitoso usando solo el ApplicationID, Tenant y huella digital del certificado.

Connecting to Azure using a Service Principal and Certificate

Conclusión

Los Principales de Servicio de Azure son el principal de seguridad que se debe tener en cuenta al crear credenciales para tareas de automatización y herramientas que acceden a los recursos de Azure. El ámbito y el rol a aplicar pueden elegirse para dar permisos de acceso “justo lo suficiente”.

En este artículo, has aprendido cómo crear Principales de Servicio de Azure utilizando PowerShell. Los Principales de Servicio de Azure pueden tener una contraseña, una clave secreta o credenciales basadas en certificados. Cada uno de estos tipos de credenciales tiene sus ventajas y escenarios de uso aplicables.

Los principales de servicio con una contraseña o una credencial de clave secreta son más portátiles, pero se consideran menos seguros porque la credencial se puede compartir como texto sin formato. Por otro lado, las credenciales basadas en certificados son la opción más segura pero requieren un poco más de esfuerzo para mantener.

Las técnicas que aprendiste en este artículo solo cubren lo básico para que puedas empezar a utilizar Principales de Servicio de Azure en tu automatización. Hay muchas más formas de configurar Principales de Servicio de Azure, como agregar, eliminar y restablecer credenciales. Depende de ti descubrirlas a medida que avanzas.

¡Gracias por leer!

Recursos adicionales de aprendizaje

Aquí tienes algunos recursos que pueden ser útiles para complementar este artículo.

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