linux下查看TCP端口所属进程/线程

来源:互联网 发布:手机淘宝注册店铺步骤 编辑:程序博客网 时间:2024/06/07 00:34

在linux下面经常会需要“进程打开了哪些端口,某端口是哪个进程打开的”相关信息,下面来看下如何获取这些信息。

注:"进程打开了哪些端口"与“某个端口属于哪个进程/线程”信息收集过程相近,只看“某个端口属于哪个进程/线程”情况

 

1 netstat查看端口及进程
用以下命令(需要root权限)查看端口及对应的进程

[redhat@localhost ~]$ su密码:[root@localhost redhat]# netstat -npta | grep 22tcp        0      0 0.0.0.0:22                  0.0.0.0:*                   LISTEN      1962/sshdtcp        0      0 :::22                       :::*                        LISTEN      1962/sshd

由于一些嵌入式平台的netstat并不支持-p选项:

# ls -l /bin/netstatlrwxrwxrwx    1 0        0               7 Jul 25 17:35 /bin/netstat -> busybox# netstat -pnetstat: invalid option -- pBusyBox v1.10.1 (2011-03-30 16:10:40 CST) multi-call binaryUsage: netstat [-laentuwxrW]Display networking informationOptions:        -l      Display listening server sockets        -a      Display all sockets (default: connected)        -e      Display other/more information        -n      Don't resolve names        -t      Tcp sockets        -u      Udp sockets        -w      Raw sockets        -x      Unix sockets        -r      Display routing table        -W      Display with no column truncation


下面跟踪下netstat是如何收集这些信息的,以便不使用netstat命令的情况下,也能知道某端口所属进程/线程

 

2 strace netstat
用strace来跟踪netstat -ntpa都干了什么

[root@localhost redhat]# strace netstat -ntpaexecve("/bin/netstat", ["netstat", "-ntpa"], [/* 47 vars */]) = 0brk(0)                                  = 0x9e2d000mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb78e6000access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)open("/etc/ld.so.cache", O_RDONLY)      = 3...open("/proc", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_CLOEXEC) = 3fcntl64(3, F_GETFD)                     = 0x1 (flags FD_CLOEXEC)getdents(3, /* 264 entries */, 32768)   = 4456open("/proc/1/fd", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_CLOEXEC) = 4getdents(4, /* 11 entries */, 32768)    = 176readlink("/proc/1/fd/0", "/dev/null"..., 29) = 9readlink("/proc/1/fd/1", "/dev/null", 29) = 9readlink("/proc/1/fd/2", "/dev/null", 29) = 9readlink("/proc/1/fd/3", "pipe:[8927]"..., 29) = 11readlink("/proc/1/fd/4", "pipe:[8927]", 29) = 11readlink("/proc/1/fd/5", "inotify"..., 29) = 7readlink("/proc/1/fd/6", "inotify", 29) = 7readlink("/proc/1/fd/7", "socket:[8928]"..., 29) = 13open("/proc/1/cmdline", O_RDONLY)       = 5read(5, "/sbin/init\0", 511)            = 11close(5)                                = 0open("/proc/1/attr/current", O_RDONLY|O_LARGEFILE) = 5read(5, "system_u:system_r:init_t:s0\0", 4095) = 28close(5)                                = 0open("/selinux/mls", O_RDONLY|O_LARGEFILE) = 5read(5, "1", 19)                        = 1close(5)                                = 0socket(PF_FILE, SOCK_STREAM|SOCK_CLOEXEC, 0) = 5connect(5, {sa_family=AF_FILE, path="/var/run/setrans/.setrans-unix"}, 110) = -1 ENOENT (No such file or directory)close(5)                                = 0readlink("/proc/1/fd/9", "socket:[12555]"..., 29) = 14open("/proc/1/attr/current", O_RDONLY|O_LARGEFILE) = 5read(5, "system_u:system_r:init_t:s0\0", 4095) = 28close(5)                                = 0getdents(4, /* 0 entries */, 32768)     = 0close(4)                                = 0open("/proc/2/fd", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_CLOEXEC) = 4getdents(4, /* 2 entries */, 32768)     = 32getdents(4, /* 0 entries */, 32768)     = 0close(4)                                = 0...write(1, "Active Internet connections (ser"..., 54Active Internet connections (servers and established)) = 54write(1, "Proto Recv-Q Send-Q Local Addres"..., 108Proto Recv-Q Send-Q Local Address               Foreign Address             State       PID/Program name   ) = 108open("/proc/net/tcp", O_RDONLY)         = 3fstat64(3, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7535000read(3, "  sl  local_address rem_address "..., 1024) = 900write(1, "tcp        0      0 0.0.0.0:22  "..., 109tcp        0      0 0.0.0.0:22                  0.0.0.0:*                   LISTEN      1962/sshd           ) = 109write(1, "tcp        0      0 127.0.0.1:63"..., 109tcp        0      0 127.0.0.1:631               0.0.0.0:*                   LISTEN      1656/cupsd          ) = 109write(1, "tcp        0      0 127.0.0.1:25"..., 109tcp        0      0 127.0.0.1:25                0.0.0.0:*                   LISTEN      2050/master         ) = 109write(1, "tcp        0      0 0.0.0.0:5286"..., 109tcp        0      0 0.0.0.0:52867               0.0.0.0:*                   LISTEN      1692/rpc.statd      ) = 109write(1, "tcp        0      0 0.0.0.0:111 "..., 109tcp        0      0 0.0.0.0:111                 0.0.0.0:*                   LISTEN      1596/rpcbind        ) = 109read(3, "", 1024)                       = 0close(3)                                = 0munmap(0xb7535000, 4096)                = 0[root@localhost redhat]# 

由以上信息可以看出,netstat -anpt做了如下几件事:
a.shell创建进程,exec netstat,ld装载netstat用到的动态链接库
b.通过遍历proc文件系统,收集进程打开的socket文件信息;/proc/pid/fd/目录下面文件为实际文件的软链接,socket文件为socket:[inodeno]
c.从/proc/net/tcp中收集tcp信息
d.通过inode号,将进程与tcp关联起来,并将信息整理输出


3 模拟netstat -p功能
3.1 查找socket对应的inode

[root@localhost redhat]# head -n 1 /proc/net/tcp && cat /proc/net/tcp | grep :0016  sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode   0: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 13828 1 ecb02140 299 0 0 2 -1

在linux中socket也可以如文件一样操作(如read/write),而对应的文件系统就是socketfs(挂载到内核,用户空间无法看到)
/proc/pid/fd/下面的socket文件,通常是socket:[inode]的软链接

3.2  根据socket文件inode号关联进程与socket

for dir in `find /proc -name "fd"`do    ls -l $dir | grep "socket\:\[13828\]" && echo $dirdone

for dir in `find /proc/ -name "fd"`; do ls -l $dir | grep 'socket\:\[13828\]' && echo $dir;done

结果为

[root@localhost redhat]# for dir in `find /proc -name "fd"`> do>     ls -l $dir | grep "socket\:\[13828\]" && echo $dir> donelrwx------. 1 root root 64 11月 21 19:19 3 -> socket:[13828]/proc/1962/task/1962/fdlrwx------. 1 root root 64 11月 21 19:04 3 -> socket:[13828]/proc/1962/fd[root@localhost redhat]# head -n 1 /proc/1962/statusName:sshd[root@localhost redhat]#

可以看到22端口是4162/sshd进程打开的

注:/proc/pid/task/下面是对应进程的线程(轻量级进程)信息

 

原创粉丝点击