Where to start First steps track · 15 stages
Linux Labs

nmap: which ports are visible from outside

8 min Ubuntu 24.04 · nmap 7.94

A port scanner: shows which ports of a machine are open, closed or filtered, as another machine sees them.

Cheat sheet

9 commands Printable version
  • 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

Overview

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:

text
student@ubuntu:~$ sudo ip netns exec lab-outside \
> nmap -p 22,80,5432,8080 192.0.2.1
Starting Nmap 7.94SVN ( https://nmap.org ) at 2026-10-21 05:35 UTC
Nmap scan report for 192.0.2.1
Host is up (0.000022s latency).
PORT     STATE  SERVICE
22/tcp   open   ssh
80/tcp   open   http
5432/tcp closed postgresql
8080/tcp open   http-proxy
MAC Address: 22:C9:B6:56:61:18 (Unknown)
Nmap done: 1 IP address (1 host up) scanned in 13.09 seconds

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.

States

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:

text
PORT     STATE    SERVICE         REASON
22/tcp   open     ssh             syn-ack ttl 64
8080/tcp filtered http-proxy      no-response
8081/tcp closed   blackice-icecap reset ttl 64

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:

text
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 9.6p1 Ubuntu 3ubuntu13.20
  (Ubuntu Linux; protocol 2.0)
80/tcp open  http    nginx 1.24.0 (Ubuntu)

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.

How nmap scans

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:

text
student@ubuntu:~$ nmap -sS -p 22 127.0.0.1
You requested a scan type which requires root privileges.
QUITTING!

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:

text
Note: Host seems down. If it is really up, but blocking our ping
  probes, try -Pn
Nmap done: 1 IP address (0 hosts up) scanned in 1.46 seconds

-Pn scans the ports without that check.

Outside and inside

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.

Options

10

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.

Recipes

3

What the machine shows to the outside

bash
sudo ss -tlnp                         # what listens, from inside
sudo ip netns exec lab-outside nmap 192.0.2.1   # what is seen 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.

Output for a script

bash
sudo nmap -oG - -p 22,80,8080 192.0.2.1 | grep Ports
text
Host: 192.0.2.1 ()	Ports: 22/open/tcp//ssh///, 80/open/tcp//http///,
  8080/filtered/tcp//http-proxy///

Each port is number/state/protocol//name///: such a line is easy to take apart with grep and cut.

Check one port

bash
nmap -p 5432 192.0.2.1 | grep 5432
nc -zvw3 192.0.2.1 5432           # the same without nmap

Troubleshooting

4

Host seems down

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 port is closed, but the service is running

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 port is filtered, but there is no rule

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.

You requested a scan type which requires root privileges

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.

Danger zone

1

Scanning other people's machines

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.

See also

  • ss — what listens on the machine itself.
  • firewall — nftables and closing ports.
  • nc — check one port without nmap.
  • network-diagnostics — ping, traceroute and other network checks.
  • ip — addresses and network namespaces.
Loading…