GNU/Linux >> Linux Esercitazione >  >> Linux

API Linux per determinare i socket di proprietà di un processo

Per determinare i socket di proprietà di un processo puoi semplicemente usare netstat . Ecco un esempio con output (abbreviato) di netstat con opzioni che faranno quello che vuoi.

$ 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

Assicurati di eseguire netstat come root altrimenti riceverai questo messaggio:

(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 spiegazione del -apeen opzioni dalla manpage di 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.

Penso che tu debba prima esaminare gli fd aperti in /proc/*/fd, ad es.

4 -> socket:[11147]

e quindi cercare i socket di riferimento (dall'inode) in /proc/net/tcp (o /proc/net/udp), ad es.

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

Il /proc filesystem fornisce dettagli su ciascun processo, comprese le informazioni di rete. Le informazioni sui socket aperti sono elencate in /proc/net/tcp . I socket IPv6 sono elencati separatamente nel tcp6 file. Le informazioni sul socket includono informazioni come le porte locale e remota e il numero di inode del socket, che possono essere ricondotti al processo analizzando il /proc/{pid}/fd/* informazioni.

Se non hai familiarità con il /proc filesystem, è fondamentalmente un filesystem virtuale che consente al kernel di pubblicare tutti i tipi di informazioni utili nello spazio utente. I file sono normalmente semplici file di testo strutturati che sono facili da analizzare.

Ad esempio, sul mio sistema Ubuntu ho usato netcat per il test ed ha eseguito nc -l -p 8321 in ascolto sulla porta 8321. Guardando il tcp informazioni sul 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 prima riga mostra che è in ascolto su tutti gli indirizzi al punto 8321 (0x2081). Il numero di inode è 26442, che possiamo usare per cercare il pid corrispondente in /proc/{pid}/fd/* , che consiste in una serie di collegamenti simbolici dal numero di handle del file al dispositivo. Quindi, se cerchiamo il pid per netcat e controlla il suo fd mappatura:

$ 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]

E lì vediamo che il descrittore di file 3 in questo processo è mappato al socket con l'inode 26442, proprio come ci aspettiamo.

Quindi ovviamente per costruire una mappa completa dei socket, dovrai prima enumerare tutti i /proc/**/fd/* file, cercare i collegamenti simbolici del socket, quindi confrontare l'inode del socket con le tabelle da /proc/net/tcp che contiene le informazioni sull'endpoint.

Questo è il modo in cui il lsof strumento funziona (vedi lsof/dialects/linux/dsocket.c per l'implementazione).

  • Wikipedia su procfs
  • Il filesystem Linux /proc come strumento per programmatori

Linux
  1. Come installare vtop su Linux

  2. Linux:bloccare l'accesso alla rete di un processo?

  3. Linux:un processo "subreaper"?

  4. Introduzione ai thread di Linux – Parte I

  5. Processo di avvio di Linux

Come uccidere un processo in Linux

Comando Ps in Linux (Elenca processi)

Comando Pstree in Linux

Kill Command in Linux

Monitoraggio dei processi su Linux

Come KILL un processo su Linux