Here is the third post of the series on network troubleshooting and tools under RHEL / CentOS.
In this post, I will talk about the netstat and ss commands.
Other posts of the series
This post is part of a series of Linux Networking tips and tricks.
The other posts of this series are:
netstat
The netstat command is a network utility used to display network connections, protocol or interface statistics, routing table, multicast memberships, etc.
However, the netstat command has been deprecated and replaced by the faster and more human-readable ss command from the IPROUTE suite of tools.
SS
The ss command is a powerful tool used to display socket statistics information.
Basic usage
If you type the ss command without any argument or option, it will return a complete list of sockets and connections status:
$ ss Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process u_seq ESTAB 0 0 @0000d 181366 * 181367 u_seq ESTAB 0 0 @00010 725730 * 725731 u_str ESTAB 0 0 * 2854839 * 2854840 u_str ESTAB 0 0 * 2751706 * 2751707 u_str ESTAB 0 0 /run/dbus/system_bus_socket 180672 * 179776 u_str ESTAB 0 0 * 27273 * 29242 u_str ESTAB 0 0 * 26947 * 30830 u_str ESTAB 0 0 * 24243 * 24242 u_str ESTAB 0 0 * 2821521 * 2821522 u_str ESTAB 0 0 /run/systemd/journal/stdout 29761 * 30825 u_str ESTAB 0 0 * 2757532 * 2757531 ...
We can pipe the output to less to have a scrollable output. As you can see, the output will contain all tcp, udp, and socket connections details. Not really usable as is. But we will see below the different options to filter the output.
TCP/UDP established connections (-t or -u)
To view only TCP or UDP connections, we can use the -t or -u options.
Here is an example of an application browsing a web page:
$ ss -t State Recv-Q Send-Q Local Address:Port Peer Address:Port ESTAB 0 0 10.0.2.15:43144 216.58.215.227:https ESTAB 0 0 10.0.2.15:48536 172.217.168.74:https ESTAB 0 0 10.0.2.15:42394 216.58.215.237:https ESTAB 0 0 10.0.2.15:59988 216.58.215.238:https ESTAB 0 0 10.0.2.15:53512 172.217.168.46:https ESTAB 0 0 10.0.2.15:54576 216.58.215.226:https ESTAB 0 0 10.0.2.15:60292 216.58.215.228:https ESTAB 0 0 10.0.2.15:55660 216.58.192.35:https
Listening sockets only (-l)
By default, the -t option reports only the established connections. To report only the listening sockets, we can use the -l option.
Here are two examples, first with UDP, then with TCP:
$ ss -ul State Recv-Q Send-Q Local Address:Port Peer Address:Port UNCONN 0 0 224.0.0.251:mdns 0.0.0.0:* UNCONN 0 0 224.0.0.251:mdns 0.0.0.0:* UNCONN 0 0 0.0.0.0:mdns 0.0.0.0:* UNCONN 0 0 0.0.0.0:58847 0.0.0.0:* UNCONN 0 0 10.0.2.15%enp0s3:bootpc 0.0.0.0:* UNCONN 0 0 [::]:mdns [::]:* UNCONN 0 0 [::]:44725 [::]:* $ ss -tl State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 5 127.0.0.1:ipp 0.0.0.0:* LISTEN 0 5 [::1]:ipp [::]:*
Non-listening and listening sockets (-a)
Now, if we want to see all TCP or UDP ports in established and listening states, we can use the -a option.
$ ss -ua State Recv-Q Send-Q Local Address:Port Peer Address:Port UNCONN 0 0 224.0.0.251:mdns 0.0.0.0:* UNCONN 0 0 224.0.0.251:mdns 0.0.0.0:* UNCONN 0 0 0.0.0.0:mdns 0.0.0.0:* UNCONN 0 0 0.0.0.0:58847 0.0.0.0:* UNCONN 0 0 10.0.2.15%enp0s3:bootpc 0.0.0.0:* UNCONN 0 0 [::]:mdns [::]:* UNCONN 0 0 [::]:44725 [::]:* $ ss -ta State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 5 127.0.0.1:ipp 0.0.0.0:* ESTAB 0 0 10.0.2.15:53292 172.217.168.66:https ESTAB 0 0 10.0.2.15:34152 216.58.215.238:http ESTAB 0 0 10.0.2.15:60396 216.58.215.228:https CLOSE-WAIT 1 0 10.0.2.15:41884 195.176.255.205:http ESTAB 0 0 10.0.2.15:43220 216.58.215.227:https CLOSE-WAIT 1 0 10.0.2.15:38740 195.176.255.204:http ESTAB 580 0 10.0.2.15:60068 216.58.215.238:https CLOSE-WAIT 1 0 10.0.2.15:55920 195.176.255.206:http ESTAB 0 0 10.0.2.15:60064 216.58.215.238:https ESTAB 580 0 10.0.2.15:43240 216.58.215.227:https ESTAB 580 0 10.0.2.15:32936 172.217.168.67:https ESTAB 0 0 10.0.2.15:34028 216.58.194.195:https LISTEN 0 5 [::1]:ipp [::]:*
Do not resolve hostnames and port numbers (-n)
The -n option prevents the resolution of hostnames and port numbers:
Here, we see ports 443 instead of HTTPS, for example:
$ ss -tan State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 5 127.0.0.1:631 0.0.0.0:* ESTAB 0 0 10.0.2.15:53292 172.217.168.66:443 CLOSE-WAIT 1 0 10.0.2.15:34152 216.58.215.238:80 ESTAB 0 0 10.0.2.15:60396 216.58.215.228:443 CLOSE-WAIT 1 0 10.0.2.15:41884 195.176.255.205:80 CLOSE-WAIT 1 0 10.0.2.15:38740 195.176.255.204:80 ESTAB 580 0 10.0.2.15:60068 216.58.215.238:443 CLOSE-WAIT 1 0 10.0.2.15:55920 195.176.255.206:80 ESTAB 0 0 10.0.2.15:60064 216.58.215.238:443 ESTAB 580 0 10.0.2.15:43240 216.58.215.227:443 ESTAB 580 0 10.0.2.15:32936 172.217.168.67:443 ESTAB 0 0 10.0.2.15:34028 216.58.194.195:443 LISTEN 0 5 [::1]:631 [::]:*
Print the process id and name
To see the process id (PID) and name using the socket, we can use the -p option.
Here is an example where we can see Google Chrome, using the PID 13596, browsing an HTTPS web page:
$ ss -tp State Recv-Q Send-Q Local Address:Port Peer Address:Port ESTAB 0 0 10.0.2.15:53308 172.217.168.66:https users:(("chrome",pid=13596,fd=41)) ESTAB 0 0 10.0.2.15:42728 172.217.168.78:https users:(("chrome",pid=13596,fd=37)) ESTAB 0 0 10.0.2.15:53314 172.217.168.66:https users:(("chrome",pid=13596,fd=47))
Timer information
With the -o option, the timer information is displayed, for example:
$ ss -tpo State Recv-Q Send-Q Local Address:Port Peer Address:Port Process ESTAB 0 0 10.0.2.15:37652 216.58.215.238:http users:(("chrome",pid=7493,fd=42)) timer:(keepalive,28sec,0) ESTAB 0 0 10.0.2.15:59288 193.134.255.73:http users:(("chrome",pid=7493,fd=44)) timer:(keepalive,28sec,0) ESTAB 0 0 10.0.2.15:37954 172.217.168.46:https users:(("chrome",pid=7493,fd=30)) timer:(keepalive,30sec,0) ESTAB 0 0 10.0.2.15:34172 172.217.25.163:https users:(("chrome",pid=7493,fd=58)) timer:(keepalive,43sec,0) ESTAB 0 0 10.0.2.15:55900 216.58.215.225:https users:(("chrome",pid=7493,fd=39)) timer:(keepalive,14sec,0) ESTAB 0 0 10.0.2.15:54376 216.58.215.238:https users:(("chrome",pid=7493,fd=49)) timer:(keepalive,40sec,0) ESTAB 0 0 10.0.2.15:58426 172.217.168.35:https users:(("chrome",pid=7493,fd=40)) timer:(keepalive,24sec,0) ESTAB 0 0 10.0.2.15:54332 216.58.215.238:https users:(("chrome",pid=7493,fd=29)) timer:(keepalive,14sec,0) ESTAB 0 0 10.0.2.15:52244 193.134.255.72:https users:(("chrome",pid=7493,fd=38)) timer:(keepalive,14sec,0) ESTAB 0 0 10.0.2.15:49672 172.217.168.67:https users:(("chrome",pid=7493,fd=51)) timer:(keepalive,38sec,0) ESTAB 0 0 10.0.2.15:41776 216.58.215.227:https users:(("chrome",pid=7493,fd=41)) timer:(keepalive,28sec,0)
Summary protocols statistics
With the -s option, we can see the protocols statistics:
$ ss -s Total: 1467 TCP: 74 (estab 27, closed 1, orphaned 33, timewait 1) Transport Total IP IPv6 RAW 3 2 1 UDP 221 213 8 TCP 73 64 9 INET 297 279 18 FRAG 0 0 0
Useful options combination
Here is an example, to see if an IPv4 service is listening:
$ ss -tunlp4
Where:
- -t Show TCP ports.
- -u Show UDP ports.
- -n Do not try to resolve hostnames.
- -l Show only listening ports.
- -p Show the processes that are using a particular socket.
- -4 Show only IPv4 sockets.
State filters
Another very nice option available with the ss command is the ability to filter using TCP states.
The syntax is:
$ ss [OPTIONS] [FILTER]
We can use the following filters:
- established
- syn-sent
- syn-recv
- fin-wait-1
- fin-wait-2
- time-wait
- closed
- close-wait
- last-ack
- listening
- closing
There are also some predefined combinations of states:
- all – All of the above states
- connected – All the states except for listen and closed
- synchronized – All the connected states except for syn-sent
- bucket – Show states, which are maintained as minisockets, i.e. time-wait and syn-recv.
- big – Opposite to bucket state.
Here is an example to see the TCP sessions in established state:
$ ss -t state established Recv-Q Send-Q Local Address:Port Peer Address:Port Process 0 0 10.0.2.15:39074 172.217.168.10:https 0 0 10.0.2.15:53094 172.217.168.78:http 0 0 10.0.2.15:49696 172.217.168.67:https 0 0 10.0.2.15:41776 216.58.215.227:https
Or, to see all IPv4 sockets in listening state:
$ ss -4 state listening
Address filters
As we can filter using state, we can also filter by address or port number.
First example: first I will list all IPv4 (-4) established sessions, then I will filter to see only the session with destination 193.247.171.26:
$ ss -4 state established Netid Recv-Q Send-Q Local Address:Port Peer Address:Port Process udp 0 0 10.0.2.15%enp0s3:bootpc 10.0.2.2:bootps tcp 0 0 10.0.2.15:35610 193.247.171.26:telnet $ ss -4 state established dst 193.247.171.26 Netid Recv-Q Send-Q Local Address:Port Peer Address:Port Process tcp 0 0 10.0.2.15:35610 193.247.171.26:telnet
Yes! It’s a telnet session, I hope you like legacy protocols 🙂
We can also filter on the source address, if your server has multiple interfaces, with the src filter:
$ ss -4 state established src 10.0.2.15
Note, we can also use CIDR notation:
$ ss -4 state established dst 193.247.0.0/16 Netid Recv-Q Send-Q Local Address:Port Peer Address:Port Process tcp 0 0 10.0.2.15:35618 193.247.171.26:telnet
Ports filters
To filter on the port number or application, the syntax is this:
$ ss -4 state established dport = :telnet Netid Recv-Q Send-Q Local Address:Port Peer Address:Port Process tcp 0 0 10.0.2.15:35618 193.247.171.26:telnet
dport and sport are the possible filters.
Then, we can use the application name (ssh, telnet, HTTP, HTTPS, etc…) or the port number (22, 23, 80, 443, etc…).
We can also use port ranges. For example, to see all sockets using a source port greater than 1023:
$ ss -nt sport \> :1023 State Recv-Q Send-Q Local Address:Port Peer Address:Port Process CLOSE-WAIT 1 0 10.0.2.15:37652 216.58.215.238:80 CLOSE-WAIT 1 0 10.0.2.15:59288 193.134.255.73:80 CLOSE-WAIT 57 0 10.0.2.15:34172 172.217.25.163:443 CLOSE-WAIT 1 0 10.0.2.15:52244 193.134.255.72:443 CLOSE-WAIT 1 0 10.0.2.15:44792 193.134.255.72:80
If we use special characters, we must add a backslash in front, like above. Otherwise, use “le”, “ge”, “eq”, etc.
The options are:
- <= or le : Less than or equal to port
- >= or ge : Greater than or equal to port
- == or eq : Equal to port
- != or ne : Not equal to port
- < or lt : Less than port
- > or gt : Greater than port
For example:
$ ss -nt sport gt :1023 is the same as: $ ss -nt sport \> :1023
Then, we can combine everything:
$ ss state established '( dport = :telnet or sport = :telnet and dst 193.247.0.0/16 )' Netid Recv-Q Send-Q Local Address:Port Peer Address:Port Process tcp 0 0 10.0.2.15:35618 193.247.171.26:telnet
Other examples
Display all TCP sockets:
ss -t -a
Display all TCP sockets with process SELinux security contexts:
ss -taZ
Display all UDP sockets:
ss -ua
Display all (in and out) established ssh connections:
ss -o state established '( dport = :ssh or sport = :ssh )'
Display all outgoing established HTTP and HTTPS connections:
ss -o state established '( dport = :http or dport = :https )'
Find all local processes connected to X server:
ss -x src /tmp/.X11-unix/*
List all the TCP sockets in state FIN-WAIT-1 for our web server, to network 193.233.7/24 and look at their timers:
ss -o state fin-wait-1 '( sport = :http or sport = :https )' dst 193.233.7/24
List sockets in all states from all socket tables but TCP:
ss -a -A 'all,!tcp'
Read more
Other posts of the series
This post is part of a series of Linux Networking tips and tricks.
The other posts of this series are: