lsof(查看端口)
阅读原文时间:2023年07月15日阅读:1

简介
lsof(list open files)是一个列出当前系统打开文件的工具。在linux环境下,任何事物都以文件的形式存在,通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件。所以如传输控制协议 (TCP) 和用户数据报协议 (UDP) 套接字等,系统在后台都为该应用程序分配了一个文件描述符,无论这个文件的本质如何,该文件描述符为应用程序与基础操作系统之间的交互提供了通用接口。因为应用程序打开文件的描述符列表提供了大量关于这个应用程序本身的信息,因此通过lsof工具能够查看这个列表对系统监测以及排错将是很有帮助的。

语法:

$ lsof (选项)

选项:

选项

描述

-a

列出打开文件存在的进程;

-c<进程名>

列出指定进程所打开的文件;

-g

列出GID号进程详情;

-d<文件号>

列出占用该文件号的进程;

+d<目录>

列出目录下被打开的文件;

+D<目录>

递归列出目录下被打开的文件;

-n<目录>

列出使用NFS的文件;

-i<条件>

列出符合条件的进程。(4、6、协议、:端口、 @ip

-p<进程号>

列出指定进程号所打开的文件;

-u

列出UID号进程详情;

-h

显示帮助信息;

-v

显示版本信息。

在终端下输入lsof即可显示系统打开的文件,因为 lsof 需要访问核心内存和各种文件,所以必须以 root 用户的身份运行它才能够充分地发挥其功能。

直接输入lsof部分输出为:

$ lsof

    COMMAND     PID        USER   FD      TYPE             DEVICE SIZE/OFF       NODE NAME
    init          1        root  cwd       DIR                8,1     4096          2 /
    init          1        root  rtd       DIR                8,1     4096          2 /
    init          1        root  txt       REG                8,1   150584     654127 /sbin/init
    udevd       415        root    0u      CHR                1,3      0t0       6254 /dev/null
    udevd       415        root    1u      CHR                1,3      0t0       6254 /dev/null
    udevd       415        root    2u      CHR                1,3      0t0       6254 /dev/null
    udevd       690        root  mem       REG                8,1    51736     302589 /lib/x86_64-linux-gnu/libnss_files-2.13.so
    syslogd    1246      syslog    2w      REG                8,1    10187     245418 /var/log/auth.log
    syslogd    1246      syslog    3w      REG                8,1    10118     245342 /var/log/syslog
    dd         1271        root    0r      REG                0,3        0 4026532038 /proc/kmsg
    dd         1271        root    1w     FIFO               0,15      0t0        409 /run/klogd/kmsg
    dd         1271        root    2u      CHR                1,3      0t0       6254 /dev/null

lsof输出各列信息的意义如下:

  • COMMAND:进程的名称

  • PID:进程标识符

  • USER:进程所有者

  • FD:文件描述符,应用程序通过文件描述符识别该文件。如cwd、txt等 TYPE:文件类型,如DIR、REG等

  • TYOE:文件类型

  • DEVICE:指定磁盘的名称

  • SIZE:文件的大小

  • NODE:索引节点(文件在磁盘上的标识)

  • NAME:打开文件的确切名称

FD文件描述符列表

  • cwd:表示current work dirctory,即:应用程序的当前工作目录,这是该应用程序启动的目录,除非它本身对这个目录进行更改
  • txt:该类型的文件是程序代码,如应用程序二进制文件本身或共享库,如上列表中显示的 /sbin/init 程序
  • lnn:library references (AIX)(库引用);
  • er:FD information error (see NAME column)(fd信息错误);
  • jld:jail directory (FreeBSD)(监控目录);
  • ltx:shared library text (code and data)(共享库文本);
  • mxx :hex memory-mapped type number xx(十六进制内存映射类型号xx);
  • m86:DOS Merge mapped file(DOS合并映射文件);
  • mem:memory-mapped file(内存映射文件);
  • mmap:memory-mapped device(内存映射设备);
  • pd:parent directory(父目录);
  • rtd:root directory(跟目录);
  • tr:kernel trace file (OpenBSD)(内核跟踪文件);
  • v86 VP/ix mapped file(VP/IX映射文件);
  • 0:表示标准输出
  • 1:表示标准输入
  • 2:表示标准错误

文件类型:

  • DIR:表示目录。
  • CHR:表示字符类型。
  • BLK:块设备类型。
  • UNIX: UNIX 域套接字。
  • FIFO:先进先出 (FIFO) 队列。
  • IPv4:网际协议 (IP) 套接字。
  • DEVICE:指定磁盘的名称
  • SIZE:文件的大小
  • NODE:索引节点(文件在磁盘上的标识)
  • NAME:打开文件的确切名称

一般在标准输出、标准错误、标准输入后还跟着文件状态模式:

  • u:表示该文件被打开并处于读取/写入模式。
  • r:表示该文件被打开并处于只读模式。
  • w:表示该文件被打开并处于。
  • 空格:表示该文件的状态模式为unknow,且没有锁定。
  • -:表示该文件的状态模式为unknow,且被锁定。

同时在文件状态模式后面,还跟着相关的锁:

  • N:for a Solaris NFS lock of unknown type(对于未知类型的Solaris NFS锁);

  • r:for read lock on part of the file(用于对文件的一部分进行读取锁定);

  • R:for a read lock on the entire file(整个文件的读取锁定);

  • w:for a write lock on part of the file;(文件的部分写锁)

  • W:for a write lock on the entire file;(整个文件的写锁)

  • u:for a read and write lock of any length(对于任意长度的读写锁);

  • U:for a lock of unknown type(对于未知类型的锁);

  • x:for an SCO OpenServer Xenix lock on part of the file(对于文件的sco openserver xenix锁);

  • X:for an SCO OpenServer Xenix lock on the entire file(对于整个文件的sco openserver xenix锁);

  • space:if there is no lock(如果没有锁).

    #列出所有打开的文件:
    lsof
    备注: 如果不加任何参数,就会打开所有被打开的文件,建议加上一下参数来具体定位

    查看谁正在使用某个文件

    lsof /filepath/file

    #递归查看某个目录的文件信息
    lsof +D /filepath/filepath2/
    备注: 使用了+D,对应目录下的所有子目录和文件都会被列出

    比使用+D选项,遍历查看某个目录的所有文件信息 的方法

    lsof | grep ‘/filepath/filepath2/’

    列出某个用户打开的文件信息

    lsof -u username
    备注: -u 选项,u其实是user的缩写

    列出某个程序所打开的文件信息

    lsof -c mysql
    备注: -c 选项将会列出所有以mysql开头的程序的文件,其实你也可以写成lsof | grep mysql,但是第一种方法明显比第二种方法要少打几个字符了

    列出多个程序多打开的文件信息

    lsof -c mysql -c apache

    列出某个用户以及某个程序所打开的文件信息

    lsof -u test -c mysql

    列出除了某个用户外的被打开的文件信息

    lsof -u ^root
    备注:^这个符号在用户名之前,将会把是root用户打开的进程不让显示

    通过某个进程号显示该进行打开的文件

    lsof -p 1

    列出多个进程号对应的文件信息

    lsof -p 123,456,789

    列出除了某个进程号,其他进程号所打开的文件信息

    lsof -p ^1

    列出所有的网络连接

    lsof -i

    列出所有tcp 网络连接信息

    lsof -i tcp

    列出所有udp网络连接信息

    lsof -i udp

    列出谁在使用某个端口

    lsof -i :3306

    列出谁在使用某个特定的udp端口

    lsof -i udp:55

    特定的tcp端口

    lsof -i tcp:80

    列出某个用户的所有活跃的网络端口

    lsof -a -u test -i

    列出所有网络文件系统

    lsof -N

    #域名socket文件
    lsof -u

    #某个用户组所打开的文件信息
    lsof -g 5555

    根据文件描述列出对应的文件信息

    lsof -d description(like 2)

    根据文件描述范围列出文件信息

    lsof -d 2-3

命令详解

关键选项

 usage: [-?abhlnNoOPRtUvV] [+|-c c] [+|-d s] [+D D] [+|-f[cgG]]
 [-F [f]] [-g [s]] [-i [i]] [+|-L [l]] [+|-M] [-o [o]] [-p s]
 [+|-r [t]] [-s [p:s]] [-S [t]] [-T [t]] [-u s] [+|-w] [-x [fl]] [--] [names]

理解一些关于lsof如何工作的关键性东西是很重要的。最重要的是,当你给它传递选项时,默认行为是对结果进行“或”运算。因此,如果你正是用-i来拉出一个端口列表,同时又用-p来拉出一个进程列表,那么默认情况下你会获得两者的结果。

下面的一些其它东西需要牢记:

默认 : 没有选项,lsof列出活跃进程的所有打开文件
组合 : 可以将选项组合到一起,如-abc,但要当心哪些选项需要参数
-a : 结果进行“与”运算(而不是“或”)
-l : 在输出显示用户ID而不是用户名
-h : 获得帮助
-t : 仅获取进程ID
-U : 获取UNIX套接口地址
-F : 格式化输出结果,用于其它命令。可以通过多种方式格式化,如-F pcfn(用于进程id、命令名、文件描述符、文件名,并以空终止)

获取网络信息

使用-i显示所有连接

有些人喜欢用netstat来获取网络连接,但是我更喜欢使用lsof来进行此项工作。结果以对我来说很直观的方式呈现,我仅仅只需改变我的语法,就可以通过同样的命令来获取更多信息。

语法: lsof -i[46] [protocol][@hostname|hostaddr][:service|port]

1. $ lsof  -i

2. COMMAND  PID USER   FD   TYPE DEVICE SIZE NODE NAME
3. dhcpcd 6061 root 4u  IPv4  4510 UDP *:bootpc
4. sshd  7703 root 3u  IPv6  6499 TCP *:ssh  (LISTEN)
5. sshd  7892 root 3u  IPv6  6757 TCP 10.10.1.5:ssh->192.168.1.5:49901  (ESTABLISHED)

使用-i 6仅获取IPv6流量

$ lsof -i 6

仅显示-iTCP连接(同理可获得UDP连接)

$ lsof -iTCP

COMMAND     PID USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
rapportd    249 alon    3u  IPv4 0xbf4f51b061be171d      0t0  TCP *:62740 (LISTEN)
rapportd    249 alon    4u  IPv6 0xbf4f51b0709f2fdd      0t0  TCP *:62740 (LISTEN)
rapportd    249 alon   10u  IPv4 0xbf4f51b06aaa1d9d      0t0  TCP alon-mbp:62740->alon:51824 (ESTABLISHED)

使用-i:port来显示与指定端口相关的网络信息

或者,你也可以通过端口搜索,这对于要找出什么阻止了另外一个应用绑定到指定端口实在是太棒了。
$ lsof -i:8080

COMMAND PID USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
nginx   442 alon    7u  IPv4 0xbf4f51b06b5f071d      0t0  TCP *:http-alt (LISTEN)
nginx   474 alon    7u  IPv4 0xbf4f51b06b5f071d      0t0  TCP *:http-alt (LISTEN)

使用-i@host来显示指定到指定主机的连接

这对于你在检查是否开放连接到网络中或互联网上某个指定主机的连接时十分有用。

$ lsof -i@192.168.1.3    //ssh服务器地址

COMMAND   PID USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
ssh     13971 alon    3u  IPv4 0xbf4f51b065af171d      0t0  TCP alon-mbp:63001->redminote5a-hongmish:ssh (ESTABLISHED)

使用-i@host:port显示基于主机与端口的连接

你也可以组合主机与端口的显示信息。

$ lsof -i@192.168.1.3:22  //ssh服务器地址

COMMAND   PID USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
ssh     13971 alon    3u  IPv4 0xbf4f51b065af171d      0t0  TCP alon-mbp:63001->redminote5a-hongmish:ssh (ESTABLISHED)

找出监听端口

找出正等候连接的端口。

$ lsof -i -sTCP:LISTEN
你也可以grep “LISTEN”来完成该任务。

$ lsof  -i |  grep  -i LISTEN

 iTunes 400 daniel 16u  IPv4  0x4575228  0t0 TCP *:daap (LISTEN)

找出已建立的连接

你也可以显示任何已经连接的连接。

$ lsof -i -sTCP:ESTABLISHED

你也可以通过grep搜索“ESTABLISHED”来完成该任务。

$ lsof  -i |  grep  -i ESTABLISHED

firefox-b 169 daniel 49u  IPv4  0t0 TCP 1.2.3.3:1863->1.2.3.4:http (ESTABLISHED)

用户信息

你也可以获取各种用户的信息,以及它们在系统上正干着的事情,包括它们的网络活动、对文件的操作等。

使用-u显示指定用户打开了什么

$ lsof -u alon

Dock        258 alon  cwd       DIR                1,4         960           2 /
Dock        258 alon  txt       REG                1,4     5468560 12885166254 /System/Library/CoreServices/Dock.app/Contents/MacOS/Dock
Dock        258 alon  txt       REG                1,4       65556 12892552336 /Library/Caches/com.apple.iconservices.store/822428C4-1B74-4D07-3A23-9F4D9799678E.isdata
Dock        258 alon  txt       REG                1,4       21104 12895185769 /Library/Preferences/Logging/.plist-cache.BdSX1osv
Dock        258 alon  txt       REG                1,4    27154336 12885622695 /usr/share/icu/icudt62l.dat
Dock        258 alon  txt       REG                1,4      239648 12887956801 /private/var/db/timezone/tz/2019c.1.0/icutz/icutz44l.dat
Dock        258 alon  txt       REG                1,4       21960 12894991454 /Library/Application Support/CrashReporter/SubmitDiagInfo.domains
Dock        258 alon  txt       REG                1,4        4116 12892587129 /Library/Caches/com.apple.iconservices.store/54ADF811-CE68-A6FB-3ADC-D61EF5134EEB.isdata

使用-u ^ user来显示除指定用户以外的其它所有用户所做的事情

 $ lsof -u ^alon
Dock        258 root  cwd       DIR                1,4         960           2 /
Dock        258 root  txt       REG                1,4     5468560 12885166254 /System/Library/CoreServices/Dock.app/Contents/MacOS/Dock

杀死指定用户所做的一切事情

可以消灭指定用户运行的所有东西,这真不错。

$ kill -9 `lsof -t -u daniel`

命令和进程

可以查看指定程序或进程由什么启动,这通常会很有用,而你可以使用lsof通过名称或进程ID过滤来完成这个任务。下面列出了一些选项:

使用-c查看指定的命令正在使用的文件和网络连接

$ lsof  -c syslog-ng

COMMAND    PID USER   FD   TYPE     DEVICE    SIZE       NODE NAME
 syslog-ng 7547 root  cwd    DIR 3,3  4096  2  /
syslog-ng 7547 root  rtd    DIR 3,3  4096  2  /
syslog-ng 7547 root  txt    REG 3,3  113524  1064970  /usr/sbin/syslog-ng
-- snipped --

使用-p查看指定进程ID已打开的内容

$  lsof  -p 10075

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

$  lsof  -t -c Mail

350

文件和目录

通过查看指定文件或目录,你可以看到系统上所有正与其交互的资源——包括用户、进程等。

显示与指定目录交互的所有一切

$ lsof  /var/log/messages/

COMMAND    PID USER   FD   TYPE DEVICE   SIZE   NODE NAME
syslog-ng 7547 root 4w REG 3,3  217309  834024  /var/log/messages

显示与指定文件交互的所有一切

$ lsof  /home/daniel/firewall_whitelist.txt
高级用法

与tcpdump类似,当你开始组合查询时,它就显示了它强大的功能。

显示alon连接到1.1.1.1所做的一切

$ lsof  -u daniel -i @1.1.1.1

bkdr 1893 daniel 3u  IPv6  3456 TCP 10.10.1.10:1234->1.1.1.1:31337  (ESTABLISHED)

同时使用-t和-c选项以给进程发送 HUP 信号

$ kill -HUP `lsof -t -c sshd`

lsof +L1显示所有打开的链接数小于1的文件

这通常(当不总是)表示某个攻击者正尝试通过删除文件入口来隐藏文件内容。

$ lsof  +L1

(hopefully nothing)

显示某个端口范围的打开的连接

$ lsof -i @fw.google.com:2150=2180

简书: 西华子(Linux 命令神器:lsof)

lsof-wiki