lsof 常用技巧
发表于|更新于
|阅读量:
前言
lsof: lists openfiles. 在 Unix 中一切(包括网络套接口)都是文件。
例如:
- 普通文件
- 目录
- 符号链接
- 面向块的设备文件
- 面向字符的设备文件
- 管道和命名管道
- 套接字
- …
关键选项 
 理解一些关于 lsof 如何工作的关键性东西是很重要的。最重要的是,当你给它传递选项时,默认行为是对结果进行“或”运算。因此,如果你正是用 -i 来拉出一个端口列表,同时又用 -p 来拉出一个进程列表,那么默认情况下你会获得两者的结果。
下面的一些其它东西需要牢记:
- 默认 : 没有选项,lsof 列出活跃进程的所有打开文件
- 组合 : 可以将选项组合到一起,如 -abc,但要当心哪些选项需要参数
- -a : 结果进行“与”运算(而不是“或”)
- -l : 在输出显示用户 ID 而不是用户名
- -h : 获得帮助
- -t : 仅获取进程 ID
- -U : 获取 UNIX 套接口地址
- -F : 格式化输出结果,用于其它命令。可以通过多种方式格式化,如 -F pcfn(用于进程 id、命令名、文件描述符、文件名,并以空终止)
1. 获取网络信息 
 正如我所说的,我主要将 lsof 用于获取关于系统怎么和网络交互的信息。这里提供了关于此信息的一些主题:
1.1 使用 -i 显示所有连接 
 语法: lsof -i[46] [protocol][@hostname|hostaddr][:service|port]
| 12
 3
 4
 5
 6
 
 | #  lsof  -i
 COMMAND  PID USER   FD   TYPE DEVICE SIZE NODE NAME
 dhcpcd 6061 root 4u  IPv4  4510 UDP *:bootpc
 sshd  7703 root 3u  IPv6  6499 TCP *:ssh  (LISTEN)
 sshd  7892 root 3u  IPv6  6757 TCP 10.10.1.5:ssh->192.168.1.5:49901  (ESTABLISHED)
 
 | 
使用-i 6 仅获取 IPv6 流量
仅显示 TCP 连接(同理可获得 UDP 连接)
你也可以通过在 -i 后提供对应的协议来仅仅显示 TCP 或者 UDP 连接信息。
| 12
 3
 4
 5
 
 | lsof  -iTCP
 COMMAND  PID USER   FD   TYPE DEVICE SIZE NODE NAME
 sshd  7703 root 3u  IPv6  6499 TCP *:ssh  (LISTEN)
 sshd  7892 root 3u  IPv6  6757 TCP 10.10.1.5:ssh->192.168.1.5:49901  (ESTABLISHED)
 
 | 
使用 -i :port 来显示与指定端口相关的网络信息 
 或者,你也可以通过端口搜索,这对于要找出什么阻止了另外一个应用绑定到指定端口实在是太棒了。
| 12
 3
 4
 5
 
 | #  lsof  -i :22
 COMMAND  PID USER   FD   TYPE DEVICE SIZE NODE NAME
 sshd  7703 root 3u  IPv6  6499 TCP *:ssh  (LISTEN)
 sshd  7892 root 3u  IPv6  6757 TCP 10.10.1.5:ssh->192.168.1.5:49901  (ESTABLISHED)
 
 | 
使用 @host 来显示指定到指定主机的连接 
 这对于你在检查是否开放连接到网络中或互联网上某个指定主机的连接时十分有用。
| 12
 3
 
 | #  lsof  -i@172.16.12.5
 sshd  7892 root 3u  IPv6  6757 TCP 10.10.1.5:ssh->172.16.12.5:49901  (ESTABLISHED)
 
 | 
使用 @host:port 显示基于主机与端口的连接 
 你也可以组合主机与端口的显示信息。
| 12
 3
 
 | 
 sshd  7892 root 3u  IPv6  6757 TCP 10.10.1.5:ssh->172.16.12.5:49901  (ESTABLISHED)
 
 | 
找出监听端口 
 找出正等候连接的端口。
也可以 grep “LISTEN”来完成该任务。
| 12
 3
 
 | 
 iTunes 400 daniel 16u  IPv4  0x4575228  0t0 TCP *:daap (LISTEN)
 
 | 
找出已建立的连接 
 你也可以显示任何已经连接的连接。
也可以通过 grep 搜索“ESTABLISHED”来完成该任务。
| 12
 3
 
 | 
 3.  firefox-b 169 daniel 49u  IPv4  0t0 TCP 1.2.3.3:1863->1.2.3.4:http (ESTABLISHED)
 
 | 
2. 获取用户信息 
 你也可以获取各种用户的信息,以及它们在系统上正干着的事情,包括它们的网络活动、对文件的操作等。
使用 -u 显示指定用户打开了什么
| 12
 3
 4
 5
 6
 7
 8
 9
 
 | lsof  -u daniel
 -- snipped --
 Dock  155 daniel  txt REG 14,2  2798436  823208  /usr/lib/libicucore.A.dylib
 Dock  155 daniel  txt REG 14,2  1580212  823126  /usr/lib/libobjc.A.dylib
 Dock  155 daniel  txt REG 14,2  2934184  823498  /usr/lib/libstdc++.6.0.4.dylib
 Dock  155 daniel  txt REG 14,2  132008  823505  /usr/lib/libgcc_s.1.dylib
 Dock  155 daniel  txt REG 14,2  212160  823214  /usr/lib/libauto.dylib
 -- snipped --
 
 | 
使用 -u user 来显示除指定用户以外的其它所有用户所做的事情
| 12
 3
 4
 5
 6
 7
 8
 9
 
 | 
 -- snipped --
 Dock  155 jim  txt REG 14,2  2798436  823208  /usr/lib/libicucore.A.dylib
 Dock  155 jim  txt REG 14,2  1580212  823126  /usr/lib/libobjc.A.dylib
 Dock  155 jim  txt REG 14,2  2934184  823498  /usr/lib/libstdc++.6.0.4.dylib
 Dock  155 jim  txt REG 14,2  132008  823505  /usr/lib/libgcc_s.1.dylib
 Dock  155 jim  txt REG 14,2  212160  823214  /usr/lib/libauto.dylib
 -- snipped --
 
 | 
杀死指定用户所做的一切事情 
 可以消灭指定用户运行的所有东西,这真不错。
3. 命令和进程 
 可以查看指定程序或进程由什么启动,这通常会很有用,而你可以使用 lsof 通过名称或进程 ID 过滤来完成这个任务。下面列出了一些选项:
使用 -c 查看指定的命令正在使用的文件和网络连接
| 12
 3
 4
 5
 6
 7
 
 | 1.  
 3.  COMMAND    PID USER   FD   TYPE     DEVICE    SIZE       NODE NAME
 4.  syslog-ng 7547 root  cwd    DIR 3,3  4096  2  /
 5.  syslog-ng 7547 root  rtd    DIR 3,3  4096  2  /
 6.  syslog-ng 7547 root  txt    REG 3,3  113524  1064970  /usr/sbin/syslog-ng
 7.  -- snipped --
 
 | 
使用 -p 查看指定进程 ID 已打开的内容
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 
 | 1.  
 3.  -- snipped --
 4.  sshd  10068 root  mem    REG 3,3  34808  850407  /lib/libnss_files-2.4.so
 5.  sshd  10068 root  mem    REG 3,3  34924  850409  /lib/libnss_nis-2.4.so
 6.  sshd  10068 root  mem    REG 3,3  26596  850405  /lib/libnss_compat-2.4.so
 7.  sshd  10068 root  mem    REG 3,3  200152  509940  /usr/lib/libssl.so.0.9.7
 8.  sshd  10068 root  mem    REG 3,3  46216  510014  /usr/lib/liblber-2.3
 9.  sshd  10068 root  mem    REG 3,3  59868  850413  /lib/libresolv-2.4.so
 10.  sshd  10068 root  mem    REG 3,3  1197180  850396  /lib/libc-2.4.so
 11.  sshd  10068 root  mem    REG 3,3  22168  850398  /lib/libcrypt-2.4.so
 12.  sshd  10068 root  mem    REG 3,3  72784  850404  /lib/libnsl-2.4.so
 13.  sshd  10068 root  mem    REG 3,3  70632  850417  /lib/libz.so.1.2.3
 14.  sshd  10068 root  mem    REG 3,3  9992  850416  /lib/libutil-2.4.so
 15.  -- snipped --
 
 | 
-t选项只返回 PID
4. 文件和目录 
 通过查看指定文件或目录,你可以看到系统上所有正与其交互的资源——包括用户、进程等。
显示与指定目录交互的所有一切
| 12
 3
 4
 
 | 1.  
 3.  COMMAND    PID USER   FD   TYPE DEVICE   SIZE   NODE NAME
 4.  syslog-ng 7547 root 4w REG 3,3  217309  834024  /var/log/messages
 
 | 
显示与指定文件交互的所有一切
5. 高级用法 
 与tcpdump类似,当你开始组合查询时,它就显示了它强大的功能。
显示 daniel 连接到 1.1.1.1 所做的一切
| 12
 3
 
 | 1.  #  lsof  -u daniel -i @1.1.1.1
 3.  bkdr 1893 daniel 3u  IPv6  3456 TCP 10.10.1.10:1234->1.1.1.1:31337  (ESTABLISHED)
 
 | 
同时使用 -t 和 -c 选项以给进程发送 HUP 信号
lsof +L1 显示所有打开的链接数小于 1 的文件 
 这通常(当不总是)表示某个攻击者正尝试通过删除文件入口来隐藏文件内容。
显示某个端口范围的打开的连接
结尾 
 本入门教程只是管窥了 lsof 功能的一斑,要查看完整参考,运行 man lsof 命令或查看  在线版本 。希望本文对你有所助益,也随时 欢迎你的评论和指正。
资源
本文由 Daniel Miessler 撰写,首次在他  博客  上贴出
一般 root 用户才能执行 lsof 命令,普通用户可以看见 /usr/sbin/lsof 命令,
但是普通用户执行会显示“permission denied”
我总结一下 lsof 指令的用法:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 
 | lsof abc.txt 显示开启文件 abc.txt 的进程 
 lsof -i :22 知道 22 端口现在运行什么程序
 
 lsof -c abc 显示 abc 进程现在打开的文件
 
 lsof -g gid 显示归属 gid 的进程情况
 
 lsof +d /usr/local/ 显示目录下被进程开启的文件
 
 lsof +D /usr/local/ 同上,但是会搜索目录下的目录,时间较长
 
 lsof -d 4 显示使用 fd 为 4 的进程  [www.2cto.com](http://www.2cto.com)
 
 lsof -i 用以显示符合条件的进程情况
 
 语法: lsof -i[46] [protocol][@hostname|hostaddr][:service|port]
 
 46 --> IPv4 or IPv6
 
 protocol --> TCP or UDP
 
 hostname --> Internet host name
 
 hostaddr --> IPv4 位置
 
 service --> /etc/service 中的 service name (可以不只一个)
 
 port --> 端口号 (可以不只一个)
 
 例子: TCP:25 - TCP and port 25
 
 @1.2.3.4 - Internet IPv4 host address 1.2.3.4
 
 [tcp@ohaha.ks.edu.tw](mailto:tcp@ohaha.ks.edu.tw):ftp - TCP protocol [hosthaha.ks.edu.tw](http://hosthaha.ks.edu.tw) service name:ftp
 
 lsof -n 不将 IP 转换为 hostname,缺省是不加上 -n 参数
 
 例子: lsof -i [tcp@ohaha.ks.edu.tw](mailto:tcp@ohaha.ks.edu.tw):ftp -n
 
 lsof -p 12 看进程号为 12 的进程打开了哪些文件
 
 lsof +|-r [t] 控制 lsof 不断重复执行,缺省是 15s 刷新
 
 -r,lsof 会永远不断的执行,直到收到中断信号
 
 +r,lsof 会一直执行,直到没有档案被显示
 
 例子:不断查看目前 ftp 连接的情况:lsof -i [tcp@ohaha.ks.edu.tw](mailto:tcp@ohaha.ks.edu.tw):ftp -r
 
 lsof -s 列出打开文件的大小,如果没有大小,则留下空白
 
 lsof -u username 以 UID,列出打开的文件  [www.2cto.com](http://www.2cto.com)
 
 | 
原文转载自 https://www.jianshu.com/p/a3aa6b01b2e1