Commands - Getting more info out of ss

23 Jul 2023

The linux tool ss or socket statistics (not verified) is merely installed as a default on many linux systems and considered as the updated alternative of netstat. In this post a deeper look at the possible detailed information of ss is taken.

When invoked without any options or flags, it features the common output you'd also see with netstat. But when looking at the man page the following note comes up:

It can display more TCP and state information than other tools.

Let's put that to the test and try to access and nicely display the advertized advanced output starting with the following command:

ss -Hitn state big exclude listening \( not dst 192.168.1.0/24 and not dst 192.168.2.0/24 \)

ESTAB 0 0 192.168.2.201:56250 93.184.216.34:443
cubic wscale:8,7 rto:224 ...
ESTAB 0 0 192.168.2.201:46138 93.184.216.34:80
cubic wscale:8,7 rto:216 ...
ESTAB 0 0 192.168.2.201:46132 93.184.216.34:80
cubic wscale:8,7 rto:216 ...

Describing the options, the headers were supressed (H), only TCP-based connections are displayed (t), hostnames and services are not resolved (n) and finally the i-flag is used to display internal TCP information. In the above output this had to be shortened for better readability.

The next section is a so called state filter for the tcp connections to list. Here only states classified as big are showed and listening connections are excluded. The technical definition for the big classified states are states which are not maintained as minisockets. At the end an expression is appended that's meant to exclude further local traffic from displaying.

Getting back to the initial goal, it'd be preferable to extract some interesting data out of the internal TCP information. Let's imagine that the congestion control needs troubleshooting and therefore we'd like to display the tcp pacing. This can be done like this:

ss -Hitn state big exclude listening \( not dst 192.168.1.0/24 and not dst 192.168.2.0/24 \) | paste -sd ' \n' | awk 'match($0, /pacing_rate [0-9\.]+?bps/) {print $4 "\t" $5 "\t" substr($0, RSTART, RLENGTH)}'

192.168.2.201:56250 93.184.216.34:443 pacing_rate 10386960bps
192.168.2.201:46138 93.184.216.34:80 pacing_rate 14611032bps
192.168.2.201:46132 93.184.216.34:80 pacing_rate 14731992bps

In this example the output is piped to paste and awk. Paste is utilized to concatenate each two line pairs of ip address info and the internal information below that. Awk is then used with a regex to pick up the detail we want to extract and display it. The match function of awk puts the positional data of the found string into RSTART and RLENGTH, which is used at the end to print the resulting lines.