Friday, March 30, 2018

Azure MSI Overview - No Credentials

One of the features that I am really liking is Azure Managed Service Identity (MSI).  The goal of this post is to provide a quick overview of the current state and how you can use it in applications.

The MSI feature essentially extends the idea of computer trust.  At the Azure level, one can associate an Azure Active Directory (AAD) identity with a particular Azure resource (lets say a web app).  This identity can then be used to make authentication decisions against various Azure resources.  Currently, the following targets are supported:
  • Azure Resource Manager
  • Azure Key Vault
  • Azure Data Lake
  • Azure SQL
  • Azure Event Hubs
  • Azure Service Bus
You can see the office list here. This is a pretty comprehensive list, and allows you to access most things natively without needing credentials.

When MSI is enabled on a resource, such as a VM, a special endpoint is setup on the local machine. This endpoint can be hit by any code running on the machine itself, and by providing the right parameters, you can get a token that is valid for the resource requested.  By default, this endpoint is the following:

http://localhost:50432/oauth2/token

Here is an example of how to call this via powershell:
 
 $response = Invoke-WebRequest -Uri http://localhost:50342/oauth2/token -Method GET -Body @{resource="https://vault.azure.net"} -Headers @{Metadata="true"}


The response is JSON, and the important part of the response is the access_token property.

In some cases, for example Azure Web Apps, enabling MSI populates a couple of environment variables that can be used to determine the exact location of your endpoint.  In specific, it is the MSI_ENDPOINT environment variable.  For more information, see the documentation here.

In C#, all of the above logic has been abstracted away in the Microsoft.Azure.Services.AppAuthentication library (currently in preview).  You can simply add this nuget package to your application to request tokens.  Please note that this works well for Azure Web Apps, but that you may have issues with Azure VMs as the environment variables required are not populated by default.

One really cool thing about the AppAuthentication library is that it provides features for local development.  When used with visual studio, the library makes use of the developer credentials currently associated to gain access to Azure resources.  This is pretty cool!

One last thing on usage is ensuring you are using the right resource type when requesting tokens.  The token issued is valid for a paticular resource type, and so you may need to make the call to the endpoint multiple times to get all the tokens required for your application.

Azure Resource Manager = https://management.azure.com/
Azure Key Vault = https://vault.azure.net/
Azure Data Lake = https://datalake.azure.net/
Azure SQL = https://database.windows.net/
Azure Event Hubs = https://eventhubs.azure.net/
Azure Service Bus = https://servicebus.azure.net/

Please note that the trailing slashes are required as part of the request.

When using MSI, you should probably note the following:

- Azure MSI is machine trust, and you now need to concern yourself with all security concerns related to this approach
- If you are using VMs, you will want to combine this with other solutions/techniques that ensure only authorized software can run on your VM
- You will probably want to audit/alert on usage of the MSI identity, including, if you can, the IP which originates the request
- Remember that you need to grant the least privilege to the MSI identity that is being used

I am loving Azure MSI, and the idea that I can now create applications without having to manage identity (or without my devs having to manage it).  Hopefully you enjoyed this post!

Tuesday, March 20, 2018

Exploring Azure DNS Analytics

You would be hard pressed to review a security benchmark that did not talk about controlling outbound connections.  Generally, one would tackle this problem by doing one of the following:

- Outbound firewall
- Web Proxy
- Services such as OpenDNS

In Azure, it can become somewhat onerous to deploy any of the solutions above.  It isn't that it isn't possible, it is that you generally want to shy away from creating/adding more gear to support this type of activity.  Further, OpenDNS can become kind of a pain when you have to specify IP addresses to enforce rules.

That is why I was super excited when Azure announced DNS analytics solution in OMS.  While lacking any pro-active capabilities, I can now use this solution in OMS to help me understand what DNS queries are being made in my environment.  I also get the power of Azure Security as it analyzes my DNS requests for communication with any malicious domains.

You can read more about the solution here.

After having this solution turned on for a few days now, I've noticed the following:

- I hate how IE defaults to MSN as homepage, even for servers
- My servers are all configured to hit windows update directly, I should probably change that :S
- There are lots of Azure addresses that get hit as part of normal operation.  Opinsights, automation, etc, and they all use different domain names.
- My servers are all dynamically registering properly, with no failures

I'm skipping a lot of screenshots here because the documentation was pretty indepth.  Here is what gets stored in Log Analytics for the DNS solution.

 

 In short, I think this is a great service, and a must-have when you set up OMS to help monitor your Azure environment. 


Friday, March 16, 2018

Reporting on Azure Application Security Groups

In my last two posts, we have been talking about Azure Application Security groups.  The goal of this post is to create a small powershell script that we can use to audit/report on assignment of the groups against NIC resources.

The script below essentially goes through each NIC and looks at the IpConfigurations configuration.  If an application security group is present, it displays it in a list.

The script is a little rough, but it does the trick for now. Enjoy!


param(
    [Parameter(Mandatory=$true)]
    [string]$subscriptionId,
    [string]$resourceGroupName
)

"Authenticating to Azure..."
try
{
    $azureLogin = Get-AzureRmContext
 if ($azureLogin.Subscription.Id -ne $subscriptionId){
  $azureLogin
  throw "This session is NOT logged in with the subscription id $subscriptionId"
 }
}
catch
{
    Login-AzureRmAccount -SubscriptionId $subscriptionId
}

if ($resourceGroupName){
    $nics = Get-AzureRmNetworkInterface -ResourceGroupName $resourceGroupName
} else {
    $nics = Get-AzureRmNetworkInterface
}

$nicObjects = @()

foreach ($nic in $nics){
    $nicName = $nic.Name
    $applicationSecurityGroups = @()
    foreach ($secGroup in $nic.IpConfigurations.ApplicationSecurityGroups){
        $secGroupResource = Get-AzureRmResource -resourceId $secGroup.id
        $applicationSecurityGroups += "{0}/{1}" -f $secGroupResource.ResourceGroupName, $secGroupResource.Name
    }
    $nicObject = New-object System.Object
    $nicObject | Add-Member -MemberType NoteProperty -name "name" -value $nicName
    $nicObject | Add-Member -MemberType NoteProperty -Name "Application Security Groups" -value ($applicationSecurityGroups)

    $nicObjects += $nicObject
}

$nicObjects | Format-Table

Tuesday, March 13, 2018

Applying Azure Application Security Groups

In a previous post, I discussed the initial steps to creating application security groups in ARM templates.  This post takes this one step further and applies them to a NIC.  For reference, the Network Interface ARM template schema can be found here.

Fundamentally, application security groups are an array of groups that can be applied to a specific IP configuration on a specific nic.  I think this is a really elegant place to attach these constructs, and will allow for some interesting designs into the future.

Here is a quick ARM template of a bare-bones network interface with an associated application security group.


{
    "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {},
    "variables": {},
    "resources": [
        {
            "type":"Microsoft.Network/networkInterfaces",
            "name": "IISWebServer-NIC1",
            "apiVersion": "2017-10-01",
            "location":"[resourceGroup().location]",
            "tags":{},
            "properties":{
                "ipConfigurations":[
                    {
                        "name":"ipconfig1",
                        "properties":{
                            "privateIPAllocationMethod":"Dynamic",
                            "subnet":{
                                "id": "[concat(resourceId('Microsoft.network/virtualNetworks','appsecurity'),'/subnets/', 'default')]"
                            },
                            "ApplicationSecurityGroups": [
                                {
                                    "id": "/subscriptions/xxxx/resourceGroups/testappsecuritygroups/providers/Microsoft.Network/applicationSecurityGroups/IISWebServers",
                                    "location":"[resourceGroup().location]"
                                }
                            ]
                        }
                    }
                ]
            }
        }
    ],
    "outputs": {}
}


As with a lot of ARM template constructs, application security groups are referenced via ID.  If you are creating a parameterized version of the above, you will need to pass in both the resource group and the name of the application security group.

Sunday, March 11, 2018

Creating Azure Application Security Groups

Azure application security groups are are relatively new construct for network security in Azure.  In the days of old, network security group administration in Azure was all done via IP addresses.  While the nested application of network security groups allowed for some interesting designs, most traditional firewall admins missed the idea of grouping servers together and then applying firewall rules to those groups.

Application security groups is an attempt to solve this problem.  Using them requires the following steps:
- Create an application security group
- Assign an application security group to a NIC, or set of NICs
- Create network security groups with application security group tags

The goal of this post is to demonstrate how to create an application security group from an ARM template.  The official documentation for this can be found here.

Here is my example of an application security group template:


{
    "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {},
    "variables": {},
    "resources": [
        {
            "type":"Microsoft.Network/applicationSecurityGroups",
            "name": "IISWebServers",
            "apiVersion": "2017-10-01",
            "location":"[resourceGroup().location]",
            "tags":{},
            "properties":{}
        }
    ],
    "outputs": {}
}


The above example essentially creates a group named IISWebServers.  Interestingly, this does not show up as a resource in the portal, even after deployed:



Here is the return from powershell: (Get-AzureRmApplicationSecurityGroup)



When you go to delete the resource group, you do see the item in the list:



Interesting!