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