Subnet Level Network Security Groups
Azure provides lots of services and options for hosting IT solutions in the cloud. This lab tests one of the building blocks of cloud solutions; Network Security Groups. These are used to secure traffic in and out of virtual networks.

The Goal
To control inbound traffic to Virtual Machines using Network Security Groups (NSGs).
The Lab
This lab is also available on YouTube
In this lab the following resources were used in Azure:
- A Resource Group.
- A Virtual Network (VNET) with Subnets.
- A Windows 11 machine (VM).
- A Linux web server (VM).
- Azure Bastion (a secure, fully managed service that provides private RDP/SSH access to virtual machines without exposing them to the internet).
- Network Security Groups (NSGs).
In order to avoid using public IP addresses on the 2 VMs in Azure, I use Azure Bastion from within the Azure portal to access either VM on their private addresses securely via RDP or SSH.
I start with a a Resource Group and then a Virtual Network (VNET). It will need at least 2 subnets: one for Azure Bastion that must be in its own subnet and one subnet for the PC and web server.
The default behaviour of VNETS and subnets is to allow resources to communicate with each other. The setup would look like this:

With this setup, from Azure Bastion I can access both VMs and from the Windows 11 VM I can access the web app on the web server. If Bastion provides secure access and the VNET is private, this solution is already secure so why would I need Network Security Groups (NSGs)?
The Why
The proposed design means that any new VMs added to the subnets or added to new subnets will have interconnectivity by default. The server can connect to the VM, the VM can connect to the server, any new VMs can connect to each other as well as the existing VM and server.
In the old days, this would be perfectly acceptable since private networks were considered trusted. The modern security approach is to treat all devices as untrusted and therefore control traffic between devices, even in the same network. This is to prevent unintended access to devices on the network and reduce lateral movement (when a compromised device moves from one device to another within a network with malicious intent).
For example, if I setup a new web server for a finance app, I'll probably want to prevent other VMs getting access to it unless they need it. With NSGs, I can control traffic to resources at the infrastructure level so that I control what accesses what on the network.
Using a VPN is a secure and simple way to protect your data.
The How
NSGs are similar to stateful firewalls in that inbound and outbound traffic can be controlled using rules based on where traffic is coming from (source) and going to (destination) and what ports and protocols are in use. Also like firewalls, the priority (which rule is assessed first) can be set along with the action to be taken; allow or deny the traffic.
Unlike firewalls, NSGs are not central appliances but control mechanisms that can be applied liberally to subnets or directly to individual virtual machines.
- If I need to protect a single VM, I can associate the NSG to the NIC of that machine.
- If I want to protect a collection of VMs, I can associate the NSG to the subnet containing the VMs.
The Solution
The PC and web server are separated into their own subnets and a NSG is associated to each subnet. The Bastion subnet remains unchanged. The lab design now looks like this:

NSGs on their own don't control traffic, rules do.
There are 3 default rules in place for inbound and and outbound traffic.
- The first one allows inter-VNET connectivity.
- The second one allows the Azure Load Balancer access to the VNET (even when not using a load balancer, Microsoft recommends adding this rule since other services might need this connectivity).
- The last one denies all other traffic.
These rules use large numbers to set the priority to allow for custom rules to be added that will override these rules because smaller numbers (starting at 100) are evaluated first.

Here's the final solution with details of subnets and ports which will help me decide which inbound rules I need to create for the NSGs:

For the NSG associated with the PC subnet, I setup the following rules:

- The first rule allows RDP access from the Bastion subnet to the PC subnet.
- The second rule allow the Azure Load Balancer as recommended by Microsoft.
- The last one denies ALL OTHER traffic.
The first 2 rules override the default rules because of their priority and the last deny rule stops the processing of the other rules because all traffic is being denied. This now secures any VMs in the PC subnet.
For the NSG associated with the web server subnet, I setup the following rules:

- The first rule allows SSH access from the Bastion subnet to the web server subnet.
- The second rule allows the PC subnet to access web services (port 80) in the web server subnet.
- The third rule allow the Azure Load Balancer as recommended by Microsoft.
- The last one denies ALL OTHER traffic.
This now secures any VMs in the web server subnet.
The Results
Before putting in the NSGs and their rules connectivity between VMs in the VNET was possible without restriction.
With the NSGs in place:
- Only Bastion is allowed to access the Windows 11 PC and only via RDP.
- Only Bastion is allowed to access the web server via SSH.
- Only the Windows 11 PC is able to access the web app on port 80.
- All other traffic is denied by the NSGs (with the exception of Azure Load Balancer).
The result is that traffic is tightly controlled to access specific resources that it needs access to, in other words it follows the security principle of least privilege access.
The Conclusion
This lab successfully controlled traffic coming inbound to Azure resources using NSGs in a private network.
If you'd like to support my work, show your appreciation!
Comments ()