如何调查在linux中的某个进程打开的端口?

假设进程的PID是已知的

netstat --all --program | grep '3265' 

显示监听和非监听套接字。
– 程序显示套接字所属程序的PID和名称。

您也可以使用端口扫描程序,如nmap。

你可以使用下面的命令:

 lsof -i -P |grep pid 

作为一个方面的说明,netstat -ao将读取/ proc / PID / tcp等来查看进程打开的端口。 这意味着它的系统提供的读取信息(linux KERNEL),而不是直接查看networking接口或其他方式。 同样适用于lsof。

如果你这样做是一个安全措施,你失败了。 即使你100%确定你正在运行一个真正的netstat程序(而不是一个troyned版本)或任何其他读取/ proc文件系统的程序,永远不要(从来没有)信任netstat的输出。 有些人似乎认为netstat,ls,ps或任何其他的标准unix工具都会从源头上获得某种魔法和轮询信息,事实是所有这些都依赖于/ proc文件系统来获取所有的数据,这可以很容易地被rootkit或pipe理程序颠覆。

您可以使用带有-p命令行参数的netstat命令行工具:

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

示例部分给出了这个例子:

显示由id为pid的进程打开的所有端口
netstat -ao | find“pid”

在一些embedded式设备或旧的Linux中,问题是netstat没有–process或-p选项是可用的。 以下脚本显示了使用其IP和端口的过程,您必须是root用户。

 #!/bin/bash for protocol in tcp udp ; do #echo "protocol $protocol" ; for ipportinode in `cat /proc/net/tcp | 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 

输出es喜欢

 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 

我已经添加了IPv6支持并做了一些修复。 另外在我的系统上,IP地址的八位字节是相反的。 依赖只是posix shell,awk和剪切。

我的版本可以在Github上find

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