| |

LFCS 105 ๐Ÿง Socket Inspection โ€” ss, netstat

โฑ๏ธ Estimated read: 8 min | |

A network connection is more than an IP address and a port. It is a socket: a stateful object in the kernel that tracks the local address, the remote address, the protocol, the connection state, and the process that owns it. When a service fails to start because “the port is already in use,” or when a connection hangs in CLOSE_WAIT, the tools that reveal this state are ss and netstat. The LFCS exam expects ss as the modern replacement for the deprecated netstat, but it also tests netstat because it remains present on many systems and appears in older documentation.

Key point: ss is the modern tool. It reads socket statistics directly from the kernel via netlink, making it significantly faster than netstat, which parses /proc/net/tcp and related files. Both show the same information, but ss scales better and is the default on modern distributions.


Why socket inspection tools exist

The port conflict problem. A service fails to bind to port 8080 because another process is already listening on it. Without a tool to map ports to processes, the only recourse is to kill processes until the bind succeeds. ss -tlnp (or netstat -tlnp) maps the listening socket to the PID and program name, identifying the conflicting process immediately.

The connection state problem. TCP connections have states: ESTABLISHED, TIME_WAIT, CLOSE_WAIT, LISTEN, and others. A server that accepts connections but never closes them accumulates CLOSE_WAIT socketsโ€”the remote side has closed, but the local application has not. This is an application bug, not a network bug. ss -tan state close-wait reveals the problem.

The performance problem. netstat reads /proc/net/tcp, /proc/net/udp, and related files line by line. On a system with tens of thousands of connections, this is slow. ss uses netlink sockets to query the kernel directly, retrieving the same information in a fraction of the time. The ss man page explicitly states: “This tool is obsolete. Use ss instead” for netstat.

The filtering problem. ss supports a rich filter syntax that netstat lacks. You can filter by source port, destination port, connection state, and address. This makes ss a diagnostic tool, not just a listing tool.

The trade-off. netstat is installed on older systems and appears in many tutorials. ss is faster and more capable, but the filter syntax is more complex. The exam tests both, but the practical recommendation is ss.


a. Listing listening sockets

The most common use of ss is to list sockets in the LISTEN state, showing which services are accepting connections.

# TCP listening sockets
ss -tln

# TCP and UDP listening sockets
ss -tuln

# Listening sockets with process information
sudo ss -tlnp

# Listening sockets with process and no name resolution
sudo ss -tlnp -n

The flags are the same as netstat:

  • -t โ€” TCP
  • -u โ€” UDP
  • -l โ€” listening only
  • -n โ€” numeric (no DNS or service name resolution)
  • -p โ€” process (requires root to see other users’ processes)

The -p flag shows the PID and program name for each socket. Without it, the users:(("sshd",pid=1234,fd=3)) column is omitted.


b. Inspecting established connections and states

Listing all connections, not just listening sockets, reveals active sessions and their states. The -a flag includes all sockets (listening and non-listening).

# All TCP connections
ss -tan

# All TCP connections with process info
sudo ss -tanp

# Filter by connection state
ss -tan state established
ss -tan state close-wait

# Filter by port
ss -tan sport = :22
ss -tan dport = :443

The state filter uses the TCP state names: established, syn-sent, syn-recv, fin-wait-1, fin-wait-2, time-wait, close-wait, last-ack, closing. The filters sport and dport accept a port number or service name.

A server accumulating CLOSE_WAIT sockets is not closing connections after the remote side sends FIN. This is an application-level bug and cannot be fixed with network configuration.


c. netstat: the legacy alternative

netstat provides similar information through the same flag vocabulary. It reads from /proc/net/*, which makes it slower on systems with many sockets.

# Listening TCP sockets
netstat -tln

# All connections
netstat -tan

# With process info
sudo netstat -tlnp

# With routing table
netstat -rn

The output columns are Proto, Recv-Q, Send-Q, Local Address, Foreign Address, State, and (with -p) PID/Program name. The ss output is nearly identical, which is why migration between the two is straightforward.

netstat is deprecated. The ss man page states: “This program is obsolete. Replacement for netstat is ss. Replacement for netstat -r is ip route. Replacement for netstat -i is ip -s link. Replacement for netstat -g is ip maddr.” Systems that still install netstat do so for backward compatibility, not because it is preferred.


Complete Example Session

# ============================================
# PART 1: LIST LISTENING TCP SOCKETS
# ============================================

ss -tln
# State  Recv-Q  Send-Q  Local Address:Port  Peer Address:Port
# LISTEN 0       128     0.0.0.0:22          0.0.0.0:*
# LISTEN 0       128     0.0.0.0:80          0.0.0.0:*
# ============================================
# PART 2: ADD PROCESS INFORMATION
# ============================================

sudo ss -tlnp
# ... users:(("sshd",pid=812,fd=3))
# ... users:(("nginx",pid=1050,fd=6))
# ============================================
# PART 3: LIST ALL CONNECTIONS
# ============================================

ss -tan
# Includes ESTABLISHED, TIME-WAIT, and LISTEN states.
# ============================================
# PART 4: FILTER BY STATE
# ============================================

ss -tan state established
# Only established connections.
# ============================================
# PART 5: FILTER BY PORT
# ============================================

ss -tan dport = :443
# All connections with destination port 443.
# ============================================
# PART 6: FIND CLOSE_WAIT SOCKETS
# ============================================

ss -tan state close-wait
# If this list grows, the application is not closing sockets.
# ============================================
# PART 7: NETSTAT EQUIVALENT
# ============================================

netstat -tlnp
# Same information, slower on large systems.
# ============================================
# PART 8: ROUTING TABLE
# ============================================

ip route
# The modern replacement for "netstat -rn".
# ============================================
# PART 9: INTERFACE STATISTICS
# ============================================

ip -s link
# The modern replacement for "netstat -i".

The nine parts trace the workflow: listening sockets, process mapping, all connections, state filtering, port filtering, close-wait inspection, netstat comparison, and the modern replacements for netstat‘s other modes.


Quick Reference

ss Commands

CommandPurpose
ss -tlnTCP listening sockets
ss -tulnTCP and UDP listening
ss -tlnpListening with process
ss -tanAll TCP sockets
ss -tanpAll TCP with process
ss -tan state establishedEstablished only
ss -tan state close-waitClose-wait only
ss -tan dport = :443By destination port
ss -sSummary statistics

netstat Commands

CommandEquivalent ss
netstat -tlnss -tln
netstat -tanss -tan
netstat -tlnpss -tlnp
netstat -rnip route
netstat -iip -s link

TCP States

StateMeaning
LISTENAccepting connections
ESTABLISHEDActive connection
TIME-WAITLocal close, awaiting final ACK
CLOSE-WAITRemote closed, local not yet closed
SYN-SENTConnection requested
SYN-RECVConnection request received

Best Practices

โœ… Do This:

sudo ss -tlnp
<!-- Map listening ports to processes -->            # โœ…
ss -tan state established
<!-- Filter by connection state -->                  # โœ…
ip route
<!-- Use modern replacement for "netstat -rn" -->    # โœ…

โŒ Don’t Do This:

# Use netstat on a system with tens of thousands of sockets
<!-- Parsing /proc is slow and may time out -->      # โŒ
# Ignore CLOSE_WAIT accumulation
<!-- Indicates application bug, not network issue --> # โŒ
# Assume port conflict is solved by killing a process
<!-- Verify with ss -tlnp which process owns it -->  # โŒ

Common Pitfalls

PitfallWhy It HappensFix
ss -p shows no processNot rootRun with sudo
ss output shows long namesDNS and service resolutionAdd -n flag
Cannot diagnose slow netstatReading /proc on large systemsSwitch to ss
CLOSE_WAIT accumulationApplication not closingFix application logic
Filter syntax errorsss filter uses different syntaxUse state, sport, dport

Real-World Examples

1. Listening TCP Ports

ss -tln

2. Listening with Process

sudo ss -tlnp

3. All Connections

ss -tan

4. Established Only

ss -tan state established

5. Close-Wait

ss -tan state close-wait

6. Filter by Port

ss -tan dport = :443

7. netstat Equivalent

netstat -tlnp

8. Routing Table

ip route

9. Interface Statistics

ip -s link

10. Socket Summary

ss -s

Visual

Socket States

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  LISTEN                                      โ”‚
โ”‚  Waiting for incoming connections            โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                   โ”‚
                   โ”‚ 3-way handshake
                   โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  ESTABLISHED                                 โ”‚
โ”‚  Data flows in both directions               โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                   โ”‚
                   โ”‚ remote sends FIN
                   โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  CLOSE-WAIT                                  โ”‚
โ”‚  Local app must close; accumulating is a bug โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                   โ”‚
                   โ”‚ local app closes
                   โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  LAST-ACK โ†’ CLOSED                           โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Port-to-Process Mapping

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  ss -tlnp                                    โ”‚
โ”‚                                              โ”‚
โ”‚  LISTEN  0  128  0.0.0.0:22  0.0.0.0:*       โ”‚
โ”‚      users:(("sshd",pid=812,fd=3))           โ”‚
โ”‚                                              โ”‚
โ”‚  LISTEN  0  128  0.0.0.0:80  0.0.0.0:*       โ”‚
โ”‚      users:(("nginx",pid=1050,fd=6))         โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

The users: field is only shown with -p and sudo.


Summary

ItemValue
Modern toolss
Legacy toolnetstat
Listening TCPss -tln
Listening with processsudo ss -tlnp
All connectionsss -tan
Filter by statess -tan state <state>
Filter by portss -tan dport = :<port>
Routing tableip route
Interface statsip -s link

Key takeaways:

  • ss is faster and more capable than netstat. It queries the kernel via netlink instead of parsing /proc, and it supports filtering by state, port, and address.
  • -p requires root. Process information is restricted; without sudo, the users: column is omitted.
  • CLOSE-WAIT accumulation is an application bug. The local application is not closing sockets after the remote side closes. This cannot be fixed with network configuration.
  • netstat is deprecated but still present. The ss man page explicitly recommends replacement: ss for sockets, ip route for routes, ip -s link for interfaces.
  • Filtering is the diagnostic power. ss -tan state close-wait and ss -tan dport = :443 are more useful than listing every socket and reading by eye.

Remember: A socket is the kernel’s representation of a connection. ss shows the kernel’s view: which ports are listening, which connections are established, which are stuck in a transitional state, and which process owns each socket. The flags control the view: -t for TCP, -u for UDP, -l for listening, -a for all, -n for numeric, -p for process. The filters narrow the list to the specific problem.

Was this helpful?


Stop using slow, ad-bloated tool sites! ๐Ÿคฎ

๐Ÿ”Ž Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
โœ… Finance (Mortgage, Interest, Inflation)
โœ… Tech (Base64, JSON, Dev Suite, IP)
โœ… Health (BMI, BMR, TDEE)
โœ… Productivity (Timer, Workspace, QR)

โšก๏ธ Fast & Private
๐Ÿ”’ No data leaves your device
๐Ÿ’Ž 100% Free

๐Ÿ”— Use it now: https://tools.kandz.me
๐Ÿ”– Bookmark itโ€”youโ€™ll need it later!