GNU/Linux >> Tutoriels Linux >  >> Linux

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

Solution 1 :

Cette réponse est pour Linux uniquement.

Mise à jour pour Linux 3.3 : Comme Zulakis l'a écrit dans une réponse séparée (+1 cela), vous pouvez utiliser ss de iproute2 pour obtenir une paire de numéros d'inode pour chaque connexion de socket identifiant l'extrémité locale et l'homologue. Cela semble être basé sur le même mécanisme que sock_diag(7) avec le UNIX_DIAG_PEER attribut identifiant le pair. Une réponse de Totor sur Unix &Linux Stack Exchange renvoie aux commits pertinents dans le noyau et iproute2 et mentionne également la nécessité du UNIX_DIAG paramètre de configuration du noyau.

La réponse originale pour Linux pré 3.3 suit.

Sur la base d'une réponse de Unix &Linux Stack Exchange, j'ai identifié avec succès l'autre extrémité d'un socket de domaine unix à l'aide de structures de données dans le noyau, accessibles à l'aide de gdb et /proc/kcore . Vous devez activer le CONFIG_DEBUG_INFO et CONFIG_PROC_KCORE options du noyau.

Vous pouvez utiliser lsof pour obtenir l'adresse du noyau du socket, qui prend la forme d'un pointeur, par ex. 0xffff8803e256d9c0 . Ce numéro est en fait l'adresse de la structure de mémoire interne pertinente ou du type struct unix_sock . Cette structure a un champ appelé peer qui pointe vers l'autre extrémité de la douille. 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 -U pour ce numéro afin d'identifier le processus et le numéro de descripteur de fichier de cette autre extrémité.

Certaines distributions semblent fournir des symboles de débogage du noyau dans un package séparé, qui remplacerait le vmlinux fichier dans la commande ci-dessus.

Solution 2 :

Tout récemment, je suis tombé sur un problème similaire. J'ai été choqué d'apprendre qu'il y a des cas où cela pourrait ne pas être possible. J'ai déterré un commentaire du créateur de lsof (Vic Abell) où il a souligné que cela dépend fortement de l'implémentation du socket Unix. Parfois, les informations dites "endpoint" pour socket sont disponibles et parfois non. Malheureusement, c'est impossible sous Linux, comme il le souligne.

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 aucune information de point de terminaison. Souvent, il n'y a pas de chemin lié. Cela rend souvent impossible de déterminer l'autre point de terminaison, mais c'est le résultat de l'implémentation du système de fichiers Linux /proc.

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

Solution 3 :

En fait, ss à partir de iproute2 (remplacement de netstat, ifconfig, etc.) peut afficher ces informations.

Voici un exemple montrant un socket de domaine unix ssh-agent auquel un ssh le processus s'est 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))

Solution 4 :

Sockets Unix habituellement se voient 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.

Solution 5 :

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

Pour connecter le processus à un socket donné, passez-lui le numéro d'inode :

# socket_peer 1013410
3703 thunderbird 

Pour le savoir pour tous les processus à la fois, utilisez netstat_unix , il ajoute une colonne à 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 --dump si vous avez besoin d'une sortie facile à analyser.
Voir https://github.com/lemonsqueeze/unix_sockets_peers pour plus de détails.

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


Linux
  1. Guide pratique :programmation de sockets en Python

  2. Comment trouver tous les fichiers appartenant à un utilisateur spécifique sous Unix/Linux ?

  3. Comment trouver le répertoire personnel d'un utilisateur sous Linux ou Unix ?

  4. Comment trouver la taille du tampon de socket de Linux

  5. Comment supprimer une connexion de socket CLOSE_WAIT

Comment trouver des fichiers sous Linux

Comment savoir si un package est installé ou non sous Linux et Unix

Comment trouver une adresse IP sous Linux

Comment trouver le nom d'hôte sous Linux

Comment basculer l'écoute PHP-FPM sur le socket Unix

Comment trouver des fichiers dans Debian