How to Use Ubuntu ss Command to Analyze Active Network Socket Statistics

The Deprecation of netstat

For twenty years, Linux network engineers relied entirely on the netstat command to troubleshoot routing tables, identify listening ports, and view active TCP connections. However, netstat has a fatal architectural flaw: it pulls its data by slowly reading thousands of flat text files located in the /proc directory. On a massive, high-performance Ubuntu web server with 50,000 concurrent HTTP connections, running netstat will severely spike the CPU and can take several minutes to generate a report.

Because of this inefficiency, the entire net-tools suite (which includes netstat, ifconfig, and route) has been officially deprecated in modern Linux distributions.

The modern replacement is the ss (Socket Statistics) command, part of the iproute2 suite. ss is fundamentally superior because it communicates directly with the Linux kernel’s internal netlink architecture. It bypasses the /proc filesystem entirely, allowing it to dump hundreds of thousands of active socket connections in milliseconds. Mastering the ss command is an absolute requirement for diagnosing modern, high-density network bottlenecks.

Step 1: The Basic Interrogation (Listening Ports)

The most common network troubleshooting question is: “Is the application actually listening on the correct port?”

If you suspect Nginx is dead, you need to verify if port 80 or 443 is actively listening.

Run the ss command with the listening and TCP flags:

sudo ss -ltn

Decoding the Flags:

  • -l (Listening): Only show sockets that are actively waiting for a connection. (It strips out all the established connections to reduce noise).
  • -t (TCP): Only show TCP sockets (ignoring UDP or RAW sockets).
  • -n (Numeric): Do not attempt to reverse-resolve IP addresses into DNS hostnames, or port numbers into service names. (Attempting DNS resolution on 5,000 IPs will freeze your terminal. Always use -n).

The output will clearly show LISTEN in the state column, followed by the local address and port (e.g., 0.0.0.0:80), mathematically proving the kernel is keeping the port open.

Step 2: Identifying the Rogue Process (-p)

Suppose you run the ss -ltn command and discover that Port 8080 is listening, but you have no idea what application is holding that port hostage. If you try to start a new web server on 8080, it will crash with a “Port already in use” error.

You must add the -p (Process) flag. This flag requires sudo privileges, as it forces the kernel to reveal the exact Process ID (PID) and executable name that owns the socket.

sudo ss -ltnp

The output will append a new column at the end: users:(("java",pid=4599,fd=6)).

You have instantly identified that a rogue Java application (PID 4599) has seized control of the port. You can now use kill -9 4599 to forcefully terminate the process and free the socket.

Step 3: Interrogating Active Connections and Timers

If a server is experiencing a Denial of Service (DoS) attack, you don’t care about listening ports; you care about the thousands of Established connections flooding the machine.

To view all established connections, drop the -l flag:

ss -tn state established

If a load balancer is failing because connections are hanging, you can use ss to interrogate the kernel’s internal TCP timers using the -o (Options) flag.

ss -tno

This output is invaluable. It adds a column showing the exact TCP keepalive timer (e.g., timer:(keepalive,45sec,0)). If you see hundreds of connections sitting in the FIN-WAIT-2 state with timers counting down for minutes, you have mathematically proven that the remote clients are dropping off the internet without sending proper TCP closure packets, causing your server to waste RAM holding dead sockets open.

Step 4: Advanced Filtering (The Power of State)

The true power of ss is its ability to execute complex, SQL-like queries against the kernel’s socket database.

Suppose you want to find all SSH connections (Port 22) originating from a specific internal subnet (10.0.5.0/24). Piping ss into grep is inefficient. You should let the ss engine perform the filtering natively.

ss -tn dport = :22 and dst 10.0.5.0/24

You can also filter by precise TCP states. If you are diagnosing a SYN Flood attack (where an attacker sends thousands of initiation packets but never completes the handshake, exhausting the server’s backlog), you can specifically query the SYN-RECV state:

ss -tn state syn-recv

If this command outputs thousands of lines, you are mathematically confirming a volumetric SYN flood, and you must immediately deploy iptables rate-limiting or adjust the tcp_max_syn_backlog kernel parameter in sysctl.

Conclusion

Continuing to use netstat on modern, high-density Linux servers guarantees CPU spikes and unacceptable diagnostic latency. By mastering the ss (Socket Statistics) command, network engineers interface directly with the kernel’s high-speed netlink architecture. The ability to instantly map Process IDs to listening ports, dump internal TCP keepalive timers, and execute complex state-based filtering transforms raw network troubleshooting into a precise, millisecond-fast operation.

RELATED POSTS

  • How to Configure systemd-resolved for Custom DNS Routing on Ubuntu
  • How to Create and Manage Swap Space on Ubuntu Linux
  • How to Install and Configure the Lighttpd Web Server on Ubuntu
  • How to Use Ubuntu sysstat to Generate Historical Performance Analytics
  • How to Install and Configure the Postfix Mail Server on Ubuntu
  • Get the best tech tips delivered straight to your inbox.

    Join thousands of readers mastering Apple, Google, Microsoft, and Linux.