TMA-AZURE-NSG-NO-RDP-FROM-INTERNET
Ensure RDP access from the Internet is restricted in network security groups
Description
Inbound RDP (3389) from any/Internet is continuously brute-forced. No Allow inbound rule in any NSG may combine a source of *, 0.0.0.0/0, Internet or ::/0 with a destination port range covering 3389. Read-only Azure CLI calls against the current subscription; credentials come from the CLI's normal sign-in (az login, a service principal or managed identity; select the subscription with az account set). A missing CLI or session fails the check.
How it is checked
Audit method: Shell command
out=$(az network nsg list --query '[].securityRules[?access==`"Allow"` && direction==`"Inbound"`][].[name, sourceAddressPrefix, join(`","`, sourceAddressPrefixes || `[]`), destinationPortRange, join(`","`, destinationPortRanges || `[]`)]' -o tsv 2>/dev/null) || exit 1
printf '%s\n' "$out" | awk -F '\t' -v p=3389 '
function pub(s, n, i, a) { n = split(s, a, ","); for (i = 1; i <= n; i++) if (a[i] == "*" || a[i] == "0.0.0.0/0" || a[i] == "Internet" || a[i] == "Any" || a[i] == "::/0") return 1; return 0 }
function hit(s, n, i, a, b) { n = split(s, a, ","); for (i = 1; i <= n; i++) { if (a[i] == "*") return 1; if (split(a[i], b, "-") == 2) { if (p >= b[1] + 0 && p <= b[2] + 0) return 1 } else if (a[i] + 0 == p) return 1 } return 0 }
NF && (pub($2) || pub($3)) && (hit($4) || hit($5)) { n++; print "open: " $1 }
END { if (!n) print "compliant" }'- Expected output
compliant
How it is fixed
Fix method: Guidance or infrastructure patch
Delete or narrow the listed rules (az network nsg rule update --source-address-prefixes <admin-cidr>, or az network nsg rule delete) and use Azure Bastion or just-in-time VM access for RDP.
Properties
- Operating systems
- Any
- Tags
- azurenetwork
- Reference
- CIS Microsoft Azure Foundations Benchmark v6.0.0 - Networking - RDP access from the Internet evaluated and restricted (verify section number for your release)
Check this host
Run this on a machine you are allowed to audit. The scan is read-only.
tmaegis scan --target azure