Onboard to Azure Arc with Security in Mind
Published Apr 17 2024 09:00 AM 4,438 Views
Microsoft

Introduction

Azure Arc allows certain on-premises resources, typically servers, to be managed from Azure, depending on the configuration mode selected and currently available features.

 

While this allows for a more integrated approach to hybrid environments, it also further blurs the administrative boundary between on-premises and cloud.

 

This increases the risk that a vulnerability on either side lowers the level of security across the entire plane. This article contains tips for managing this risk and approaching Arc Onboarding with security in mind.

 

It focuses only on servers. The link below contains information about the full range of Azure Arc:

Azure Arc overview - Azure Arc | Microsoft Learn.

 

Azure Arc and its service principal

Onboarding to Azure Arc can be done using a service principal in Entra ID for authentication.

 

Service principals can be thought of as “service accounts” in Azure.

 

One way of generating this service principal is from the Azure Arc blade in the Azure portal. Navigate to Azure Arc / Management / Service principals. Below one such an entry:

 

Figure 1: Azure Arc service principalsFigure 1: Azure Arc service principals

Here the scope of the service principal (for example the resource group “RG-ARC”) and the Arc-specific roles can be assigned.  Most common is the “Azure Connected Machine Onboarding” role, as shown above. 

 

These options ensure that the powers of this service principal are restricted. It is critical that the service principal does not get any other privileges, because this principal will be exposed across all machines that will be onboarded. Local administrators of those machines, and any threat actor that compromises the machines, can access the secret, even if it is encrypted as suggested below. 

 

By constraining the service principal using the “scope” and the “role”,  we avoid accidental administrative exposure of the Azure environment.

 

But what about the secret?

Creating a service principal within the Azure Arc blade generates a text file with the value of its “secret”.  Think of this as the password of the service principal. By default, it will have a very short lifetime, although a longer lifetime can be configured during creation of the service principal (the service principal is only needed at the time of onboarding to Azure Arc, not for subsequent communications).

 

Note that it is also possible to upload a (public key) certificate as an alternative authentication mechanism, but here we focus on the secret.

 

Onboarding a machine to Azure Arc requires download and installation of the Azure Arc agent installer (AzureConnectedMachineAgent.msi). Once this has run, we can use the azcmagent.exe utility to onboard the machine:

 

CD 'C:\Program Files\AzureConnectedMachineAgent'

 

.\azcmagent.exe connect `

--resource-name <My Computer Name> `

--service-principal-id <the client id of the service principal>`

 --service-principal-secret <the secret of the service principal>`

 --resource-group <the resource group we scoped for the service pr> `

 --tenant-id <the tenant id>  `

 --location  <the region> `

  --subscription-id <the subscription id> `

  --cloud AzureCloud 

 

The above is a simple example, suitable for one machine.

 

For bigger deployments, this public Microsoft document explains how to deploy at scale using Group Policies:

Connect machines at scale using Group Policy with a PowerShell script - Azure Arc | Microsoft Learn

 

And:

GitHub - Azure/ArcEnabledServersGroupPolicy: Guidance and sample code to perform at-scale onboarding...

 

At a high-level, this solution comprises the components shown here:

 

Figure 2: Microsoft components for onboarding to Azure Arc at scale by GPOFigure 2: Microsoft components for onboarding to Azure Arc at scale by GPO

The script DeployGPO.ps1 is only run once. It creates the Group Policy Object (GPO) and populates the share with the artifacts used by the GPO, for example- the script EnableAzureArc.ps1 (that will be executing on each machine that digests the GPO).

 

What about the secret? Will it be hardcoded in plain text in the script on the share and therefore be readable by anyone with access to the share?

 

This is where it gets interesting.

 

Amongst the items provided by Microsoft in the above link is a PowerShell module named AzureArcDeployment.psm1. The makers of this module have done something very cool here, and created a custom type that can be called from any PowerShell session that loads the module.

Here a partial screen shot (the full module is amongst the artifacts downloadable from the links above):

 

Figure 3: AzureArcDeployment.psm1Figure 3: AzureArcDeployment.psm1

Notice the class “DpapiNgUtil” and its methods “ProtectBase64” and “UnprotectBase64”.

The DeployGPO.ps1 script uses this class (or “type”) to take the plain text secret and convert it into an encrypted blob on the share (partial screenshot):

 

Figure 4: DeployGPO.ps1Figure 4: DeployGPO.ps1

The script that runs on all endpoints that get the GPO, EnableAzureArc.ps1, will decrypt, “unprotect”, the secret, as long as these machines’ accounts in AD are member of the groups used to encrypt the secret.

 

Figure 5: EnableAzureArc.ps1Figure 5: EnableAzureArc.ps1

This magic is possible thanks to “DPAPI NG” or Data Protection API Next Gen, which has been around since Windows 8 (what can we say, the name stuck).  To cut a long story short, this allows DPAPI to be a joint effort between your local machine and the domain controller, which is why we can use the AD group memberships as a factor.

 

Why this is interesting

The objective is to avoid any “uninvited guests” to the Azure Arc party in the form of machines that are not supposed to be there, for example to avoid any unintended data- or code sharing.

 

DeployGPO.ps1 as it is downloaded from the links above, allows all members of  “Domain Controllers” and “Domain Computers” to decrypt the secret by adding the SID’s of these groups to the “descriptor” fed into [DpapiUtil]::ProtectBase64.

This means that only domain-joined machines can be onboarded to Azure Arc, as they are the only ones that can get to the secret of the service principal.

 

However, we can imagine creating our own version of DeployGPO.ps1 and instead use our own custom AD group’s SID, say “Allowed to Arc”, and place only specific machine accounts into that group.

 

This can then serve as a double protection layer for ensuring systems go to the right resource group or subscription in Azure. To clarify this, in the Cloud Adoption Framework shown below, DC’s may only go into the Identity subscription, as administrative access to this area is strictly limited. Accidentally onboarding them to any other landing zone may cause lower-level Azure administrators to gain access to them.

 

The DPAPI technique described can be used in conjunction with correct GPO linking to ensure systems are properly directed into the right area in Azure.

Figure 8: Identity subscription in CAFFigure 8: Identity subscription in CAF

What is an Azure landing zone? - Cloud Adoption Framework | Microsoft Learn

 

Azure Arc Modes

To further protect machines onboarded to Azure Arc, the configuration of the agent should be considered.

 

The Azure Arc agent has different modes (config.mode). The mode on each machine can be checked using the azcmagent.exe utility, as shown here:

 

Figure 6: azcmagent config listFigure 6: azcmagent config list

The command above is: C:\Program Files\AzureConnectedMachineAgent> azcmagent config list 

 

The default is full mode, and this may be what is required in order to manage on-premises machines from Azure, for example for running custom extensions and other code on these machines from Azure.

 

For example, full mode also allows anyone with the right RBAC role in Azure to execute Azure Automation Runbooks against on-premises Azure Arc enabled machines (by including them in a Hybrid Worker Group). These Runbooks can launch scripts that run in System context. This merits repeating, especially for domain controllers: System context. This means full control of the system, and in the case of a domain controller, Active Directory itself and with it the rest of the environment.

 

Also deserving attention is the Run Command capability, described here:

How to remotely and securely configure servers using Run command (Preview) - Azure Arc | Microsoft L...

 

This screenshot shows the output of “whoami” run against an Azure Arc-enabled DC:

 

Figure 7: whoami Run CommandFigure 7: whoami Run Command

All that said, today we still see many customers onboard machines to Azure Arc for the sole purpose of monitoring (the Azure Monitor Agent for on-premises machines requires that these are Azure Arc-enabled). In that case, the more secure option is to change the mode to monitor only:

 

Figure 8: azcmagent config set config.mode monitorFigure 8: azcmagent config set config.mode monitor

The command above is: C:\Program Files\AzureConnectedMachineAgent> azcmagent config set config.mode monitor

 

As can be seen above, this white-lists only certain extensions. When configured like this, script executions such as those with Azure Automation Runbooks can no longer be run on this Arc-enabled on-premises machine.

 

A useful reference can be found here: Security overview - Azure Arc | Microsoft Learn.

 

Conclusion

The tips in this article can help you correctly scope, configure, and direct systems into the right areas, so that they are not unnecessarily exposed as part of the Azure Arc onboarding.

10 Comments
Co-Authors
Version history
Last update:
‎Apr 16 2024 12:40 PM
Updated by: