Protecting your Azure Container Registry by denying all requests except from allowed IP addresses

Tobias Zimmergren
Tobias Zimmergren
💡🤖TIP: Check out the guidance for AI adoption on Azure!

With Azure Container Registry, or ACR, we get a lot of great capabilities to host our Docker images in the Azure cloud. With that, as with everything else, comes security concerns we should not overlook.

In this post I'm exploring how we can lock down all access to our ACR by default, and then enable access based on an IP address or range of IP addresses.

This is similar to what I've already explained in another post about Secure your Azure Storage Accounts with restrictions based on public IP addresses. If you haven't seen that, take a look there how to learn to protect the storage accounts the same way.

Note 2019-03-20: This feature is currently in Preview for ACR.
That said, it's an important upcoming roll-out you should be aware of.

In this post I'm restricting access purely based on IP Addresses; but you can also restrict access through vnet's which is another great capability if all your resources reside within this virtual network and you want to add another layer of security around it. That's for another post, though.

Let's take a look at how to secure our Azure Container Registry based on IP Addresses. In the end, if you don't have yourself whitelisted, it'll end up with a 403 Forbidden as per this image:

Azure Container Registry gets 403 Forbidden because Firewall rules denies all traffic until we've whitelisted our IP/IP-range.

Pre-requisites

Upgrade your ACR to Premium SKU

If you're running Azure Container Registry with Basic or Standard SKUs, you're out of luck. The firewall feature is part of the Premium SKU only, hence you'll need to ensure your ACR is on this SKU before you start.

Show your current SKU with the Azure CLI

You can use the Azure Portal and go to your ACR -> "Update" button and then select the Premium SKU.

Alternatively, which I prefer personally, you just do it from the Azure CLI:

az acr show -n acrdemomagic -g demos --query sku

The output will be JSON and display your existing SKU:

{
  "name": "Basic",
  "tier": "Basic"
}

Upgrade ACR to Premium SKU

We could just see that the Azure Container Registry was in Basic as per my above command. Then it's time to upgrade to Premium:

az acr update -n acrdemomagic -g demos --sku Premium

The output json will display the state of your ACR now, which should have the "sku" property populated as such, to display Premium:

"sku": {
"name": "Premium",
"tier": "Premium"
}

Restrict all access to Azure Container Registry

When we've reached this point, we are prepared to enable access restrictions to our ACR. We're in the Premium tier, and there's no stopping us now!

Step 1: Check the network rules for your Azure Container Registry

First, I'm getting my ACR to see what current configurations I have for my network rules:

az acr network-rule list -n acrdemomagic

Output:

{
  "ipRules": [],
  "virtualNetworkRules": []
}

We can easily see that we have no network rules. None for IP, and none for VNets. Let's go ahead and change that.

Step 2: Deny all traffic to your Container Registry

Run the following command to DENY ALL traffic to your Azure Container Registry. Remember, you should do this only if you're keen on restricting any access until you've added either a vnet or ip-range whitelist.

az acr update -n acrdemomagic --default-action Deny

You'll be able to verify the output JSON by finding this information:

  ...
  "name": "acrdemomagic",
  "networkRuleSet": {
    "defaultAction": "Deny",
    "ipRules": [],
    "virtualNetworkRules": []
  },
  ...

As you can see in the above JSON output, there's a new entry for defaultAction which tells our ACR to automatically Deny any traffic that comes its way - and since there's nothing in ipRules or virtualNetworkRules that would allow us access, everything should be blocked from accessing your ACR right now. Let's verify.

Step 3: Verify blocked access to our Azure Container Registry

To verify if we can access our ACR now after we've enabled the firewall to automatically deny all traffic, we can do it straight from the Azure CLI and using Docker pull, or any other commands that interacts with your ACR:

az acr login -n acrdemomagic

I'm now getting this response immediately when I try to do something with my ACR:

Unable to get AAD authorization tokens with message: Registry 'acrdemomagic.azurecr.io' did not issue a challenge.

Error response from daemon: login attempt to https://acrdemomagic.azurecr.io/v2/ failed with status: 403 Forbidden

So there we have it. Nobody, including myself and my servers cannot access the ACR. But that's suboptimal, given I have both dev routines, DevOps pipelines, and services that require communication with this Azure Container Registry. Let's continue by opening up some IP ranges to the ACR and verify that it works. Tag along to the next section.

Step 4: Add your allowed/whitelisted IP addresses and ranges

Great, you made it all the way here. Let's continue with adding our own IP address to the whitelist of ipRules, which can easily be done like this:

az acr network-rule add -n acrdemomagic --ip-address 217.123.121.232

We can easily verify that it exist, just like we did in "Step 1" above:

az acr network-rule list -n acrdemomagic

It should now yield a slightly different output:

{
  "ipRules": [
    {
      "action": "Allow",
      "ipAddressOrRange": "217.123.121.232"
    }
  ],
  "virtualNetworkRules": []
}

Et voila. We can see that the IP address I entered now successfully is included as an Allow action, with my IP Address (or IP-range).

Tip: The --ip-address parameter accepts either a single IPv4 address or a CIDR range.

Step 5: Verify whitelisted access to Azure Container Registry

One easy way to verify that we once again have access (since I know I'm using the same IP address as I just added above), I can simply issue the az acr login -n acrdemomagic command again and see the results. It should be successful.

Login Succeeded

I also verified it by connecting to a VPN service and tried to authenticate this way; it failed with 403 Forbidden as expected.

We've taken a look at how we can easily whitelist any of our IP Addresses, while the rest of the world will be locked out of our ACR entirely. Another layer of security for another one of your resources in Azure.

In this post we briefly walked through:

  • Configuring Premium SKU of our Azure Container Registry
  • Enable Firewall support of our ACR, denying all requests by default
  • Tested that we could no longer access our ACR from outside any trusted IP ranges
  • Added our IP to the whitelist
  • Tested that we COULD access the ACR now, from this one location only

Microsoft announced the preview of the vnet and firewall rules a couple of days ago, and there might be more to keep an eye out for:

AzureContainersACRSecurity

Tobias Zimmergren Twitter

Hi, I'm Tobias! 👋 I write about Microsoft Azure, security, cybersecurity, compliance, cloud architecture, Microsoft 365, and general tech!

Reactions and mentions


Hi, I'm Tobias 👋

Tobias Zimmergren profile picture

Find out more about me.

Recent comments

Mastodon