Manage data exfiltration to Azure Storage accounts with virtual network service endpoint policies using the Azure CLI
Virtual network service endpoint policies enable you to apply access control on Azure Storage accounts from within a virtual network over service endpoints. This is a key to securing your workloads, managing what storage accounts are allowed and where data exfiltration is allowed. In this article, you learn how to:
- Create a virtual network and add a subnet.
- Enable service endpoint for Azure Storage.
- Create two Azure Storage accounts and allow network access to it from the subnet created above.
- Create a service endpoint policy to allow access only to one of the storage accounts.
- Deploy a virtual machine (VM) to the subnet.
- Confirm access to the allowed storage account from the subnet.
- Confirm access is denied to the non-allowed storage account from the subnet.
If you don't have an Azure subscription, create an Azure free account before you begin.
Prerequisites
Use the Bash environment in Azure Cloud Shell. For more information, see Quickstart for Bash in Azure Cloud Shell.
If you prefer to run CLI reference commands locally, install the Azure CLI. If you're running on Windows or macOS, consider running Azure CLI in a Docker container. For more information, see How to run the Azure CLI in a Docker container.
If you're using a local installation, sign in to the Azure CLI by using the az login command. To finish the authentication process, follow the steps displayed in your terminal. For other sign-in options, see Sign in with the Azure CLI.
When you're prompted, install the Azure CLI extension on first use. For more information about extensions, see Use extensions with the Azure CLI.
Run az version to find the version and dependent libraries that are installed. To upgrade to the latest version, run az upgrade.
- This article requires version 2.0.28 or later of the Azure CLI. If using Azure Cloud Shell, the latest version is already installed.
Create a virtual network
Before creating a virtual network, you have to create a resource group for the virtual network, and all other resources created in this article. Create a resource group with az group create. The following example creates a resource group named myResourceGroup in the eastus location.
az group create \
--name myResourceGroup \
--location eastus
Create a virtual network with one subnet with az network vnet create.
az network vnet create \
--name myVirtualNetwork \
--resource-group myResourceGroup \
--address-prefix 10.0.0.0/16 \
--subnet-name Private \
--subnet-prefix 10.0.0.0/24
Enable a service endpoint
In this example, a service endpoint for Microsoft.Storage is created for the subnet Private:
az network vnet subnet create \
--vnet-name myVirtualNetwork \
--resource-group myResourceGroup \
--name Private \
--address-prefix 10.0.0.0/24 \
--service-endpoints Microsoft.Storage
Restrict network access for a subnet
Create a network security group with az network nsg create. The following example creates a network security group named myNsgPrivate.
az network nsg create \
--resource-group myResourceGroup \
--name myNsgPrivate
Associate the network security group to the Private subnet with az network vnet subnet update. The following example associates the myNsgPrivate network security group to the Private subnet:
az network vnet subnet update \
--vnet-name myVirtualNetwork \
--name Private \
--resource-group myResourceGroup \
--network-security-group myNsgPrivate
Create security rules with az network nsg rule create. The rule that follows allows outbound access to the public IP addresses assigned to the Azure Storage service:
az network nsg rule create \
--resource-group myResourceGroup \
--nsg-name myNsgPrivate \
--name Allow-Storage-All \
--access Allow \
--protocol "*" \
--direction Outbound \
--priority 100 \
--source-address-prefix "VirtualNetwork" \
--source-port-range "*" \
--destination-address-prefix "Storage" \
--destination-port-range "*"
Each network security group contains several default security rules. The rule that follows overrides a default security rule that allows outbound access to all public IP addresses. The destination-address-prefix "Internet"
option denies outbound access to all public IP addresses. The previous rule overrides this rule, due to its higher priority, which allows access to the public IP addresses of Azure Storage.
az network nsg rule create \
--resource-group myResourceGroup \
--nsg-name myNsgPrivate \
--name Deny-Internet-All \
--access Deny \
--protocol "*" \
--direction Outbound \
--priority 110 \
--source-address-prefix "VirtualNetwork" \
--source-port-range "*" \
--destination-address-prefix "Internet" \
--destination-port-range "*"
The following rule allows SSH traffic inbound to the subnet from anywhere. The rule overrides a default security rule that denies all inbound traffic from the internet. SSH is allowed to the subnet so that connectivity can be tested in a later step.
az network nsg rule create \
--resource-group myResourceGroup \
--nsg-name myNsgPrivate \
--name Allow-SSH-All \
--access Allow \
--protocol Tcp \
--direction Inbound \
--priority 120 \
--source-address-prefix "*" \
--source-port-range "*" \
--destination-address-prefix "VirtualNetwork" \
--destination-port-range "22"
Restrict network access to Azure Storage accounts
This section lists steps to restrict network access for an Azure Storage account from the given subnet in a Virtual network via service endpoint.
Create a storage account
Create two Azure storage accounts with az storage account create.
storageAcctName1="allowedstorageacc"
az storage account create \
--name $storageAcctName1 \
--resource-group myResourceGroup \
--sku Standard_LRS \
--kind StorageV2
storageAcctName2="notallowedstorageacc"
az storage account create \
--name $storageAcctName2 \
--resource-group myResourceGroup \
--sku Standard_LRS \
--kind StorageV2
After the storage accounts are created, retrieve the connection string for the storage accounts into a variable with az storage account show-connection-string. The connection string is used to create a file share in a later step.
saConnectionString1=$(az storage account show-connection-string \
--name $storageAcctName1 \
--resource-group myResourceGroup \
--query 'connectionString' \
--out tsv)
saConnectionString2=$(az storage account show-connection-string \
--name $storageAcctName2 \
--resource-group myResourceGroup \
--query 'connectionString' \
--out tsv)
View the contents of the variable and note the value for AccountKey returned in the output, because it's used in a later step.
echo $saConnectionString1
echo $saConnectionString2
Create a file share in the storage account
Create a file share in the storage account with az storage share create. In a later step, this file share is mounted to confirm network access to it.
az storage share create \
--name my-file-share \
--quota 2048 \
--connection-string $saConnectionString1 > /dev/null
az storage share create \
--name my-file-share \
--quota 2048 \
--connection-string $saConnectionString2 > /dev/null
Deny all network access to the storage account
By default, storage accounts accept network connections from clients in any network. To limit access to selected networks, change the default action to Deny with az storage account update. Once network access is denied, the storage account is not accessible from any network.
az storage account update \
--name $storageAcctName1 \
--resource-group myResourceGroup \
--default-action Deny
az storage account update \
--name $storageAcctName2 \
--resource-group myResourceGroup \
--default-action Deny
Enable network access from virtual network subnet
Allow network access to the storage account from the Private subnet with az storage account network-rule add.
az storage account network-rule add \
--resource-group myResourceGroup \
--account-name $storageAcctName1 \
--vnet-name myVirtualNetwork \
--subnet Private
az storage account network-rule add \
--resource-group myResourceGroup \
--account-name $storageAcctName2 \
--vnet-name myVirtualNetwork \
--subnet Private
Apply policy to allow access to valid storage account
Azure Service Endpoint policies are only available for Azure Storage. So, we'll be enabling Service Endpoint for Microsoft.Storage on this subnet for this example setup.
Service endpoint policies are applied over service endpoints. We will start by creating a service endpoint policy. We will then create the policy definitions under this policy for Azure Storage accounts to be approved for this subnet
Create a service endpoint policy
az network service-endpoint policy create \
--resource-group myResourceGroup \
--name mysepolicy \
--location eastus
Save the resource URI for the allowed storage account in a variable. Before executing the command below, replace <your-subscription-id> with actual value of your subscription ID.
$serviceResourceId="/subscriptions/<your-subscription-id>/resourceGroups/myResourceGroup/providers/Microsoft.Storage/storageAccounts/allowedstorageacc"
Create & add a policy definition for allowing the above Azure Storage account to the service endpoint policy
az network service-endpoint policy-definition create \
--resource-group myResourceGroup \
--policy-name mysepolicy \
--name mypolicydefinition \
--service "Microsoft.Storage" \
--service-resources $serviceResourceId
And update the virtual network subnet to associate with it the service endpoint policy created in the previous step
az network vnet subnet update \
--vnet-name myVirtualNetwork \
--resource-group myResourceGroup \
--name Private \
--service-endpoints Microsoft.Storage \
--service-endpoint-policy mysepolicy
Validate access restriction to Azure Storage accounts
Create the virtual machine
To test network access to a storage account, deploy a VM to the subnet.
Create a VM in the Private subnet with az vm create. If SSH keys do not already exist in a default key location, the command creates them. To use a specific set of keys, use the --ssh-key-value
option.
az vm create \
--resource-group myResourceGroup \
--name myVmPrivate \
--image <SKU linux image> \
--vnet-name myVirtualNetwork \
--subnet Private \
--generate-ssh-keys
The VM takes a few minutes to create. After creation, take note of the publicIpAddress in the output returned. This address is used to access the VM from the internet in a later step.
Confirm access to storage account
SSH into the myVmPrivate VM. Replace <publicIpAddress> with the public IP address of your myVmPrivate VM.
ssh <publicIpAddress>
Create a folder for a mount point:
sudo mkdir /mnt/MyAzureFileShare1
Mount the Azure file share to the directory you created. Before executing the command below, replace <storage-account-key> with value of AccountKey from $saConnectionString1.
sudo mount --types cifs //allowedstorageacc.file.core.windows.net/my-file-share /mnt/MyAzureFileShare1 --options vers=3.0,username=allowedstorageacc,password=<storage-account-key>,dir_mode=0777,file_mode=0777,serverino
You receive the user@myVmPrivate:~$
prompt. The Azure file share successfully mounted to /mnt/MyAzureFileShare.
Confirm access is denied to storage account
From the same VM myVmPrivate, create a directory for a mount point:
sudo mkdir /mnt/MyAzureFileShare2
Attempt to mount the Azure file share from storage account notallowedstorageacc to the directory you created. This article assumes you deployed the latest version of Linux distribution. If you are using earlier versions of Linux distribution, see Mount on Linux for additional instructions about mounting file shares.
Before executing the command below, replace <storage-account-key> with value of AccountKey from $saConnectionString2.
sudo mount --types cifs //notallowedstorageacc.file.core.windows.net/my-file-share /mnt/MyAzureFileShare2 --options vers=3.0,username=notallowedstorageacc,password=<storage-account-key>,dir_mode=0777,file_mode=0777,serverino
Access is denied, and you receive a mount error(13): Permission denied
error, because this storage account is not in the allow list of the service endpoint policy we applied to the subnet.
Exit the SSH session to the myVmPublic VM.
Clean up resources
When no longer needed, use az group delete to remove the resource group and all of the resources it contains.
az group delete --name myResourceGroup --yes
Next steps
In this article, you applied a service endpoint policy over an Azure virtual network service endpoint to Azure Storage. You created Azure Storage accounts and limited network access to only certain storage accounts (and thus denied others) from a virtual network subnet. To learn more about service endpoint policies, see Service endpoints policies overview.