Geo-restricting Azure services with Front Door
I’ve just finished a design for a client which required restricting various web endpoints to NZ IP addresses only.
I hadn’t used Azure Front Door prior to this project, because frankly it seemed like overkill for a small, NZ-based platform. I figured, “meh, I’ll just whitelist the IP ranges using an NSG, and be done with it. How hard can it be?”
It turns out little ol’ NZ has 7,295,124 IP addresses. (That’s just under double our population!) To whitelist these IPs, I’d need 221 individual IP entries! (point of geekiness - the first range assigned to NZ was 31 years ago, on 10/08/88, to Massey University)
So, the IP whitelist option was out.
But Azure Front Door was a viable approach. It’s got an attractive, minimal configuration (unlike the beast that is Application Gateway v1), and it supports fancy WAF rules, as well as custom rules, for which geo-location of the remote source is a configurable filter:
So we setup an Azure Front Door, with a dirty ol’ application gateway as its backend. Then in the NSG protecting the application gateway (applied at the subnet level), we whitelisted the IP ranges which Front Door traffic would be expected to ingress from, and locked all you unwashed barbarians outside the gates.
This all went mostly according to plan, but here are some gotchas to save you time:
Gotchas to avoid
Avoid using Frontdoor-managed certificates
Front Door will provide you with a free SSL certificate for your frontends. But I’ve had poor experience making it work. Mostly, choosing this option causes the “Updating” process to take 2+ hours.
Instead, the way to go is to put your certificates into KeyVault (you should be doing this already), and then to follow the following, super-user-unfriendly process:
- Launch a cloud shell from the Azure portal, select PowerShell (of course, you weren’t using it by default, were you?), and paste in the following incantation:
New-AzureRmADServicePrincipal -ApplicationId "ad0e1c7e-6d38-4ba4-9efd-0bc77ba9f037"(these are the instructions directly from Azure! They couldn’t make this into a button?)
- Now that the service principal has been added to your AADC, create a new access policy, and grant it the
secret.getpermission in Key Vault.
Avoid hard-coding the backend host header
When you setup your backend hosts, you’re prompted to choose a backend host header. If you set this value, then the “Host” field on every forwarded request will be rewritten to what you chose. If you’ve routing more than one domain name to the backend, then this static value will break ability of the backend host to determine what content to send, based on the request header.
Rather, leave the backend host header blank, so that Front Door will just pass through the Host header from the original request:
Avoid omitting the host header with curl when you test
I baffled myself for a while after implementing the above, because I was running
curl <hostname of frontdoor-protected-website>, and receiving a 404 error from my backend in response. Turns out, you have to submit a host header of some sort, so
curl -H 'Host: myawesomesite.com' <hostname of frontdoor-protected-website> did the trick.