NFsec Logo

lsof – Lista otwartych plików

24/12/2008 w Administracja 1 komentarz.  (artykuł nr 55, ilość słów: 1717)

L

soflist open files – jest mało znaną, ale jakże potężną i małą aplikacją, która pozwala na uzyskanie informacji o połączeniach sieciowych czy procesach działających w systemie. Dlaczego akurat to narzędzie nazywa się “lista otwartych plików”? Ponieważ należy pamiętać, że w systemach uniksopodobnych prawie wszystkie “elementy systemowe” (włączając w to sieciowe gniazda) są plikami. Lsof jest także poleceniem systemu Linux / Unix, które tak posiada dużo parametrów, że używa zarówno przełączników w postaci plusów (“+”) jak i minusów (“-“):

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

Jak widać polecenie to posiada na prawdę mocne wsparcie jeśli chodzi o możliwości użycia parametrów. Poniżej zostanie przedstawionych kilka przykładów do zastosowania tego polecenia do wyświetlenia informacji o połączeniach i urządzeniach sieciowych oraz aktywności użytkowników w systemie. Można powiedzieć, że lsof pod względem swoich możliwości jest połączeniem komend netstat i ps:

Wyświetlanie połączeń sieciowych:

Pokaż wszystkie połączenia (przełącznik -i -i4 = IPv4 -i6 = IPv6): lsof -i

COMMAND   PID     USER   FD   TYPE DEVICE SIZE NODE NAME
dnscache 2439 dnscache    3u  IPv4   8169       UDP localhost:domain 
dnscache 2439 dnscache    4u  IPv4   8170       TCP localhost:domain (LISTEN)
ssh      2751  agresor    3u  IPv4  29442       TCP 10.10.1.9:3637->nfsec.pl:ssh

Pokaż wszystkie połączenia TCP (ta sama składna dla UDP): lsof -iTCP

COMMAND   PID     USER   FD   TYPE DEVICE SIZE NODE NAME
dnscache 2439 dnscache    4u  IPv4   8170       TCP localhost:domain (LISTEN)
telnet   2786  agresor    3u  IPv4  36956       TCP 10.10.1.13:5771->hh.pl:telnet

Pokaż połączenie powiązane z danym portem: lsof -i:80

COMMAND  PID    USER   FD   TYPE DEVICE SIZE NODE NAME
links   2803 agresor   10u  IPv4  39688       TCP 10.10.1.13:40711->nfsec.pl:http

Pokaż połączenia z wybranym hostem: lsof -i@10.10.1.13

COMMAND    PID    USER   FD   TYPE DEVICE SIZE NODE NAME
ncftp     2561 agresor   40u  IPv4  12173       TCP 10.10.1.9:3134->10.10.1.1:ftp

Pokaż połączenia z wybranym hostem na danym porcie: lsof -i@10.10.1.1:22

COMMAND  PID    USER   FD   TYPE DEVICE SIZE NODE NAME
ssh     2661 agresor    3u  IPv4  19686       TCP 10.10.1.13:49357->10.10.1.1:ssh

Pokaż wszystkie połączenia nasłuchujące: lsof -i | grep LISTEN

dnscache 2439 dnscache    4u  IPv4   8170       TCP localhost:domain (LISTEN)

Pokaż wszystkie połączenia nawiązane: lsof -i | grep ESTABLISHED

ssh     2728 agresor    3u  IPv4  24350       TCP 10.10.1.13:59773->nfsec.pl:ssh

Praca z użytkownikami, procesami i plikami:

Pokaż otworzone pliki przez użytkownika agresor: lsof -u agresor

bash      2417 agresor  mem    REG        3,2   131468    1362741 /lib/ld-2.7.so
bash      2417 agresor    0u   CHR        4,1                3053 /dev/tty1
bash      2417 agresor    1u   CHR        4,1                3053 /dev/tty1
bash      2417 agresor    2u   CHR        4,1                3053 /dev/tty1
bash      2417 agresor  255u   CHR        4,1                3053 /dev/tty1
startx    2467 agresor  cwd    DIR        3,3     8192    2023681 /home/agresor
startx    2467 agresor  rtd    DIR        3,2     4096          2 /
startx    2467 agresor  txt    REG        3,2   678832     295491 /bin/bash
...

Pokaż otwarte pliki i połączenia sieciowe danego programu: lsof -c dnscache

COMMAND   PID     USER   FD   TYPE DEVICE    SIZE    NODE NAME
dnscache 2439 dnscache  cwd    DIR    3,2    4096 1838723 /svscan/dnscache/root
dnscache 2439 dnscache  rtd    DIR    3,2    4096 1838723 /svscan/dnscache/root
dnscache 2439 dnscache  txt    REG    3,2   48336  430955 /usr/local/bin/dnscache
dnscache 2439 dnscache  mem    REG    3,2 1570593 1362717 /lib/libc-2.7.so
dnscache 2439 dnscache  mem    REG    3,2  131468 1362741 /lib/ld-2.7.so
dnscache 2439 dnscache    1w  FIFO    0,5            8148 pipe
dnscache 2439 dnscache    2w  FIFO    0,5            8148 pipe
dnscache 2439 dnscache    3u  IPv4   8169             UDP localhost:dns 
dnscache 2439 dnscache    4u  IPv4   8170             TCP localhost:dns (LISTEN)

Pokaż procesy będące w interakcji z danym plikiem: lsof /var/log/messages

COMMAND  PID USER   FD   TYPE DEVICE   SIZE    NODE NAME
syslogd 2111 root    1w   REG    3,2 159441 1855011 /var/log/messages

Pokaż szczegóły procesu o danym ID: lsof -p 2418

COMMAND  PID USER   FD   TYPE DEVICE    SIZE    NODE NAME
agetty  2418 root  cwd    DIR   0,12   14300     125 /dev
agetty  2418 root  rtd    DIR    3,2    4096       2 /
agetty  2418 root  txt    REG    3,2   15264  985123 /sbin/agetty
agetty  2418 root  mem    REG    3,2 1570593 1362717 /lib/libc-2.7.so
agetty  2418 root  mem    REG    3,2  131468 1362741 /lib/ld-2.7.so
agetty  2418 root    0u   CHR    4,2            3141 /dev/tty2
agetty  2418 root    1u   CHR    4,2            3141 /dev/tty2
agetty  2418 root    2u   CHR    4,2            3141 /dev/tty2

Pokaż tylko numer ID danego procesu: lsof -t -c acpid

2326

Przykłady zaawansowanego użycia lsof:

Pokaż wszystkie połączenia użytkownika agresor z hostem 10.10.1.13 na porcie 22: lsof -a -u agresor -i @10.10.1.1:22

COMMAND  PID    USER   FD   TYPE DEVICE SIZE NODE NAME
ssh     2661 agresor    3u  IPv4  19686       TCP 10.10.1.13:49357->10.10.1.1:ssh

Wyślij sygnał HUP do procesu o danym ID odczytanym za pomocą lsof: kill -HUP `lsof -t -c sshd`. Należy przypomnieć, że wysyłanie sygnału HUP do procesu rodzica (ang. parent) powoduje zatrzymanie procesów potomnych (ang. children), ale nie zatrzymuje samego procesu rodzica. Następuje ponowne odczytanie plików konfiguracyjnych, otwarcie logów, uruchomienie nowych procesów potomnych i kontynuacja pracy serwera. Możemy użyć również przełącznika -u razem z -t by zabić wszystkie procesy użytkownika: kill -9 `lsof -t -u agresor`. Polecenie lsof jest również bardzo przydatne w przypadku, gdy pragniemy odmontować dane urządzenie lub system plików, a otrzymujemy komunikat:

# unmount /dev/hda1
unmount: /dev/hda1 device is busy

Co oznacza, że każde urządzenie lub system plików przed odmontowaniem musi być w pełni nieaktywne(y). Jeśli jakiś proces (systemu lub użytkownika) posiada otworzony plik w tej przestrzeni otrzymamy powyższy komunikat. By sprawdzić szczegóły tej aktywności wystarczy wydać po prostu polecenie: lsof /dev/hda1.

Rozłączony otwarty plik – (ang. unlinked open file) ciekawym przypadkiem jest sytuacja procesu, który otworzył dany plik by dokonywać w nim czynność zapisu, po czym plik ten zostaje usunięty z systemu plików. Ponieważ deskryptor pliku został już otwarty w rzeczywistości został skasowany tylko i-węzeł skojarzony z otwartym deskryptorem. Dlatego proces może kontynuować czynność zapisu do otwartego deskryptora pliku tym samym zapełniając wolne miejsce systemu pliku w prawie niewykrywalny sposób. Miejsce na dysku zostanie zwolnione dopiero wówczas, gdy dany proces zostanie zakończony.

Wszystkie w/w przypadki rozłączonych otwartych plików możemy wykryć za pomocą polecenia: lsof +L1

bash-3.1$ lsof +L1
COMMAND    PID    USER   FD   TYPE DEVICE  SIZE NLINK    NODE NAME
firefox-b 2629 agresor   48u   REG    3,2 28700     0 1838710 /tmp/gltk (deleted)

Prostą symulacją takiego przypadku może być usunięcie pliku /var/log/messages podczas działania daemona syslogd. Należy pamiętać, że lsof może nie być w stanie ukazać wszystkich rodzajów plików z zerową sumą dowiązania – szczególnie tyczy się potoków (ang. pipe), gniazd (ang. socket) czy plików udostępnionych przez NFS (ang. Network File System).

Więcej informacji: A Quick Start for Lsof, Strona manualna dla polecenia: man lsof

Kategorie K a t e g o r i e : Administracja

Tagi T a g i : , , , , ,

1 komentarz.

  1. Skróconą listę otwartych programów możemy uzyskać za pomocą polecenia:

    lsof | awk '{print $1}' | sort | uniq -c