Investigate Sockets when Working with Linux System
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.