首页 文章

如何确定哪个进程正在打开某个tcp端口?

提问于
浏览
3

我通常使用fuser命令检查pid打开某个tcp端口,如下所示

fuser 22/tcp //To get pid opening the 22 tcp port

我有一个运行嵌入式linux的参考板 . 它已经为ssh连接打开了22个tcp端口 . 但是热熔器不显示任何关于22端口的输出 . 所以我尝试了另一个ssh守护进程打开322端口,然后尝试使用fuser检查pid,它运行正常 .

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 !!

我怎样才能确定哪个进程正在打开tcp 22端口 . (在主板中,lsof命令不可用,并且.. netstat没有-p选项 . )

3 回答

  • 2

    我安装了 /proc 并安装了 bashreadlink ,您可以编写一个解析 /proc/net/tcp 的小bash脚本,并扫描 /proc/*/fd/ 以查找相应的套接字 .

    我对嵌入式linux不太熟悉,但是如果你找不到 readlink ,它可能会包含在 busybox 中 .

    /proc/net/tcp 是这样的

    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_addressHOST:PORT 的十六进制字符串,因此当您要搜索tcp 22端口时,脚本会搜索 :0016 .

    一旦它在 local_address 中找到包含 :0016 的行, inode 就是相应的套接字号 .

    然后它使用 readlink 命令搜索具有套接字号的 /proc/*/fd/* .

    #!/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
    
  • 0

    谢谢@ymonad !! :)正如你提到的,我已经能够获得对应于端口的pid,如下所示 .

    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
    

    你的shell脚本工作正常,它可以正常得到pid,如下所示 .

    root@imx6qsabreauto:~# /tmp/find.sh 22
    1
    

    奇怪的是结果pid是1.它是init进程;;

    UID        PID  PPID  C STIME TTY          TIME CMD
    root         1     0  0 04:21 ?        00:00:04 /sbin/init
    

    我想我需要弄清楚init进程如何打开22 tcp端口 . 真的很谢谢你 . :D我学到了很多东西 . 再次感谢 !!

  • 0

    这是在Tomato / BusyBox路由器上运行的ymonad脚本的一个版本:

    #!/bin/sh
    
    # This works with BusyBox on a Tomato router
    
    PORT="$1"
    HEX_PORT=`printf %04X $PORT`
    INODE=""
    if ! [ "$PORT" ]; then
        echo "Find the process that is listening on an open TCP network port."
        echo "usage $0 [PORT]"
        exit 2
    fi
    # sl localip:port remip:port st tx_q:rx_q tr:when retrns uid timeout inode ...
    while read num host_port _ _ _ _ _ _ _ inode _; do
        port=`echo "$host_port" | awk -F: '{print $2}'`
        if [ "$port" = "$HEX_PORT" ]; then
            INODE=$inode
        fi
    done < /proc/net/tcp
    if ! [ "$INODE" ]; then
        echo "no process using $PORT"
        exit 1
    fi
    echo "found inode $INODE"
    f=`ls -l /proc/[1-9]*/fd/* 2>/dev/null | fgrep "socket:[$INODE]" | awk '{print $9}'`
    if ! [ "$f" ] ; then
        echo "no process found using inode $INODE"
        exit 1
    fi
    pid=`echo "$f" | awk -F/ '{print $3}'`
    echo "Process matching PID=$pid:"
    ps w | awk "\$1==$pid {print}"
    

相关问题