Archivos y sockets abiertos en Linux, El comando lsof

Share

Quien no ha tenido ganas de patear el PC cuando no se sabe qué, quién, cómo y cuándo se abrió un archivo y no se puede avanzar más por temor a perder información.

Situaciones como edicion con vi, intentar desmontar un sistema de archivos donde alguien se quedo parado en un directorio. Saber que puertos tiene uno abierto. Saber por qué la conexión a Internet está tan lenta, inspeccionando las conexiones sin romperse el cráneo con tcpdump. Todo, todo esto se puede hacer con un único comando. Estoy hablando de lsof.

Vamos por partes. Primero que nada, el comando lsof necesita en algunos casos, donde su funcionalidad lo requiere, privilegios de root como es el caso cuando preguntamos por sockets abiertos.

Si queremos desmontar un sistema de archivos, pero algún bruto o nosotros mismos tenemos archivos o directorios abiertos no podremos desmontar el filesystem. Claro está, podríamos llegar a ocupar el comando fuser para esos menesteres, pero como dice un amigo, eso es similar a sacar una muela por el trasero. Emplearemos ahora lsof y en otro momento describiremo la bazuka que es fuser.

Si el punto de montage es MOUNT_POINT y queremos saber quién tiene un archivo tomado o está parado en un directorio de la jererquía basta con ejecutar

lsof +D MOUNT_POINT

lsof acá escapa de los cánones comunes de los utilitarios de GNU, pués es raro pasarle opciones con un signo mas (+). Incluso no acepta opciones de doble guión como ocurre con el resto. Esto es por la historia y origen de este turbio comando. Para ayudarlos un poco a memorizar este comando nemotécnicamente, pueden pensar de lsof como LS de Open Files.

La salida podría ser como sigue. Con la información que entrega podemos obtener el PID (process ID) para matar el proceso. También podemos saber quien tiene abierto el archivo o directorio, incluso que comando o nombre de proceso está estorbando para nuestras intenciones.

![ayin.copesa.cl:~]# lsof +D /home
COMMAND     PID     USER   FD   TYPE DEVICE     SIZE     NODE NAME
startx     4295  titosky  cwd    DIR   8,19     4096 17825793 /home/titosky
xinit      6320  titosky  cwd    DIR   8,19     4096 17825793 /home/titosky
X          6321     root  cwd    DIR   8,19     4096 17825793 /home/titosky
ck-xinit-  6379  titosky  cwd    DIR   8,19     4096 17825793 /home/titosky
gnome-ses  6396  titosky  cwd    DIR   8,19     4096 17825793 /home/titosky
gnome-key  6529  titosky  cwd    DIR   8,19     4096 17825793 /home/titosky

Ahora, en el caso que queramos saber qué está pasando con nuestra conexión a Internet que está tan lenta, lsof nos puede ser de gran ayuda sin tener que ocupar tcpdump. TCPDUMP requiere mucho know-how de TCP para llegar a debuggear problemas de este estilo, así que para qué sufrir si con lsof lo puedes hacer fácil para saber qué conexiones tienes con

lsof -n -P -i TCP

La opcion -P es para indicarle a lsof que nos entrege el puerto de conexión de forma numérica. La opción -n es para decirle que no resuelva los números IP de las conexiones, que los entregue como Dios los mandó al mundo. La opción -i es la más controversial y es la que guarda relación con el stack de TCP. Al ponerla con -i TCP le estoy diciendo que me liste las conexiones de TCP. Podríamos, sin pérdida de generalidad, decirle a lsof que nos de las conexiones de UDP con

lsof -P -n -i UDP

Un ejemplo de salida para ver que conexiones sería:

COMMAND    PID    USER   FD   TYPE DEVICE SIZE NODE NAME
named     7946   named   21u  IPv4   9914       TCP 127.0.0.1:53 (LISTEN)
named     7946   named   25u  IPv4   9918       TCP 127.0.0.1:953 (LISTEN)
sshd      8027    root    3u  IPv4  10048       TCP *:22 (LISTEN)
sendmail  8093    root    4u  IPv4  10399       TCP 127.0.0.1:25 (LISTEN)
squid     8132   squid   14u  IPv4  10514       TCP *:3128 (LISTEN)
cupsd     8159    root    4u  IPv4  10583       TCP 127.0.0.1:631 (LISTEN)
fyre      8166  nobody    6u  IPv4  10614       TCP *:7931 (LISTEN)
X         8326    root    1u  IPv4  11024       TCP *:6000 (LISTEN)
firefox-b 8746 titosky   21u  IPv4  17255       TCP 190.47.213.2:58399->209.164.36.167:80 (ESTABLISHED)
firefox-b 8746 titosky   44u  IPv4  29120       TCP 190.47.213.2:52675->72.14.247.18:80 (ESTABLISHED)
firefox-b 8746 titosky   48u  IPv4  29167       TCP 190.47.213.2:52686->72.14.24

Notar que hay entradas que en el número IP traen la palabra LISTEN. Esto indica que hay un servicio escuchando en ese puerto. En la primera columna tenemos el nombre de la aplicación y en la segunda el PID si queremos acriminarnos con la aplicación. Las últimas tres entradas del listado muestran la actividad del firefox. Como pueden apreciar, se nota que la IP 190.47.213.2 tiene conexiones al puerto 80 con 209.164.36.167 (YouTube) y con 72.14.247.18 (Google). Si quiero saber quienes son estas IP`s puedo quitar la opcion -n, pero lo como efecto colateral la resolución de nombres hará que se demore un poco más el comando en entregar los resultados, esto por la resolución del DNS.

Les recomiendo que vean que puertos UDP que tienen abiertos en su máquina. Se les caerá el pelo si ven la cantidad de servicios que tienen corriendo en sus máquinas.

Espero que les sirva.

Atte.

Titosky (titosky@edreams.cl)

Next post: