Restrict network access to PaaS resources with virtual network service endpoints using the Azure CLI
Virtual network service endpoints enable you to limit network access to some Azure service resources to a virtual network subnet. You can also remove internet access to the resources. Service endpoints provide direct connection from your virtual network to supported Azure services, allowing you to use your virtual network's private address space to access the Azure services. Traffic destined to Azure resources through service endpoints always stays on the Azure backbone network. In this article, you learn how to:
- Create a virtual network with one subnet
- Add a subnet and enable a service endpoint
- Create an Azure resource and allow network access to it from only a subnet
- Deploy a virtual machine (VM) to each subnet
- Confirm access to a resource from a subnet
- Confirm access is denied to a resource from a subnet and the internet
If you don't have an Azure trail subscription, create a trial subscription before you begin.
Prerequisites
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.
Note
Before you can use Azure CLI in Microsoft Azure operated by 21Vianet, please run az cloud set -n AzureChinaCloud
first to change the cloud environment. If you want to switch back to Azure Public Cloud, run az cloud set -n AzureCloud
again.
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 chinaeast location.
az group create \
--name myResourceGroup \
--location chinaeast
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 Public \
--subnet-prefix 10.0.0.0/24
Enable a service endpoint
You can enable service endpoints only for services that support service endpoints. View service endpoint-enabled services available in an Azure location with az network vnet list-endpoint-services. The following example returns a list of service-endpoint-enabled services available in the chinaeast region. The list of services returned will grow over time, as more Azure services become service endpoint enabled.
az network vnet list-endpoint-services \
--location chinaeast \
--out table
Create an additional subnet in the virtual network with az network vnet subnet create. In this example, a service endpoint for Microsoft.Storage is created for the subnet:
az network vnet subnet create \
--vnet-name myVirtualNetwork \
--resource-group myResourceGroup \
--name Private \
--address-prefix 10.0.1.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 a resource
The steps necessary to restrict network access to resources created through Azure services enabled for service endpoints varies across services. See the documentation for individual services for specific steps for each service. The remainder of this article includes steps to restrict network access for an Azure Storage account, as an example.
Create a storage account
Create an Azure storage account with az storage account create. Replace <replace-with-your-unique-storage-account-name>
with a name that is unique across all Azure locations, between 3-24 characters in length, using only numbers and lower-case letters.
storageAcctName="<replace-with-your-unique-storage-account-name>"
az storage account create \
--name $storageAcctName \
--resource-group myResourceGroup \
--sku Standard_LRS \
--kind StorageV2
After the storage account is created, retrieve the connection string for the storage account into a variable with az storage account show-connection-string. The connection string is used to create a file share in a later step.
saConnectionString=$(az storage account show-connection-string \
--name $storageAcctName \
--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 $saConnectionString
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 $saConnectionString > /dev/null
Deny all network access to a 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 $storageAcctName \
--resource-group myResourceGroup \
--default-action Deny
Enable network access from a 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 $storageAcctName \
--vnet-name myVirtualNetwork \
--subnet Private
Create virtual machines
To test network access to a storage account, deploy a VM to each subnet.
Create the first virtual machine
Create a VM in the Public 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 myVmPublic \
--image UbuntuLTS \
--vnet-name myVirtualNetwork \
--subnet Public \
--generate-ssh-keys
The VM takes a few minutes to create. After the VM is created, the Azure CLI shows information similar to the following example:
{
"fqdns": "",
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myResourceGroup/providers/Microsoft.Compute/virtualMachines/myVmPublic",
"location": "chinaeast",
"macAddress": "00-0D-3A-23-9A-49",
"powerState": "VM running",
"privateIpAddress": "10.0.0.4",
"publicIpAddress": "13.90.242.231",
"resourceGroup": "myResourceGroup"
}
Take note of the publicIpAddress in the returned output. This address is used to access the VM from the internet in a later step.
Create the second virtual machine
az vm create \
--resource-group myResourceGroup \
--name myVmPrivate \
--image UbuntuLTS \
--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/MyAzureFileShare
Mount the Azure file share to the directory you created. Before running the following command, replace <storage-account-name>
with the account name and <storage-account-key>
with the key you retrieved in Create a storage account.
sudo mount --types cifs //<storage-account-name>.file.core.chinacloudapi.cn/my-file-share /mnt/MyAzureFileShare --options vers=3.0,username=<storage-account-name>,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 that the VM has no outbound connectivity to any other public IP addresses:
ping bing.com -c 4
You receive no replies, because the network security group associated to the Private subnet does not allow outbound access to public IP addresses other than the addresses assigned to the Azure Storage service.
Exit the SSH session to the myVmPrivate VM.
Confirm access is denied to storage account
Use the following command to create an SSH session with the myVmPublic VM. Replace <publicIpAddress>
with the public IP address of your myVmPublic VM:
ssh <publicIpAddress>
Create a directory for a mount point:
sudo mkdir /mnt/MyAzureFileShare
Attempt to mount the Azure file share to the directory you created. This article assumes you deployed the latest version of Ubuntu. If you are using earlier versions of Ubuntu, see Mount on Linux for additional instructions about mounting file shares. Before running the following command, replace <storage-account-name>
with the account name and <storage-account-key>
with the key you retrieved in Create a storage account:
sudo mount --types cifs //storage-account-name>.file.core.chinacloudapi.cn/my-file-share /mnt/MyAzureFileShare --options vers=3.0,username=<storage-account-name>,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 the myVmPublic VM is deployed within the Public subnet. The Public subnet does not have a service endpoint enabled for Azure Storage, and the storage account only allows network access from the Private subnet, not the Public subnet.
Exit the SSH session to the myVmPublic VM.
From your computer, attempt to view the shares in your storage account with az storage share list. Replace <account-name>
and <account-key>
with the storage account name and key from Create a storage account:
az storage share list \
--account-name <account-name> \
--account-key <account-key>
Access is denied and you receive a This request is not authorized to perform this operation error, because your computer is not in the Private subnet of the MyVirtualNetwork virtual network.
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 enabled a service endpoint for a virtual network subnet. You learned that service endpoints can be enabled for resources deployed with multiple Azure services. You created an Azure Storage account and limited network access to the storage account to only resources within a virtual network subnet. To learn more about service endpoints, see Service endpoints overview and Manage subnets.
If you have multiple virtual networks in your account, you may want to connect two virtual networks together so the resources within each virtual network can communicate with each other. To learn how, see Connect virtual networks.