Lock Down Traffic with NSGs

Learn how to lock down traffic with NSGs in Azure. This hands-on lesson covers the core concept, step-by-step configuration, troubleshooting tips, and what to study next.

Focus: lock down traffic with nsgs

Sponsored

Picture this: you've just deployed a shiny new web app to Azure, and the public endpoint is live. Within hours, you notice suspicious requests from random IPs probing your app, or worse — a misconfigured port is wide open, exposing your database to the internet. Without a way to control who can reach your resources, your cloud environment is a liability. This is exactly the pain that Network Security Groups (NSGs) solve. In this lesson, you'll learn how to use NSGs to lock down traffic with precision, so only the right clients can reach your services — and everything else gets dropped at the door.

The problem this lesson solves

Every Azure virtual machine, App Service, or load balancer has a public or private endpoint. By default, Azure's security model is permissive: if a port is open in the network, traffic can flow unless you explicitly block it. This leads to a harsh reality: many breaches start because a firewall rule was left open "just for testing" or a port was accidentally exposed during deployment.

The problem isn't just about malicious attackers. It's also about accidental exposure — a developer opens port 1433 (SQL Server) to the public for a quick test and forgets to close it. Or a security scan flags your subnet because port 22 (SSH) is open to the whole internet.

Without proper traffic lockdown, you face: - Unauthorized access to your services. - Data breaches when databases or admin panels are exposed. - Compliance failures if you're handling sensitive data (HIPAA, GDPR, SOC 2).

This lesson gives you a practical, repeatable method to define exactly who can talk to what in your Azure infrastructure.

Core concept / mental model

Think of an NSG as a bouncer at a club. The club is your virtual network. The bouncer stands at the door (the network interface or subnet) and checks every person (network packet) trying to enter or leave. The bouncer has a list of rules: some people are allowed in, others are turned away. If no rule matches, the default policy kicks in — and in Azure, the default is to deny all inbound and allow all outbound (unless you override it).

Here's a mental diagram:

Internet → NSG (check rules) → Subnet → VM
            |                      |
            |--- allow: 443 from trust-IPs
            |--- deny: all else

An NSG contains a list of security rules. Each rule has: - Priority (lower number = higher priority) - Direction (inbound or outbound) - Source (IP, CIDR, service tag, or application security group) - Destination (IP, CIDR, or service tag) - Protocol (TCP, UDP, ICMP, or any) - Port range (e.g., 80, 443, 1024-2048) - Action (allow or deny)

Rules are evaluated in priority order; the first matching rule decides the fate of the packet. If no rule matches, the default rules kick in: deny all inbound, allow all outbound.

How it works step by step

Let's break down the flow of configuring an NSG to lock down traffic:

  1. Identify the resources you want to protect — typically a subnet or a network interface (NIC) attached to a VM.
  2. Create an NSG — you can do this via the Azure portal, CLI, PowerShell, or Infrastructure as Code (Bicep/ARM).
  3. Define allow rules — start with the specific ports and sources that must be open (e.g., HTTPS from your office IP).
  4. Define deny rules — add deny rules for any traffic you explicitly want to block, even if a broader allow rule exists. This catches edge cases.
  5. Associate the NSG — attach it to a subnet or NIC. Subnet-level NSGs affect all resources in that subnet; NIC-level NSGs affect only that VM.
  6. Test and validate — use tools like nc (netcat), telnet, or Azure Network Watcher to verify your rules work as intended.
  7. Monitor and adjust — Azure Monitor logs can show NSG flow logs for auditing and alerting.

Important: Rule evaluation is nondeterministic ordering if you have overlapping rules, but you control it with the priority number. Always leave gaps in priority to avoid conflicts.

Hands-on walkthrough

Let's put this into practice. We'll create an NSG that allows web traffic (port 443) only from a trusted IP range, and denies everything else. We'll use the Azure CLI for speed.

Prerequisites

  • Azure subscription with az CLI installed and logged in (az login)
  • An existing resource group (or create one)
  • An existing virtual network with a subnet (or create one)

Example 1: Create an NSG and rules

First, let's set up the NSG with two allow rules: one for HTTPS from a trusted IP, one for SSH from your admin IP. Then we'll add a deny-all rule at a high priority to block everything else.

# Set variables
export RESOURCE_GROUP="myResourceGroup"
export LOCATION="eastus"
export NSG_NAME="web-nsg"

# Create NSG
az network nsg create --name $NSG_NAME --resource-group $RESOURCE_GROUP --location $LOCATION

# Allow inbound HTTPS (443) from trusted IP range (e.g., 203.0.113.0/24)
az network nsg rule create \
    --resource-group $RESOURCE_GROUP \
    --nsg-name $NSG_NAME \
    --name "Allow-HTTPS-Trusted" \
    --priority 100 \
    --direction Inbound \
    --access Allow \
    --protocol Tcp \
    --source-address-prefixes 203.0.113.0/24 \
    --source-port-ranges '*' \
    --destination-address-prefixes '*' \
    --destination-port-ranges 443

# Allow SSH from admin IP (e.g., 198.51.100.0/24)
az network nsg rule create \
    --resource-group $RESOURCE_GROUP \
    --nsg-name $NSG_NAME \
    --name "Allow-SSH-Admin" \
    --priority 110 \
    --direction Inbound \
    --access Allow \
    --protocol Tcp \
    --source-address-prefixes 198.51.100.0/24 \
    --source-port-ranges '*' \
    --destination-address-prefixes '*' \
    --destination-port-ranges 22

# Deny all other inbound traffic (priority 4000)
az network nsg rule create \
    --resource-group $RESOURCE_GROUP \
    --nsg-name $NSG_NAME \
    --name "Deny-All-Inbound" \
    --priority 4000 \
    --direction Inbound \
    --access Deny \
    --protocol '*' \
    --source-address-prefixes '*' \
    --source-port-ranges '*' \
    --destination-address-prefixes '*' \
    --destination-port-ranges '*'

echo "NSG rules created:"
az network nsg rule list --resource-group $RESOURCE_GROUP --nsg-name $NSG_NAME --output table

Expected output (simplified):

Name                   Priority  Direction  Access  Protocol  SourceAddressPrefixes  DestPortRanges
Allow-HTTPS-Trusted    100       Inbound    Allow   Tcp       203.0.113.0/24          443
Allow-SSH-Admin        110       Inbound    Allow   Tcp       198.51.100.0/24         22
Deny-All-Inbound       4000      Inbound    Deny    *         *                      *

Example 2: Associate NSG to a subnet

Now attach the NSG to a subnet to enforce these rules on all VMs in that subnet.

az network vnet subnet update \
    --resource-group $RESOURCE_GROUP \
    --vnet-name "myVNet" \
    --name "mySubnet" \
    --network-security-group $NSG_NAME

echo "NSG attached to subnet."

Example 3: Test with netcat (client-side)

From a trusted IP, test that port 443 is reachable; from an untrusted IP, it should time out.

# From trusted IP (203.0.113.10)
nc -zv 40.65.10.20 443
# Expected: Connection to 40.65.10.20 port 443 succeeded!

# From untrusted IP (e.g., any other public IP)
nc -zv 40.65.10.20 443
# Expected: connect to host 40.65.10.20 port 443: Connection timed out

Pro tip: Use Azure Network Watcher's next hop and IP flow verify to debug connectivity without running netcat from remote machines.

Compare options / when to choose what

NSGs are one piece of the network security puzzle. Let's compare them with other options:

Option Layer Scope Use case When to choose
NSG L4 (network) Subnet or NIC Filter traffic based on IP, port, protocol Most common for VM/subnet-level control
Azure Firewall L7 (app) Entire VNet/region Centralized policy, FQDN filtering, threat intel Enterprise requirements, hub-spoke topology
Application Security Group (ASG) L4 abstraction Group of NICs Apply same rules to a logical app tier Simplify rule management for microservices
Network Virtual Appliance (NVA) L7+ Route traffic through firewall/IDS Deep packet inspection, advanced logging Compliance or custom security stack
Service Tags L4 NSG rules Allow Azure services (e.g., Storage, Key Vault) Reduce rule count, keep IPs updated

How to choose: - If you only need IP/port filtering, NSG is sufficient and cost-effective. - If you need URL filtering, threat intelligence, or central logging, use Azure Firewall. - If you have many VMs in a service tier, use ASGs to group them. - Use service tags to avoid managing Azure IP ranges manually.

Variations: - Use Bicep or ARM templates to define NSGs as code — essential for CI/CD. - Use Azure Policy to enforce NSG presence on all subnets — governance without manual oversight. - Use flow logs with Traffic Analytics to get visual insights into blocked/allowed traffic patterns.

Troubleshooting & edge cases

Even with careful rules, things can go wrong. Here are common issues and fixes:

  • No connectivity despite allow rule: Check that the NSG is associated to the correct subnet or NIC. Also, ensure the rule priority isn't being overridden by a higher-priority deny rule.
  • Outbound traffic blocked unintentionally: By default, outbound is allowed, but if you add a deny-all outbound rule, you must explicitly allow required outbound ports (e.g., DNS on 53, HTTPS to Azure storage).
  • Unexpected 403/404 from a service: NSG filtering happens before application code, so if traffic is allowed at NSG but the app returns an error, the issue is elsewhere — but always verify with IP flow verify.
  • Rule count limits: Azure has a limit of 1000 rules per NSG (with many per subscription). If you hit the limit, consider using ASGs or consolidating rules.
  • Port exhaustion: Too many rules can cause latency. Rearrange rules to put most-used allows at lower priorities.

Edge cases: - When you use service tags like Internet, the tag expands to all public IPs, which might be too broad. Be specific where possible. - NIC-level vs subnet-level: If both are attached, the more restrictive rule takes precedence. A subnet immersive NSG applies first, then NIC. Always validate which one applies. - Testing from localhost: When you test from inside the same VM, it might bypass NSG rules. Use a separate client to verify.

What you learned & what's next

You now understand that NSGs are the first line of defense for locking down traffic in Azure. You learned: - How to create and associate NSGs to subnets or NICs. - How to define allow and deny rules with priorities. - How to choose between NSGs, Azure Firewall, and ASGs. - How to troubleshoot common connectivity issues.

You're now equipped to secure any VM or subnet you deploy. In the next lesson, we'll dive into Azure Application Gateway and WAF, where you'll learn how to protect your web application at layer 7 with a web application firewall, providing even deeper security beyond network-level controls.

Pro tip: Always combine NSGs with Azure Security Center (now Defender for Cloud) to get automated recommendations and alerts on open ports or misconfigurations.

Now go ahead and lock down your test environment with the exercise below, and you'll be ready for the next step in your Azure journey.

Practice recap

Create a new VM and its own NSG that allows HTTP (80) only from your current IP, and set up a subnet-level NSG on the same VNet that denies all other inbound traffic. Test from a public IP to confirm the block, then review the NSG flow logs to see the denied packets. This hands-on practice solidifies the priority and association concepts you just learned.

Common mistakes

  • Forgetting to associate the NSG to a subnet or NIC — creating rules but never attaching the NSG to the resource means no enforcement.
  • Using overly broad source IP ranges like * for allow rules — this defeats the purpose of lockdown; always restrict to known CIDRs or service tags.
  • Relying only on default rules without explicitly defining deny rules — default rules deny all inbound, but you might accidentally allow outbound ports you don't need.
  • Misordering priority numbers — a high-priority allow rule can override a lower-priority deny rule, so always double-check priority values.

Variations

  1. Use Application Security Groups (ASGs) to group VMs by role and apply NSG rules to logical application tiers instead of individual IPs.
  2. Leverage Azure Firewall for centralized layer-7 filtering, URL-based access, and FQDN tags when you need beyond-IP/port control.
  3. Automate NSG deployment with Bicep/ARM templates or Azure Policy to ensure consistent security posture across all environments.

Real-world use cases

  • Restricting SSH/RDP access to a production VM to only your office IP range to prevent brute-force attacks.
  • Isolating a database subnet so only app server IPs can communicate over port 1433, blocking all other inbound traffic.
  • Enabling NSG flow logs to audit and detect unauthorized port scanning from external IPs in a compliance-driven environment.

Key takeaways

  • NSGs act as a virtual firewall at the network level, filtering traffic by IP, port, and protocol with priority-based rules.
  • The default NSG rules deny all inbound and allow all outbound traffic; explicit deny rules are not always required but are good practice.
  • Attach NSGs to either subnets or NICs — subnet-level applies to all resources, NIC-level to a single VM, and both can coexist.
  • Use service tags to avoid managing Azure IP ranges manually, and prefer ASGs for rule organization in microservices architectures.
  • Always test connectivity with tools like netcat or Azure Network Watcher, and use flow logs to monitor traffic patterns.
  • Combine NSGs with Azure Firewall and Defender for Cloud for defense-in-depth across your Azure environment.

Sponsored

Sponsored

Discussion

Questions, corrections, and tips help everyone reading this page.

0 comments

Add a comment

Shown publicly with your comment.

Be constructive · max 4,000 characters

No comments yet — start the thread.

Related tutorials, quizzes, and articles for this topic.