Following from the prior post discussing Azure security and networking, I felt that additional coverage of Azure Network Security Groups was needed, as it is not the most obvious topic (and the design is quite different from how AWS does it).
Azure Network Security Groups
For full details, refer to the extensive documentation on MS Docs.
In short, Azure Network Security Groups (NSGs) provide a way to add firewall-like controls inside an Azure Virtual Network. Typical example may be to allow remote access from your IP, or cross subnet communications.
Azure NSGs can allow/deny specific protocol & port, with given source and destination.
Every NSG is pre-configured with default low-precedence rules that allow communication within the VNet and allow outbound-only Internet access.
NSGs can be applied to subnets or directly to network interfaces. This can cause issues as noted below.
Azure NSGs vs AWS SGs
Compared to the AWS offering, Azure NSGs combine the features of AWS Security Groups and Network ACLs.
AWS SGs are stateful, can only be applied to instances, and can only have Allow rules. AWS NACLs are stateless and can only be applied to subnets.
Azure NSGs are stateful and can have either allow or deny directives, and can be applied to a subnet or an interface.
NSG gotchas
The defined order of operations for NSGs bears defining:
Inbound traffic is checked against the Subnet NSG first, and if allowed, the VM NSG is checked.
Outbound traffic is checked against the VM NSG first, and if allowed, the Subnet NSG is checked.
Conceptually, whichever NSG is first on the packet's path is checked first.
What does this mean?
Stick to NSGs on subnets only (or, on VMs only though this is harder) as having NSGs on both will create unpredictable interaction and potentially undesired outages.
If no NSGs are defined at either the VM or the subnet, traffic is not checked at all, and the only checks are done by the VM OS (i.e. Windows firewall or netfilter/iptables on Linux). This should be avoided.