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.