How can I find out which process is opening a specific tcp port?
I usually use the fuser command to check the pid opening a specific tcp port as shown below.
fuser 22/tcp //To get pid opening the 22 tcp port
I have a reference board that is running embedded linux. It already opens tcp port 22 for ssh connection. But the fuser does not display anything about the 22 ports. So I tried another ssh daemon to open port 322 and then tried to check the pid with the fuser, it worked fine.
root@imx6qsabreauto:~# netstat -nlt | grep 22
tcp 0 0 0.0.0.0:4224 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:322 0.0.0.0:* LISTEN
tcp 0 0 :::322 :::* LISTEN
tcp 0 0 :::22 :::* LISTEN
root@imx6qsabreauto:~# fuser 322/tcp
351
root@imx6qsabreauto:~# ps -ef | grep 351
root 351 1 0 01:46 ? 00:00:00 /usr/sbin/dropbear -r /etc/dropbear/dropbear_rsa_host_key -p 322 -B
root 379 315 0 02:11 ttymxc3 00:00:00 grep 351
root@imx6qsabreauto:~# fuser 22/tcp
==> This output nothing !!
How can I figure out which process is opening tcp port 22. (On the board, the lsof command is not available, and .. netstat does not have the -p option.)
source to share
You have installed /proc
and bash
and readlink
installed, you can write a small bash script, which analyzes /proc/net/tcp
and scans /proc/*/fd/
to find the appropriate socket.
I'm not very familiar with embedded linux, but if you can't find it readlink
, it might be included in busybox
.
/proc/net/tcp
is something like
sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
0: 00000000:4E7A 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 13128 1 ffff8800cf960740 99 0 0 10 0
local_address
is a hex string HOST:PORT
, so the script does a search :0016
if you want to find tcp port 22.
As soon as it finds the line containing :0016
in local_address
,
inode
- the corresponding socket number.
Then it looks for /proc/*/fd/*
which one has the socket number using the command readlink
.
#!/bin/bash
PORT="$1"
HEX_PORT=$(printf %04X $PORT)
INODE=""
if ! [ "$PORT" ];then
echo "usage $0 [PORT]"
exit
fi
while read num host_port _ _ _ _ _ _ _ inode _; do
if [[ $host_port =~ :"$HEX_PORT"$ ]];then
INODE=$inode
fi
done < /proc/net/tcp
if ! [ "$INODE" ];then
echo "no process using $PORT"
exit
fi
for fn in /proc/[1-9]*/fd/*; do
if [ "$(readlink $fn)" = "socket:[$INODE]" ];then
tmp=${fn%/fd*}
echo ${tmp#/proc/}
fi
done
source to share
Thanks @ymonad !! :) As your mention, I was able to get the pid corresponding to the port as shown below.
root@imx6qsabreauto:~# cat /proc/net/tcp
sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
0: 00000000:1080 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 1018 1 d8d90a00 100 0 0 10 0
1: 00000000:0DA2 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 842 1 d8d90000 100 0 0 10 0
2: 00000000:006F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 2515 1 d8dc8000 100 0 0 10 0
3: 0100007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 877 1 d8d90500 100 0 0 10 0
root@imx6qsabreauto:~# cat /proc/net/tcp6
sl local_address remote_address st tx_queue rx_queue tr tm->when retrnsmt uid timeo
ut inode
0: 00000000000000000000000000000000:006F 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000 0
0 2518 1 d8dd0000 100 0 0 10 -1
1: 00000000000000000000000001000000:0035 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000 0
0 881 1 d8de0000 100 0 0 10 -1
2: 00000000000000000000000000000000:0016 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000 0
0 4933 1 d8da0000 100 0 0 10 -1
Your shell script is working fine, it can get the pid correctly like below.
root@imx6qsabreauto:~# /tmp/find.sh 22
1
The odd thing is the result of pid - 1. This is the init process ;;
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 04:21 ? 00:00:04 /sbin/init
I think I need to know more about how init process opens tcp port 22. Thanks a lot.: D I learned a lot. Thanks again!!
source to share