netstat and ss Basics: Monitoring Ports and Connections

netstat and ss Basics: Monitoring Ports and Connections

What You'll Learn

  • The difference between netstat and ss and when to use which
  • How to instantly see which port is listening and which process owns it
  • How to read TCP states (LISTEN / ESTAB / TIME-WAIT and more)

Quick Summary

  • Check listeners with ss -tlnp (the successor to netstat -tlnp)
  • Established connections: ss -tnp; overall summary: ss -s
  • netstat: command not found is not a failure—just use ss instead

Assumptions (target environment)

  • OS: Ubuntu / RHEL family or any common Linux
  • iproute2 (the ss command) is installed by default
  • Showing the process column (-p) requires sudo or admin privileges

What Is the Difference Between netstat and ss?

netstat ships with the legacy net-tools package and is now deprecated. ss (socket statistics) is provided by the successor iproute2 and retrieves the same information much faster. Use ss on modern systems.

Item netstat (net-tools) ss (iproute2)
Status Deprecated, unmaintained Current, recommended
Installed by default Often missing on modern OS Standard
Speed with many conns Slow (scans /proc per row) Fast (kernel API)
State filtering Not supported Filter with state

netstat: command not found is not a fault—net-tools simply isn't installed. You can add it with sudo apt install net-tools, but using ss first is the right approach.

How Do You Check Listening Ports?

ss -tlnp lists which process is listening on which port. When a service is up but unreachable, this is the first place to look to confirm whether anything is listening at all.

$ sudo ss -tlnp
State   Recv-Q  Send-Q  Local Address:Port   Peer Address:Port  Process
LISTEN  0       4096          0.0.0.0:22          0.0.0.0:*      users:(("sshd",pid=812,fd=3))
LISTEN  0       511         127.0.0.1:3000        0.0.0.0:*      users:(("node",pid=1340,fd=18))

What to read:

  • LISTEN … listening on that port
  • 0.0.0.0:22 … listening on port 22 on all interfaces (reachable externally)
  • 127.0.0.1:3000 … loopback only. Not reachable from outside (see below)
  • Process … process name and PID (shown with -p + sudo)

Add -u to include UDP.

$ sudo ss -tulnp

What Does the -tulpn Option Mean?

Each ss letter has an independent meaning. -tulpn bundles "show TCP and UDP listeners, without name resolution, with the owning process" into a single common combination.

Option Meaning
-t TCP sockets
-u UDP sockets
-l LISTEN (listening) state only
-n No name resolution (numeric, fast)
-p Show owning process (requires sudo)
-a All states (LISTEN + established, etc.)

Order does not matter—ss -tlnp and ss -plnt are identical. Without -n, reverse DNS slows things down, so always add it when investigating.

How Do You View Established Connections?

ss -tnp lists current ESTAB (established) TCP connections. Use it to see "who is connected to this server" or "is my app reaching the external API."

$ sudo ss -tnp
State  Recv-Q Send-Q   Local Address:Port    Peer Address:Port  Process
ESTAB  0      0        192.168.1.20:22      203.0.113.5:51324   users:(("sshd",pid=2210,fd=4))
ESTAB  0      0        192.168.1.20:48210   10.0.0.8:5432       users:(("node",pid=1340,fd=22))
  • Local Address:Port … the local side of the connection
  • Peer Address:Port … the remote side (the peer)
  • Line 1 … someone is logged in over SSH (22) from 203.0.113.5
  • Line 2 … the node app is connected to PostgreSQL (5432)

To grasp connection counts quickly, ss -s (summary) is handy.

$ ss -s

How Do You Filter by Port or Process?

ss accepts filter expressions directly. Instead of piping to grep, narrowing on the kernel side with sport (source port) / dport (destination port) / state is faster and more accurate.

Check whether a specific port is listening:

$ sudo ss -tlnp 'sport = :80'
$ sudo ss -tlnp sport = :443

Extract a specific state only:

$ ss -tn state established
$ ss -tn state time-wait

Inspect connections to a specific destination:

$ ss -tn dst 10.0.0.8

An app listening only on 127.0.0.1:3000 is reachable solely from inside the server. To expose it, change the app's bind setting to listen on 0.0.0.0:3000 (or a specific IP). If ss still shows 127.0.0.1 under Local Address, no amount of firewall changes will let it connect.

How Do You Read Connection States?

TCP states represent the connection lifecycle. The four that show up most in incidents are LISTEN, ESTAB, TIME-WAIT, and CLOSE-WAIT. Knowing what they mean points you toward the cause.

State Meaning What it tells you
LISTEN Listening The service is up
ESTAB Connection established Communicating normally
TIME-WAIT Post-close cooldown Usually normal even in bulk (many short conns)
CLOSE-WAIT Peer closed, local not closed Large growth suggests an app socket leak
SYN-SENT Sent request, awaiting reply Many of these suggest unreachable peer / FW drop

Ever-growing CLOSE-WAIT is a sign of an app bug (sockets not being closed). Check counts and processes with ss -tn state close-wait. A large number of TIME-WAIT is usually normal—do not rush to tweak net.ipv4.tcp_tw_reuse and friends.

netstat → ss Migration Cheat Sheet

Even if netstat muscle memory remains, learning the ss equivalents makes the move easy. Keep the table below at hand.

What you want Old (netstat) New (ss)
TCP listeners netstat -tlnp ss -tlnp
TCP/UDP listeners netstat -tulnp ss -tulnp
All connections netstat -an ss -an
Established conns netstat -tnp ss -tnp
Connection summary netstat -s ss -s
Routing table netstat -rn ip route
# Copy-paste: state overview one-liner
sudo ss -tulnp && ss -s

Combining with grep like ss -tlnp | grep ':80 ' works too, but ss -tlnp 'sport = :80' filters on the kernel side—faster and with fewer false matches.

Next Reading