Using the ss command on Linux to view details on sockets


The ss command is used to dump socket statistics on Linux systems. It serves as a replacement for the netstat command and is often used for troubleshooting network problems.

What is a socket?

To make the best use of the ss command, it’s important to understand what a socket is. A socket is a type of pseudo file (i.e., not an actual file) that represents a network connection. A socket identifies both the remote host and the port that it connects to so that data can be sent between the systems. Sockets are similar to pipes except that pipes only facilitate connections between processes on the same system where sockets work on the same or different systems. Unlike pipes, sockets also provide bidirectional communication.

Once a socket is created, communications between the local and a remote host will take the form of network packets.

Using the ss command

With no arguments, ss will list all established (open non-listening) network connections regardless of their status. Here’s an example showing just the first few lines of the command’s output along with a single line including IP addresses:

$ ss | head -3; ss | grep 192 | tail -1
Netid State  Recv-Q Send-Q      Local Address:Port      Peer Address:Port      Process
u_str ESTAB  0      0                       * 31510                * 31511
u_str ESTAB  0      0                       * 30253                * 30254
tcp   ESTAB  0      288          192.168.0.18:ssh       192.168.0.17:activesync

The fields as shown in the ss command output above include:

  • Netid – The type of socket – TCP, UDP, u_str (Unix stream), or u_seq (Unix sequence)
  • State – The state of the socket – ESTAB (established), UNCONN (unconnected) and LISTEN (listening)
  • Recv-Q – The number of received packets in the queue waiting to be read
  • Send-Q – The number of packets in the queue waiting to be sent
  • Local address:port – Address of the local system and port
  • Peer address:port – Address of the remote system and port

The * characters in the above output indicate that the sockets are listening for traffic on all addresses. I included the last line to show a connection between two specific systems – this system and an ssh connection to a local host.

You can expect to see hundreds of lines of output when you use the ss command. To count the socket connections that are established on your system (adding one line for the heading), you can use a command like this:

$ ss | wc -l
622

The command below, which uses awk to look only at the second field in each line of ss output, shows that one socket is unconnected while 620 are established connections. This command is sorting on the content of the “State” field. The second row in the output shown below shows that column heading.

$ ss | awk '{print $2}' | sort | uniq -c
    620 ESTAB
      1 State
      1 UNCONN

Using the ss -a (show all sockets) command will make the ss output display both listening and non-listening sockets. For TCP, “non-listening” means established connections while “listening” means waiting for a connection. The commands below show the difference in the amount of output.

$ ss | wc -l
617
$ ss -a | wc -l
820

For example, the ss -a output is likely to start with output like this:

$ ss -a | head -7
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process nl UNCONN 0 0 rtnl:packagekitd/1032 * nl UNCONN 0 0 rtnl:evolution-calen/1685 * nl UNCONN 0 0 rtnl:kernel * nl UNCONN 0 0 rtnl:NetworkManager/772 * nl UNCONN 0 0 rtnl:abrt-applet/1863 * nl UNCONN 0 0 rtnl:goa-daemon/1653 *

The Netid values include:

  • icmp6 — Internet control message protocol
  • nl — netlink
  • tcp — transmission control protocol (connection-oriented)
  • u_dgr — Unix datagram
  • udp — user datagram protocol (connectionless)
  • u_seq — Unix sequence
  • u_str — Unix_stream

Socket summaries

To get a summary socket report, use the -s option as shown in the command below.

$ ss -s
Total: 777
TCP:   9 (estab 1, closed 1, orphaned 0, timewait 1)

Transport Total     IP        IPv6
RAW       1         0         1
UDP       10        6         4
TCP       8         5         3
INET      19        11        8
FRAG      0         0         0

Using a script to view ss output

The script below will sort and summarize the content of any field in the ss command output.

If you add -a as an argument (or, in fact, any single argument), the script will summarize the output of the ss -a command rather than the ss command with no options. Select any field by number to select that column.

#!/bin/bash

if [ $# != 0 ]
then
  ss="ss -a"
else
  ss="ss"
fi

echo "What column do you want to see?"
echo 1: Netid
echo 2: State
echo 3: Recv-Q
echo 4: Send-Q
echo 5: Local Address:Port
echo 6: Peer Address:Port
echo 7: Process

echo -n "> "
read number

case $number in
1) echo Netid; $ss | tail -n+2 | awk '{print $1}' | sort | uniq -c;;
2) echo State; $ss | tail -n+2 | awk '{print $2}' | sort | uniq -c;;
3) echo Recv-Q; $ss | tail -n+2 | awk '{print $3}' | sort | uniq -c;;
4) echo Send-Q; $ss | tail -n+2 | awk '{print $4}' | sort | uniq -c;;
5) echo Local Address:Port; $ss | tail -n+2 | awk '{print $5}' | sort | uniq -c;;
6) echo Peer Address:port; $ss | tail -n+2 | awk '{print $6}' | sort | column;;
7) echo Process; $ss | tail -n+2 | awk '{print $7}' | sort | uniq -c;;
*) echo "huh?";;
esac

For example, to view how many times each Netid value appears, you can run the script like this:

$ ss_summary
What column do you want to see?
1: Netid
2: State
3: Recv-Q
4: Send-Q
5: Local Address:Port
6: Peer Address:Port
7: Process
> 1
Netid
      1 icmp6
      1 tcp
     46 u_dgr
      1 udp
    567 u_str

Getting help

Use the ss -h command to get a list of the command’s many options with brief descriptions.

$ ss -h
Usage: ss [ OPTIONS ]
       ss [ OPTIONS ] [ FILTER ]
   -h, --help          this message
   -V, --version       output version information
   -n, --numeric       don't resolve service names
   -r, --resolve       resolve host names
   -a, --all           display all sockets
   -l, --listening     display listening sockets
   -o, --options       show timer information
   -e, --extended      show detailed socket information
   -m, --memory        show socket memory usage
   -p, --processes     show process using socket
   -i, --info          show internal TCP information
       --tipcinfo      show internal tipc socket information
   -s, --summary       show socket usage summary
       --tos           show tos and priority information
       --cgroup        show cgroup information
   -b, --bpf           show bpf filter socket information
   -E, --events        continually display sockets as they are destroyed
   -Z, --context       display process SELinux security contexts
   -z, --contexts      display process and socket SELinux security contexts
   -N, --net           switch to the specified network namespace name
   -4, --ipv4          display only IP version 4 sockets
   -6, --ipv6          display only IP version 6 sockets
   -0, --packet        display PACKET sockets
   -t, --tcp           display only TCP sockets
   -M, --mptcp         display only MPTCP sockets
   -S, --sctp          display only SCTP sockets
   -u, --udp           display only UDP sockets
   -d, --dccp          display only DCCP sockets
   -w, --raw           display only RAW sockets
   -x, --unix          display only Unix domain sockets
       --tipc          display only TIPC sockets
       --vsock         display only vsock sockets
   -f, --family=FAMILY display sockets of type FAMILY
       FAMILY := {inet|inet6|link|unix|netlink|vsock|tipc|xdp|help}
   -K, --kill          forcibly close sockets, display what was closed
   -H, --no-header     Suppress header line
   -O, --oneline       socket's data printed on a single line
       --inet-sockopt  show various inet socket options
   -A, --query=QUERY, --socket=QUERY
       QUERY := {all|inet|tcp|mptcp|udp|raw|unix|unix_dgram|unix_stream|unix_seqpacket|packet|netlink|vsock_stream|vsock_dgram|tipc}[,QUERY]
   -D, --diag=FILE     Dump raw information about TCP sockets to FILE
   -F, --filter=FILE   read filter information from FILE
       FILTER := [ state STATE-FILTER ] [ EXPRESSION ]
       STATE-FILTER := {all|connected|synchronized|bucket|big|TCP-STATES}
         TCP-STATES := {established|syn-sent|syn-recv|fin-wait-{1,2}|time-wait|closed|close-wait|last-ack|listening|closing}
          connected := {established|syn-sent|syn-recv|fin-wait-{1,2}|time-wait|close-wait|last-ack|closing}
       synchronized := {established|syn-recv|fin-wait-{1,2}|time-wait|close-wait|last-ack|closing}
             bucket := {syn-recv|time-wait}
                big := {established|syn-sent|fin-wait-{1,2}|closed|close-wait|last-ack|listening|closing}

Note that with the –S option, ss will show SCTP sockets only. With the -a option, ss will display both listening and non-listening sockets of every kind. With the -l parameter, ss will display listening sockets (omitted by default). With the -e option, ss will display detailed socket information. These are only a handful of the options available. Check the list above or use the ss -h command to view available options on your Linux host.

Wrap-up

The ss command can provide important details on sockets – likely more than some of us imagined were available. Getting used to the command and its wide array of options may take a while, but this level of detail can be essential to understanding how your Linux systems are communicating with each other and with external systems.

Copyright © 2022 IDG Communications, Inc.



Source link