根据socket端口号查看进程信息

根据已知的一个端口号,以telnet默认端口号23为例,去查找系统中监听该端口号的进程,主要可以通过下面3种方式。

netstat

使用netstat可以查看系统网络状态,-p参数可以显示对应的进程信息pid/process

$ netstat -anp |grep ":23"
tcp        0      0 192.168.1.1:23          0.0.0.0:*               LISTEN      3698/utelnetd
tcp        0      0 192.168.1.1:23          192.168.1.10:10381      ESTABLISHED 3698/utelnetd

从上面的信息中可以看到两条信息:

  1. 监听23端口的进程是pid为3698utelnetd
  2. 目前存在一个已连接的client,client IP为192.168.1.10,tcp连接端口为10381

lsof

Linux系统中,一切皆为文件,socket也不例外,而lsof指令用于list open files,能够显示系统所有已经打开的文件描述符,根据上面已知的进程pid或进程名称,可以grep到相关信息。

$ lsof |grep utelnetd
3698    /usr/sbin/utelnetd      /dev/console
3698    /usr/sbin/utelnetd      /dev/console
3698    /usr/sbin/utelnetd      /dev/null
3698    /usr/sbin/utelnetd      socket:[12882]
3698    /usr/sbin/utelnetd      socket:[349364]

可以看出,utelnetd打开了5个文件,对应5个fd(file descriptor)。前面3个分别对应标准输入stdin,标准输出stdout和标准错误输出stderr;接着的两个socket对应的就是netstat显示的1个socket server和1个socket client。

注:socket:[12882]信息中12882对应的是inode信息,后面proc信息中可以印证。

proc

除了上面两个指令外,proc文件系统中的信息也是非常常用的,根据已经的进程pid 3698,我们可以查看进程已打开的所有文件以及socket信息。

查看文件描述符

$ ls -l /proc/3698/fd/
lr-x------    1 root     root            64 Dec 20 07:57 0 -> /dev/console
l-wx------    1 root     root            64 Dec 20 07:57 1 -> /dev/console
l-wx------    1 root     root            64 Dec 20 07:57 2 -> /dev/null
lrwx------    1 root     root            64 Dec 20 07:57 3 -> socket:[12882]
lrwx------    1 root     root            64 Dec 20 07:57 4 -> socket:[349364]

前3个0,1,2对应的就是stdin,stdout和stderr;3,4对应的就是两条socket连接。

查看socket信息

$ cat /proc/3698/net/tcp
  sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode
     0: 00000000:0D05 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 13663 1 de008000 100 0 0 10 0
   1: 00000000:0050 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 28897 1 de008500 100 0 0 10 0
   2: 00000000:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 28962 1 de008f00 100 0 0 10 0
   3: 0101A8C0:0017 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 12882 1 dcd20000 100 0 0 10 0
   4: 00000000:01BB 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 28898 1 de008a00 100 0 0 10 0
   5: 0101A8C0:0017 0A01A8C0:288D 01 00000000:00000000 00:00000000 00000000     0        0 349364 1 de00b700 24 8 25 10 -1

这个文件显示的是当前进程相关的tcp连接信息,目前我们仅考虑端口号为23的连接,由于当前数据均为16进制,所以grep时使用23的16进制数17

$ grep "17\|sl" /proc/3698/net/tcp
  sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode
   3: 0101A8C0:0017 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 12882 1 dcd20000 100 0 0 10 0
   5: 0101A8C0:0017 0A01A8C0:288D 01 00000000:00000000 00:00000000 00000000     0        0 349364 1 de00b700 24 8 25 10 -1

可以看到两个信息,先看其一,local_address为0101A8C0:0017,解析如下:

01  01  A8  C0:  0017
1   1   168 192: 23

注意网络地址与本地地址的顺序,转换为10进制便是192.168.1.1:23,其对应的inode就是12882,与lsof看到的一致。

同理,第2条信息,本地地址一致,远程地址0A01A8C0:288D对应10进制192.168.1.10:10381与上述netstat看到的一致。

总结

根据端口号查找进程及端口相应的fd,可以通过netstat,lsof,proc文件系统3种方式协同完成。