2009-12-30 5 views
27

¿Hay una biblioteca de Linux que me permita saber qué conexiones de IP son propiedad de qué procesos? Supongo que estoy buscando el equivalente programático de lsof -i. En última instancia, quiero correlacionar los paquetes vistos a través de libpcap con los procesos.API de Linux para determinar los sockets que pertenecen a un proceso

ACTUALIZACIÓN: Un par de personas han sugerido el uso de /proc/<pid>/net/tcp y udp, pero en mi sistema, se muestra los mismos datos para cada proceso, por lo que no ayuda.

+0

oh wow. Estoy escribiendo un programa para hacer esto ahora, qué casualidad –

+1

Tengo código ahora si está interesado en comparar notas. He visto algunas extrañas peculiaridades en los datos/proc, pero en general el enfoque funciona. –

Respuesta

45

Creo que primero tienes que mirar a través de los archivos fds abiertos en/proc/*/fd, p.

4 -> socket:[11147] 

y luego buscar las tomas de referencia (por el nodo-i) en/proc/net/tcp (o/proc/net/udp), por ejemplo

12: B382595D:8B40 D5C43B45:0050 01 00000000:00000000 00:00000000 00000000 1000  0 11065 1 ffff88008bd35480 69 4 12 4 -1 
+0

Este es el eslabón perdido. ¡Gracias! (No me deja votar por alguna razón.) –

+0

Respondió esto mientras escribía, y no me di cuenta ... buen trabajo :) +1 ya que aparentemente OP no puede. – ephemient

+0

Esta respuesta podría ser incluso mejor si los inodos en los 2 ejemplos se correspondieran entre sí. – Samveen

4

Usted puede leerlos desde el sistema de archivos proc. Los 'ficheros' es probable que quieren ver se encuentran en /proc/<pid>/net (es decir, TCP, UDP, Unix)

He aquí algunos examples sobre el uso del sistema de ficheros proc

+0

+1 realmente útil ... gracias :) –

+1

Quizás me falta algo, pero/proc/*/net/tcp muestra los mismos datos para diferentes pids. Debe mostrar todas las conexiones. ¿Cómo puedo asignar cada uno de nuevo al pid de origen? –

11

El sistema de ficheros /proc proporciona detalles sobre cada proceso, incluyendo la creación de redes información. La información de socket abierto se enumera en /proc/net/tcp. Los conectores IPv6 se enumeran por separado en el archivo tcp6. La información del socket incluye información tal como los puertos locales y remotos, y el número de inodo del socket, que puede correlacionarse con el proceso al analizar la información /proc/{pid}/fd/*.

Si no está familiarizado con el sistema de archivos /proc, básicamente es un sistema de archivos virtual que le permite al kernel publicar todo tipo de información útil en el espacio de usuario. Los archivos son normalmente archivos de texto estructurados simples que son fáciles de analizar.

Por ejemplo, en mi sistema Ubuntu que utiliza netcat para las pruebas, y corrieron nc -l -p 8321 a escuchar en el puerto 8321. En cuanto a la información tcp socket:

$ cat /proc/net/tcp 
    sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode              
    0: 00000000:2081 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000  0 26442 1 de0c8e40 300 0 0 2 -1        
    1: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000  0  0 7019 1 de0c84c0 300 0 0 2 -1        

La primera línea muestra que está escuchando en todas las direcciones al punto 8321 (0x2081). El número de inodo es 26442, que podemos usar para buscar el pid correspondiente en /proc/{pid}/fd/*, que consiste en un conjunto de enlaces simbólicos desde el número de identificador de archivo al dispositivo. Así que si miramos hacia arriba el pid para netcat, y comprobar su fd mapeo:

$ ls -l /proc/7266/fd 
total 0 
lrwx------ 1 gavinb gavinb 64 2009-12-31 09:10 0 -> /dev/pts/1 
lrwx------ 1 gavinb gavinb 64 2009-12-31 09:10 1 -> /dev/pts/1 
lrwx------ 1 gavinb gavinb 64 2009-12-31 09:10 2 -> /dev/pts/1 
lrwx------ 1 gavinb gavinb 64 2009-12-31 09:10 3 -> socket:[26442] 

Y no vemos que el descriptor de fichero 3 en este proceso se asigna a la toma de corriente con inodo 26442, del mismo modo que esperamos.

Así que, obviamente, para construir un mapa completo de tomas, deberá enumerar en primer lugar todos los archivos /proc/**/fd/*, buscar los enlaces simbólicos de socket, entonces coincidir con el nodo-i toma contra las tablas de /proc/net/tcp que tiene la información de punto final.

Así funciona la herramienta lsof (ver lsof/dialects/linux/dsocket.c para la implementación).

+0

La misma pregunta que tuve para Kimvais: los directorios/proc/*/net/tcp muestran los mismos datos para diferentes pids. ¿Cómo puedo asignar cada uno de nuevo al pid de origen? –

+0

He actualizado la respuesta para incluir una descripción completa de cómo asignar sockets a pids. Espero que esto esté más claro ahora, básicamente implica construir una tabla de pids para inodos de socket, y buscar estos inodos en la tabla de socket tcp. Avíseme si hay algo que necesite aclaración. – gavinb

+0

Muy claro. ¡Gracias! –

3

Se podría intentar ejecutar lsof con strace y ver qué archivos en/proc se pone los datos.

+0

directo al grano –

5

/proc/<pid>/net es equivalente a /proc/net para todos los procesos en el mismo espacio de nombres de red a medida que – en otras palabras, es la información "global".

Usted puede hacer lo que lsof y fuser hacer, que es para recorrer tanto /proc/<pid>/fd/* y /proc/net/* buscando a juego i-nodos. demostración rápida:

#!/bin/sh 
pgrep "[email protected]" | while read pid; do 
    for fd in /proc/$pid/fd/*; do 
     name=$(readlink $fd) 
     case $name in 
      socket:\[*\]) 
       ino=${name#*:} 
       for proto in tcp:10 tcp6:10 udp:10 udp6:10 unix:7; do 
        [[ ! -e /proc/net/${proto%:*} ]] || 
        awk " 
         \$${proto##*:} == ${ino:1:${#ino}-2} { 
          print \"${proto%:*}:\", \$0 
          exit 1 
         } 
        " /proc/net/${proto%:*} || break 
       done 
       ;; 
     esac 
    done 
done 

Usted puede extender esto a otros protocolos (Veo AX25, IPX, paquete, crudo, raw6, udplite, udp6lite en /proc/net/ también) o volver a escribir en un idioma de su elección.

12

Para determinar los sockets que pertenecen a un proceso, puede usar netstat. Aquí hay un ejemplo con salida (abreviado) de netstat con opciones que harán lo que usted desee.

$ sudo netstat -apeen 
Active Internet connections (servers and established) 
Proto Recv-Q Send-Q Local Address   Foreign Address   State  User  Inode  PID/Program name 
tcp  0  0 127.0.0.1:8118   0.0.0.0:*    LISTEN  138  744850  13248/privoxy 
tcp  0  0 127.0.0.1:5432   0.0.0.0:*    LISTEN  117  9612  2019/postgres 
udp  0  0 127.0.0.1:51960   127.0.0.1:51960   ESTABLISHED 117  7957  2019/postgres 
udp  0  0 0.0.0.0:68    0.0.0.0:*       0   7740  1989/dhclient 
Active UNIX domain sockets (servers and established) 
Proto RefCnt Flags  Type  State   I-Node PID/Program name Path 
unix 2  [ ACC ]  STREAM  LISTENING  7937  2019/postgres  /var/run/postgresql/.s.PGSQL.5432 
unix 2  [ ACC ]  STREAM  LISTENING  958058 8080/emacs   /tmp/emacs1000/server 
unix 2  [ ACC ]  STREAM  LISTENING  6969  1625/Xorg   /tmp/.X11-unix/X0 
unix 2  [ ]   DGRAM     9325  1989/dhclient  
unix 3  [ ]   STREAM  CONNECTED  7720  1625/Xorg   @/tmp/.X11-unix/X0 

asegúrese de ejecutar netstat como root lo contrario obtendrá este mensaje:

(Not all processes could be identified, non-owned process info 
will not be shown, you would have to be root to see it all.) 

Una explicación de las opciones de la -apeennetstat manpage:

-a, --all 
    Show both listening and non-listening sockets. With the 
    --interfaces option, show interfaces that are not up 

-p, --program 
    Show the PID and name of the program to which each socket 
    belongs. 

-e, --extend 
    Display additional information. Use this option twice for 
    maximum detail. 

--numeric , -n 
    Show numerical addresses instead of trying to determine symbolic host, port or user names. 

--numeric-hosts 
    shows numerical host addresses but does not affect the resolution of port or user names. 

--numeric-ports 
    shows numerical port numbers but does not affect the resolution of host or user names. 

--numeric-users 
    shows numerical user IDs but does not affect the resolution of host or port names. 
+0

puede obtener el pid si sudo al propietario de ese proceso (si no puede obtener la raíz). +1 en esta solución! ¡Gracias! – gred

+1

'netstat' en realidad analizará'/proc/net/tcp' et al. ver, por ejemplo, [aquí] (http://sourceforge.net/p/net-tools/code/ci/master/tree/netstat.c#l979) (código de análisis para '/ proc/net/tcp') . Rutas en uso por netstat definidas en 'lib/pathnames.h'. – z9u2k

Cuestiones relacionadas