Идентификация открытых файлов и сетевых подключений в Linux - lsof (примеры)

Lsof расшифровывает как List Open Files (список открытых файлов). Команда формирует список дескрипторов открытых файлов по процессам и именам файлов. В Линукс  все является файлами (очереди, сокеты, директории, устройства и т.д. ). Таким образом, с помощью Lsof, вы можете получить информацию о любых открытых файлов.

Автор утилиты - Вик Эйбелл из университета Пердью, штат Индиана. 
 
В большинстве дистрибутивом Linux, Lsof устанавливается по-умолчанию, во FreeBSD ее можно установить из портов - 
cd /usr/ports/sysutils/lsof
make install clean

1. Введение в lsof

Набрав в консоли lsof без ключей, мы получим все открытые файлы, принадлежащих всем активным процессам
$ sudo lsof | more
COMMAND     PID            USER   FD      TYPE             DEVICE  SIZE/OFF       NODE NAME
init          1            root  cwd       DIR               8,17      4096          2 /
init          1            root  rtd       DIR               8,17      4096          2 /
init          1            root  txt       REG               8,17    163096     393328 /sbin/init
init          1            root  mem       REG               8,17     26512    1180237 /lib/x86_64-linux-gnu/libnss_winbind.so.2
init          1            root  mem       REG               8,17     52120    1179940 /lib/x86_64-linux-gnu/libnss_files-2.15.so
init          1            root  mem       REG               8,17     47680    1179941 /lib/x86_64-linux-gnu/libnss_nis-2.15.so
init          1            root  mem       REG               8,17     97248    1179935 /lib/x86_64-linux-gnu/libnsl-2.15.so
init          1            root  mem       REG               8,17     35680    1179943 /lib/x86_64-linux-gnu/libnss_compat-2.15.so
init          1            root  mem       REG               8,17   1802936    1179931 /lib/x86_64-linux-gnu/libc-2.15.so
init          1            root  mem       REG               8,17     31752    1179937 /lib/x86_64-linux-gnu/librt-2.15.so
init          1            root  mem       REG               8,17    135366    1179951 /lib/x86_64-linux-gnu/libpthread-2.15.so
init          1            root  mem       REG               8,17    276392    1179728 /lib/x86_64-linux-gnu/libdbus-1.so.3.5.8
init          1            root  mem       REG               8,17     38888    1179928 /lib/x86_64-linux-gnu/libnih-dbus.so.1.0.0
init          1            root  mem       REG               8,17     96240    1179953 /lib/x86_64-linux-gnu/libnih.so.1.0.0
init          1            root  mem       REG               8,17    149280    1179933 /lib/x86_64-linux-gnu/ld-2.15.so
init          1            root    0u      CHR                1,3       0t0       1029 /dev/null
init          1            root    1u      CHR                1,3       0t0       1029 /dev/null
.......
Как можно увидеть из листинга, один и тот же процесс открывает много файлов, каждому из которых соответствует строка в выводе lsof . Название колонок говорят сами за себя, так что мы остановимся толькор на 2-х (FD и TYPE)
 
FD - показывает файловый дескриптор, некоторые возможные значения:
 
cwd – текущая рабочая
директория
txt – текстовый файл
mem – Memory mapped file (файл загруженный в память )
mmap – Memory mapped device
Число - номер файлового дескриптора, сопровождается символом, указывающим режим, в котором файл был открыт - r -для чтения; w – для записи; u - для чтения и записи.
 
TYPE – столбец показывает тип файла, некоторые возможные значения:
 
REG – обычный файл
DIR –  директория
FIFO – First In First Out
CHR – файл символьного устройства
 
Полный список значений этих полей вы моежете найти в руководстве по lsof (man lsof).
 
2. Список процессов открывших конкретный файл
 
Вы можете просмотреть список процессов открывших конкретный файл, используя имя файла в качестве аргумента - 
 
sudo lsof /var/log/syslog
[sudo] password for alex1812:
COMMAND  PID   USER   FD   TYPE DEVICE SIZE/OFF    NODE NAME
rsyslogd 949 syslog    1w   REG   8,17    31015 8388889 /var/log/syslog
3. Список открытых файлов в конкретной директории
 
Вы можете просмотреть список процессов, открывших файлы в конкретной директории используя ключ +D. Ключ +D просматривает каталоги рекурсивно (то бишь вместе с подкаталогами). Если рекурсия не нужна используйте ключ +d.
 
$ sudo lsof +D /var/log
COMMAND    PID     USER   FD   TYPE DEVICE SIZE/OFF    NODE NAME
rsyslogd   949   syslog    1w   REG   8,17    31506 8388889 /var/log/syslog
rsyslogd   949   syslog    2w   REG   8,17     4313 8391269 /var/log/mail.log
rsyslogd   949   syslog    5w   REG   8,17   200433 8392210 /var/log/auth.log
smbd      1040     root    2w   REG   8,17      802 8389620 /var/log/samba/log.smbd
smbd      1040     root    8w   REG   8,17      802 8389620 /var/log/samba/log.smbd
cupsd     1063     root    4u   REG   8,17      111 8389055 /var/log/cups/access_log
cupsd     1063     root    5u   REG   8,17        0 8389078 /var/log/cups/error_log
cupsd     1063     root    6u   REG   8,17        0 8395226 /var/log/cups/page_log
nmbd      1234     root    2w   REG   8,17        0 8388795 /var/log/samba/log.nmbd
nmbd      1234     root   18w   REG   8,17        0 8388795 /var/log/samba/log.nmbd
kdm       1404     root    1w   REG   8,17        0 8395279 /var/log/kdm.log
4. Просмотр списка процессов по имени, заданном неполностью 
 
Используя ключ -с можно просматривать  файлы открытые процессами начинающимися  с набранных Вами букв. Ключей -с может быть несколько в одной команде:
 
$ sudo lsof -c ssh -c init
[sudo] password for alex1812:
COMMAND     PID            USER   FD   TYPE             DEVICE SIZE/OFF    NODE NAME
init          1            root  cwd    DIR               8,17     4096       2 /
init          1            root  rtd    DIR               8,17     4096       2 /
init          1            root  txt    REG               8,17   163096  393328 /sbin/init
init          1            root  mem    REG               8,17    26512 1180237 /lib/x86_64-linux-gnu/libnss_winbind.so.2
init          1            root  mem    REG               8,17    52120 1179940 /lib/x86_64-linux-gnu/libnss_files-2.15.so
init          1            root  mem    REG               8,17    47680 1179941 /lib/x86_64-linux-gnu/libnss_nis-2.15.so
init          1            root  mem    REG               8,17    97248 1179935 /lib/x86_64-linux-gnu/libnsl-2.15.so
.........
sshd       1160            root  cwd    DIR               8,17     4096       2 /
sshd       1160            root  rtd    DIR               8,17     4096       2 /
sshd       1160            root  txt    REG               8,17   517112 3539528 /usr/sbin/sshd
sshd       1160            root  mem    REG               8,17    52120 1179940 /lib/x86_64-linux-gnu/libnss_files-2.15.so
..........
В примере, мы набрали в качестве имени процессов мы набрали только ssh и init,  и получили весь список процессов начинающихся с этого набора букв.
 
5. Просмотр процессов использующих определенную точку монтирования
 
Иногда, когда мы пытаемся размонтировать директорию, система выдает ошибку “Device or Resource Busy” (устройства или ресурс занят). Соотвественно нам необходимо найти все процессы использующие данную точку монтирования и завершить их  для удачного размонтирования данной директории.
 
# lsof /home

Также работает рекурсивный просмотр:

# lsof +D /home/

6. Просмотр файлов открытых конкретным пользователем

Для поиска  файлов открытых определенным пользователем, используем ключ -u
 

lsof -u alex1812 | more
COMMAND     PID     USER   FD      TYPE             DEVICE SIZE/OFF     NODE NAME
x-session  3188 alex1812  cwd       DIR               8,17     4096  7208963 /home/alex1812
x-session  3188 alex1812  rtd       DIR               8,17     4096        2 /
x-session  3188 alex1812  txt       REG               8,17   109768  6946945 /bin/dash
x-session  3188 alex1812  mem       REG               8,17  1802936  1179931 /lib/x86_64-linux-gnu/libc-2.15.so
x-session  3188 alex1812  mem       REG               8,17   149280  1179933 /lib/x86_64-linux-gnu/ld-2.15.so
x-session  3188 alex1812    0r      CHR                1,3      0t0     1029 /dev/null
x-session  3188 alex1812    1w      REG               8,17    18078  7208967 /home/alex1812/.xsession-errors

Иногда необходимо вывести файлы открытые всеми пользователями, за исключением конкретного. Для этого используется -'^'
 

sudo lsof -u ^alex1812 | more
alex1812@alex1812:~$ sudo lsof -u ^alex1812 | more
COMMAND     PID            USER   FD      TYPE             DEVICE  SIZE/OFF       NODE NAME
init          1            root  cwd       DIR               8,17      4096          2 /
init          1            root  rtd       DIR               8,17      4096          2 /
init          1            root  txt       REG               8,17    163096     393328 /sbin/init
init          1            root  mem       REG               8,17     26512    1180237 /lib/x86_64-linux-gnu/libnss_winbind.so.2
.......

Данная команда выводит список файлов открытых всеми пользователями, за исключением пользователя alex1812

7. Список всех файлов открытых конкретным процессом

Для вывода списка всех файлов открытых конкретным процессов используется ключ -p. Это может быть полезно для получения большей информации о  самом процессе.
 

 sudo lsof -p 2
COMMAND  PID USER   FD      TYPE DEVICE SIZE/OFF NODE NAME
kthreadd   2 root  cwd       DIR   8,17     4096    2 /
kthreadd   2 root  rtd       DIR   8,17     4096    2 /
kthreadd   2 root  txt   unknown                      /proc/2/exe

 8. Уничтожить все процессы используемые конкретным пользователем

Если необходимо уничтожить все процессы, имеющие открытые файлы, конкретного пользователя, мы можем использовать ключ -t для просмотра id процессов и уничтожить их с помощью kill -
 

# kill -9 `lsof -t -u alex1812`

Данная команда уничтожит все процессы пользователя alex1812, которые имели открытые файлы.

Аналогичным образом, вы можете использовать ключ -t для других целей, например, чтобы получить список id процессов, которые открыли /var/log/syslog
 

# lsof -t /var/log/syslog
949

9. Комбинирование ключей

По умолчанию, если вы используете более одного ключа в Lsof, то вывод  команды будет  объеденен по этим ключам. Например,
 

lsof -u alex1812 -c init | more
COMMAND     PID     USER   FD      TYPE             DEVICE SIZE/OFF     NODE NAME
init          1     root  cwd   unknown                                      /proc/1/cwd (readlink: Permission denied)
init          1     root  rtd   unknown                                      /proc/1/root (readlink: Permission denied)
init          1     root  txt   unknown                                      /proc/1/exe (readlink: Permission denied)
init          1     root NOFD                                                /proc/1/fd (opendir: Permission denied)
x-session  3188 alex1812  cwd       DIR               8,17     4096  7208963 /home/alex1812
x-session  3188 alex1812  rtd       DIR               8,17     4096        2 /
x-session  3188 alex1812  txt       REG               8,17   109768  6946945 /bin/dash

В этой команде мы используем два ключа -u и -c, таким образом команда одновременно выводит и список процессов принадлежащих пользователю alex1812, и процессы начинающиеся со слова init (принадлежащих любым пользователям).

Вы можете использовать ключ -a, чтобы совместить вывод по нескольким параметрам, например процессы принадлежащие пользователю alex1812 и начинающиеся с init:
 

lsof -u alex1812 -c init -a

10. Выполнение Lsof в режим повтора

Lsof поддерживает вывод в режиме повтора. То бишь сначала будет выведет список файлов с заданными параметрами, затем задержка на заданный интервал и опять вывод на основе этих же параметров.

Режим повтора может быть включен ключами +r и -r. Если используем +r, то режим повтора будет прерван в случае отсутствия открытых файлов. Ключ -r будет продолжать вывод с заданным интервалом вне зависимости от наличия открытых файлов.

Каждый цикл вывода будет разделен с помощью "=======". Мы также можем  указать время задержки для обоих ключей.
 

 lsof -u alex1812 -c x-session -a -r5
COMMAND    PID     USER   FD   TYPE DEVICE SIZE/OFF    NODE NAME
x-session 3188 alex1812  cwd    DIR   8,17     4096 7208963 /home/alex1812
x-session 3188 alex1812  rtd    DIR   8,17     4096       2 /
x-session 3188 alex1812  txt    REG   8,17   109768 6946945 /bin/dash
x-session 3188 alex1812  mem    REG   8,17  1802936 1179931 /lib/x86_64-linux-gnu/libc-2.15.so
x-session 3188 alex1812  mem    REG   8,17   149280 1179933 /lib/x86_64-linux-gnu/ld-2.15.so
x-session 3188 alex1812    0r   CHR    1,3      0t0    1029 /dev/null
x-session 3188 alex1812    1w   REG   8,17    18078 7208967 /home/alex1812/.xsession-errors
x-session 3188 alex1812    2w   REG   8,17    18078 7208967 /home/alex1812/.xsession-errors
x-session 3188 alex1812   10r   REG   8,17    18712 3558840 /usr/bin/startkde
=======
COMMAND    PID     USER   FD   TYPE DEVICE SIZE/OFF    NODE NAME
x-session 3188 alex1812  cwd    DIR   8,17     4096 7208963 /home/alex1812
x-session 3188 alex1812  rtd    DIR   8,17     4096       2 /
x-session 3188 alex1812  txt    REG   8,17   109768 6946945 /bin/dash
x-session 3188 alex1812  mem    REG   8,17  1802936 1179931 /lib/x86_64-linux-gnu/libc-2.15.so
x-session 3188 alex1812  mem    REG   8,17   149280 1179933 /lib/x86_64-linux-gnu/ld-2.15.so
x-session 3188 alex1812    0r   CHR    1,3      0t0    1029 /dev/null
x-session 3188 alex1812    1w   REG   8,17    18078 7208967 /home/alex1812/.xsession-errors
x-session 3188 alex1812    2w   REG   8,17    18078 7208967 /home/alex1812/.xsession-errors
x-session 3188 alex1812   10r   REG   8,17    18712 3558840 /usr/bin/startkde
=======

В данном примере мы выводим список процессов принадлежащих alex1812 c именем x-session и задержкой повторного вывода в 5 секунд.

Поиск сетевых подключений

Сетевые соединения в Linux также являются файлами. Таким образом, мы можем найти информацию о них с помощью Lsof.

11.  Просмотр всех сетевых подключений
 

Для просмотра всех сетевых подключений используем ключ -i
 

$sudo lsof -i | more
[sudo] password for alex1812:
COMMAND     PID            USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
smbd       1040            root   30u  IPv4   11108      0t0  TCP *:microsoft-ds (LISTEN)
smbd       1040            root   31u  IPv4   11110      0t0  TCP *:netbios-ssn (LISTEN)
cupsd      1063            root    8u  IPv6 2376544      0t0  TCP localhost:ipp (LISTEN)
........

Вы также можете использовать -i4 и i6 для вывода только подключений по IPv4 или IPv6 соответственно.

12. Список всех сетевых файлов используемых конкретным процессом

$sudo lsof -i -a -p 1234
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
nmbd    1234 root    9u  IPv4   7842      0t0  UDP *:netbios-ns
nmbd    1234 root   10u  IPv4   7843      0t0  UDP *:netbios-dgm
nmbd    1234 root   11u  IPv4   7845      0t0  UDP alex1812.local:netbios-ns
nmbd    1234 root   12u  IPv4   7846      0t0  UDP 10.218.138.255:netbios-ns
nmbd    1234 root   13u  IPv4   7847      0t0  UDP alex1812.local:netbios-dgm
nmbd    1234 root   14u  IPv4   7848      0t0  UDP 10.218.138.255:netbios-dgm

или

sudo lsof -i -a -c ssh
COMMAND   PID     USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
sshd     1160     root    3r  IPv4   1815      0t0  TCP *:ssh (LISTEN)
sshd     1160     root    4u  IPv6   1817      0t0  TCP *:ssh (LISTEN)
sshd    21025     root    3r  IPv4 687348      0t0  TCP alex1812.local:ssh->computer.domain.ru:63238 (ESTABLISHED)
sshd    21246 alex1812    3u  IPv4 687348      0t0  TCP alex1812.local:ssh->computer.domain.ru:63238 (ESTABLISHED)

В первом случае мы задаем процесс по его id, во втором по имени (по первым символам).

13. Список процессов прослушивающих определенный порт

Для этого используется ключ -i и номер порта через ':'

$sudo lsof -i :25
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
master  2904 root   12u  IPv4  14542      0t0  TCP localhost.domain.ru:smtp (LISTEN)
master  2904 root   13u  IPv6  14543      0t0  TCP localhost:smtp (LISTEN)
.........

14. Список всех UDP и TCP соединений

Для вывода такого списка используем -
 

lsof -i tcp

или

lsof -i udp

15. Просмотр всех NFS (Network File System) файлов

Для просмотра всех NFS файлов используем ключ -N, например просмотр всех NFS файлов открытых от пользователя alex1812 -
 

lsof -N -u alex1812 -a

Надеюсь информация данной статьи будет кому-либо полезна, особенно тем, кто не любит читать man'ы =)

 

Интересное на сайте: 
0
Голосов пока нет