Skip to content

Commit 502f9db

Browse files
Merge pull request #284323 from asudbring/sfi-us295037
SFI-ROPC edit article to add verbiage on more secure method in production.
2 parents 1b146dd + 511c1b3 commit 502f9db

File tree

1 file changed

+84
-69
lines changed

1 file changed

+84
-69
lines changed
Lines changed: 84 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
11
---
22
title: Restrict network access to PaaS resources - Azure CLI
3-
description: In this article, you learn how to limit and restrict network access to Azure resources, such as Azure Storage and Azure SQL Database, with virtual network service endpoints using the Azure CLI.
4-
services: virtual-network
3+
description: This article teaches you how to use the Azure CLI to restrict network access to Azure resources like Azure Storage and Azure SQL Database with virtual network service endpoints.
54
author: asudbring
6-
manager: mtillman
75
ms.service: azure-virtual-network
8-
ms.devlang: azurecli
96
ms.topic: how-to
10-
ms.tgt_pltfrm: virtual-network
11-
ms.date: 03/14/2018
7+
ms.date: 08/11/2024
128
ms.author: allensu
139
ms.custom: devx-track-azurecli
1410
# Customer intent: I want only resources in a virtual network subnet to access an Azure PaaS resource, such as an Azure Storage account.
@@ -33,22 +29,22 @@ Virtual network service endpoints enable you to limit network access to some Azu
3329

3430
## Create a virtual network
3531

36-
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](/cli/azure/group). The following example creates a resource group named *myResourceGroup* in the *eastus* location.
32+
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](/cli/azure/group). The following example creates a resource group named *test-rg* in the *eastus* location.
3733

3834
```azurecli-interactive
3935
az group create \
40-
--name myResourceGroup \
36+
--name test-rg \
4137
--location eastus
4238
```
4339

4440
Create a virtual network with one subnet with [az network vnet create](/cli/azure/network/vnet).
4541

4642
```azurecli-interactive
4743
az network vnet create \
48-
--name myVirtualNetwork \
49-
--resource-group myResourceGroup \
44+
--name vnet-1 \
45+
--resource-group test-rg \
5046
--address-prefix 10.0.0.0/16 \
51-
--subnet-name Public \
47+
--subnet-name subnet-public \
5248
--subnet-prefix 10.0.0.0/24
5349
```
5450

@@ -62,43 +58,43 @@ az network vnet list-endpoint-services \
6258
--out table
6359
```
6460

65-
Create an additional subnet in the virtual network with [az network vnet subnet create](/cli/azure/network/vnet/subnet). In this example, a service endpoint for *Microsoft.Storage* is created for the subnet:
61+
Create another subnet in the virtual network with [az network vnet subnet create](/cli/azure/network/vnet/subnet). In this example, a service endpoint for `Microsoft.Storage` is created for the subnet:
6662

6763
```azurecli-interactive
6864
az network vnet subnet create \
69-
--vnet-name myVirtualNetwork \
70-
--resource-group myResourceGroup \
71-
--name Private \
65+
--vnet-name vnet-1 \
66+
--resource-group test-rg \
67+
--name subnet-private \
7268
--address-prefix 10.0.1.0/24 \
7369
--service-endpoints Microsoft.Storage
7470
```
7571

7672
## Restrict network access for a subnet
7773

78-
Create a network security group with [az network nsg create](/cli/azure/network/nsg). The following example creates a network security group named *myNsgPrivate*.
74+
Create a network security group with [az network nsg create](/cli/azure/network/nsg). The following example creates a network security group named *nsg-private*.
7975

8076
```azurecli-interactive
8177
az network nsg create \
82-
--resource-group myResourceGroup \
83-
--name myNsgPrivate
78+
--resource-group test-rg \
79+
--name nsg-private
8480
```
8581

86-
Associate the network security group to the *Private* subnet with [az network vnet subnet update](/cli/azure/network/vnet/subnet). The following example associates the *myNsgPrivate* network security group to the *Private* subnet:
82+
Associate the network security group to the *subnet-private* subnet with [az network vnet subnet update](/cli/azure/network/vnet/subnet). The following example associates the *nsg-private* network security group to the *subnet-private* subnet:
8783

8884
```azurecli-interactive
8985
az network vnet subnet update \
90-
--vnet-name myVirtualNetwork \
91-
--name Private \
92-
--resource-group myResourceGroup \
93-
--network-security-group myNsgPrivate
86+
--vnet-name vnet-1 \
87+
--name subnet-private \
88+
--resource-group test-rg \
89+
--network-security-group nsg-private
9490
```
9591

9692
Create security rules with [az network nsg rule create](/cli/azure/network/nsg/rule). The rule that follows allows outbound access to the public IP addresses assigned to the Azure Storage service:
9793

9894
```azurecli-interactive
9995
az network nsg rule create \
100-
--resource-group myResourceGroup \
101-
--nsg-name myNsgPrivate \
96+
--resource-group test-rg \
97+
--nsg-name nsg-private \
10298
--name Allow-Storage-All \
10399
--access Allow \
104100
--protocol "*" \
@@ -114,8 +110,8 @@ Each network security group contains several [default security rules](./network-
114110

115111
```azurecli-interactive
116112
az network nsg rule create \
117-
--resource-group myResourceGroup \
118-
--nsg-name myNsgPrivate \
113+
--resource-group test-rg \
114+
--nsg-name nsg-private \
119115
--name Deny-Internet-All \
120116
--access Deny \
121117
--protocol "*" \
@@ -131,8 +127,8 @@ The following rule allows SSH traffic inbound to the subnet from anywhere. The r
131127

132128
```azurecli-interactive
133129
az network nsg rule create \
134-
--resource-group myResourceGroup \
135-
--nsg-name myNsgPrivate \
130+
--resource-group test-rg \
131+
--nsg-name nsg-private \
136132
--name Allow-SSH-All \
137133
--access Allow \
138134
--protocol Tcp \
@@ -157,17 +153,21 @@ storageAcctName="<replace-with-your-unique-storage-account-name>"
157153
158154
az storage account create \
159155
--name $storageAcctName \
160-
--resource-group myResourceGroup \
156+
--resource-group test-rg \
161157
--sku Standard_LRS \
162158
--kind StorageV2
163159
```
164160

165161
After the storage account is created, retrieve the connection string for the storage account into a variable with [az storage account show-connection-string](/cli/azure/storage/account). The connection string is used to create a file share in a later step.
166162

163+
For the purposes of this tutorial, the connection string is used to connect to the storage account. Microsoft recommends that you use the most secure authentication flow available. The authentication flow described in this procedure requires a high degree of trust in the application, and carries risks that aren't present in other flows. You should only use this flow when other more secure flows, such as managed identities, aren't viable.
164+
165+
For more information about connecting to a storage account using a managed identity, see [Use a managed identity to access Azure Storage](/entra/identity/managed-identities-azure-resources/tutorial-linux-managed-identities-vm-access?pivots=identity-linux-mi-vm-access-storage).
166+
167167
```azurecli-interactive
168168
saConnectionString=$(az storage account show-connection-string \
169169
--name $storageAcctName \
170-
--resource-group myResourceGroup \
170+
--resource-group test-rg \
171171
--query 'connectionString' \
172172
--out tsv)
173173
```
@@ -184,48 +184,49 @@ Create a file share in the storage account with [az storage share create](/cli/a
184184

185185
```azurecli-interactive
186186
az storage share create \
187-
--name my-file-share \
187+
--name file-share \
188188
--quota 2048 \
189189
--connection-string $saConnectionString > /dev/null
190190
```
191191

192192
### Deny all network access to a storage account
193193

194-
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](/cli/azure/storage/account). Once network access is denied, the storage account is not accessible from any network.
194+
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](/cli/azure/storage/account). Once network access is denied, the storage account isn't accessible from any network.
195195

196196
```azurecli-interactive
197197
az storage account update \
198198
--name $storageAcctName \
199-
--resource-group myResourceGroup \
199+
--resource-group test-rg \
200200
--default-action Deny
201201
```
202202

203203
### Enable network access from a subnet
204204

205-
Allow network access to the storage account from the *Private* subnet with [az storage account network-rule add](/cli/azure/storage/account/network-rule).
205+
Allow network access to the storage account from the *subnet-private* subnet with [az storage account network-rule add](/cli/azure/storage/account/network-rule).
206206

207207
```azurecli-interactive
208208
az storage account network-rule add \
209-
--resource-group myResourceGroup \
209+
--resource-group test-rg \
210210
--account-name $storageAcctName \
211-
--vnet-name myVirtualNetwork \
212-
--subnet Private
211+
--vnet-name vnet-1 \
212+
--subnet subnet-private
213213
```
214214
## Create virtual machines
215215

216216
To test network access to a storage account, deploy a VM to each subnet.
217217

218218
### Create the first virtual machine
219219

220-
Create a VM in the *Public* subnet with [az vm create](/cli/azure/vm). 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.
220+
Create a VM in the *subnet-public* subnet with [az vm create](/cli/azure/vm). If SSH keys don't already exist in a default key location, the command creates them. To use a specific set of keys, use the `--ssh-key-value` option.
221221

222222
```azurecli-interactive
223223
az vm create \
224-
--resource-group myResourceGroup \
225-
--name myVmPublic \
224+
--resource-group test-rg \
225+
--name vm-public \
226226
--image Ubuntu2204 \
227-
--vnet-name myVirtualNetwork \
228-
--subnet Public \
227+
--vnet-name vnet-1 \
228+
--subnet subnet-public \
229+
--admin-username azureuser \
229230
--generate-ssh-keys
230231
```
231232

@@ -234,87 +235,98 @@ The VM takes a few minutes to create. After the VM is created, the Azure CLI sho
234235
```azurecli
235236
{
236237
"fqdns": "",
237-
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myResourceGroup/providers/Microsoft.Compute/virtualMachines/myVmPublic",
238+
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.Compute/virtualMachines/vm-public",
238239
"location": "eastus",
239240
"macAddress": "00-0D-3A-23-9A-49",
240241
"powerState": "VM running",
241242
"privateIpAddress": "10.0.0.4",
242-
"publicIpAddress": "13.90.242.231",
243-
"resourceGroup": "myResourceGroup"
243+
"publicIpAddress": "203.0.113.24",
244+
"resourceGroup": "test-rg"
244245
}
245246
```
246247

247-
Take note of the **publicIpAddress** in the returned output. This address is used to access the VM from the internet in a later step.
248-
249248
### Create the second virtual machine
250249

251250
```azurecli-interactive
252251
az vm create \
253-
--resource-group myResourceGroup \
254-
--name myVmPrivate \
252+
--resource-group test-rg \
253+
--name vm-private \
255254
--image Ubuntu2204 \
256-
--vnet-name myVirtualNetwork \
257-
--subnet Private \
255+
--vnet-name vnet-1 \
256+
--subnet subnet-private \
257+
--admin-username azureuser \
258258
--generate-ssh-keys
259259
```
260260

261261
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.
262262

263263
## Confirm access to storage account
264264

265-
SSH into the *myVmPrivate* VM. Replace *\<publicIpAddress>* with the public IP address of your *myVmPrivate* VM.
265+
SSH into the *vm-private* VM.
266+
267+
Run the following command to store the IP address of the VM as an environment variable:
268+
269+
```bash
270+
export IP_ADDRESS=$(az vm show --show-details --resource-group test-rg --name vm-private --query publicIps --output tsv)
271+
```
266272

267273
```bash
268-
ssh <publicIpAddress>
274+
ssh -o StrictHostKeyChecking=no azureuser@$IP_ADDRESS
269275
```
270276

271277
Create a folder for a mount point:
272278

273279
```bash
274-
sudo mkdir /mnt/MyAzureFileShare
280+
sudo mkdir /mnt/file-share
275281
```
276282

277283
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](#create-a-storage-account).
278284

279285
```bash
280-
sudo mount --types cifs //<storage-account-name>.file.core.windows.net/my-file-share /mnt/MyAzureFileShare --options vers=3.0,username=<storage-account-name>,password=<storage-account-key>,dir_mode=0777,file_mode=0777,serverino
286+
sudo mount --types cifs //<storage-account-name>.file.core.windows.net/my-file-share /mnt/file-share --options vers=3.0,username=<storage-account-name>,password=<storage-account-key>,dir_mode=0777,file_mode=0777,serverino
281287
```
282288

283-
You receive the `user@myVmPrivate:~$` prompt. The Azure file share successfully mounted to */mnt/MyAzureFileShare*.
289+
You receive the `user@vm-private:~$` prompt. The Azure file share successfully mounted to */mnt/file-share*.
284290

285291
Confirm that the VM has no outbound connectivity to any other public IP addresses:
286292

287293
```bash
288294
ping bing.com -c 4
289295
```
290296

291-
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.
297+
You receive no replies, because the network security group associated to the *subnet-private* subnet doesn't allow outbound access to public IP addresses other than the addresses assigned to the Azure Storage service.
292298

293-
Exit the SSH session to the *myVmPrivate* VM.
299+
Exit the SSH session to the *vm-private* VM.
294300

295301
## Confirm access is denied to storage account
296302

297-
Use the following command to create an SSH session with the *myVmPublic* VM. Replace `<publicIpAddress>` with the public IP address of your *myVmPublic* VM:
303+
SSH into the *vm-public* VM.
304+
305+
Run the following command to store the IP address of the VM as an environment variable:
306+
307+
```bash
308+
export IP_ADDRESS=$(az vm show --show-details --resource-group test-rg --name vm-public --query publicIps --output tsv)
309+
```
298310

299311
```bash
300-
ssh <publicIpAddress>
312+
ssh -o StrictHostKeyChecking=no azureuser@$IP_ADDRESS
301313
```
302314

303315
Create a directory for a mount point:
304316

305317
```bash
306-
sudo mkdir /mnt/MyAzureFileShare
318+
sudo mkdir /mnt/file-share
307319
```
308320

309-
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](../storage/files/storage-how-to-use-files-linux.md?toc=%2fazure%2fvirtual-network%2ftoc.json) 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](#create-a-storage-account):
321+
Attempt to mount the Azure file share to the directory you created. This article assumes you deployed the latest version of Ubuntu. If you're using earlier versions of Ubuntu, see [Mount on Linux](../storage/files/storage-how-to-use-files-linux.md?toc=%2fazure%2fvirtual-network%2ftoc.json) for more 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](#create-a-storage-account):
310322

311323
```bash
312-
sudo mount --types cifs //storage-account-name>.file.core.windows.net/my-file-share /mnt/MyAzureFileShare --options vers=3.0,username=<storage-account-name>,password=<storage-account-key>,dir_mode=0777,file_mode=0777,serverino
324+
sudo mount --types cifs //storage-account-name>.file.core.windows.net/file-share /mnt/file-share --options vers=3.0,username=<storage-account-name>,password=<storage-account-key>,dir_mode=0777,file_mode=0777,serverino
313325
```
314326

315-
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.
327+
Access is denied, and you receive a `mount error(13): Permission denied` error, because the *vm-public* VM is deployed within the *subnet-public* subnet. The *subnet-public* subnet doesn't have a service endpoint enabled for Azure Storage, and the storage account only allows network access from the *subnet-private* subnet, not the *subnet-public* subnet.
316328

317-
Exit the SSH session to the *myVmPublic* VM.
329+
Exit the SSH session to the *vm-public* VM.
318330

319331
From your computer, attempt to view the shares in your storage account with [az storage share list](/cli/azure/storage/share). Replace `<account-name>` and `<account-key>` with the storage account name and key from [Create a storage account](#create-a-storage-account):
320332

@@ -324,18 +336,21 @@ az storage share list \
324336
--account-key <account-key>
325337
```
326338

327-
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.
339+
Access is denied and you receive a **This request isn't authorized to perform this operation** error, because your computer isn't in the *subnet-private* subnet of the *vnet-1* virtual network.
328340

329341
## Clean up resources
330342

331343
When no longer needed, use [az group delete](/cli/azure) to remove the resource group and all of the resources it contains.
332344

333345
```azurecli-interactive
334-
az group delete --name myResourceGroup --yes
346+
az group delete \
347+
--name test-rg \
348+
--yes \
349+
--no-wait
335350
```
336351

337352
## Next steps
338353

339354
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](virtual-network-service-endpoints-overview.md) and [Manage subnets](virtual-network-manage-subnet.md).
340355

341-
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](tutorial-connect-virtual-networks-cli.md).
356+
If you have multiple virtual networks in your account, you might 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](tutorial-connect-virtual-networks-cli.md).

0 commit comments

Comments
 (0)