Uso de lsof: Herramientas UNIX (VI)

Mediante lsof podemos ver los ficheros abiertos, similar al directorio /proc/<PID>/fddónde podemos obtener una información similar. En otras ocasiones ya hemos hecho referencia a como ver los descriptores abiertos por un proceso mediante el /proc.
lsof se trata de una gran herramienta para diagnosticar problemas, vamos a ver unos ejemplos de como usarla:

Averiguar qué aplicación está usando un puerto de comunicaciones en Linux

 Podremos usar el siguiente comando Linux para obtener los procesos y el puerto de comunicaciones que usan:
lsof -w -n -i
Pasando un determinado fichero a lsof podemos obtener los procesos que lo tienen abierto, por ejemplo:


# lsof  /var/log/messages
COMMAND   PID USER   FD   TYPE DEVICE  SIZE   NODE NAME
syslogd 16459 root    2w   REG    8,1 40103 220580 /var/log/messages
Para hacer el proceso inverso (que ficheros tiene abierto un determinado proceso) lo hacemos mediante el parámetro -p y el PID, por ejemplo:
# lsof -p 16459
COMMAND   PID USER   FD   TYPE             DEVICE    SIZE     NODE NAME
syslogd 16459 root  cwd    DIR                8,1    4096        2 /
syslogd 16459 root  rtd    DIR                8,1    4096        2 /
syslogd 16459 root  txt    REG                8,1   39352    78917 /sbin/syslogd
syslogd 16459 root  mem    REG                8,1  134400   173323 /lib64/ld-2.5.so
syslogd 16459 root  mem    REG                8,1 1704256   173427 /lib64/libc-2.5.so
syslogd 16459 root  mem    REG                8,1   53880   173404 /lib64/libnss_files-2.5.so
syslogd 16459 root    0u  unix 0xffff81003cb5b680         99224344 /dev/log
syslogd 16459 root    2w   REG                8,1   40103   220580 /var/log/messages
syslogd 16459 root    3w   REG                8,1  195385   220682 /var/log/secure
syslogd 16459 root    4w   REG                8,1  570115   220721 /var/log/maillog
syslogd 16459 root    5w   REG                8,1  420315   220736 /var/log/cron
syslogd 16459 root    6w   REG                8,1       0   220727 /var/log/spooler
syslogd 16459 root    7w   REG                8,1       0   220733 /var/log/boot.log
Mediante el /proc podemos obtener la misma información. Para obtener los descriptores de ficheros abiertos lo hacemos con /proc/<PID>/fd:
# file /proc/16459/fd/*
/proc/16459/fd/0: broken symbolic link to `socket:[99224344]'
/proc/16459/fd/2: symbolic link to `/var/log/messages'
/proc/16459/fd/3: symbolic link to `/var/log/secure'
/proc/16459/fd/4: symbolic link to `/var/log/maillog'
/proc/16459/fd/5: symbolic link to `/var/log/cron'
/proc/16459/fd/6: symbolic link to `/var/log/spooler'
/proc/16459/fd/7: symbolic link to `/var/log/boot.log'
Mediante /proc/<PID>/maps podemos obtener las regiones de memória que tiene el proceso mapeadas:
# cat /proc/16459/maps
2ac8400aa000-2ac8400c4000 r-xp 00000000 08:01 173323                     /lib64/ld-2.5.so
2ac8402c4000-2ac8402c5000 r--p 0001a000 08:01 173323                     /lib64/ld-2.5.so
2ac8402c5000-2ac8402c6000 rw-p 0001b000 08:01 173323                     /lib64/ld-2.5.so
2ac8402c6000-2ac8402c8000 rw-p 2ac8402c6000 00:00 0
2ac8402d4000-2ac84041e000 r-xp 00000000 08:01 173427                     /lib64/libc-2.5.so
2ac84041e000-2ac84061e000 ---p 0014a000 08:01 173427                     /lib64/libc-2.5.so
2ac84061e000-2ac840622000 r--p 0014a000 08:01 173427                     /lib64/libc-2.5.so
2ac840622000-2ac840623000 rw-p 0014e000 08:01 173427                     /lib64/libc-2.5.so
2ac840623000-2ac84062a000 rw-p 2ac840623000 00:00 0
2ac840637000-2ac840641000 r-xp 00000000 08:01 173404                     /lib64/libnss_files-2.5.so
2ac840641000-2ac840840000 ---p 0000a000 08:01 173404                     /lib64/libnss_files-2.5.so
2ac840840000-2ac840841000 r--p 00009000 08:01 173404                     /lib64/libnss_files-2.5.so
2ac840841000-2ac840842000 rw-p 0000a000 08:01 173404                     /lib64/libnss_files-2.5.so
555555554000-55555555d000 r-xp 00000000 08:01 78917                      /sbin/syslogd
55555575c000-55555575e000 rw-p 00008000 08:01 78917                      /sbin/syslogd
55555575e000-55555577e000 rw-p 55555575e000 00:00 0                      [heap]
7fff6a9eb000-7fff6aa00000 rw-p 7ffffffea000 00:00 0                      [stack]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
Mediante el parámetro -i también podemos usar lsof para listar procesos que escuchan a un determinado puerto, por ejemplo para el puerto de ssh:
# lsof -i :22
COMMAND   PID   USER   FD   TYPE    DEVICE SIZE NODE NAME
sshd    22234   root    3u  IPv4 147028556       TCP *:ssh (LISTEN)
sshd    25626   root    3u  IPv4 190654417       TCP 172.18.1.1:ssh->172.18.1.2:aimpp-hello (ESTABLISHED)
sshd    25633 jprats    3u  IPv4 190654417       TCP 172.18.1.1:ssh->172.18.1.2:aimpp-hello (ESTABLISHED)
Para poder indicar que queremos listar podemos hacerlo mediante el siguiente formato:
[46][protocol][@hostname|hostaddr][:service|port]
Por ejemplo, para indicar que queremos ver que proceso escucha en el puerto UDP 53 lo podemos hacer así:
# lsof -i UDP:53
COMMAND   PID  USER   FD   TYPE    DEVICE SIZE NODE NAME
named   19393 named   20u  IPv4 148958979       UDP localhost:domain
named   19393 named   22u  IPv4 148958981       UDP montferri.systemadmin.es:domain
named   19393 named   24u  IPv4 148958983       UDP 172.18.1.1:domain
Para que lsof no haga resoluciones lo hacemos mediante el parámetro -n:
# lsof -ni UDP:53
COMMAND   PID  USER   FD   TYPE    DEVICE SIZE NODE NAME
named   19393 named   20u  IPv4 148958979       UDP 127.0.0.1:domain
named   19393 named   22u  IPv4 148958981       UDP 91.121.113.59:domain
named   19393 named   24u  IPv4 148958983       UDP 172.18.1.1:domain

Comentarios