Skip to main content
emnode
Compliance High severity MCSB NS-1

Microsoft Defender for Cloud · Azure Virtual Machines

All network ports should be restricted on network security groups associated to your virtual machine

Written and reviewed by Emnode · Last reviewed

What does the recommendation "All network ports should be restricted on network security groups associated to your virtual machine" check?

Flags a virtual machine whose attached network security group has an inbound 'Allow' rule that opens a port to 'Any' or the 'Internet' source instead of a specific address range. Defender for Cloud raises it per VM, evaluating the NSGs bound to the VM's network interfaces and the subnets those interfaces sit in. It is a static configuration check, not a behaviour analysis: it reads the rule text and flags any inbound Allow rule whose source is 'Any' or 'Internet', without weighing observed traffic, threat intelligence or learned trusted ranges. It does not check outbound rules, it does not validate host-level firewalls inside the guest OS, and it will not catch a port left open on an NSG that is defined but not associated to any VM.

Why does "All network ports should be restricted on network security groups associated to your virtual machine" matter?

An NSG rule sourced from Any or Internet means every IP on the planet can reach that port, so a forgotten RDP (3389), SSH (22) or database port becomes a standing invitation. Internet-wide scanners find newly exposed management ports within minutes, and credential-stuffing or unpatched-service exploits follow automatically. The business consequence is a VM compromised as a beachhead: from there an attacker pivots into the virtual network, harvests data and deploys ransomware. Narrowing the source range to known networks removes the open surface that makes these VMs a target in the first place.

How do I fix "All network ports should be restricted on network security groups associated to your virtual machine"?

  1. In the Azure portal, open the network security group, edit the offending inbound rule, and change its 'Source' from 'Any' or 'Service Tag: Internet' to a specific IP range or application security group, or via CLI: az network nsg rule update --resource-group <rg> --nsg-name <nsg> --name <rule> --source-address-prefixes <trusted-cidr>.
  2. For management ports such as 22 and 3389, prefer just-in-time VM access in Defender for Cloud (or Azure Bastion) so the port stays closed and is opened only on request for a short window from a named source.
  3. Audit the estate at scale by assigning the built-in policy 'All network ports should be restricted on network security groups associated to your virtual machine', looking the definition up by name rather than hardcoding its ID: pid=$(az policy definition list --query "[?displayName=='All network ports should be restricted on network security groups associated to your virtual machine'].name" -o tsv); az policy assignment create --name restrict-nsg-ports --policy "$pid" --scope <scope>.

Remediation script · bash

# 1. Close the highest-impact exposure first: delete any rule that
#    allows a management port from the whole internet.
for rule in $(az network nsg rule list -g prod-rg --nsg-name prod-nsg \
    --query "[?access=='Allow' && (sourceAddressPrefix=='*' || sourceAddressPrefix=='Internet') && (destinationPortRange=='3389' || destinationPortRange=='22')].name" -o tsv); do
  az network nsg rule delete -g prod-rg --nsg-name prod-nsg -n "$rule"
  echo "$rule: open management-port rule removed"
done

# 2. Add an explicit deny on the management ports as a backstop.
az network nsg rule create -g prod-rg --nsg-name prod-nsg \
  --name deny-mgmt-ports --priority 4000 --access Deny --direction Inbound \
  --protocol Tcp --source-address-prefixes Internet \
  --destination-port-ranges 22 3389

# 3. Gate the ports you still need behind just-in-time access.
#    JIT is configured via PowerShell or the portal; request access with the CLI:
az security jit-policy list -o table   # confirm the JIT policy is in place

# 4. Ratchet it shut: audit any VM left without an NSG (Defender built-in policy).
az policy assignment create \
  --name audit-internet-facing-nsg \
  --policy f6de0be7-9a8a-4b8a-b349-43cf02d22f7c \
  --scope "/subscriptions/00000000-0000-0000-0000-000000000000"

Full walkthrough (console steps, edge cases and verification) in the lesson Restrict virtual machine network exposure.

Is "All network ports should be restricted on network security groups associated to your virtual machine" a false positive?

A reverse proxy or load-balancer VM that must terminate public HTTPS will legitimately have port 443 open to Internet, so this control still flags it even though the exposure is intended. That is the correct exception: keep the rule scoped to 443 only, place the VM in its own subnet, and let the wider management ports stay restricted, rather than suppressing the finding fleet-wide.