Comment trouver l'autre extrémité de la connexion de socket Unix?


44

J'ai un processus (dbus-daemon) qui a beaucoup de connexions ouvertes sur des sockets UNIX. L'un de ces liens est le numéro 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

Basé sur le nombre de connexions, je suppose que dbus-daemon est en fait un serveur. Ce qui est OK Mais comment puis-je trouver le processus qui y est connecté - en utilisant la connexion qui est le 36e descripteur de fichier dans dbus-launcher? J'ai essayé lsof et même greps sur / proc / net / unix mais je n'arrive pas à trouver un moyen de trouver le processus client.


Réponses:


25

Tout récemment, je suis tombé sur un problème similaire. J'ai été choqué d'apprendre qu'il y avait des cas où cela pourrait ne pas être possible. J'ai découvert un commentaire du créateur de lsof (Vic Abell) dans lequel il soulignait que cela dépendait beaucoup de la mise en œuvre de la socket Unix. Parfois, les informations dites "d'extrémité" pour socket sont disponibles et parfois non. Malheureusement, il est impossible sous Linux, comme il le fait remarquer.

Sous Linux, par exemple, où lsof doit utiliser / proc / net / unix, tous les sockets de domaine UNIX ont un chemin d'accès lié, mais pas d'informations de point de terminaison. Souvent, il n'y a pas de chemin lié. Cela rend souvent impossible de déterminer l'autre extrémité, mais cela résulte de la mise en œuvre du système de fichiers Linux / proc.

Si vous regardez / proc / net / unix, vous pouvez constater par vous-même que (du moins sur mon système), il a absolument raison. Je suis toujours sous le choc, car je trouve cette fonctionnalité essentielle lors du suivi des problèmes de serveur.



Notez que /proc/net/unixvous indiquera le fichier cible d'une référence de socket de domaine aléatoire que vous avez extraite /proc/.../fd/.
i336_

27

Cette réponse concerne uniquement Linux. Sur la base d’ une réponse fournie par Unix et Linux Stack Exchange, j’ai réussi à identifier l’autre extrémité d’un socket de domaine Unix à l’aide de structures de données dans le noyau, accessibles à l’aide de gdbet /proc/kcore. Vous devez activer les options CONFIG_DEBUG_INFOet du CONFIG_PROC_KCOREnoyau.

Vous pouvez utiliser lsofpour obtenir l'adresse du noyau de la socket, qui prend la forme d'un pointeur, par exemple 0xffff8803e256d9c0. Ce numéro est en fait l'adresse de la structure ou du type de mémoire dans le noyau concerné struct unix_sock. Cette structure a un champ appelé peerqui pointe à l’autre extrémité du socket. Donc les commandes

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

imprimera l'adresse de l'autre extrémité de la connexion. Vous pouvez grep la sortie de lsof -Uce numéro pour identifier le processus et le numéro de descripteur de fichier de cette autre extrémité.

Certaines distributions semblent fournir les symboles de débogage du noyau en tant que paquet séparé, qui prendrait la place du vmlinuxfichier dans la commande ci-dessus.


Cela semble intéressant, mais l’obligation de recompiler le noyau semble exagérée. Je pense qu'il serait peut-être possible de le faire, sans noyau fabriqué à la main, et sans utiliser gdb, simplement en jetant un œil aux valeurs dans kcore et en effectuant un décodage "manuel" des valeurs.

3
@depesz, tout ce que vous devez savoir, c'est le décalage du peermembre dans la unix_sockstructure. Sur mon système x86_64, ce décalage est de 656 octets, je pourrais donc obtenir cette autre fin en utilisant p ((void**)0xffff8803e256d9c0)[0x52]. Vous avez toujours besoin CONFIG_PROC_KCORE, évidemment.
MVG le

12

En fait, ssde iproute2(remplacement de netstat, ifconfig, etc.) peut afficher cette information.

Voici un exemple montrant un socket de domaine unix ssh-agent auquel un sshprocessus a été connecté:

$ 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. Intéressant ... J'avais loupé que les colonnes "Adresse: Port" pouvaient être associées, même si la colonne "Peer" était totalement inutile pour les sockets de domaine Unix.
SamB

9

Les sockets Unix se voient généralement attribuer des numéros par paires et sont généralement consécutifs. Donc, la paire pour vous serait probablement 1013410 +/- 1. Voyez lequel de ces deux existe et devinez le coupable.


8

J'ai écrit un outil qui utilise la méthode gdb de MvG pour obtenir de manière fiable des informations d'homologue de socket, les symboles de débogage du noyau n'étant pas nécessaires.

Pour que le processus soit connecté à un socket donné, transmettez-lui le numéro d'inode:

# socket_peer 1013410
3703 thunderbird 

Pour savoir si tous les processus sont utilisés en même temps netstat_unix, une colonne est ajoutée à la sortie de 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       
...

Essayez netstat_unix --dumpsi vous avez besoin d'une sortie facile à analyser.
Voir https://github.com/lemonsqueeze/unix_sockets_peers pour plus de détails.

Pour info, l' inode + 1 / -1 bidouille n'est pas fiable. Cela fonctionne la plupart du temps mais échouera ou (pire) retournera le mauvais socket si vous n'avez pas de chance.


1

Editez votre system.conf

Dans ce fichier, vous pouvez ajouter plus de choses à des fins de débogage.

Emplacement du fichier: /etc/dbus-1/system.conf

À des fins de débogage, vous pouvez éditer votre system.conf pour permettre l’écoute:

  1. remplacer la section de la politique par:

    <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. Supprimez la ligne includedir: system.d

    <includedir>system.d</includedir>

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


Quelques autres trucs utiles concernant les sockets unix

Le moyen le plus simple de comprendre ce qui se passe dans le bus consiste à exécuter le dbus-monitorprogramme fourni avec le package D-Bus.

Vous pouvez aussi essayer d’utiliser dbus-cleanup-socketspour nettoyer les sockets restants.

La commande suivante vous montrera quel processus est connecté combien de fois aux sockets dbus en fonction de la netstatsortie:

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

(testé sur Ubuntu)

Hardcore way: Cette commande trouvera manuellement les processus de / proc et montrera ceux qui utilisent le plus de connexions (tout type de sockets):

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")}'

Exemple de sortie:

(count, PID et la ligne suivante contient des détails sur le processus)

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

(testé sur Ubuntu)

S'amuser.


Voir également les articles connexes pour la référence:

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.