簡介
簡介
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