Azure Blob Storage Private Endpoints & Firewall

Securing Network Access


Introduction

Securing Azure Blob Storage with private endpoints and firewall rules ensures that your data can only be accessed from trusted networks, preventing unauthorized access from the public internet. Private endpoints create dedicated network interfaces in your virtual network that connect directly to your storage account, while firewall rules control which IP addresses and virtual networks can access your storage. Together, these features provide defense-in-depth security for your enterprise data.

This comprehensive guide covers:

  • Private endpoints — Creating secure network connections
  • Firewall configuration — Controlling network access
  • DNS integration — Ensuring proper name resolution
  • Access patterns — Connecting through private endpoints
  • Hybrid scenarios — Supporting both private and public access
  • Best practices — Implementing comprehensive security

Understanding Network Security

Private Endpoint Architecture

┌─────────────────────────────────────────────────────────────────────┐
│                 PRIVATE ENDPOINT ARCHITECTURE                       │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│   VIRTUAL NETWORK (VNet)                                            │
│   ─────────────────────────                                         │
│   ┌─────────────────────────────────────────────────────────────┐   │
│   │                    SUBNET                                   │   │
│   │                                                             │   │
│   │   ┌─────────────────────┐                                   │   │
│   │   │  PRIVATE ENDPOINT   │──────┐                            │   │
│   │   │  (Network Interface)│      │                            │   │
│   │   │  IP: 10.0.1.50      │      │                            │   │
│   │   └─────────────────────┘      │      Private Link          │   │
│   │                                │      Connection            │   │
│   │   ┌─────────────────────┐      │      (Private IPs)         │   │
│   │   │   VM / Function     │──────┘                            │   │
│   │   │   (Access storage)  │                                   │   │
│   │   └─────────────────────┘                                   │   │
│   └────────────────────────────┬────────────────────────────────┘   │
│                                │                                    │
└────────────────────────────────┼────────────────────────────────────┘
                                 │
                                 ▼
┌─────────────────────────────────────────────────────────────────────┐
│                      STORAGE ACCOUNT                                │
│                                                                     │
│   ┌─────────────────────────────────────────────────────────────┐   │
│   │  Private Endpoint: mystorage.privatelink.blob.core.windows  │   │
│   │  Public access: Disabled                                    │   │
│   │  Firewall: Allow selected networks only                     │   │
│   └─────────────────────────────────────────────────────────────┘   │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

Access Comparison

┌─────────────────────────────────────────────────────────────────────┐
│                 PUBLIC VS PRIVATE ACCESS                            │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│   PUBLIC ACCESS (Traditional)                                       │
│   ──────────────────────────                                        │
│   ┌────────────┐                                                    │
│   │   Internet │──────▶ mystorage.blob.core.windows.net             │
│   └────────────┘       (Public IP, anyone can access)               │
│                                                                     │
│   PRIVATE ENDPOINT (Secured)                                        │
│   ───────────────────────────                                       │
│   ┌────────────┐                                                    │
│   │   VNet     │──────▶ mystorage.privatelink.blob.core.windows.net │
│   └────────────┘       (Private IP, VNet only)                      │
│                                                                     │
│   FIREWALL RULES                                                    │
│   ───────────────                                                   │
│   ┌────────────┐                                                    │
│   │  Allowed   │──────▶ mystorage.blob.core.windows.net             │
│   │  IPs/VNets │       (Specific IPs or VNets only)                 │
│   └────────────┘                                                    │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

Create Private Endpoint

Using Azure Portal

  1. Navigate to Storage AccountNetworkingPrivate endpoint connections
  2. Click + Private endpoint
  3. Configure:
    • Subscription: Your subscription
    • Resource group: Your resource group
    • Name: blob-private-endpoint
    • Region: Same as storage account
    • Target resource type: Blob
    • Target sub-resource: Blob
    • Virtual Network: Your VNet
    • Subnet: Your subnet (or create new)
  4. Review and create

Using Azure CLI

# Create private endpoint for blob storage
az network private-endpoint create \
  --name blob-private-endpoint \
  --resource-group my-rg \
  --vnet-name myvnet \
  --subnet mysubnet \
  --connection-name storage-connection \
  --private-link-resource-type Microsoft.Storage/storageAccounts \
  --group-id blob \
  --target-resource /subscriptions/xxx/resourceGroups/my-rg/providers/Microsoft.Storage/storageAccounts/mystorage

# Get private endpoint details
az network private-endpoint show \
  --name blob-private-endpoint \
  --resource-group my-rg

Using ARM Template

{
  "resources": [
    {
      "type": "Microsoft.Network/privateEndpoints",
      "apiVersion": "2023-04-01",
      "name": "blob-private-endpoint",
      "location": "eastus",
      "properties": {
        "privateLinkServiceConnections": [
          {
            "name": "storage-connection",
            "properties": {
              "privateLinkServiceId": "/subscriptions/xxx/resourceGroups/my-rg/providers/Microsoft.Storage/storageAccounts/mystorage",
              "groupIds": ["blob"]
            }
          }
        ],
        "subnet": {
          "id": "/subscriptions/xxx/resourceGroups/my-rg/providers/Microsoft.Network/virtualNetworks/myvnet/subnets/mysubnet"
        }
      }
    }
  ]
}

Configure Firewall Rules

Allow Specific Virtual Networks

# Enable firewall and allow specific VNet
az storage account update \
  --name mystorage \
  --resource-group my-rg \
  --network-rule-set '{
    "default-action": "Deny",
    "bypass": ["AzureServices"],
    "virtualNetworkRules": [
      {
        "virtualNetworkResourceId": "/subscriptions/xxx/resourceGroups/my-rg/providers/Microsoft.Network/virtualNetworks/myvnet/subnets/mysubnet",
        "action": "Allow"
      }
    ],
    "ipRules": [
      {"ipAddressOrRange": "203.0.113.0/24", "action": "Allow"}
    ]
  }'

Allow Specific IP Addresses

# Add IP rules to allow specific public IPs
az storage account update \
  --name mystorage \
  --resource-group my-rg \
  --network-rule-set '{
    "ipRules": [
      {"ipAddressOrRange": "203.0.113.10", "action": "Allow"},
      {"ipAddressOrRange": "203.0.113.0/24", "action": "Allow"}
    ]
  }'

# Remove all IP rules
az storage account update \
  --name mystorage \
  --resource-group my-rg \
  --network-rule-set '{"ipRules": []}'

Configure via ARM Template

{
  "resources": [
    {
      "type": "Microsoft.Storage/storageAccounts",
      "apiVersion": "2023-01-01",
      "name": "mystorage",
      "location": "eastus",
      "properties": {
        "networkAcls": {
          "defaultAction": "Deny",
          "bypass": "AzureServices",
          "virtualNetworkRules": [
            {
              "id": "/subscriptions/xxx/resourceGroups/my-rg/providers/Microsoft.Network/virtualNetworks/myvnet/subnets/mysubnet",
              "action": "Allow"
            }
          ],
          "ipRules": [
            {"ipAddressOrRange": "203.0.113.0/24", "action": "Allow"}
          ]
        }
      }
    }
  ]
}

DNS Configuration

Create Private DNS Zone

# Create DNS zone for blob private links
az network private-dns zone create \
  --name privatelink.blob.core.windows.net \
  --resource-group my-rg

# Create DNS zone for file private links
az network private-dns zone create \
  --name privatelink.file.core.windows.net \
  --resource-group my-rg

Link DNS Zone to VNet

# Link blob DNS zone to VNet
az network private-dns link vnet create \
  --name blob-dns-link \
  --zone-name privatelink.blob.core.windows.net \
  --virtual-network myvnet \
  --resource-group my-rg \
  --registration-enabled false

# Link file DNS zone to VNet
az network private-dns link vnet create \
  --name file-dns-link \
  --zone-name privatelink.file.core.windows.net \
  --virtual-network myvnet \
  --resource-group my-rg \
  --registration-enabled false

DNS Record Configuration

┌─────────────────────────────────────────────────────────────────────┐
│                    DNS RESOLUTION FLOW                              │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│   Without Private Endpoint:                                         │
│   mystorage.blob.core.windows.net                                   │
│   → Resolves to Public IP (104.xxx.xxx.xxx)                         │
│                                                                     │
│   With Private Endpoint:                                            │
│   mystorage.blob.core.windows.net                                   │
│   → CNAME: mystorage.privatelink.blob.core.windows.net              │
│   → A Record: 10.0.1.50 (Private IP)                                │
│                                                                     │
│   Resolution in VNet:                                               │
│   ✓ mystorage.blob.core.windows.net → 10.0.1.50                     │
│   ✓ mystorage.privatelink.blob.core.windows.net → 10.0.1.50         │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

Access Storage via Private Endpoint

From Azure VM

// Access storage from VM in the same VNet
var blobServiceClient = new BlobServiceClient(
    new Uri("https://mystorage.blob.core.windows.net"),
    new DefaultAzureCredential());

// This automatically resolves to private endpoint
var containerClient = blobServiceClient.GetBlobContainerClient("mycontainer");
await containerClient.CreateIfNotExistsAsync();

From Azure Function in VNet

// Azure Function with VNet integration
public class VNetFunction
{
    [Function("ReadBlob")]
    public async Task<IActionResult> Run(
        [HttpTrigger(AuthorizationLevel.Function, "get")] HttpRequest req)
    {
        var blobServiceClient = new BlobServiceClient(
            new Uri("https://mystorage.blob.core.windows.net"),
            new DefaultAzureCredential());

        var blob = blobServiceClient.GetBlobContainerClient("secure-container")
            .GetBlobClient("data.txt");

        var content = await blob.DownloadContentAsync();
        return new OkObjectResult(content.Value.Content);
    }
}

From On-Premises via VPN

// On-premises application connecting via VPN
// Uses the same endpoint - DNS resolution handles routing
var blobServiceClient = new BlobServiceClient(
    new Uri("https://mystorage.blob.core.windows.net"),
    new DefaultAzureCredential());

Hybrid Access Scenarios

Allow Specific Public Access

# Allow access from specific IP ranges (e.g., corporate office)
az storage account update \
  --name mystorage \
  --resource-group my-rg \
  --network-rule-set '{
    "default-action": "Deny",
    "bypass": ["AzureServices"],
    "ipRules": [
      {"ipAddressOrRange": "203.0.113.0/24", "action": "Allow"}
    ]
  }'

Allow Azure Services

# Allow trusted Azure services
az storage account update \
  --name mystorage \
  --resource-group my-rg \
  --bypass AzureServices

Best Practices

Security Configuration

PracticeDescription
Default denySet default action to Deny
Use private endpointsFor all internal traffic
Limit IP rulesAllow only necessary IPs
Use managed identityFor Azure service access
Monitor accessLog all access attempts

Network Security Checklist

┌─────────────────────────────────────────────────────────────────────┐
│                 SECURITY IMPLEMENTATION CHECKLIST                   │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│   1. Create Private Endpoints                                       │
│   └─ Blob, File, Table, Queue endpoints                             │
│                                                                     │
│   2. Configure DNS Resolution                                       │
│   └─ Private DNS zones for each service                             │
│                                                                     │
│   3. Set Firewall Rules                                             │
│   └─ Default deny, allow specific networks                          │
│                                                                     │
│   4. Enable Private Link Access                                     │
│   └─ Disable public access where possible                           │
│                                                                     │
│   5. Use Managed Identity                                           │
│   └─ For Azure services accessing storage                           │
│                                                                     │
│   6. Monitor and Audit                                              │
│   └─ Enable logging, review access patterns                         │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

Related Topics


Azure Integration Hub - Intermediate Level