Reading the Network: netstat, ss & nmap Explained

Master ss, netstat, and nmap to see every open port, active connection, and service on your system. Real terminal output walkthroughs and pro security tips.

Terminal windows showing ss, netstat, and nmap command outputs with open ports and active connections
📧

Get weekly IT guides

Join 5,000+ IT professionals

Subscribe Free

You just got called in for an emergency. A server is running slow. Something is using your database port. An unknown process is phoning home to a strange IP. Where do you even start?

The answer is always the same: read the network.

In less than 5 minutes, you can see every port your server is listening on, every active connection, and the exact process responsible. If you know three commands — ss, netstat, and nmap — you can diagnose any network problem that comes your way.

Your Three Diagnostic Tools

What You'll Learn
  • Use ss to see every open port and active connection on your system
  • Use netstat when on legacy systems, macOS, or Windows
  • Use nmap to scan remote hosts and discover what services are exposed
  • Read real terminal output and understand every column
  • Know which tool to reach for in which situation
Three cards comparing ss, netstat, and nmap tools — ss is modern local tool, netstat is legacy cross-platform, nmap scans remote hosts
ss and netstat look inward (your local machine). nmap looks outward (what others can see). Learn both perspectives.

Tool 1: ss — The Modern Standard

ss stands for Socket Statistics. It replaced netstat as the standard tool on modern Linux because it queries the kernel directly, making it dramatically faster on busy servers with thousands of sockets.

Mental Model: ss is a Snapshot

ss takes a snapshot of all open network sockets on your machine right now. A “socket” is any active or listening network connection — each one has a protocol, local address, remote address (if connected), and a process using it.

The Most Important ss Command

ss -tulpn

Show all TCP + UDP ports your system is currently listening on, with the process name

beginner
  • -t = TCP sockets only | -u = UDP sockets | combine: -tu = both
  • -l = listening sockets only (servers waiting for connections)
  • -p = show the process name and PID using each socket
  • -n = show port numbers instead of service names (e.g., 22 not 'ssh')
  • 'ss' with no flags shows all active connections — often overwhelming on servers

Example output explained:

Netid  State    Recv-Q  Send-Q  Local Address:Port   Peer Address:Port  Process
tcp    LISTEN   0       128     0.0.0.0:22            0.0.0.0:*         sshd
tcp    LISTEN   0       511     0.0.0.0:80            0.0.0.0:*         nginx
tcp    LISTEN   0       511     0.0.0.0:443           0.0.0.0:*         nginx
tcp    LISTEN   0       70      127.0.0.1:3306        0.0.0.0:*         mysqld
udp    UNCONN   0       0       0.0.0.0:53            0.0.0.0:*         systemd-resolved

Reading each column:

ColumnWhat It Means
NetidProtocol: tcp, udp, unix (local socket)
StateLISTEN = waiting for connections. ESTAB = active connection. UNCONN = UDP (connectionless).
Local Address:Port0.0.0.0 = all interfaces. 127.0.0.1 = localhost only (not reachable from internet).
Peer Address0.0.0.0:* = listening (no peer yet). An IP here = active connection to that remote host.
ProcessThe process name using this socket. Requires sudo to see all processes.
127.0.0.1 vs 0.0.0.0 — This Matters for Security
  • 0.0.0.0:3306 = MySQL is reachable from the internet. Critical misconfiguration.
  • 127.0.0.1:3306 = MySQL only accepts connections from localhost. Correct and secure.

This is the single most important thing to check in ss output. Database ports should always show 127.0.0.1, never 0.0.0.0.


Seeing Active Connections

ss -tn

Show all active TCP connections — who your server is talking to right now

beginner
  • ESTABLISHED = active, bidirectional conversation in progress
  • TIME_WAIT = connection just closed, OS holding port temporarily (normal)
  • SYN_SENT = you tried to connect, waiting for server to respond (may mean firewall blocked)
  • The 'Peer Address:Port' column shows the remote IP — look up on ipinfo.io to identify it

Example output:

State       Recv-Q  Send-Q  Local Address:Port   Peer Address:Port
ESTABLISHED 0       0       10.0.0.5:54823       142.250.80.46:443
ESTABLISHED 0       0       10.0.0.5:57012       151.101.1.140:443
TIME_WAIT   0       0       10.0.0.5:60100       93.184.216.34:80

This shows your server has two active HTTPS connections (port 443) and one recently-closed HTTP connection (port 80 in TIME_WAIT).


Find Which Process Owns a Specific Port

sudo ss -tlpn sport = :80

Show only the process listening on port 80

beginner
  • Replace 80 with any port number you're investigating
  • 'sport' = source port (the local port). 'dport' = destination port
  • Useful when you get 'address already in use' errors starting a service
  • The process name appears in the last column — then use 'kill PID' or 'systemctl stop service'

ss Quick Reference

CommandWhat It Shows
ss -tulpnAll listening ports + process names (use this first)
ss -tnAll active TCP connections
ss -sSummary statistics (total sockets, TCP states)
ss -tnp state establishedOnly ESTABLISHED connections with process names
sudo ss -tlpn sport = :PORTWhich process owns a specific port

Tool 2: netstat — The Classic That’s Still Everywhere

netstat is deprecated on modern Linux (replaced by ss), but you’ll encounter it in three scenarios:

  1. macOS (netstat is current and fully supported)
  2. Windows (built in, still used daily by sysadmins)
  3. Old Linux servers (RHEL 7, CentOS 7, Debian 9) where ss may not pre-installed with identical flags

The output format differs slightly from ss, but the core flags work the same way.

netstat on macOS vs Linux

macOS netstat doesn’t support -p (process names) without sudo lsof. On macOS, use: netstat -an | grep LISTEN for listening ports, then lsof -i :PORT to identify the process.

netstat -tulpn

Show all listening TCP + UDP ports with process names (Linux only)

beginner
  • Same flags as ss: -t (TCP), -u (UDP), -l (listening), -p (process), -n (numbers)
  • On macOS: use 'netstat -an | grep LISTEN' instead
  • On Windows: use 'netstat -ano' (no process names, but shows PID — match in Task Manager)
  • If 'netstat' is not found on Linux: 'sudo apt install net-tools' or use ss instead

Windows users — your version:

netstat -ano

Show all connections with process IDs on Windows (no -u, no -p for process names)

beginner
  • -a = all connections, -n = numbers not names, -o = show PID
  • Open Task Manager → Details tab to match PID to a process name
  • Or: 'Get-Process -Id PID' in PowerShell to find process by PID

Routing Table (Bonus netstat Feature)

netstat -rn

Show the kernel routing table — how your machine decides where to send each packet

beginner
  • The 'Gateway' column shows your default gateway (router IP)
  • '0.0.0.0' in destination = default route (where all non-local traffic goes)
  • If the gateway is wrong, you won't reach the internet — this is a quick diagnostic check
  • Equivalent with 'ip route show' on modern Linux

ss doesn’t show routing tables — this is where netstat -rn still has a role.


Tool 3: nmap — See What the World Sees

ss and netstat answer: “What is my machine doing?”

nmap answers: “What can someone on the outside see and access?”

This is the critical difference. A firewall can block a port even if your app is listening on it — ss sees the listening service, but nmap from outside shows you whether the firewall is actually doing its job.

⚠️ Only Scan Hosts You Own or Have Permission to Scan

Running nmap against hosts without permission is illegal in many jurisdictions and violates most Terms of Service. Always scan only your own servers, your own network, or systems you have explicit permission to test.

Scan Your Own Server

nmap -sV localhost

Scan your own machine and discover what services (and versions) are visible

beginner
  • -sV = service version detection (find what software is running on each port)
  • This shows you what an attacker would see from inside the same machine
  • Compare to 'ss -tulpn' — differences may indicate firewall rules in effect
  • Replace 'localhost' with your server's public IP to simulate an external attack

Example output:

Starting Nmap 7.93 ( https://nmap.org )
Nmap scan report for localhost (127.0.0.1)
Host is up (0.000076s latency).

PORT     STATE  SERVICE  VERSION
22/tcp   open   ssh      OpenSSH 9.3p2 Ubuntu 9.3p2-1ubuntu3.4
80/tcp   open   http     nginx 1.25.3
443/tcp  open   https    nginx 1.25.3
3306/tcp open   mysql    MySQL 8.0.35

Nmap done: 1 IP address (1 host up) scanned in 1.24 seconds

Reading this output:

  • STATE: open = the port is reachable and responding
  • STATE: closed = the port is reachable but no service is listening
  • STATE: filtered = a firewall is blocking the port (nmap can’t tell if it’s open or closed)
  • VERSION = the exact software version — attackers use this to find known CVEs

Scan a Range of Ports

nmap -p 1-1023 your-server-ip

Scan all well-known ports (0-1023) on a target — the most security-relevant range

beginner
  • -p 22,80,443 = scan specific ports only
  • -p- = scan ALL 65,535 ports (slow, but thorough)
  • Default nmap scan covers the top 1000 most common ports
  • Add -v for verbose output to see progress during a slow scan

Quick Host Discovery

nmap -sn 192.168.1.0/24

Ping scan — discover which hosts are alive in your local network (no port scanning)

beginner
  • -sn = no port scan, just ping to find live hosts
  • Replace 192.168.1.0/24 with your actual subnet (find it with 'ip addr')
  • Useful for mapping your home lab or office network
  • Much faster than a full port scan — good first step to inventory your network

When to Use Which Tool

SituationBest ToolCommand
What ports is MY server listening on?ssss -tulpn
Who is connected to my server right now?ssss -tn state established
Port conflict — what app is using port X?sssudo ss -tlpn sport = :X
Need to check routing tablenetstatnetstat -rn
On macOS or old Linuxnetstatnetstat -an | grep LISTEN
On Windowsnetstatnetstat -ano
What does the FIREWALL show externally?nmapnmap -sV your-ip
Security audit of your networknmapnmap -sV -p- your-ip
Discover devices in local networknmapnmap -sn 192.168.1.0/24
🔑 The Golden Workflow for Any Port Problem
  1. ss -tulpn → See what’s listening and who owns it
  2. ss -tn → See what’s actively connected
  3. nmap -sV your-ip → See what the firewall actually exposes
  4. Compare: if ss shows port 3306 listening but nmap doesn’t see it = firewall is working correctly

Real-World Scenario Walkthrough

Scenario: Your web app stopped working. Users get a connection refused error on port 443.

Step 1: Check if your web server is actually listening:

$ ss -tulpn | grep 443
# If empty → nginx/apache crashed. Restart it.
# If shows LISTEN → service is up. Problem is elsewhere.

Step 2: Test from outside your server with nmap:

$ nmap -p 443 your-server-ip
# PORT    STATE    SERVICE
# 443/tcp filtered https   ← Firewall is blocking port 443
# 443/tcp closed   https   ← Service not listening
# 443/tcp open     https   ← Port is reachable (problem is app-level)

Step 3: Check active connections to confirm if any traffic is flowing:

$ ss -tn | grep :443
# ESTABLISHED connections here = users ARE connecting
# Empty = no one can reach port 443

This workflow isolates whether the problem is: service crashed → firewall blocking → app error → or something else entirely.


Key Takeaways

  1. ss -tulpn is your first command every time you investigate a network issue. Run it, understand the output.
  2. 0.0.0.0:PORT vs 127.0.0.1:PORT is the security check — databases should bind to localhost only.
  3. netstat is alive on macOS and Windows but replaced by ss on modern Linux. Know both.
  4. nmap gives the external view — what someone from the internet actually sees, including firewall effects.
  5. STATE: filtered in nmap = firewall working. STATE: open = port reachable. STATE: closed = nothing listening.
  6. Scan only hosts you own. Running nmap against unauthorized targets is illegal.
You Now Know

You can now read the full network state of any Linux server in 30 seconds. With ss, netstat, and nmap in your toolkit, no port mystery is unsolvable — you can see exactly what’s listening, who’s connected, and what the outside world can access.

Next Steps in This Series

🧠

Test Your Knowledge

Take a quick 5-question quiz to check your understanding.

📧

Get weekly IT guides

Join 5,000+ IT professionals

Subscribe Free
Type to start searching...