Let’s say you have a socket that is listening on a particular port. How do you find the process that is listening on a port just by using the Linux Proc FS or /proc
filesystem?
Before getting your hands dirty, make sure that you have root access to the Linux system.
Find Process Listening on TCP Port
Get the TCP network connections list by running the netstat
command.
1 2 3 4 5 6 7 |
# netstat -tan Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 0.0.0.0:8834 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN tcp 1 0 192.168.10.11:60689 91.189.94.25:80 CLOSE_WAIT |
Now, let’s say that we want to find out the process that is listening on port 80. First, we convert the port number from decimal to hexadecimal. So, port 80 becomes 0x50 (in hexadecimal).
Next, we will need to retrieve information from the proc
filesystem. For TCP connections, we will need to analyse the /proc/net/tcp
file. We will need to filter for source port 0x0050 (hexadecimal for port 80 and zero padded to 4 digits) and the state must be 0x0A – LISTEN state.
1 2 3 4 |
# cat /proc/net/tcp | head -1 ; cat /proc/net/tcp | grep :0050 sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode 2: 00000000:0050 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 8516 1 ffff8801fec69a00 100 0 0 10 -1 7: 0B0AA8C0:ED11 195EBD5B:0050 08 00000000:00000001 00:00000000 00000000 107 0 10813 1 ffff8801fec6b400 74 4 16 10 -1 |
We have got 2 entries. The first entry has the state 0x0A which is in the LISTEN
state and the source port is 0x50. The second entry’s source port is 0xED11, destination port is 0x50 and state is 0x08 which is the CLOSE_WAIT
state. We are interested in the first entry. From the first entry, we can get the socket inode number – 8516
.
Once we have retrieved the socket inode number, we will have to scan through all the processes to determine which process has a open file descriptor that points to a socket with inode number 8516
.
1 2 3 4 |
# find /proc/*/fd/* -type l 2>/dev/null | xargs ls -l 2>/dev/null | grep 'socket:\[8516\]' lrwx------ 1 root root 64 Jun 29 15:23 /proc/1044/fd/3 -> socket:[8516] lrwx------ 1 root root 64 Jun 29 15:23 /proc/17843/fd/3 -> socket:[8516] lrwx------ 1 root root 64 Jun 29 15:23 /proc/17844/fd/3 -> socket:[8516] |
Based on the find command, we can see that PIDs (or process IDs) 1044
, 17843
and 17844
are listening on port 80. To determine the process names of the PIDs, use the ps
command.
1 2 3 4 5 |
# ps -fp 1044,17843,17844 UID PID PPID C STIME TTY TIME CMD root 1044 1 0 15:03 ? 00:00:00 /usr/sbin/apache2 -k start www-data 17843 1044 0 15:22 ? 00:00:00 /usr/sbin/apache2 -k start www-data 17844 1044 0 15:22 ? 00:00:00 /usr/sbin/apache2 -k start |
We can now conclude that the apache2
process is listening on port 80. The apache2
process with PID 1044
is the correct one as that’s the parent process of the other two processes.
Find Process Listening on UDP Port
The way to determine processes listening on UDP ports is similar to what we have seen for TCP ports. The only difference is the file that we need to work on. For UDP, use the /proc/net/udp
file. Let’s go through an example to find the process listening on UDP port 68.
1 2 3 4 5 6 7 8 |
netstat -unp Active Internet connections (w/o servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name root@builder:~# netstat -uan Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State udp 0 0 0.0.0.0:59994 0.0.0.0:* udp 0 0 0.0.0.0:68 0.0.0.0:* |
UDP port 68 is 0x44 in hexadecimal.
1 2 3 |
# cat /proc/net/udp | head -1 ; cat /proc/net/udp | grep 0044 sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode ref pointer drops 2084: 00000000:0044 00000000:0000 07 00000000:00000000 00:00000000 00000000 0 0 7347 2 ffff8801ffd1c000 0 |
Socket inode number is 7347
.
1 2 |
# find /proc/*/fd/* -type l 2>/dev/null | xargs ls -l 2>/dev/null | grep 'socket:\[7347\]' lrwx------ 1 root root 64 Jun 29 15:23 /proc/648/fd/6 -> socket:[7347] |
1 2 3 |
# ps -p 648 PID TTY TIME CMD 648 ? 00:00:00 dhclient3 |
The process listening on UDP port 68 is called dhclient3
.
Find Process Listening on IPv6 TCP or UDP Ports
If the system is running on IPv6, you will need to use the /proc/net/tcp6
file for IPv6 TCP ports and /proc/net/udp6
file for IPv6 UDP ports.