Network Segmentation Testing with nmap

Segmentation testing is the exercise of proving — from a defined source network — that traffic into a protected network is restricted as intended. Most commonly this is driven by PCI DSS Requirement 11.4.5 (annual segmentation testing for merchants, semi-annual for service providers) and analogous controls in HIPAA, NIST 800-53, and internal zoning standards.

The goal is not to find vulnerabilities. It is to confirm that the firewall/ACL/SDN rules between source and target zones match the documented design — no more, no less. Findings are usually “port X is reachable that shouldn’t be” or “this source IP can reach this CDE host.”

Below is the playbook I lean on with nmap. Run from a representative host inside the source segment.

Phase 1 — Host discovery

You first need to know what’s actually up in the target range without committing to a full port scan. -sn (“no port scan”) performs only discovery probes.

SwitchExampleWhat it does
-snnmap -sn 10.1.0.0/24Disable port scanning. Host discovery only (ICMP echo, TCP SYN/ACK to 443/80, ARP on local).
-PSnmap -PS22,80,443 10.1.0.0/24TCP SYN ping to listed ports — useful when ICMP is blocked.
-PAnmap -PA22,80,443 10.1.0.0/24TCP ACK ping — sometimes traverses stateless filters that drop SYN.
-PUnmap -PU53,161 10.1.0.0/24UDP ping — useful where TCP probes are filtered.
-Pnnmap -Pn ...Skip discovery, treat all hosts as up. Use as a fallback only — it slows things down and produces noise.

When you run as root, nmap will also use ARP for any targets on the local link, which is the most reliable signal you have.

sudo nmap -sn -PE -PS22,80,443 -PA22,80,443 -PU53,161 -iL targets.txt -oA discovery

-oA <basename> writes normal, grepable, and XML output in one shot — keep all three for reporting.

Phase 2 — Port coverage

Once you have the live set, you need full port coverage. Do not rely on default top-1000 for a segmentation test; partial coverage will not pass a QSA review.

TCP, all 65535 ports, with version detection and reason text (which packet flag drove each verdict — important evidence):

sudo nmap -sS -p- -sV --reason -iL alive.txt -oA tcp_full

If TCP SYN is being blocked outright by the source’s egress (e.g. an outbound proxy that only forwards established sessions), fall back to a TCP connect scan:

nmap -sT -p- -sV --reason -iL alive.txt -oA tcp_connect

UDP is slow and unreliable but required for a complete test. Cover the common service ports at minimum, and use --version-intensity 0 to keep runtime sane:

sudo nmap -sU --top-ports 200 -sV --version-intensity 0 --reason -iL alive.txt -oA udp_top200

Phase 3 — Evidence

What a reviewer (internal or external) will ask for:

  1. The source IP(s) the scan was run from, with date/time.
  2. The target scope (targets.txt) and the alive list.
  3. The raw nmap output for each scan (-oA artifacts).
  4. A diff between observed open ports and the documented allow-list. Anything reachable that isn’t on the allow-list is a finding.

For diffing, the grepable output (.gnmap) plus a one-liner like:

grep "/open/" tcp_full.gnmap | awk '{print $2}' | sort -u

…gives you a clean “hosts with any open port” list to compare against expectations.

Notes on timing and safety

  • -T4 is usually fine on modern networks and a lot faster than the default -T3. Avoid -T5 against production unless you’ve cleared it — it will trip IDS and can knock over fragile devices.
  • Coordinate with the SOC. A segmentation test that triggers an unannounced incident response is a bad day.
  • If the target zone contains IDS/IPS or rate-limiting, your results may be incomplete by design. Document the controls observed; they’re part of the report, not a problem with your methodology.