Come trovare l'altra estremità della connessione socket unix?


44

Ho un processo (dbus-daemon) che ha molte connessioni aperte su socket UNIX. Una di queste connessioni è fd # 36:

=$ ps uw -p 23284
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
depesz   23284  0.0  0.0  24680  1772 ?        Ss   15:25   0:00 /bin/dbus-daemon --fork --print-pid 5 --print-address 7 --session

=$ ls -l /proc/23284/fd/36 
lrwx------ 1 depesz depesz 64 2011-03-28 15:32 /proc/23284/fd/36 -> socket:[1013410]

=$ netstat -nxp | grep 1013410
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
unix  3      [ ]         STREAM     CONNECTED     1013410  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD

=$ netstat -nxp | grep dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1013953  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1013825  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1013726  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1013471  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1013410  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1012325  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1012302  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1012289  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1012151  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011957  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011937  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011900  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011775  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011771  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011769  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011766  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011663  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011635  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011627  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011540  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011480  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011349  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011312  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011284  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011250  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011231  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011155  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011061  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011049  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011035  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011013  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1010961  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1010945  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD

Sulla base di connessioni numeriche, suppongo che dbus-daemon sia in realtà un server. Che va bene Ma come posso trovare quale processo è collegato ad esso - usando la connessione che è il 36esimo file handle in dbus-launcher? Ho provato lsof e anche greps su / proc / net / unix ma non riesco a trovare un modo per trovare il processo client.


Risposte:


25

Molto recentemente mi sono imbattuto in un problema simile. Sono rimasto scioccato nello scoprire che ci sono casi in cui ciò potrebbe non essere possibile. Ho raccolto un commento dal creatore di lsof (Vic Abell) in cui ha sottolineato che questo dipende fortemente dall'implementazione del socket unix. A volte sono disponibili le informazioni cosiddette "endpoint" per socket e altre volte no. Sfortunatamente è impossibile in Linux come sottolinea.

Su Linux, ad esempio, dove lsof deve usare / proc / net / unix, tutti i socket di dominio UNIX hanno un percorso associato, ma nessuna informazione sull'endpoint. Spesso non esiste un percorso associato. Ciò spesso rende impossibile determinare l'altro endpoint, ma è il risultato dell'implementazione del file system Linux / proc.

Se guardi / proc / net / unix puoi vedere da solo che (almeno sul mio sistema) ha assolutamente ragione. Sono ancora scioccato, perché trovo tale funzionalità essenziale durante il monitoraggio dei problemi del server.



Nota che /proc/net/unixti dirà il file di destinazione di un riferimento socket di dominio casuale da cui hai estratto /proc/.../fd/.
i336_

27

Questa risposta è solo per Linux. Sulla base di una risposta dallo scambio di stack Unix e Linux, ho identificato con successo l'altra estremità di un socket di dominio unix utilizzando strutture di dati nel kernel, cui si accede tramite gdbe /proc/kcore. È necessario abilitare le opzioni CONFIG_DEBUG_INFOe del CONFIG_PROC_KCOREkernel.

È possibile utilizzare lsofper ottenere l'indirizzo del kernel del socket, che assume la forma di un puntatore, ad es 0xffff8803e256d9c0. Quel numero è in realtà l'indirizzo della struttura o del tipo di memoria nel kernel rilevante struct unix_sock. Tale struttura ha un campo chiamato peerche punta all'altra estremità del socket. Quindi i comandi

# gdb /usr/src/linux/vmlinux /proc/kcore
(gdb) p ((struct unix_sock*)0xffff8803e256d9c0)->peer

stamperà l'indirizzo dell'altra estremità della connessione. È possibile visualizzare l'output di lsof -Uper quel numero per identificare il processo e il numero del descrittore di file dell'altra estremità.

Alcune distribuzioni sembrano fornire i simboli di debug del kernel come pacchetto separato, che prenderebbe il posto del vmlinuxfile nel comando sopra.


Sembra interessante, ma il requisito per ricompilare il kernel sembra essere eccessivo. Sto pensando che forse sarebbe possibile farlo, senza kernel fatto a mano, e senza usare gdb, semplicemente dando una occhiata ai valori in kcore e facendo una decodifica "manuale" dei valori.

3
@depesz, tutto ciò che devi sapere è l'offset del peermembro nella unix_sockstruttura. Sul mio sistema x86_64, quell'offset è di 656 byte, quindi ho potuto ottenere quell'altra estremità usando p ((void**)0xffff8803e256d9c0)[0x52]. Hai ancora bisogno CONFIG_PROC_KCORE, ovviamente.
MvG

12

In realtà, ssda iproute2(sostituzione per netstat, ifconfig, ecc.) Può mostrare queste informazioni.

Ecco un esempio che mostra un socket di dominio unix ssh-agent a cui sshè connesso un processo:

$ sudo ss -a --unix -p
Netid  State      Recv-Q Send-Q Local                             Address:Port          Peer    Address:Port
u_str  ESTAB      0      0      /tmp/ssh-XxnMh2MdLBxo/agent.27402 651026                *       651642                users:(("ssh-agent",pid=27403,fd=4)
u_str  ESTAB      0      0       *                                651642                *       651026                users:(("ssh",pid=2019,fd=4))

Hmm. Interessante ... Mi ero perso che le colonne "Indirizzo: Porta" possono essere abbinate, anche se la colonna "Peer" è totalmente inutile per i socket di dominio unix.
SamB,

9

Alle prese Unix di solito vengono assegnati numeri in coppia e di solito sono consecutivi. Quindi la coppia per te sarebbe probabilmente 1013410 +/- 1. Scopri quale di questi due esiste e indovina il colpevole.


8

Ho scritto uno strumento che utilizza il metodo gdb di MvG per ottenere in modo affidabile informazioni sui peer dei socket, simboli di debug del kernel non necessari.

Per connettere il processo a un determinato socket, passagli il numero di inode:

# socket_peer 1013410
3703 thunderbird 

Per scoprire tutti i processi contemporaneamente netstat_unix, aggiunge una colonna all'output di netstat:

# netstat_unix
Proto RefCnt Flags       Type       State         I-Node   PID/Program name     Peer PID/Program name  Path
unix  3      [ ]         STREAM     CONNECTED     6825     982/Xorg             1497/compiz            /tmp/.X11-unix/X0
unix  3      [ ]         STREAM     CONNECTED     6824     1497/compiz          982/Xorg                 
unix  3      [ ]         SEQPACKET  CONNECTED     207142   3770/chromium-brows  17783/UMA-Session-R       
unix  3      [ ]         STREAM     CONNECTED     204903   1523/pulseaudio      3703/thunderbird       
unix  3      [ ]         STREAM     CONNECTED     204902   3703/thunderbird     1523/pulseaudio           
unix  3      [ ]         STREAM     CONNECTED     204666   1523/pulseaudio      3703/thunderbird       
...

Prova netstat_unix --dumpse hai bisogno di un output facile da analizzare.
Vedi https://github.com/lemonsqueeze/unix_sockets_peers per i dettagli.

Per informazioni, l' inode + 1 / -1 hack non è affidabile. Funziona la maggior parte delle volte ma fallirà o (peggio) restituirà il socket sbagliato se sei sfortunato.


1

Modifica il tuo system.conf

In questo file è possibile aggiungere più elementi a scopo di debug.

Posizione del file: /etc/dbus-1/system.conf

Ai fini del debug, è possibile modificare il file system.conf per consentire l'intercettazione:

  1. sostituire la sezione politica con:

    <policy context="default">

    <!-- Allow everything to be sent -->

    <allow send_destination="*" eavesdrop="true"/>

    <!-- Allow everything to be received -->

    <allow eavesdrop="true"/>

    <!-- Allow anyone to own anything -->

    <allow own="*"/>

    <!-- XXX: Allow all users to connect -->

    <allow user="*"/> </policy>

  2. Rimuovere la linea inclusa: system.d

    <includedir>system.d</includedir>

Fonte: http://old.nabble.com/dbus-send-error-td29893862.html


Alcune altre cose utili riguardanti i socket unix

Il modo più semplice per capire cosa sta succedendo sul bus è eseguire il dbus-monitorprogramma, che viene fornito con il pacchetto D-Bus

Inoltre, puoi provare a utilizzare dbus-cleanup-socketsper pulire le prese rimanenti.

Il comando seguente mostra quale processo è collegato quante volte ai socket dbus in base netstatall'output:

sudo netstat -nap | grep dbus | grep CONNECTED | awk '{print $8}' | sort | uniq -c

(testato su Ubuntu)

Modo hardcore: questo comando troverà manualmente i processi da / proc e mostrerà quali stanno usando il maggior numero di connessioni (tutti i tipi di socket):

ls -lR */fd/* | grep socket | sed -r "s@([0-9{1}]+)/fd/@_\1_@g" | awk -F_ '{print $2}' | uniq -c | sort -n | awk '{print $1" "$2; print system("ps "$2"|tail -n1")}'

Esempio di output:

(conteggio, PID e la riga successiva contiene dettagli sul processo)

25 3732
 3732 ?        Ss     0:38 /usr/bin/wineserver
89 1970
 1970 ?        Ss     0:02 //bin/dbus-daemon --fork --print-pid 5 --print-address 7 --session

(testato su Ubuntu)

Divertiti.


Vedi anche articoli correlati per il riferimento:

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.