What the machine shows to the outside
A port that listens on 0.0.0.0 and shows as open from outside is part
of the attack surface. To close it, bind the service to 127.0.0.1 or
close it with a filter.
A port scanner: shows which ports of a machine are open, closed or filtered, as another machine sees them.
nmap 192.0.2.1
1000 common TCP ports
nmap -p 22,80,5432,8080 192.0.2.1
only these ports
nmap -p- 192.0.2.1
all 65535 ports
nmap --open 192.0.2.1
open ports only
sudo nmap --reason -p 8080 192.0.2.1
why this state
sudo nmap -sV -p 22,80 192.0.2.1
program and version
sudo nmap -sU -p 53 192.0.2.1
UDP
nmap -Pn -p 22 192.0.2.1
skip the "is it alive" check
nmap -n -p 22 192.0.2.1
no DNS — faster
nmap sends packets to a machine's ports and sorts the ports by the
answers into open, closed and filtered. ss -tlnp on the machine itself
shows what listens; nmap from another machine shows what can be reached
through the firewall. Together they give the
attack surface.
A scan of the lab machine 192.0.2.1 from the lab-outside network
namespace — a "stranger's machine" on the same VM:
Without -p it checks the 1000 most common ports and folds the rest into
Not shown: 997 closed tcp ports (reset).
nmap spent 13 seconds of this scan waiting for DNS: in the lab-outside
namespace /etc/resolv.conf points to 127.0.0.53, and that address does
not exist there. With -n (no name lookups) the same scan takes 0.09
seconds.
| State | Answer to the probe | Meaning |
|---|---|---|
open |
SYN-ACK | a service listens, and packets reach it |
closed |
RST | the machine answered, but nothing listens on the port — or a reject with tcp reset rule |
filtered |
no answer | the packet was dropped on the way: a firewall, a drop policy |
--reason tells which answer decided the state. Here port 8080 is closed
by the rule tcp dport 8080 drop, 8081 by reject with tcp reset:
The SERVICE column is just the port's name from nmap's list: there is no
blackice-icecap on 8081. -sV shows which program really answers:
UDP often gives no answer at all, and nmap reports such a port as
open|filtered; it is closed when an ICMP "port unreachable" arrives.
| Who runs it | Method | Summary line |
|---|---|---|
| root | SYN scan -sS: sends SYN, does not complete the connection |
closed tcp ports (reset) |
| an ordinary user | -sT: a full connection through connect() |
closed tcp ports (conn-refused) |
Raw packets require root. student without sudo gets:
Before the scan nmap checks whether the host is alive: in its own subnet by
ARP (Host is up, received arp-response), further away by ping and probes
to 80 and 443. A host that stays silent is skipped:
-Pn scans the ports without that check.
Scanning a machine from itself goes through the lo interface, and a
firewall usually lets lo through entirely. A port closed by a drop
policy looks open from inside. Test the firewall from another machine or
a separate network namespace — more in firewall.
The main options are in the table below; the full list is in nmap
--help and man nmap. Options combine: `sudo nmap -sV --reason -p 22,80
| Option | What it does | Example |
|---|---|---|
-p PORTS |
Which ports to scan — a list, a range, or -p- for all 65535. | nmap -p 22,80,8000-8100 192.0.2.1 |
--open |
Show open ports only. | nmap --open 192.0.2.1 |
--reason |
Print which answer decided the port state (syn-ack, reset, no-response). | sudo nmap --reason -p 8080 192.0.2.1 |
-sV |
Detect the program and version on open ports. | sudo nmap -sV -p 22,80 192.0.2.1 |
-sS |
A SYN scan without a full connection; needs root, the default for root. | sudo nmap -sS 192.0.2.1 |
-sT |
A scan with full connect() connections; the default for an ordinary user. | nmap -sT -p 22 192.0.2.1 |
-sU |
A UDP port scan; needs root. | sudo nmap -sU -p 53,123 192.0.2.1 |
-Pn |
Skip the host discovery and scan the ports straight away. | nmap -Pn -p 22 192.0.2.1 |
-n |
Do not resolve addresses to names through DNS. | nmap -n 192.0.2.0/24 |
-oG FILE |
One line per host for grep; - prints to the screen. | sudo nmap -oG - -p 22,80 192.0.2.1 |
Nothing found. Try a shorter query.
A port that listens on 0.0.0.0 and shows as open from outside is part
of the attack surface. To close it, bind the service to 127.0.0.1 or
close it with a filter.
Each port is number/state/protocol//name///: such a line is easy to
take apart with grep and cut.
The host did not answer the discovery probes: it is off, the address is
wrong, or a firewall drops ping. Check the address (ip -br a on that
machine) and repeat with -Pn.
The service listens on another address. 127.0.0.1:5432 in ss -tlnp
is not visible from outside: nmap gets an RST and reports closed. The
service needs the interface address or 0.0.0.0 in its settings.
The packets are dropped by the chain policy (policy drop) or by a rule
in another table — sudo nft list ruleset shows every table, including
fail2ban's and Docker's.
A SYN scan, UDP (-sU) and OS detection send raw packets. Run it with
sudo or keep the plain scan — without root nmap picks -sT by itself.
A port scan of someone else's server without the owner's permission looks like preparation for an attack: IDS catch it, the address gets banned, and hosting contracts sometimes forbid it. Scan your own machines.
Found an inaccuracy? Report an error in the article