如何在Linux中查找进程ID打开的端口?

发布于 2024-07-22 03:43:46 字数 17 浏览 6 评论 0原文

假设进程的PID已知

Suppose the PID of the process is already known

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

贪恋 2024-07-29 03:43:46
netstat --all --program | grep '3265'
  • --all 显示监听和非监听套接字。
  • --program 显示socket所属程序的PID和名称。

您还可以使用端口扫描器,例如 Nmap。

netstat --all --program | grep '3265'
  • --all show listening and non-listening sockets.
  • --program show the PID and name of the program to which socket belongs.

You could also use a port scanner such as Nmap.

岁月染过的梦 2024-07-29 03:43:46

您可以使用以下命令:

lsof -i -P |grep pid

You can use the command below:

lsof -i -P |grep pid
懒的傷心 2024-07-29 03:43:46

附带说明一下,netstat -ao 将读取 /proc/PID/tcp 等以查看进程打开的端口。 这意味着它读取的信息是由系统(linux KERNEL)提供的,而绝不是直接通过网络接口或其他方式查找。
lsof 也是如此。

如果您这样做是为了安全措施,那么您就失败了。 你永远不应该(永远)相信 netstat 的输出,即使你 100% 确定你实际上正在运行一个真正的 netstat 程序(而不是木马版本)或任何其他读取 /proc 文件系统的程序。 有些人似乎认为 netstat、ls、ps 或任何其他标准 unix 工具会执行某种魔法并从源轮询信息,事实是它们都依赖于 /proc 文件系统来获取所有数据,这很容易被 rootkit 或虚拟机管理程序破坏。

As a side note, netstat -ao will read the /proc/PID/tcp etc to see the ports opened by the process. This means that its reading information supplied by the system (the linux KERNEL), and is in no way directly looking on the network interface or other means.
Same goes for lsof.

If you are doing this as a security measure, you failed. You should never (NEVER EVER) trust the output of netstat, even if you are 100% sure you are in fact running a real netstat program (as opposed to a trojaned version) or any other program that reads the /proc filesystem. Some people seem to think that netstat, ls, ps or any other of the standard unix tools do some sort of magic and poll information from the sources, the truth is all of them rely on the /proc filesystem to get all of their data, which can be easily subverted by a rootkit or hypervisor.

少女净妖师 2024-07-29 03:43:46

您可以将 netstat 命令行工具与 -p 命令结合使用行参数:

-p (Linux):

进程:显示哪些进程正在使用哪些套接字(类似于Windows下的-b)。 您必须是 root 才能执行此操作。

示例部分给出了以下示例:

显示 ID 为 $PID 的进程打开的所有端口:

netstat -ao |   grep '\b'$PID'\b' 
  

You can use the netstat command line tool with the -p command line argument:

-p (Linux):

Process: Show which processes are using which sockets (similar to -b under Windows). You must be root to do this.

The example section gives this example:

To display all ports open by a process with id $PID:

netstat -ao | grep '\b'$PID'\b'
笑红尘 2024-07-29 03:43:46

在某些嵌入式设备或旧版本的 Linux 中,问题是 netstat 没有可用的 --process-p 选项。

以下脚本显示了进程及其 IP 和端口,您必须是 root。

#!/bin/bash

for protocol in tcp udp ; 
do 
    #echo "protocol $protocol" ; 
    for ipportinode in `cat /proc/net/${protocol} | awk '/.*:.*:.*/{print $2"|"$3"|"$10 ;}'` ; 
    do 
        #echo "#ipportinode=$ipportinode"
        inode=`echo "$ipportinode" | cut -d"|" -f3` ;
        if [ "#$inode" = "#" ] ; then continue ; fi 
        lspid=`ls -l /proc/*/fd/* 2>/dev/null | grep "socket:\[$inode\]" 2>/dev/null` ; 
        pid=`echo "lspid=$lspid" | awk 'BEGIN{FS="/"} /socket/{print $3}'` ;
        if [ "#$pid" = "#" ] ; then continue ; fi
        exefile=`ls -l /proc/$pid/exe | awk 'BEGIN{FS=" -> "}/->/{print $2;}'`
        #echo "$protocol|$pid|$ipportinode" 
        echo "$protocol|$pid|$ipportinode|$exefile" | awk '
            BEGIN{FS="|"}
            function iphex2dec(ipport){ 
                ret=sprintf("%d.%d.%d.%d:    %d","0x"substr(ipport,1,2),"0x"substr(ipport,3,2),
                "0x"substr(ipport,5,2),"0x"substr(ipport,7,2),"0x"substr(ipport,10,4)) ;
                if( ret == "0.0.0.0:0" ) #compatibility others awk versions 
                {
                    ret=        strtonum("0x"substr(ipport,1,2)) ;
                    ret=ret "." strtonum("0x"substr(ipport,3,2)) ;
                    ret=ret "." strtonum("0x"substr(ipport,5,2)) ;
                    ret=ret "." strtonum("0x"substr(ipport,7,2)) ;
                    ret=ret ":" strtonum("0x"substr(ipport,10)) ;
                }
                return ret ;
            }
            { 
            print $1" pid:"$2" local="iphex2dec($3)" remote="iphex2dec($4)" inode:"$5" exe=" $6 ;  
            }
            ' ; 
        #ls -l /proc/$pid/exe ; 
    done ; 
done

输出如下:

tcp pid:1454 local=1.0.0.127:5939 remote=0.0.0.0:0 inode:13955 exe=/opt/teamviewer/tv_bin/teamviewerd
tcp pid:1468 local=1.1.0.127:53 remote=0.0.0.0:0 inode:12757 exe=/usr/sbin/dnsmasq
tcp pid:1292 local=0.0.0.0:22 remote=0.0.0.0:0 inode:12599 exe=/usr/sbin/sshd
tcp pid:4361 local=1.0.0.127:631 remote=0.0.0.0:0 inode:30576 exe=/usr/sbin/cupsd
tcp pid:1375 local=1.0.0.127:5432 remote=0.0.0.0:0 inode:12650 exe=/usr/lib/postgresql/9.3/bin/postgres

In some embedded devices or with old version of Linux, the problem is netstat do not have --process or -p options available.

The following script shows process with its IP and port, you must be root.

#!/bin/bash

for protocol in tcp udp ; 
do 
    #echo "protocol $protocol" ; 
    for ipportinode in `cat /proc/net/${protocol} | awk '/.*:.*:.*/{print $2"|"$3"|"$10 ;}'` ; 
    do 
        #echo "#ipportinode=$ipportinode"
        inode=`echo "$ipportinode" | cut -d"|" -f3` ;
        if [ "#$inode" = "#" ] ; then continue ; fi 
        lspid=`ls -l /proc/*/fd/* 2>/dev/null | grep "socket:\[$inode\]" 2>/dev/null` ; 
        pid=`echo "lspid=$lspid" | awk 'BEGIN{FS="/"} /socket/{print $3}'` ;
        if [ "#$pid" = "#" ] ; then continue ; fi
        exefile=`ls -l /proc/$pid/exe | awk 'BEGIN{FS=" -> "}/->/{print $2;}'`
        #echo "$protocol|$pid|$ipportinode" 
        echo "$protocol|$pid|$ipportinode|$exefile" | awk '
            BEGIN{FS="|"}
            function iphex2dec(ipport){ 
                ret=sprintf("%d.%d.%d.%d:    %d","0x"substr(ipport,1,2),"0x"substr(ipport,3,2),
                "0x"substr(ipport,5,2),"0x"substr(ipport,7,2),"0x"substr(ipport,10,4)) ;
                if( ret == "0.0.0.0:0" ) #compatibility others awk versions 
                {
                    ret=        strtonum("0x"substr(ipport,1,2)) ;
                    ret=ret "." strtonum("0x"substr(ipport,3,2)) ;
                    ret=ret "." strtonum("0x"substr(ipport,5,2)) ;
                    ret=ret "." strtonum("0x"substr(ipport,7,2)) ;
                    ret=ret ":" strtonum("0x"substr(ipport,10)) ;
                }
                return ret ;
            }
            { 
            print $1" pid:"$2" local="iphex2dec($3)" remote="iphex2dec($4)" inode:"$5" exe=" $6 ;  
            }
            ' ; 
        #ls -l /proc/$pid/exe ; 
    done ; 
done

The output is like:

tcp pid:1454 local=1.0.0.127:5939 remote=0.0.0.0:0 inode:13955 exe=/opt/teamviewer/tv_bin/teamviewerd
tcp pid:1468 local=1.1.0.127:53 remote=0.0.0.0:0 inode:12757 exe=/usr/sbin/dnsmasq
tcp pid:1292 local=0.0.0.0:22 remote=0.0.0.0:0 inode:12599 exe=/usr/sbin/sshd
tcp pid:4361 local=1.0.0.127:631 remote=0.0.0.0:0 inode:30576 exe=/usr/sbin/cupsd
tcp pid:1375 local=1.0.0.127:5432 remote=0.0.0.0:0 inode:12650 exe=/usr/lib/postgresql/9.3/bin/postgres
ゃ懵逼小萝莉 2024-07-29 03:43:46

通过ls可以知道进程的路线。

示例:

fuser 25/tcp

fuser 命令表示进程为:2054

ls -l /proc/2054/exe

进程路径显示

提取自:https://www.sysadmit.com/2018/06/linux-que-proceso-usa-un-puerto.html

图像示例

With ls you can know the process route.

Example:

fuser 25/tcp

The fuser command says that the process is: 2054

ls -l /proc/2054/exe

The process path appears

Extracted from: https://www.sysadmit.com/2018/06/linux-que-proceso-usa-un-puerto.html

Image example

苍暮颜 2024-07-29 03:43:46

我添加了 IPv6 支持并进行了一些修复。 另外,在我的系统上,IP 地址的八位字节是相反的。 依赖项仅针对 posix shell、awk 和 cut。

我的版本可以在
Github

#!/bin/sh


# prints all open ports from /proc/net/* 
#
# for pretty output (if available) start with 
# ./linux-get-programm-to-port.sh | column -t -s 
\t' 


#set -x

ip4hex2dec () {
    local ip4_1octet="0x${1%???????????}"

    local ip4_2octet="${1%?????????}"
    ip4_2octet="0x${ip4_2octet#??}"

    local ip4_3octet="${1%???????}"
    ip4_3octet="0x${ip4_3octet#????}"

    local ip4_4octet="${1%?????}"
    ip4_4octet="0x${ip4_4octet#??????}"

    local ip4_port="0x${1##*:}"

    # if not used inverse
    #printf "%d.%d.%d.%d:%d" "$ip4_1octet" "$ip4_2octet" "$ip4_3octet" "$ip4_4octet" "$ip4_port"
    printf "%d.%d.%d.%d:%d" "$ip4_4octet" "$ip4_3octet" "$ip4_2octet" "$ip4_1octet" "$ip4_port"
}


# reoder bytes, byte4 is byte1 byte2 is byte3 ...
reorderByte(){
    if [ ${#1} -ne 8 ]; then echo "missuse of function reorderByte"; exit; fi

    local byte1="${1%??????}"

    local byte2="${1%????}"
    byte2="${byte2#??}"

    local byte3="${1%??}"
    byte3="${byte3#????}"

    local byte4="${1#??????}"

    echo "$byte4$byte3:$byte2$byte1"
}

# on normal intel platform the byte order of the ipv6 address in /proc/net/*6 has to be reordered.
ip6hex2dec(){
    local ip_str="${1%%:*}"
    local ip6_port="0x${1##*:}"
    local ipv6="$(reorderByte ${ip_str%????????????????????????})"
    local shiftmask="${ip_str%????????????????}"
    ipv6="$ipv6:$(reorderByte ${shiftmask#????????})"
    shiftmask="${ip_str%????????}"
    ipv6="$ipv6:$(reorderByte ${shiftmask#????????????????})"
    ipv6="$ipv6:$(reorderByte ${ip_str#????????????????????????})"
    ipv6=$(echo $ipv6 | awk '{ gsub(/(:0{1,3}|^0{1,3})/, ":"); sub(/(:0)+:/, "::");print}')
    printf "%s:%d" "$ipv6" "$ip6_port"
}

for protocol in tcp tcp6 udp udp6 raw raw6; 
do 
    #echo "protocol $protocol" ; 
    for ipportinode in `cat /proc/net/$protocol | awk '/.*:.*:.*/{print $2"|"$3"|"$10 ;}'` ; 
    do 
        #echo "#ipportinode=$ipportinode"
        inode=${ipportinode##*|}
        if [ "#$inode" = "#" ] ; then continue ; fi 

        lspid=`ls -l /proc/*/fd/* 2>/dev/null | grep "socket:\[$inode\]" 2>/dev/null` ; 
        pids=`echo "$lspid" | awk 'BEGIN{FS="/"} /socket/{pids[$3]} END{for (pid in pids) {print pid;}}'` ;  # removes duplicats for this pid
        #echo "#lspid:$lspid  #pids:$pids"

        for pid in $pids; do
            if [ "#$pid" = "#" ] ; then continue ; fi
            exefile=`ls -l /proc/$pid/exe | awk 'BEGIN{FS=" -> "}/->/{print $2;}'`;
            cmdline=`cat /proc/$pid/cmdline`

            local_adr_hex=${ipportinode%%|*}
            remote_adr_hex=${ipportinode#*|}
            remote_adr_hex=${remote_adr_hex%%|*}

            if [ "#${protocol#???}" = "#6" ]; then
                local_adr=$(ip6hex2dec $local_adr_hex)
                remote_adr=$(ip6hex2dec $remote_adr_hex)
            else
        local_adr=$(ip4hex2dec $local_adr_hex)
        remote_adr=$(ip4hex2dec $remote_adr_hex)
            fi 

            echo "$protocol pid:$pid \t$local_adr \t$remote_adr \tinode:$inode \t$exefile $cmdline" 
    done
    done  
done

I've added IPv6 support and made a few fixes. Additionally on my system the octets of the IP address are reversed. Dependencies are only to posix shell, awk and cut.

My Version can be found on
Github

#!/bin/sh


# prints all open ports from /proc/net/* 
#
# for pretty output (if available) start with 
# ./linux-get-programm-to-port.sh | column -t -s 
\t' 


#set -x

ip4hex2dec () {
    local ip4_1octet="0x${1%???????????}"

    local ip4_2octet="${1%?????????}"
    ip4_2octet="0x${ip4_2octet#??}"

    local ip4_3octet="${1%???????}"
    ip4_3octet="0x${ip4_3octet#????}"

    local ip4_4octet="${1%?????}"
    ip4_4octet="0x${ip4_4octet#??????}"

    local ip4_port="0x${1##*:}"

    # if not used inverse
    #printf "%d.%d.%d.%d:%d" "$ip4_1octet" "$ip4_2octet" "$ip4_3octet" "$ip4_4octet" "$ip4_port"
    printf "%d.%d.%d.%d:%d" "$ip4_4octet" "$ip4_3octet" "$ip4_2octet" "$ip4_1octet" "$ip4_port"
}


# reoder bytes, byte4 is byte1 byte2 is byte3 ...
reorderByte(){
    if [ ${#1} -ne 8 ]; then echo "missuse of function reorderByte"; exit; fi

    local byte1="${1%??????}"

    local byte2="${1%????}"
    byte2="${byte2#??}"

    local byte3="${1%??}"
    byte3="${byte3#????}"

    local byte4="${1#??????}"

    echo "$byte4$byte3:$byte2$byte1"
}

# on normal intel platform the byte order of the ipv6 address in /proc/net/*6 has to be reordered.
ip6hex2dec(){
    local ip_str="${1%%:*}"
    local ip6_port="0x${1##*:}"
    local ipv6="$(reorderByte ${ip_str%????????????????????????})"
    local shiftmask="${ip_str%????????????????}"
    ipv6="$ipv6:$(reorderByte ${shiftmask#????????})"
    shiftmask="${ip_str%????????}"
    ipv6="$ipv6:$(reorderByte ${shiftmask#????????????????})"
    ipv6="$ipv6:$(reorderByte ${ip_str#????????????????????????})"
    ipv6=$(echo $ipv6 | awk '{ gsub(/(:0{1,3}|^0{1,3})/, ":"); sub(/(:0)+:/, "::");print}')
    printf "%s:%d" "$ipv6" "$ip6_port"
}

for protocol in tcp tcp6 udp udp6 raw raw6; 
do 
    #echo "protocol $protocol" ; 
    for ipportinode in `cat /proc/net/$protocol | awk '/.*:.*:.*/{print $2"|"$3"|"$10 ;}'` ; 
    do 
        #echo "#ipportinode=$ipportinode"
        inode=${ipportinode##*|}
        if [ "#$inode" = "#" ] ; then continue ; fi 

        lspid=`ls -l /proc/*/fd/* 2>/dev/null | grep "socket:\[$inode\]" 2>/dev/null` ; 
        pids=`echo "$lspid" | awk 'BEGIN{FS="/"} /socket/{pids[$3]} END{for (pid in pids) {print pid;}}'` ;  # removes duplicats for this pid
        #echo "#lspid:$lspid  #pids:$pids"

        for pid in $pids; do
            if [ "#$pid" = "#" ] ; then continue ; fi
            exefile=`ls -l /proc/$pid/exe | awk 'BEGIN{FS=" -> "}/->/{print $2;}'`;
            cmdline=`cat /proc/$pid/cmdline`

            local_adr_hex=${ipportinode%%|*}
            remote_adr_hex=${ipportinode#*|}
            remote_adr_hex=${remote_adr_hex%%|*}

            if [ "#${protocol#???}" = "#6" ]; then
                local_adr=$(ip6hex2dec $local_adr_hex)
                remote_adr=$(ip6hex2dec $remote_adr_hex)
            else
        local_adr=$(ip4hex2dec $local_adr_hex)
        remote_adr=$(ip4hex2dec $remote_adr_hex)
            fi 

            echo "$protocol pid:$pid \t$local_adr \t$remote_adr \tinode:$inode \t$exefile $cmdline" 
    done
    done  
done
小草泠泠 2024-07-29 03:43:46

这对我有用,是具有详细流程信息的唯一选项:

$ lsof | grep "1234"

1234 是我正在寻找的端口号。

This worked for me, was the only option with detailed process info:

$ lsof | grep "1234"

1234 is the port number I'm looking for.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文