Limit access to your Azure Web App from your Azure Front Door only

Azure Front Door team just GA’d March 2020 updates which include easier lockdown for backends. Now instead of using multiple values for X-Forwarded-Host header for filtering traffic to your backends, you can use the Front Door ID field for a new header X-Azure-FDID to lockdown your backends for both production traffic as well as health probes.

Background

I’m working on a project in which we are using Azure Front Door to serve our application faster and more secure by having the Web Application Firewall intercepting incoming requests. Here is the architecture for a reference:

Hilma architecture

By default you can access resources behind the Front Door if you know (or guess) the correct endpoints such as xx-yy-production.azurewebsites.net. There is still very little documentation of how you can handle the issue so I decided to post a step-by-step walkthrough how you can lock down access to your Web App from your Front Door instance only.

IP restrictions

Configure IP ACLing for your backends to accept traffic from Azure Front Door’s backend IP address space and Azure’s infrastructure services only. Refer the IP details below for ACLing your backend:

  • Refer AzureFrontDoor.Backend section in Azure IP Ranges and Service Tags for Front Door’s IPv4 backend IP address range or you can also use the service tag AzureFrontDoor.Backend in your network security groups or with Azure Firewall.
  • Front Door’s IPv6 backend IP space while covered in the service tag, is not listed in the Azure IP ranges JSON file. If you are looking for explicit IPv6 address range, it is currently limited to 2a01:111:2050::/44
  • Azure’s basic infrastructure services through virtualized host IP addresses: 168.63.129.16 and 169.254.169.254

You Web App network restrictions should look something like this now:

Web App network restrictions Front Door

Now this of course doesn’t cut it yet. One can still create their own Azure Front Door instance and could still bypass your own Front Door. That’s why you have to make sure requests are coming from a specific Front Door.

Use .NET Core Middleware to constrain X-Azure-FDID header value

XAzureFDIDMiddleware.cs

First we need to create the middleware itself. All it has to do is to grab the X-Azure-FDID header value and compare it against a value in our appsettings (AzureFrontDoorId in my case) and if it’s not a match, short-circuit the rest of the pipeline.

using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;

namespace Hilma.Web.Middleware
{
    public class XAzureFDIDMiddleware
    {
        private readonly RequestDelegate _next;

        public XAzureFDIDMiddleware(RequestDelegate next)
        {
            _next = next;
        }

        public async Task InvokeAsync(HttpContext context, IHostingEnvironment environment, IConfiguration configuration)
        {            
            var fdidHeaderValue = context.Request.Headers["X-Azure-FDID"].ToString();

            if (fdidHeaderValue != configuration["AzureFrontDoorId"])
            {
                await context.Response.WriteAsync("Blocked");
            }
            else
            {
                await _next(context);
            }
        }
    }
}

XAzureFDIDMiddlewareExtensions.cs

Create an extension to have your middleware available in Startup.Configure:

using Microsoft.AspNetCore.Builder;

namespace Hilma.Web.Middleware
{
    public static class XAzureFDIDMiddlewareExtensions
    {
        public static IApplicationBuilder UseXAzureFDID(
            this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<XAzureFDIDMiddleware>();
        }
    }
}

Startup.cs

Use the middleware by injecting it to the pipeline in Startup.Configure:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseXAzureFDID();
    }
    // ... (the rest of your pipeline)
}

GET your Front Door ID and put it in your app configuration

You can fetch the frontdoorId from Front Door’s management API. The easiest way to do this is going to https://docs.microsoft.com/en-us/rest/api/frontdoorservice/frontdoor/frontdoors/get and click “Try it”. Note that you have to use API version 2020-01-01 or newer for this.

It will ask you to log in and fill in information about your subscription, resource group and front door resource name. At the bottom of the response you can find the frontdoorId (GUID) that you can put in your App Configuration.

frontdoorId

Put the value in your App Configuration and you are done. Happy Front Dooring!

 

Leave a Reply

Your email address will not be published. Required fields are marked *