2009-12-30 4 views
27

Y a-t-il une bibliothèque Linux qui me permette de dire quelles sockets IP appartiennent à quels processus? Je suppose que je suis à la recherche de l'équivalent programmatique de lsof -i. En fin de compte, je veux corréler les paquets vus à travers libpcap aux processus.API Linux pour déterminer les sockets appartenant à un processus

MISE À JOUR: Quelques personnes ont suggéré d'utiliser /proc/<pid>/net/tcp et udp, mais sur mon système, les mêmes données sont affichées pour chaque processus, il ne vous aide pas.

+0

oh wow. J'écris un programme pour faire juste cela maintenant, quelle coïncidence –

+1

J'ai le code maintenant si vous êtes intéressé par la comparaison des notes. J'ai vu quelques bizarreries rares dans les données/proc, mais dans l'ensemble l'approche fonctionne. –

Répondre

45

Je pense que vous devez d'abord regarder à travers les fds ouverts dans/proc/*/fd, par exemple.

4 -> socket:[11147] 

puis chercher les prises référencés (par le inode) dans/proc/net/tcp (ou/proc/net/udp), par exemple

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

Ceci est le lien manquant. Merci! (Je ne me laisserai pas revenir pour une raison quelconque.) –

+0

Vous avez répondu à cette question pendant que j'écrivais, et je n'ai pas remarqué ... bon travail :) +1 puisque OP ne peut apparemment pas. – ephemient

+0

Cette réponse pourrait être encore meilleure si les inodes dans les 2 exemples se correspondent. – Samveen

4

Vous pouvez les lire à partir système de fichiers proc. Les fichiers « » que vous voulez probablement regarder se trouvent dans /proc/<pid>/net (à savoir tcp, udp, unix)

Voici quelques examples sur l'utilisation du système de fichiers proc

+0

+1 vraiment utile ... merci :) –

+1

Peut-être qu'il me manque quelque chose, mais/proc/*/net/tcp montre les mêmes données pour différents pids. Doit montrer toutes les connexions. Comment puis-je mapper chacun d'entre eux au pid source? –

11

Le système de fichiers /proc fournit des informations détaillées sur chaque processus, y compris la mise en réseau information. Les informations de socket ouvert sont répertoriées dans /proc/net/tcp. Les sockets IPv6 sont répertoriés séparément dans le fichier tcp6. Les informations de prise de courant comprend des informations telles que les ports locaux et distants, et la douille numéro de i-node, qui peuvent être mappées vers le procédé en analysant les informations /proc/{pid}/fd/*.

Si vous n'êtes pas familier avec le système de fichiers /proc, il s'agit essentiellement d'un système de fichiers virtuel qui permet au noyau de publier toutes sortes d'informations utiles dans l'espace utilisateur. Les fichiers sont normalement des fichiers texte structurés simples et faciles à analyser.

Par exemple, sur mon système Ubuntu j'ai utilisé netcat pour les tests, et courut nc -l -p 8321 écouter sur le port 8321. En regardant les informations de prise tcp:

$ 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 première ligne montre qu'il est à l'écoute sur toutes les adresses au point 8321 (0x2081). Le numéro d'inode est 26442, que nous pouvons utiliser pour rechercher le pid correspondant dans /proc/{pid}/fd/*, qui consiste en un tas de liens symboliques à partir du numéro de descripteur de fichier sur le périphérique. Donc, si nous regardons le pid pour netcat, et vérifier son fd mapping:

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

Et là, nous voyons que le descripteur de fichier 3 dans ce processus est associé à la prise avec inode 26442, tout comme nous attendons.

Alors, évidemment, de construire une carte complète de prises, vous devez d'abord énumérer tous les /proc/**/fd/* fichiers, rechercher les sockets symlinks, correspondent alors la prise inode sur les tables de /proc/net/tcp qui a l'information point final.

C'est la manière dont fonctionne l'outil lsof (voir lsof/dialects/linux/dsocket.c pour la mise en œuvre).

+0

Même question que pour Kimvais: Les répertoires/proc/*/net/tcp montrent les mêmes données pour différents pids. Comment puis-je mapper chacun d'entre eux au pid source? –

+0

J'ai mis à jour la réponse pour inclure une description complète de la façon de mapper les prises aux pids. J'espère que ceci est plus clair maintenant - cela implique essentiellement de construire une table de pids à inodes de socket, et de rechercher ces inodes dans la table socket tcp. Faites-moi savoir s'il y a quelque chose qui a besoin d'être clarifié. – gavinb

+0

Très clair. Merci! –

3

Vous pouvez essayer d'exécuter lsof avec strace et voir à quels fichiers/proc il obtient des données.

+0

directement au point –

5

/proc/<pid>/net est équivalent à /proc/net pour tous les processus dans le même espace de noms de réseau que vous – autrement dit, il est l'information « globale ».

Vous pouvez faire ce que lsof et fuser faire, ce qui est à la fois itérer /proc/<pid>/fd/* et /proc/net/* recherche inodes correspondant. démonstration rapide:

#!/bin/sh 
pgrep "[email protected]" | while read pid; do 
    for fd in /proc/$pid/fd/*; do 
     name=$(readlink $fd) 
     case $name in 
      socket:\[*\]) 
       ino=${name#*:} 
       for proto in tcp:10 tcp6:10 udp:10 udp6:10 unix:7; do 
        [[ ! -e /proc/net/${proto%:*} ]] || 
        awk " 
         \$${proto##*:} == ${ino:1:${#ino}-2} { 
          print \"${proto%:*}:\", \$0 
          exit 1 
         } 
        " /proc/net/${proto%:*} || break 
       done 
       ;; 
     esac 
    done 
done 

Vous pouvez étendre à d'autres protocoles (je vois AX25, ipx, paquet, cru, raw6, udplite, udp6lite dans /proc/net/ aussi) ou réécrire dans une langue de votre choix.

12

Pour déterminer les sockets appartenant à un processus, vous pouvez simplement utiliser netstat. Voici un exemple w/output (raccourci) de netstat avec des options qui feront ce que vous voulez.

$ 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 

Assurez-vous que vous exécutez netstat en tant que root sinon vous obtiendrez ce message:

(Not all processes could be identified, non-owned process info 
will not be shown, you would have to be root to see it all.) 

Une explication des -apeen options du netstat manpage:

-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. 
+0

vous pouvez obtenir le pid si vous sudo au propriétaire de ce processus (si vous ne pouvez pas obtenir la racine). +1 sur cette solution! Merci! – gred

+1

'netstat' analysera réellement'/proc/net/tcp' et al. voir, par exemple, [ici] (http://sourceforge.net/p/net-tools/code/ci/master/tree/netstat.c#l979) (code d'analyse pour '/ proc/net/tcp') . Chemins utilisés par netstat définis dans 'lib/pathnames.h'. – z9u2k

Questions connexes