Filter network traffic with a network security group using the Azure CLI

You can filter network traffic inbound to and outbound from a virtual network subnet with a network security group. Network security groups contain security rules that filter network traffic by IP address, port, and protocol. Security rules are applied to resources deployed in a subnet. In this article, you learn how to:

  • Create a network security group and security rules
  • Create a virtual network and associate a network security group to a subnet
  • Deploy virtual machines (VM) into a subnet
  • Test traffic filters

If you don't have an Azure subscription, create a free account before you begin.

Open Azure Cloud Shell

Azure Cloud Shell is a free, interactive shell that you can use to run the steps in this article. Common Azure tools are preinstalled and configured in Cloud Shell for you to use with your account. Just select the Copy button to copy the code, paste it in Cloud Shell, and then press Enter to run it. There are a few ways to open Cloud Shell:

Select Try It in the upper-right corner of a code block. Cloud Shell in this article
Open Cloud Shell in your browser. https://shell.azure.com/bash
Select the Cloud Shell button on the menu in the upper-right corner of the Azure portal. Cloud Shell in the portal

If you choose to install and use the CLI locally, this article requires that you are running the Azure CLI version 2.0.28 or later. To find the version, run az --version. If you need to install or upgrade, see Install Azure CLI 2.0.

Create a network security group

A network security group contains security rules. Security rules specify a source and destination. Sources and destinations can be application security groups.

Create application security groups

First create a resource group for all the resources created in this article with az group create. The following example creates a resource group in the eastus location:

az group create \
  --name myResourceGroup \
  --location eastus

Create an application security group with az network asg create. An application security group enables you to group servers with similar port filtering requirements. The following example creates two application security groups.

az network asg create \
  --resource-group myResourceGroup \
  --name myAsgWebServers \
  --location eastus

az network asg create \
  --resource-group myResourceGroup \
  --name myAsgMgmtServers \
  --location eastus

Create a network security group

Create a network security group with az network nsg create. The following example creates a network security group named myNsg:

# Create a network security group
az network nsg create \
  --resource-group myResourceGroup \
  --name myNsg

Create security rules

Create a security rule with az network nsg rule create. The following example creates a rule that allows traffic inbound from the internet to the myWebServers application security group over ports 80 and 443:

az network nsg rule create \
  --resource-group myResourceGroup \
  --nsg-name myNsg \
  --name Allow-Web-All \
  --access Allow \
  --protocol Tcp \
  --direction Inbound \
  --priority 100 \
  --source-address-prefix Internet \
  --source-port-range "*" \
  --destination-asgs "myAsgWebServers" \
  --destination-port-range 80 443

The following example creates a rule that allows traffic inbound from the Internet to the myMgmtServers application security group over port 22:

az network nsg rule create \
  --resource-group myResourceGroup \
  --nsg-name myNsg \
  --name Allow-SSH-All \
  --access Allow \
  --protocol Tcp \
  --direction Inbound \
  --priority 110 \
  --source-address-prefix Internet \
  --source-port-range "*" \
  --destination-asgs "myAsgMgmtServers" \
  --destination-port-range 22

In this article, SSH (port 22) is exposed to the internet for the myAsgMgmtServers VM. For production environments, instead of exposing port 22 to the internet, it's recommended that you connect to Azure resources that you want to manage using a VPN or private network connection.

Create a virtual network

Create a virtual network with az network vnet create. The following example creates a virtual named myVirtualNetwork:

az network vnet create \
  --name myVirtualNetwork \
  --resource-group myResourceGroup \
  --address-prefixes 10.0.0.0/16

Add a subnet to a virtual network with az network vnet subnet create. The following example adds a subnet named mySubnet to the virtual network and associates the myNsg network security group to it:

az network vnet subnet create \
  --vnet-name myVirtualNetwork \
  --resource-group myResourceGroup \
  --name mySubnet \
  --address-prefix 10.0.0.0/24 \
  --network-security-group myNsg

Create virtual machines

Create two VMs in the virtual network so you can validate traffic filtering in a later step.

Create a VM with az vm create. The following example creates a VM that will serve as a web server. The --asgs myAsgWebServers option causes Azure to make the network interface it creates for the VM a member of the myAsgWebServers application security group.

The --nsg "" option is specified to prevent Azure from creating a default network security group for the network interface Azure creates when it creates the VM. To streamline this article, a password is used. Keys are typically used in production deployments. If you use keys, you must also configure SSH agent forwarding for the remaining steps. For more information, see the documentation for your SSH client. Replace <replace-with-your-password> in the following command with a password of your choosing.

adminPassword="<replace-with-your-password>"

az vm create \
  --resource-group myResourceGroup \
  --name myVmWeb \
  --image UbuntuLTS \
  --vnet-name myVirtualNetwork \
  --subnet mySubnet \
  --nsg "" \
  --asgs myAsgWebServers \
  --admin-username azureuser \
  --admin-password $adminPassword

The VM takes a few minutes to create. After the VM is created, output similar to the following example is returned:

{
  "fqdns": "",
  "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myResourceGroup/providers/Microsoft.Compute/virtualMachines/myVmWeb",
  "location": "eastus",
  "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. This address is used to access the VM from the internet in a later step. Create a VM to serve as a management server:

az vm create \
  --resource-group myResourceGroup \
  --name myVmMgmt \
  --image UbuntuLTS \
  --vnet-name myVirtualNetwork \
  --subnet mySubnet \
  --nsg "" \
  --asgs myAsgMgmtServers \
  --admin-username azureuser \
  --admin-password $adminPassword

The VM takes a few minutes to create. After the VM is created, note the publicIpAddress in the returned output. This address is used to access the VM in the next step. Don't continue with the next step until Azure finishes creating the VM.

Test traffic filters

Use the command that follows to create an SSH session with the myVmMgmt VM. Replace with the public IP address of your VM. In the example above, the IP address is 13.90.242.231.

ssh azureuser@<publicIpAddress>

When prompted for a password, enter the password you entered in Create VMs.

The connection succeeds, because port 22 is allowed inbound from the Internet to the myAsgMgmtServers application security group that the network interface attached to the myVmMgmt VM is in.

Use the following command to SSH to the myVmWeb VM from the myVmMgmt VM:

ssh azureuser@myVmWeb

The connection succeeds because a default security rule within each network security group allows traffic over all ports between all IP addresses within a virtual network. You can't SSH to the myVmWeb VM from the Internet because the security rule for the myAsgWebServers doesn't allow port 22 inbound from the Internet.

Use the following commands to install the nginx web server on the myVmWeb VM:

# Update package source
sudo apt-get -y update

# Install NGINX
sudo apt-get -y install nginx

The myVmWeb VM is allowed outbound to the Internet to retrieve nginx because a default security rule allows all outbound traffic to the Internet. Exit the myVmWeb SSH session, which leaves you at the username@myVmMgmt:~$ prompt of the myVmMgmt VM. To retrieve the nginx welcome screen from the myVmWeb VM, enter the following command:

curl myVmWeb

Logout of the myVmMgmt VM. To confirm that you can access the myVmWeb web server from outside of Azure, enter curl <publicIpAddress> from your own computer. The connection succeeds, because port 80 is allowed inbound from the Internet to the myAsgWebServers application security group that the network interface attached to the myVmWeb VM is in.

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 created a network security group and associated it to a virtual network subnet. To learn more about network security groups, see Network security group overview and Manage a network security group.

Azure routes traffic between subnets by default. You may instead, choose to route traffic between subnets through a VM, serving as a firewall, for example. To learn how, see Create a route table.