Is it a fake website?

26 enero 2007

Resolviendo problemas en Linux con lsof

Una de las herramientas unix más desconocidas pero de una gran utilidad en la administración de sistemas, es lsof. Lsof lista la información de los archivos abiertos por los procesos. Pero realmente esto ¿que quiere decir?.

Con este post podremos resolver problemas típicos como:
  • Qué archivos está usando un usuario actualmente
  • ¿Por qué no puedo desmontar un sistema de ficheros? (device is busy)
  • Encuentra archivos borrados pero que siguen creciendo
  • Encuentra que aplicacion utiliza un puerto dado



Casi todo el mundo olvida que, en UNIX, (casi) todo es tratado como un ARCHIVO. El sistema operativo crea el hardware disponible a las aplicaciones mediante los archivos de /dev. La información del Kernel, sistema, memoria, dispositivos etc está disponible a través de los archivos en /proc. Los sockets TCP/UDP a veces son representados internamente como archivos. Incluso los directorios son realmente ficheros conteniendo otros nombres de fichero.Lsof trabaja examinando las estructuras de datos del kernel y proporciona una gran variedad de información relacionada con los ficheros, pipes, sockets y demás.Lsof viene instalado por defecto en la mayoría de distribuciones Linux y muchos de las versiones de Unix.Veamos algo de práctica con lsof.Descifrando su salida.Cámbiate a root y escribe lsof en la línea de comandos.

COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
init 1 root cwd DIR 8,5 4096 2 /
init 1 root rtd DIR 8,5 4096 2 /
init 1 root txt REG 8,5 32684 163815 /sbin/init
init 1 root mem REG 8,5 106397 404872 /lib/ld-2.3.4.so
init 1 root mem REG 8,5 1454802 404874 /lib/tls/libc-2.3.4.so
init 1 root mem REG 8,5 53736 404893 /lib/libsepol.so.1
syslogd 2622 root 5w REG 8,5 0 566965 /var/log/spooler
syslogd 2622 root 6w REG 8,5 8752 566771 /var/log/boot.log
syslogd 2622 root 8w REG 8,5 42232 566913 /var/log/kernel
klogd 2626 root cwd DIR 8,5 4096 2 /
klogd 2626 root txt REG 8,5 22320 163570 /sbin/klogd
klogd 2626 root mem REG 8,5 1454802 404874 /lib/tls/libc-2.3.4.so
klogd 2626 root mem REG 8,5 106397 404872 /lib/ld-2.3.4.so


Se presentará una lista muy larga de archivos abiertos, de la cual puedes querer utilizar
cat o tu paginador favorito para verla completa.

Por defecto (en Linux), lsof muestra la siguiente información sobre los archivos abiertos:

  • COMMAND: Nombre del comando unix asociado con el proceso.
  • PID: El ID del proceso.
  • USER: El id del usuario o nombre de login al cual pertenece el proceso.
  • FD: El número del descriptor de fichero del archivo o un código representando más información sobre la estructura. Mira la página del manual para más detalles.
  • TYPE: El tipo del nodo asociado con el fichero. Ejem. REG significa un archivo regular, IPV4 O IPV6 significa un socket IP, DIR un directorio, "unix" un dominio socket UNIX, etc.
  • DEVICE: Usualmente contiene números de dispositivo mayores y menores para los ficheros, o direcciones/referencias para otras estructuras.
  • SIZE: El tamaño del archivo o el offset del archivo, en bytes. (Si está disponible). En el caso de archivos que no tienen tamaños verdaderos (Ejem, socket, pipes), lsof muestra el tamaño de el contenido del buffer de los descriptores del kernel.
  • NODE: Número de nodo / inodo / Tipo del protocolo de Internet (TCP) etc.
  • NOMBRE: El nombre del archivo / punto de montaje / dispositivo / Dirección de Internet etc.

Para una comprensión exhaustiva de estos campos y mas parámetros, echar un vistazo a las páginas de manual de lsof.

Como lsof trabaja examinando la memoria del kernel, necesitarás acceso root para ser capaz de utilizarlo sin ningún tipo de restricción. Un usuario que no sea root, no tendrá acceso a la información perteneciente a otros usuarios.

Uso común

lsof, normalmente es usado con una o más de las siguientes opciones:

  • /directorio/del/archivo: Lista procesos, propietarios y descriptores de fichero abiertos que están usando actualmente el archivo especificado.
-i [46][protocolo][@hostname|hostaddr][:service|port]: Lista archivos de internet o sockets.
  • -u name: Lista archivos propiedad del usuario especificado.
  • -p pid: Lista los archivos abiertos por el proceso especificado.
  • -t: Salida lacónica. Sin cabeceras, sólo PIDs. Util para scripts.
  • -n: Deshabilita la resolución de nombres de red.
  • -N: Lista archivos NFS
Estas opciones son de tipo OR por defecto.

Muestra los archivos de Internet OR los archivos abiertos por el usuario "foobar"

# lsof -u foobar -i
Para mostrar todos los archivos de Internet abiertos por "foobar", es necesario aplicar la condición AND (-a) entre las opciones.

# lsof -u foobar -i

Las fórmulas siguientes, demuestran como lsof puede usarse para resolver problemas en el mundo real de Linux.

Formula #1 Encontrar puertos problematicos.

Tu servidor web está rechazando levantarse porque el puerto 80 esta en uso por otro proceso. ¿Cómo consigues para ese proceso que no deja levantar al servidor web?

# lsof -i

... SNIP ...

asterisk 7554 root 16u IPv4 6861 UDP *:4569
postmaste 7688 postgres 5u IPv4 5955 UDP localhost:32768->localhost:32768
postmaste 7689 postgres 5u IPv4 5955 UDP localhost:32768->localhost:32768
sshd 27038 root 3u IPv4 677971 TCP reddwarf:ssh->CPE.xxxx.com:61702 (ESTABLISHED)
sshd 27043 mohit 3u IPv4 677971 TCP reddwarf:ssh->CPE.xxxx.com:61702 (ESTABLISHED)

... SNIP ...

Bien. Una lista de Sockets de Internet abiertos, junto con el proceso, direcciones y propietarios. Tambien, fijate que (igual que netstat) se muestra el estado TCP. Arriba, podemos ver dos sesiones SSH establecidas en progreso.

Vamos a añadir un filtro con el puerto para buscar exactamente lo que queremos.

# lsof -i TCP:80
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
lighttpd 7356 lighttpd 3u IPv4 6409 TCP *:http (LISTEN)
OK, vemos que lighttpd es la razón de que apache no se levante. Esto es probablemente una buena noticia.

Este problema tambien puede resolverse facilmente con la herramienta fuser, aquí no entraremos en detalle en ella, daría para otro post, sólo realizar esta solución con fuser.

# fuser -n tcp 80
80/tcp: 7356

Formula #2 Encontrar procesos entre un rango de puertos dados.

Necesitas encontrar un rango de puertos libres para tu nueva aplicación multimedia.

# lsof -i TCP:5000-5200
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
asterisk 7001 root 10u IPv4 6015 TCP localhost:5038 (LISTEN)
asterisk 7001 root 14u IPv4 6016 TCP localhost:5038->localhost:32768 (ESTABLISHED)
asterisk 7002 root 10u IPv4 6015 TCP localhost:5038 (LISTEN)
asterisk 7002 root 14u IPv4 6016 TCP localhost:5038->localhost:32768 (ESTABLISHED)
asterisk 7039 root 10u IPv4 6015 TCP localhost:5038 (LISTEN)
asterisk 7039 root 14u IPv4 6016 TCP localhost:5038->localhost:32768 (ESTABLISHED)
asterisk 7040 root 10u IPv4 6015 TCP localhost:5038 (LISTEN)
asterisk 7040 root 14u IPv4 6016 TCP localhost:5038->localhost:32768 (ESTABLISHED)
asterisk 7041 root 10u IPv4 6015 TCP localhost:5038 (LISTEN)
asterisk 7041 root 14u IPv4 6016 TCP localhost:5038->localhost:32768 (ESTABLISHED)
asterisk 7042 root 10u IPv4 6015 TCP localhost:5038 (LISTEN)
asterisk 7042 root 14u IPv4 6016 TCP localhost:5038->localhost:32768 (ESTABLISHED)
asterisk 7044 root 10u IPv4 6015 TCP localhost:5038 (LISTEN)
asterisk 7044 root 14u IPv4 6016 TCP localhost:5038->localhost:32768 (ESTABLISHED)
perl 7046 root 3u IPv4 6054 TCP *:5100 (LISTEN)
perl 7046 root 4u IPv4 6055 TCP *:5101 (LISTEN)
perl 7046 root 6u IPv4 6056 TCP localhost:32768->localhost:5038 (ESTABLISHED)
asterisk 7073 root 10u IPv4 6015 TCP localhost:5038 (LISTEN)

Formula #3 Mostrando archivos de usuario

Qué archivos tienen abiertos los usuarios squid y smmsp

# lsof -u squid,smmsp

squid 7606 squid 1254u IPv4 121922382 TCP orfeo.cti.unav.es:59250->filter.cti.unav.es:webcache (ESTABLISHED)
squid 7606 squid 1274u IPv4 120935612 TCP orfeo.cti.unav.es:webcache->159.237.12.243:1842 (ESTABLISHED)
unlinkd 7637 squid cwd DIR 8,8 4096 229825 /usr/local/squid
unlinkd 7637 squid mem REG 8,8 1571692 574569 /lib/tls/libc-2.3.2.so
unlinkd 7637 squid mem REG 8,8 106912 623822 /lib/ld-2.3.2.so
unlinkd 7637 squid 0r FIFO 0,5 99332239 pipe
unlinkd 7637 squid 1w FIFO 0,5 99332238 pipe
unlinkd 7637 squid 2u CHR 1,3 67219 /dev/null
sendmail 10209 smmsp cwd DIR 8,3 1380352 320004 /var/spool/clientmqueue
sendmail 10209 smmsp txt REG 8,8 650816 640420 /usr/sbin/sendmail.sendmail

Muestra los puertos UDP en uso por el usuario squid.

# lsof -i UDP -a -u squid

COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
squid 7606 squid 8u IPv4 120916507 UDP *:37818
squid 7606 squid 72u IPv4 120916602 UDP *:3401
squid 28074 squid 6u IPv4 119796988 UDP *:37812
squid 28074 squid 35u IPv4 119797047 UDP *:3401

Formula #4 Desmontando un disco o sistema de ficheros.

A veces, necesitas localizar el usuario o proceso que te está bloqueando de poder permitir desmontar un disco, por ejemplo.


# umount /usr/local/etc3
umount: /usr/local/etc3: device is busy
umount: /usr/local/etc3: device is busy

# mount | grep "/etc3"
/dev/sdb1 on /usr/local/etc3 type ext3 (rw)

# lsof /dev/sdb1
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
bash 3667 root cwd DIR 8,17 4096 2 /usr/local/etc3

Ups, estoy dentro de esa partición. :)
# kill 3667

# umount /usr/local/etc3

O simplemente:
# kill `lsof -t /dev/sdb1`


Formula #5 Encontrando dispositivos problemáticos

¿Quién está usando el administrador de audio?
# lsof /dev/audio

¿Porqué no puedo iniciar mi logger alternativo?
# lsof /dev/log

¿Por qué no sale mi bandeja de CD?
# lsof /dev/cdrom



Formula #6 Usando exclusiones

El modificador negativo '^' puede usarse como prefijo en los parámetros de Usuario o proceso para excluirlos de la lista de resultados. Como representan exclusiones, se aplican sin OR o AND y toman efecto antes de que se aplique cualquier otro criterio de selección.

Muestra todos los archivos /sockets abiertos por usuarios no root.

# lsof -i -u^root


Formula #7 Recursividad en directorios

La opción '+D' hace que lsof busque archivos abiertos dentro del directorio especificado, recursivamente hasta completarlo.

# lsof +D /tmp

La opción '+d' realiza lo mismo pero no desciende por recursivamente por el directorio.


Formula #8 Coincidencias por nombre de proceso

Muestra todos los archivos abiertos que empiecen con las letras mpg

# lsof -c mpg

Usando expresiones regulares

# lsof -c '/post.*er/'



Formula #9 Examinando procesos sospechosos

Lsof puede ser usado junto con strace para examinar y monitorizar la actividad de virus, gusanos o spyware.

¿Qué archivos tiene abiertos el PID 14554?

# lsof -p 14554

¿Quién está usando/mirando el archivo de passwords?

# lsof /etc/passwd


Formula #10 Modo repetidor

La opción '-r' pone a lsof en modo repetición. Retarda cada 15 segundos (a menos que se especifique), y muestra otro listado.

Mirando los archivos abiertos por un usuario cada 5 segundos.

# lsof -u badcop -r5

Monitorizando el archivo de password.

# lsof /etc/passwd -r 2

Formula #11 Encontrando archivos abiertos borrados.

Uno de los problemas más molestos es tener un sistema de archivos mostrando rápidamente el mensaje "running out of space" sin tener ninguna pista de que archivo es responsable de ello.
Esto suele ocurrir cuando un archivo (generalmente un archivo de log) se borra mientras se está escribiendo sobre él. Cuando borras un archivo abierto, el kernel quitá el link del archivo en el directorio, pero no puede borrar el inodo, ya que todavía está abierto.

Esto causa que el archivo siga creciendo, sin tener conocimiento de su existencia en algún lugar. Bien... al menos alguna parte.

Lsof proporciona el parámetro +L para listar el número de enlaces que tiene un archivo abierto. Cuando está seguido por un número, lsof sólo muestra archivos con un número de enlaces menores que el número especificado.

mohit@reddwarf ~ $ lsof +L3
COMMAND PID USER FD TYPE DEVICE SIZE NLINK NODE NAME
sshd 11540 mohit mem REG 3,69 303448 1 85869 /usr/sbin/sshd
sshd 11540 mohit mem REG 3,65 35404 1 94075 /lib/libnss_nis-2.3.5.so
sshd 11540 mohit mem REG 3,65 30928 1 94086 /lib/libnss_compat-2.3.5.so
sshd 11540 mohit mem REG 3,65 35236 1 93958 /lib/libnss_files-2.3.5.so
sshd 11540 mohit mem REG 3,65 28444 1 94094 /lib/libcrack.so.2.8.0

Un archivo borrado tiene cero enlaces. Por lo que el siguiente comando mostrará archivos abiertos-pero-borrados en el sistema.

# lsof +L1

Muestra una lista de los archivos borrados-pero-abiertos de un sistema de ficheros específico.

# lsof +aL1 /tmp

Para terminar

Apenas hemos visto la superficie de lo que se puede hacer con lsof, pero con los anteriores consejos hemos podido comprobar que es una poderosa herramienta. Sería interesante conocer de que manera es utilizado por otros usuarios, si te ha sido útil de alguna manera o como lo sueles usar, dejame un comentario please. ;)



Gracias 0xfe


10 comentarios:

Anónimo dijo...

Lo que me parece una pasada es el nuevo gestor de ventanas que se le puede instalar, echarle un vistazo al compiz
Un saludo
Juan
diseño web

Anónimo dijo...

Gracias. Interesante resumen. Hace unos días, justamente, lo estuve usando en un equipo con Solaris :-)

Anónimo dijo...

Muy bune tutorial, con conocimiento de red y algunos proceso te ayuda a ver que procesos te estan corriendo y en si te ayuda a ver cuando algun servidor fue hackedo. Gracias por el aporte al mundo del Internet.

Atte.
Vinicio

Anónimo dijo...

Excelente tutorial. mi amigo muchas gracias.

ldgm_99 dijo...

Muy bueno tu aporte amigo, deberias explicarlo junto a netstat para ver la utilidad de lsof en este escenario.


Gracias

Tavo dijo...

Orales no que buuen tutorial esta de lujo sigue asi mi hermano

Brigo dijo...

Para mostrar todos los archivos de Internet abiertos por "foobar", es necesario aplicar la condición AND (-a) entre las opciones.

# lsof -u foobar -i

¿No falta el -a en algún sito? por ejemplo

# lsof -u foobar -a -i

SirGerard dijo...

Muchas Gracias por el post, me ha servido de mucha tu ayuda.

Saludos,

Unknown dijo...

Muchas gracias, ha sido muy útil la ayuda.
Raúl.

Mónica dijo...

Muchas gracias!
Lo utilicé para localizar un problema con el acceso a los puertos serie, pero toda esta información me será muy útil.