Auditing the use of Managed Service Identity in Azure

Managed Identity in Azure quite simply provides an AAD backed identity for your Web App or Virtual Machine, in order to communicate with other Azure services without explicitly providing credentials.

The range of Azure services that you can communicate with is growing, for the sake of this blog post we’re not going to focus on a specific service – instead querying the control plane to find all applicable RBAC assignments that have been set up for our Managed Identity. Please note that the script and example is all focussed around App Service, not a VM.

Switching it on

Turning on Managed Identity for a Web App you’ve published to Azure is easy. Navigate to the Web App, under settings you’ll finding Managed Service Identity, then flip the toggle box on before hitting Save.

This is what happens under the covers;

The App Gets a nice GUID assigned, this should be familiar to those working with ApplicationId’s and ServicePrincipals.

Toggling it

If you remove the Managed Identity from the app, and then set it back on again then a new PrincipalId is generated and any permissions you’d set up for this identity onto other Azure services will have been removed.

Auditing the Identity permissions

In an ideal world you’ll have a deployment script that sets up permissions for your Web App or VM on it’s dependant services with the least privilege required, however having a way of auditing a deployed applications permissions is going to be helpful in getting to that state. The script I’ve made looks at;

  • All Web Apps in your Azure subscription
  • Reports RBAC assignments for the Web Apps Identity
  • Checks all Keyvaults for Access Policies that the Identity has been allowed to use

The script: https://github.com/Gordonby/Snippets/blob/master/Powershell/Get-ManagedIdentityAssignments.ps1

The script populates two arrays with the pertinent information that you want to capture. From these arrays you can then start building a script that would restore the permissions to be used in a failure scenario.
Here’s what the they look like;

AlternativeIdentifierRefs problems with ACME New Certificate

The AlternativeIdentifierRefs parameter is used by the New-ACMECertificate cmdlet in ACMESharp when you want Let’s encrypt to have an secondary domain in the same certificate as your primary alias.
This is handy because Let’s Encrypt doesn’t support wildcards. EDIT: Let’s Encrypt ACMEv2 endpoint DOES support wildcards, but the Powershell module as it stands does not use ACMEv2.

I was having an issue when trying to do this;

New-ACMECertificate : The given key was not present in the dictionary

This was because in the previous steps in my script, I was only validating my ownership of the first alias – not of the alternative domains. I need to validate all domains before a certificate will be issued.

Here’s some code snippets of what I ended up with;

TemplateParameterObject Parameter in Azure Powershell New-AzureRmResourceGroupDeployment

If you’re initiating a deployment to Azure using an ARM template, then you can make use of the TemplateParameterObject to pass through a hashtable that contains the parameters for the template.

EG.

When you come to deploy the template using Powershell, you can therefore run something like this.

Getting started with domain management and DNS in Azure

One of the features in Azure that i hadn’t used until lately was the DNS Zone management for your own domain. It’s easy to use, but crucially allows a better degree of configuration than the previous company I’ve used for years.

  • Changing the Time To Live of specific DNS entries.
  • It’s API accessible, which means much better integration with automation scripts.
  • The cost of the domain comes out of your Azure bill which is actually pretty convenient for me.

You can see some of the other features here: https://azure.microsoft.com/en-gb/blog/app-service-domain/

Domain registration

I registered Azdemo.co.uk, and it took about 10 minutes before it was ready to use. You can find the feature under “App Service Domains”, although the naming can be a little confusing because you don’t need to use them just with App Service.

Automatic management of DNS for the domain.

The DNS Zones for the domain were automatically created as Azure is the default name server to provide DNS management. It also makes Custom Domain assignment much faster in App Service because you don’t have to perform the same validation steps.

DNS entities can then be added with Powershell, eg.

SSL Certificates

The next logical step is to deal with SSL Certificates for your subdomains/domain. You can either buy your SSL certificate through the Azure portal
https://docs.microsoft.com/en-gb/azure/app-service/web-sites-purchase-ssl-web-site or you can Bring Your Own Certificate. My personal preference is to leverage a free CA such as https://letsencrypt.org/, I’ll cover how I use Lets Encrypt in my next blog post.

Application Gateway with Public facing Web Apps

Azure Application Gateway

The most common use of Application Gateway is to expose web sites running on VM’s. I’m going to walkthrough configuring an existing App Gateway to target a Web App running on the public Azure App Service, and then securing the Web App to only take traffic from the Application Gateway. By putting an Application Gateway in front of your website, you can make use of the Web Application Firewall that it provides.

Lets start with creating the Web App. I’m using a standard ASP.NET web forms app from Visual Studio, and have tweaked the main page to output all of the HTTP headers onto the default web page so i can see what’s going on. Here’s the code needed to do that.

Once i’ve published it to Azure Web Apps, i now need to add my custom domains. This is pretty easy – with your Domain Registrar, you add a CNAME entry for the right subdomain to point to the FQDN for your web app. EG. WestEurope4.byers.me maps to WestEurope4.azurewebsites.net.

After you’ve done this for all the subdomains you want, you come back to the Azure Portal, Verify each domain and Add each hostname in the Custom Domains section of your Web App.

At this point we’re ready to configure/create the Application Gateway. You can find several scripts here; https://github.com/Gordonby/Snippets/tree/master/Powershell/AppGatewayForPublicWebApps
I can recommend the CreateAppGW-ForWebApp-v2 script because it creates the AppGW. This means that it rules out any config mistakes/issues you may have on an existing gateway. However there is a script there for when you have an existing gateway which i’ve used a couple of times.
NOTE: If you’re using a script that creates the Application Gateway, it will take over 30 minutes to provision.

After the Application Gateway has been created, you can now flip the DNS CNAME(s) to target the Application Gateway instead of the Web App directly. You should use the cloudapp.net address associated with the Application Gateways IP address. For me, this is f7a6e9e7-be60-4c41-b5a5-d211f5f56a91.cloudapp.net.

Once you have made the DNS changes, and they have been acknowledged by the various DNS servers and your cache you’ll get a page that looks like this.

This just leaves the process to lockdown the Web Application to only take traffic once it’s originated from the Application Gateway.
Azure App Service Static IP Restrictions
https://docs.microsoft.com/en-us/azure/app-service/app-service-ip-restrictions

After configuring the IP restriction with the IP address of your Application Gateway, when navigating to your Web App directly, you will be told;

This just leaves one remaining gotcha. Application Gateway only supports Dynamic Public IP Addresses. This of course means that should your Application Gateway change IP (not an expected operation, but still possible) you will need to adjust the configuration of your Web App IP Restriction.

New-AzureRmApplicationGateway : FrontendIpConfiguration /providers/Microsoft.N
etwork/applicationGateways/AppGwForWebAppsStatic/frontendIPConfigurations/fipcon
fig01 of Application Gateway with SKU tier WAF can only reference a
PublicIPAddress with IpAllocationMethod as Dynamic.

Application Gateway will support a Static IP address soon, but as of the time of writing – there is only a private preview programme open for it. https://docs.microsoft.com/en-us/azure/application-gateway/create-zone-redundant