Sockets and Ports: ss Replaces netstat

“What’s listening on port 80?” “Why is this connection stuck?” “Is anyone connected to my SSH right now?” The answer to all of these is ss — Linux’s modern socket inspection tool. It replaces netstat and is significantly faster on busy systems.

The most useful invocation

sudo ss -tulpn

Memorize this one. It shows:

  • -t TCP sockets
  • -u UDP sockets
  • -l only LISTENING sockets
  • -p show the process (needs sudo to see other users)
  • -n numeric (no DNS lookup, instant output)

Output: every port your machine is listening on, the protocol, and which program is doing the listening.

Other common queries

ss                  # show all open sockets (huge)
ss -t               # TCP only
ss -u               # UDP only
ss -l               # LISTENING only
ss -a               # ALL (listening + established)
ss -p               # show process (needs sudo)
ss -n               # numeric (no DNS)
ss -e               # extended info
ss -s               # summary statistics

Filter by port or address

# What's listening on port 80?
sudo ss -tlnp 'sport = :80'

# All connections to port 443
sudo ss -tnp 'dport = :443'

# Connections from a specific IP
ss -tn 'src 192.168.1.50'

# Connections to a remote IP
ss -tn 'dst 1.1.1.1'

# Specific port range
ss -tln 'sport >= :8000 and sport <= :9000'

Filter by state

ss -t state established       # active connections
ss -t state listening         # listeners (same as -l)
ss -t state time-wait         # connections in TIME_WAIT
ss -t state close-wait        # CLOSE_WAIT (often a server bug)
ss -t state syn-sent          # outgoing connection attempts

Practical workflows

“What’s using port 80?”

sudo ss -tlnp 'sport = :80'
# users:(("nginx",pid=1234,fd=6))
# → nginx with PID 1234

“What program owns this connection?”

sudo ss -tnp | grep 1.2.3.4

“Why does my server slow down under load?”

ss -s            # summary - look at TIME_WAIT and CLOSE_WAIT counts
ss -t state time-wait | wc -l        # too many TIME_WAITs?
ss -t state close-wait | wc -l       # too many CLOSE_WAITs = bug

“Is my SSH server reachable from this client?”

# From client side
ss -tn 'dst myserver.com:22 state established'

“Find ALL listeners on this machine”

sudo ss -tulpn

Useful related commands

lsof — what files (incl. sockets) does a process have open?

sudo lsof -i :80           # what's using port 80
sudo lsof -i tcp           # all TCP connections
sudo lsof -i @1.2.3.4      # connections to/from 1.2.3.4
sudo lsof -p 1234          # everything PID 1234 has open

fuser — kill the process holding a port

sudo fuser -v 80/tcp                # who has port 80 open
sudo fuser -k 80/tcp                # KILL whoever has port 80 (rough)

nmap (from another machine)

nmap -p 1-1000 myserver.com         # scan a range
nmap -sV -p 22,80,443 myserver.com  # detect service versions

The legacy netstat (still works most places)

sudo netstat -tulpn       # roughly equivalent to ss -tulpn

If you find yourself on a system without ss (rare), netstat is fine. Both come from the same dataset.

Common mistakes

  • Running ss -p without sudo and not seeing process names. The kernel hides ownership info.
  • Forgetting -n on a server with broken DNS — DNS lookups stall the command.
  • Confusing TIME_WAIT (normal cleanup state) with CLOSE_WAIT (often a bug in your server code).

What to learn next

Now that you can see what’s listening, DNS — how machines find each other by name — is the next networking topic.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *