Investigate Sockets when Working with Linux System

cables connected to ethernet ports
Photo by Brett Sayles on Pexels.com

If you do work with Linux Servers or Linux Systems like me, you must have heard about the command “ss“. If you are not sure, you might know “netstat“. Netstat is obsolete now. The features it provided now can be obtained or achieved by “ss” and some other commands.
If you check the man page of Netstat you will find these lines.

This program is mostly obsolete.  Replacement for netstat is ss.
       Replacement for netstat -r is ip route.  Replacement for netstat
       -i is ip -s link.  Replacement for netstat -g is ip maddr.

You can also find some replacements table from this google spreadsheet link.

I am not going to talk about the legacy command of “netstat“. The purpose of this article will be about “ss“.

SS tool collects the network information directly from the kernel via sockets API. I will share some commands and expected results from that.

But, first, let me ask you the question which is an example of what you can ask SS.

How to find the process id of a port that is open for connection?

# ss -tulpn | grep ":22 "
Netid   State    Recv-Q   Send-Q      Local Address:Port      Peer Address:Port  Process                                                                   
tcp     LISTEN   0        128               0.0.0.0:22             0.0.0.0:*      users:(("sshd",pid=756,fd=3))                                    
tcp     LISTEN   0        128                  [::]:22                [::]:*      users:(("sshd",pid=756,fd=4))                             

Let me break down the command and its outputs. To be clear, I have added the heading. It is not supposed to be there as I grepped the lines having a port. For better understanding, I did add the line.
Here,

       -t, --tcp
              Display TCP sockets.
       -u, --udp
              Display UDP sockets.
       -l, --listening
              Display only listening sockets (these are omitted by
              default).
       -p, --processes
              Show process using socket.
       -n, --numeric
              Do not try to resolve service names. Show exact bandwidth
              values, instead of human-readable.

You will not be able to view all the process information without “root” user. After finding the process id you can go further with “ps” command.

How many connections right now in a particular port and what are the IP addresses of those connections are from?

# ss -t -a  | grep ssh
LISTEN    0      128           0.0.0.0:ssh               0.0.0.0:*           
ESTAB     0      36     SERVER_PUBLIC_IP:ssh         CLIENTS_IP:58852       
LISTEN    0      128              [::]:ssh                  [::]:*

You can test this by doing telnet SERVER_PUBLIC_IP 22 to test using the above command. It will have another connection with “ESTAB”.
This command is not pretty. We can achieve the same goal by using only SS.

ss -o state established '( dport = :ssh or sport = :ssh )'
Netid       Recv-Q        Send-Q                Local Address:Port                Peer Address:Port        Process                          
tcp         0             0                    SERVER_PUBLIC_IP:ssh                CLIENTS_IP1:58852        timer:(keepalive,87min,0)       
tcp         0             0                    SERVER_PUBLIC_IP:ssh                 CLIENTS_IP2:45892        timer:(keepalive,118min,0)

How to find connections to certain ports from specific IP addresses? Also, you want to close the connections other than specific IP addresses. How?

# ss -o state established '( dport = :ssh or sport = :ssh not dst = ALLOWED_IP )' -p
Netid          Recv-Q          Send-Q                    Local Address:Port                    Peer Address:Port           Process          
tcp            0               0                        SERVER_PUBLIC_IP:ssh                    CLIENT_IP:53750           users:(("ssh",pid=894,fd=13))

The result is pretty clear. It is searching for SSH connection and also filtering the result where IP is not the allowed one. If you add “-K” at the above command, it will close all the connections that are found through the filter.

ss -o state established '( dport = :ssh or sport = :ssh not dst = ALLOWED_IP )' -p -k

I guess that is it for today. I will share my other experience with SS and associated or extended commands with a similar purpose later.

Thanks for reading.