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
- Use
ssto see every open port and active connection on your system - Use
netstatwhen on legacy systems, macOS, or Windows - Use
nmapto 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
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.
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
Show all TCP + UDP ports your system is currently listening on, with the process name
- •-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:
| Column | What It Means |
|---|---|
| Netid | Protocol: tcp, udp, unix (local socket) |
| State | LISTEN = waiting for connections. ESTAB = active connection. UNCONN = UDP (connectionless). |
| Local Address:Port | 0.0.0.0 = all interfaces. 127.0.0.1 = localhost only (not reachable from internet). |
| Peer Address | 0.0.0.0:* = listening (no peer yet). An IP here = active connection to that remote host. |
| Process | The process name using this socket. Requires sudo to see all processes. |
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
Show all active TCP connections — who your server is talking to right now
- •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
Show only the process listening on port 80
- •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
| Command | What It Shows |
|---|---|
ss -tulpn | All listening ports + process names (use this first) |
ss -tn | All active TCP connections |
ss -s | Summary statistics (total sockets, TCP states) |
ss -tnp state established | Only ESTABLISHED connections with process names |
sudo ss -tlpn sport = :PORT | Which 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:
- macOS (netstat is current and fully supported)
- Windows (built in, still used daily by sysadmins)
- Old Linux servers (RHEL 7, CentOS 7, Debian 9) where
ssmay not pre-installed with identical flags
The output format differs slightly from ss, but the core flags work the same way.
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.
Show all listening TCP + UDP ports with process names (Linux only)
- •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:
Show all connections with process IDs on Windows (no -u, no -p for process names)
- •-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)
Show the kernel routing table — how your machine decides where to send each packet
- •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.
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
Scan your own machine and discover what services (and versions) are visible
- •-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 respondingSTATE: closed= the port is reachable but no service is listeningSTATE: 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
Scan all well-known ports (0-1023) on a target — the most security-relevant range
- •-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
Ping scan — discover which hosts are alive in your local network (no port scanning)
- •-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
| Situation | Best Tool | Command |
|---|---|---|
| What ports is MY server listening on? | ss | ss -tulpn |
| Who is connected to my server right now? | ss | ss -tn state established |
| Port conflict — what app is using port X? | ss | sudo ss -tlpn sport = :X |
| Need to check routing table | netstat | netstat -rn |
| On macOS or old Linux | netstat | netstat -an | grep LISTEN |
| On Windows | netstat | netstat -ano |
| What does the FIREWALL show externally? | nmap | nmap -sV your-ip |
| Security audit of your network | nmap | nmap -sV -p- your-ip |
| Discover devices in local network | nmap | nmap -sn 192.168.1.0/24 |
ss -tulpn→ See what’s listening and who owns itss -tn→ See what’s actively connectednmap -sV your-ip→ See what the firewall actually exposes- Compare: if
ssshows port 3306 listening butnmapdoesn’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
ss -tulpnis your first command every time you investigate a network issue. Run it, understand the output.0.0.0.0:PORTvs127.0.0.1:PORTis the security check — databases should bind to localhost only.netstatis alive on macOS and Windows but replaced bysson modern Linux. Know both.nmapgives the external view — what someone from the internet actually sees, including firewall effects.- STATE: filtered in nmap = firewall working. STATE: open = port reachable. STATE: closed = nothing listening.
- Scan only hosts you own. Running nmap against unauthorized targets is illegal.
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
- What is a Port? — The foundational explainer on how ports work
- Top 20 Ports Every IT Pro Must Know — The reference guide to the most important port numbers
- TCP vs UDP Explained — Understand the transport layer protocols these ports use
Test Your Knowledge
Take a quick 5-question quiz to check your understanding.