GNU/Linux >> Tutoriales Linux >  >> Linux

API de Linux para determinar los sockets que pertenecen a un proceso

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

$ 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; de lo contrario, recibirá 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 del -apeen opciones de la página de manual de netstat:

-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.

Creo que primero tienes que mirar a través de los fds abiertos en /proc/*/fd, por ejemplo,

4 -> socket:[11147]

y luego busque los sockets a los que se hace referencia (por el inodo) 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

El /proc El sistema de archivos proporciona detalles sobre cada proceso, incluida la información de red. La información de sockets abiertos se encuentra en /proc/net/tcp . Los sockets IPv6 se enumeran por separado en el tcp6 expediente. La información del socket incluye información como los puertos locales y remotos, y el número de inodo del socket, que se puede asignar al proceso analizando el /proc/{pid}/fd/* información.

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

Por ejemplo, en mi sistema Ubuntu usé netcat para probar y ejecutó nc -l -p 8321 para escuchar en el puerto 8321. Mirando el tcp información del enchufe:

$ 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 hasta el punto 8321 (0x2081). El número de inodo es 26442, que podemos usar para buscar el pid coincidente en /proc/{pid}/fd/* , que consta de un montón de enlaces simbólicos desde el número de identificación del archivo hasta el dispositivo. Entonces, si buscamos el pid para netcat y comprueba su fd asignación:

$ 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 allí vemos que el descriptor de archivo 3 en este proceso está asignado al socket con el inodo 26442, tal como esperábamos.

Entonces, obviamente, para construir un mapa completo de sockets, primero deberá enumerar todos los /proc/**/fd/* archivos, busque los enlaces simbólicos del socket, luego haga coincidir el inodo del socket con las tablas de /proc/net/tcp que tiene la información del punto final.

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

  • Wikipedia en procfs
  • El sistema de archivos /proc de Linux como herramienta de programación

Linux
  1. Cómo instalar vtop en Linux

  2. Linux:¿un proceso de "subsegador"?

  3. Introducción a los subprocesos de Linux - Parte I

  4. Proceso de arranque de Linux

  5. Cómo determinar qué proceso está escribiendo en el disco en Linux

Cómo matar un proceso en Linux

Comando Ps en Linux (Lista de Procesos)

Comando Pstree en Linux

Comando matar en Linux

Supervisión de procesos en Linux

Cómo MATAR un proceso en Linux