Nmap: The Complete Linux Network Scanner Tutorial

A comprehensive Nmap tutorial for Linux, covering installation, target specification, host discovery, port scanning techniques, service and OS detection, the Nmap Scripting Engine, timing and performance, output formats, and practical examples from the official reference guide.
Nmap (Network Mapper) is an open-source tool for network exploration and security auditing. It was designed to rapidly scan large networks, although it works fine against single hosts. Nmap uses raw IP packets to determine what hosts are available on the network, what services (and versions) those hosts are offering, what operating systems they are running, what type of packet filters/firewalls are in use, and dozens of other characteristics.
While Nmap is commonly used for security audits, systems and network administrators find it useful for routine tasks such as network inventory, managing service upgrade schedules, and monitoring host or service uptime.
This tutorial is based on the official Nmap Reference Guide.
Installing Nmap
Most Linux distributions include Nmap in their package repositories.
# Debian / Ubuntu / Kali
sudo apt update && sudo apt install -y nmap
# RHEL / CentOS / Fedora
sudo dnf install nmap
# Arch Linux
sudo pacman -S nmap
# macOS (Homebrew)
brew install nmap
# Verify the installation
nmap --versionHow to Read Nmap Output
Nmap's output is a list of scanned targets with an interesting ports table that lists the port number, protocol, service name, and state. The state is one of:
| State | Meaning |
|---|---|
open | An application on the target is listening for connections on that port |
filtered | A firewall, filter, or other obstacle is blocking the port, so Nmap can't tell if it's open or closed |
closed | No application is listening, though the port could open at any time |
unfiltered | The port is reachable by Nmap's probes, but Nmap can't determine if it's open or closed |
open|filtered | Nmap can't distinguish between open and filtered |
A typical scan:
# The classic example scan from the reference guide
nmap -A -T4 scanme.nmap.orgNmap scan report for scanme.nmap.org (74.207.244.221)
Host is up (0.029s latency).
Not shown: 995 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 5.3p1 Debian 3ubuntu7
80/tcp open http Apache httpd 2.2.14 ((Ubuntu))
646/tcp filtered ldp
1720/tcp filtered H.323/Q.931
9929/tcp open nping-echo Nping echo
Device type: general purpose
Running: Linux 2.6.X
OS details: Linux 2.6.39Target Specification
Everything on the Nmap command line that isn't an option is treated as a target. You can scan single hosts, ranges, or entire networks.
# Single IP address
nmap 192.168.1.1
# Single hostname
nmap scanme.nmap.org
# CIDR notation - scan a whole subnet (256 hosts)
nmap 192.168.1.0/24
# Octet ranges - scan 192.168.1.1 through 192.168.1.254
# (skips .0 and .255, often network/broadcast addresses)
nmap 192.168.1-254.1
# Multiple non-contiguous octets
nmap 192.168.3-5,7.1
# Multiple targets of different types
nmap scanme.nmap.org 192.168.0.0/8 10.0.0,1,3-7.-
# IPv6 addresses (with zone ID for link-local)
nmap fe80::a8bb:ccff:fedd:eeff%eth0Input from a file
# Read targets from a file (one per line, # comments allowed)
nmap -iL hosts.txt
# Read targets from standard input
cat hosts.txt | nmap -iL -
# Generate random targets (0 = never-ending)
nmap -Pn -sS -p 80 -iR 0 --openExcluding targets
# Exclude specific hosts or networks
nmap 192.168.1.0/24 --exclude 192.168.1.10,192.168.1.50
# Exclude from a file
nmap 192.168.1.0/24 --excludefile exclude.txtDNS control
# Skip reverse DNS (faster scans)
nmap -n 192.168.1.0/24
# Always do reverse DNS on all targets
nmap -R 192.168.1.0/24
# Use specific DNS servers
nmap --dns-servers 8.8.8.8,1.1.1.1 scanme.nmap.orgHost Discovery
Host discovery (sometimes called a ping scan) reduces a huge set of IP ranges into a list of active hosts. By default Nmap sends an ICMP echo request, a TCP SYN to port 443, a TCP ACK to port 80, and an ICMP timestamp request. On local ethernet networks it uses ARP instead, which is faster and more effective.
# List scan - just list targets, no packets sent
nmap -sL 192.168.1.0/24
# Ping scan - host discovery only, no port scan
nmap -sn 192.168.1.0/24
# Skip host discovery - port scan everything (useful when firewalls block pings)
nmap -Pn 192.168.1.0/24
# TCP SYN ping (probe port 22 and 80)
nmap -PS22,80 192.168.1.0/24
# TCP ACK ping (cuts through stateless firewalls)
nmap -PA80 192.168.1.0/24
# UDP ping
nmap -PU53 192.168.1.0/24
# ICMP ping types: echo request, timestamp, address mask
nmap -PE 192.168.1.0/24
nmap -PP 192.168.1.0/24
nmap -PM 192.168.1.0/24
# Combine probe types to penetrate strict firewalls
nmap -PE -PS443 -PA80 -PP 192.168.1.0/24
# Trace the route to the target
nmap --traceroute scanme.nmap.orgPort Scanning Techniques
Port scan type options all follow the -s* form. Only one TCP scan method can be used at a time, though UDP scan (-sU) can be combined with a TCP scan. Most scan types require root privileges because they send raw packets. Unprivileged users can only run the connect scan (-sT) and FTP bounce scan (-b).
TCP SYN scan -sS (default)
The default and most popular scan. It's fast, relatively stealthy, and works against any compliant TCP stack. Known as half-open scanning because it never completes a TCP connection: send SYN, a SYN/ACK means open, a RST means closed, no response means filtered.
sudo nmap -sS 192.168.1.1TCP connect scan -sT
The fallback for unprivileged users. Nmap asks the OS to complete a full TCP connection via the connect system call. Slower and more likely to be logged by the target.
nmap -sT 192.168.1.1UDP scan -sU
UDP services (DNS 53, SNMP 161, DHCP 67/68) are often overlooked by auditors but are frequently exploitable. UDP scanning is slow because open and filtered ports rarely respond. An ICMP port unreachable (type 3, code 3) means closed; a UDP response means open; no response means open|filtered.
sudo nmap -sU 192.168.1.1
# Combine UDP and TCP scans in one run
sudo nmap -sS -sU 192.168.1.1NULL, FIN, and Xmas scans -sN, -sF, -sX
These exploit a loophole in RFC 793: packets without SYN, RST, or ACK bits should get a RST back from closed ports and no response from open ports. They can sneak through some non-stateful firewalls. Big downside: Microsoft Windows, many Cisco devices, and BSDI don't follow the RFC and will mark everything closed.
sudo nmap -sN 192.168.1.1 # no flags set
sudo nmap -sF 192.168.1.1 # FIN flag only
sudo nmap -sX 192.168.1.1 # FIN, PSH, URG set (lit up like a Christmas tree)ACK scan -sA
Never determines open ports — it's used to map firewall rulesets. Open and closed ports both return a RST, labeled unfiltered; ports that don't respond are filtered.
sudo nmap -sA 192.168.1.1Window scan -sW
Like ACK scan, but examines the TCP Window field of returned RST packets. On some systems, open ports return a positive window size while closed ones return zero. Works on a minority of systems, so results aren't always trustworthy.
sudo nmap -sW 192.168.1.1Custom scans with --scanflags
Design your own scan by combining flags.
# Set specific flags (URG, ACK, PSH, RST, SYN, FIN)
sudo nmap --scanflags URGACKPSH 192.168.1.1Idle scan -sI
A truly blind port scan using a "zombie" host's predictable IP ID sequence. No packets to the target come from your real IP — the scan appears to come from the zombie.
sudo nmap -sI zombie.example.com:80 target.example.comIP protocol scan -sO
Determines which IP protocols (TCP, ICMP, IGMP, etc.) a host supports.
sudo nmap -sO 192.168.1.1FTP bounce scan -b
Abuses a vulnerable FTP server's proxy feature to scan other hosts through it — a classic way to bypass firewalls.
sudo nmap -b user:pass@ftp.example.com target.example.comPort Specification and Scan Order
By default Nmap scans the most common 1,000 ports for each protocol.
# Scan specific ports
nmap -p 80,443 192.168.1.1
# Scan a range
nmap -p 1-1024 192.168.1.1
# Scan all 65,535 ports
nmap -p- 192.168.1.1
# Mix protocols with qualifiers (T: TCP, U: UDP, S: SCTP, P: IP)
nmap -p U:53,111,137,T:21-25,80,139,8080 192.168.1.1
# Scan by service name (wildcards allowed)
nmap -p ftp,http* 192.168.1.1
# Fast scan - only the top 100 ports
nmap -F 192.168.1.1
# Scan the top N ports by frequency
nmap --top-ports 200 192.168.1.1
# Don't randomize port scan order
nmap -r 192.168.1.1
# Exclude certain ports from scanning
nmap --exclude-ports 80,443 192.168.1.1Service and Version Detection
A port number tells you what service is probably running, but people run services on strange ports. Version detection interrogates open ports to determine the service protocol (FTP, SSH, HTTP...), application name, version number, and sometimes OS family and device type.
# Enable version detection
nmap -sV 192.168.1.1
# -sR is an alias for -sV (RPC services get fingerprinted automatically)
nmap -sR 192.168.1.1
# Light mode - faster but less likely to identify services
nmap -sV --version-light 192.168.1.1
# Maximum intensity - try every probe
nmap -sV --version-all 192.168.1.1
# Set intensity manually (0-9, default 7)
nmap -sV --version-intensity 5 192.168.1.1
# Don't skip port 9100 (printers print anything sent there)
nmap -sV --allports 192.168.1.1OS Detection
Nmap fingerprints the remote OS by sending a series of TCP and UDP packets and examining details like TCP ISN sampling, TCP options, and initial window size. It compares the results against a database of over 2,600 fingerprints. It also estimates uptime and TCP sequence predictability.
# Enable OS detection
sudo nmap -O 192.168.1.1
# Only try OS detection when at least one open and one closed port were found
sudo nmap -O --osscan-limit 192.168.1.1
# Guess more aggressively when there's no perfect match
sudo nmap -O --osscan-guess 192.168.1.1
# Limit retries for faster scans
sudo nmap -O --max-os-tries 1 192.168.1.1The Nmap Scripting Engine (NSE)
NSE is one of Nmap's most powerful features. It lets you run (and write) scripts in Lua to automate network discovery, advanced version detection, vulnerability detection, and even exploitation. Scripts are grouped into categories: auth, broadcast, default, discovery, dos, exploit, external, fuzzer, intrusive, malware, safe, version, and vuln.
Warning: scripts are not run in a sandbox and can damage systems or invade privacy. Never run third-party scripts you don't trust.
# Default script scan (equivalent to --script=default)
nmap -sC 192.168.1.1
# Run a specific script
nmap --script=http-title 192.168.1.1
# Run scripts matching a wildcard
nmap --script "http-*" 192.168.1.1
# Run scripts from a category
nmap --script=vuln 192.168.1.1
# Boolean expressions (quote to protect from the shell)
nmap --script "not intrusive" 192.168.1.1
nmap --script "default or safe" 192.168.1.1
nmap --script "(default or safe or intrusive) and not http-*" 192.168.1.1
# Pass arguments to scripts
nmap --script=http-title --script-args http.useragent="MyAgent" 192.168.1.1
# Get help about scripts before running them
nmap --script-help default
nmap --script-help ftp-anon
# Update the script database after adding/removing scripts
nmap --script-updatedbA few practical NSE examples:
# Check for FTP anonymous login
nmap --script=ftp-anon -p 21 192.168.1.1
# Check for common web server vulnerabilities
nmap --script=vuln -p 80,443 192.168.1.1
# Enumerate SMB shares and OS info
nmap --script=smb-enum-shares,smb-os-discovery -p 445 192.168.1.1
# Check if SSH allows weak ciphers
nmap --script=ssh2-enum-algos -p 22 192.168.1.1Timing and Performance
Nmap offers six timing templates via -T plus fine-grained controls for precision tuning.
| Template | Value | Use case |
|---|---|---|
-T0 paranoid | 0 | IDS evasion, extremely slow |
-T1 sneaky | 1 | IDS evasion, slow |
-T2 polite | 2 | Less bandwidth, 10x slower than default |
-T3 normal | 3 | Default |
-T4 aggressive | 4 | Fast, reasonably reliable networks |
-T5 insane | 5 | Very fast networks, may sacrifice accuracy |
# Recommended for most modern networks
nmap -T4 192.168.1.0/24
# Slow scan to avoid IDS detection
nmap -T0 scanme.nmap.org
# Give up on a host after a timeout (time suffixes: ms, s, m, h)
nmap --host-timeout 30m 192.168.1.0/24
# Limit retransmissions
nmap --max-retries 3 192.168.1.0/24
# Force a minimum/maximum sending rate (packets per second)
nmap --min-rate 300 192.168.1.0/24
nmap --max-rate 100 192.168.1.0/24
# Wait between probes (beats rate limiting)
nmap --scan-delay 1s 192.168.1.0/24
# Cap script execution time
nmap --script-timeout 10m 192.168.1.0/24
# Ignore RST rate limiting for faster scans of closed ports
nmap --defeat-rst-ratelimit 192.168.1.0/24Firewall/IDS Evasion and Spoofing
Nmap offers many ways to understand (and bypass) network defenses. Use these against your own networks to test your security posture.
# Fragment packets into tiny pieces to evade packet filters
sudo nmap -f 192.168.1.1
sudo nmap -f -f 192.168.1.1 # 16-byte fragments
sudo nmap --mtu 8 192.168.1.1 # custom fragment size (multiple of 8)
# Hide your scan among decoys (ME marks your real position)
sudo nmap -D RND:10,ME 192.168.1.1
sudo nmap -D 1.2.3.4,5.6.7.8,ME 192.168.1.1
# Spoof the source IP (you usually won't receive replies)
sudo nmap -S 1.2.3.4 -Pn -e eth0 192.168.1.1
# Spoof source port (exploits firewalls that trust port 53, 20, etc.)
sudo nmap --source-port 53 192.168.1.1
sudo nmap -g 20 192.168.1.1
# Append random data to packets to look less suspicious
sudo nmap --data-length 25 192.168.1.1
# Spoof your MAC address
sudo nmap --spoof-mac 0 192.168.1.1
sudo nmap --spoof-mac Apple 192.168.1.1
# Send packets with bogus checksums (responses reveal firewalls/IDS)
sudo nmap --badsum 192.168.1.1
# Randomize target host order
nmap --randomize-hosts 192.168.1.0/24Note that version detection and NSE rely on your host's TCP stack and don't support fragmentation or MAC spoofing.
Output Formats
Nmap offers five output formats, and the verbosity/debugging controls to go with them. Output flags take a filename argument with a mandatory space between flag and filename (e.g. -oX scan.xml).
# Normal output - for human review after the scan
nmap -oN scan.nmap 192.168.1.1
# XML output - for parsing by programs
nmap -oX scan.xml 192.168.1.1
# Grepable output - one line per host, easy to grep/awk/cut
nmap -oG scan.gnmap 192.168.1.1
# All three formats at once
nmap -oA scan 192.168.1.1 # creates scan.nmap, scan.xml, scan.gnmap
# Pipe output to stdout instead of a file (-oX -)
nmap -oX - 192.168.1.1
# Increase verbosity (more detail, live progress)
nmap -v scanme.nmap.org
nmap -vv scanme.nmap.org
nmap -v3 scanme.nmap.org
# Debug output
nmap -d scanme.nmap.org
# Show why each port is in its state
nmap --reason 192.168.1.1
# Only show open ports and hosts with open ports
nmap --open 192.168.1.1
# Append to output files instead of overwriting
nmap -oN scan.nmap --append-output 192.168.1.1
# Resume an aborted scan from its output file
nmap --resume scan.nmap
# Print periodic timing stats every 10 seconds
nmap --stats-every 10s 192.168.1.0/24
# Trace every packet sent and received
sudo nmap --packet-trace -p20-30 192.168.1.1Combine outputs with Unix tools for quick filtering:
# All hosts with SSH open
grep "22/open" scan.gnmap | cut -d' ' -f2
# List only hosts with port 80 open
nmap -p 80 --open -oG - 192.168.1.0/24 | grep "/open/"The All-In-One Command
-A enables OS detection, version detection, default script scanning, and traceroute in one shot:
sudo nmap -A -T4 scanme.nmap.orgPractical Examples
From the official reference guide's examples section:
# Verbose scan of a single host
nmap -v scanme.nmap.org
# Stealth SYN scan + OS detection of a whole subnet
sudo nmap -sS -O scanme.nmap.org/24
# Version detection on specific ports across a range of subnets
nmap -sV -p 22,53,110,143,4564 198.116.0-255.1-127
# 100,000 random hosts checked for web servers
nmap -v -iR 100000 -Pn -p 80
# Scan 4096 IPs for web servers, save grepable and XML output
nmap -Pn -p80 -oX logs/pb-port80scan.xml -oG logs/pb-port80scan.gnmap 216.163.128.20/20A Typical Recon Workflow
Here's how the pieces fit together in a real engagement:
# 1. Discover which hosts are alive
nmap -sn 192.168.1.0/24
# 2. Full port scan of the live hosts (fast)
nmap -T4 -p- --open 192.168.1.5
# 3. Version + OS detection on the interesting ports
sudo nmap -sV -O -p 22,80,443 192.168.1.5
# 4. Script scan against the services you found
nmap -sC -p 80,443 192.168.1.5
# 5. Save everything for the report
sudo nmap -A -T4 -oA report 192.168.1.5Legal and Ethical Notes
- Always get permission before scanning networks you don't own. Some administrators don't appreciate unsolicited scans and may complain.
- scanme.nmap.org is a host the Nmap project makes available specifically for testing. Permission only covers Nmap scanning — not exploits or denial-of-service attacks — and please limit yourself to a dozen scans per day.
- The
--script=vuln, brute-force, and exploit scripts can cause real damage. Run them only against systems you own or have written authorization to test.
Summary
Nmap is the Swiss Army knife of network reconnaissance. Master the fundamentals — target specification, host discovery, the -sS/-sT/-sU scan types, -sV version detection, -O OS detection, and -sC/--script for NSE — and you can map out any network you're authorized to test, identify services and their versions, and fingerprint the underlying operating system. Combine that knowledge with the timing (-T4), output (-oA), and evasion options, and you have a complete toolchain for security auditing and network administration alike.
Happy scanning!

Written by Robin te Hofstee
Technology enthusiast with a deep love for programming. Sharing practical guides on React, Next.js, Linux and self-hosting.
Related Posts
Linux File Permissions Explained
A comprehensive guide to Linux file permissions — what they are, how the rwx model works, how to read and change permissions with chmod, chown and umask, plus special permissions like setuid, setgid and sticky bits.
Securing a Next.js Application in Production
Securing a Next.js app in production means protecting the client bundle, the server, and the data flow. This post shows how to lock down Content‑Secur
How Git Works
Git is a distributed version control system that allows multiple people to collaborate on a project while maintaining a complete history of all change


