Bulk add Cloudflare's IPs to Azure App Service Access Restrictions using Az PowerShell
Niels Swimberghe - - Azure
Follow me on Twitter, buy me a coffee
When enabling Cloudflare on your website, Cloudflare acts as a caching proxy and web application firewall (WAF). By default Azure's App Services are exposed publicly using the following format [APPSERVICE_NAME].azurewebsites.net. If you leave your app service publicly exposed via that domain name, Cloudflare's security can be easily bypassed by attacking your service via Azure's default DNS.
You can block access to your service by using Azure App Service's Access Restriction feature which allows you to lock it down to a list of IPv4 ranges, IPv6 ranges, or specific Virtual Network. This will prevent attackers from accessing your service directly, but it will also block Cloudflare. To resolve this you need to add Cloudflare's IP ranges.
Cloudflare hosts 2 text files containing all their IP ranges: IPv4's & IPv6's. This list is rather long and if you want to insert those IP ranges manually using Azure's GUI, it'll will take a few minutes. When adding a single IP range manually, all traffic is blocked immediately except coming from that IP range. So the longer you take inserting the ranges manually, the more legitimate traffic is being blocked from Cloudflare. For that reason and general laziness, you should use a script to do this for you.
Bulk insert Cloudflare's IP Ranges script #
In a previous post, I shared a script you can use to bulk insert IP Access Restrictions to your Azure App Service using PowerShell. In this post I'll build upon that script and add the functionality necessary to insert all Cloudflare's IP ranges. The following script will:
- Fetch Cloudflare's IP range text files
- Parse the text file into valid IP Access Restriction Hashtables
- Pass the IP range hashtables to the bulk insert script
Param( [Parameter(Mandatory = $true)] [string] $ResourceGroupName, [Parameter(Mandatory = $true)] [string] $AppServiceName, [Parameter(Mandatory = $true)] [string] $SubscriptionId, [Parameter(Mandatory = $true)] [string] $RulePriority ) $ErrorActionPreference = "Stop" $IPv4s = (Invoke-WebRequest -Uri "https://www.cloudflare.com/ips-v4").Content -split '\r?\n|\r' $IPv6s = (Invoke-WebRequest -Uri "https://www.cloudflare.com/ips-v6").Content -split '\r?\n|\r' $NewIpRestrictions = @(); foreach($IPv4 in $IPv4s){ $NewIpRestrictions += @{ ipAddress = $IPv4; action = "Allow"; priority = $RulePriority; name = "Cloudflare IPv4"; description = "Cloudflare IPv4"; tag = "Default"; } } foreach($IPv6 in $IPv6s){ $NewIpRestrictions += @{ ipAddress = $IPv6; action = "Allow"; priority = $RulePriority; name = "Cloudflare IPv6"; description = "Cloudflare IPv6"; tag = "Default"; } } & "$PSScriptRoot\AddRestrictedIPAzureAppService.ps1" -ResourceGroupName $ResourceGroupName -AppServiceName $AppServiceName -SubscriptionId $SubscriptionId -NewIpRules $NewIpRestrictions
Usage:
.\AddCloudflareRestrictedIPApp.ps1 ` -ResourceGroupName "YourResourceGroup" ` -AppServiceName "YourAppServiceName" ` -SubscriptionId "YourSubscriptionGuid" ` -RulePriority "100"
- You need to save both scripts to your disk and make sure they're in the same folder. Download the scripts from this GitHub gist.
- You need to have the Az PowerShell module installed.
- The RulePriority matters in case you already have access restrictions and will determine the order of evaluation when a request is made against your service.
I hope this script saved you some time!