读取“/proc”以了解进程是否打开了端口

读取“/proc”以了解进程是否打开了端口

我需要知道具有给定 PID 的进程是否在不使用外部命令的情况下打开了端口。然后我必须使用/proc文件系统。例如,我可以读取该/proc/$PID/net/tcp文件并获取有关进程打开的 TCP 端口的信息。但是,在多线程进程上,该/proc/$PID/task/$TID目录还将包含一个net/tcp文件。我的问题是:

我是否需要检查所有线程net/tcp文件,或者将线程打开的端口写入进程net/tcp文件中。

答案1

例如,我可以读取 /proc/$PID/net/tcp 文件并获取有关进程打开的 TCP 端口的信息。

该文件不是由过程。它是当前网络命名空间中所有打开的tcp端口的列表,对于在同一网络命名空间中运行的进程来说是完全相同的的内容/proc/net/tcp

要查找进程打开的端口,您需要从 获取套接字描述符列表/proc/<pid>/fd,然后将这些描述符与inode的字段进行匹配/proc/net/tcp

答案2

cat /proc/$PID/net/tcp

你会得到这样的输出

  sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode
  0: 00000000:01BB 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 2891985097 1 0000000000000000 100 0 0 10 0

local_address输出的第二列 ( ) 以十六进制显示端口。使用编程计算器将十六进制代码转换为十进制。

例如,端口 :01BB(十六进制)等于 443(十进制),这是 HTTPS 默认端口。

答案3

作为旁注,/proc/net/tcp已被 取代NETLINK_SOCK_DIAG,它本质上以二进制形式为您提供相同的数据,并且根据实现者的说法,比从/proc/...文件夹中读取更快、更安全。

有库(libmnl是基础库),并且该功能在许多语言中都可用(C/C++ 可以直接访问这些库,Go 和 Python 有扩展,我认为 perl 也有,当然还有许多其他语言)。

由于您没有透露您使用的是哪种语言,因此目前很难说更多。我在 Stackoverflow 上有一个 C 示例实现:https://stackoverflow.com/questions/68425240/can-the-netlink-sock-diag-interface-be-used-to-listen-for-listen-and-close

答案4

下面是示例脚本,它发现套接字描述符的 inode 并显示已打开此套接字的正在运行的进程的 PID。

port=9090;
hex_port=$(python -c 'print(hex('$port')[2:])');
inode=$(cat /proc/net/tcp | grep ":$hex_port" | awk '{print $10}');
for i in $(ps axo pid); do  
   ls -l /proc/$i/fd 2> /dev/null | grep -q ":\[$inode\]" &&  echo $i;
done

相关内容