blog:qui_ecoute

Qui écoute ?

lsof(8) a une option -i qui liste le ou les processus qui correspondent à la spécification. Exemple avec le port 53 (DNS) :

$ lsof -i :53
COMMAND PID USER   FD   TYPE     DEVICE SIZE/OFF NODE NAME
named   164 root   20u  IPv4 0xc46d8dac      0t0  TCP foo.local.net:domain (LISTEN)
named   164 root   21u  IPv4 0xc46d8bb8      0t0  TCP localhost:domain (LISTEN)
named   164 root  512u  IPv4 0xc46c3ec4      0t0  UDP foo.local.net:domain
named   164 root  513u  IPv4 0xc46c3dec      0t0  UDP localhost:domain

On note que la sortie par défaut de lsof(8), dans la colonne TYPE est du type IPv4 ou IPv6. Une première solution consiste donc à se contenter de :

$ lsof | grep IPv
...

mais on veut quelque chose de plus précis : la commande précédente liste aussi les connexions ouvertes. Il faudrait donc les éliminer, par exemple avec | grep -v ESTABLISHED.

netstat(1) affiche les sockets avec l'option -a et limite à IPv4 ou IPv6 selon -f inet ou -f inet6 :

$ netstat -an -f inet
tcp        0      0  127.0.0.1.63805        127.0.0.1.25           TIME_WAIT
tcp        0      0  127.0.0.1.9000         127.0.0.1.63806        TIME_WAIT
tcp        0      0  127.0.0.1.4949         127.0.0.1.63941        ESTABLISHED
tcp        0      0  127.0.0.1.6012         *.*                    LISTEN
tcp        0      0  192.168.1.254.22       192.168.1.122.53695    ESTABLISHED
tcp        0      0  192.168.1.254.8443     *.*                    LISTEN
[...]
udp        0      0  *.5353                 *.*                   
udp        0      0  *.514                  *.*                   
[...]

donc pour avoir une liste des sokets ouvertes, n'affichons plus que la quatrième colonne des lignes qui nous intéressent :

$ netstat -lan -f inet | awk '/(udp|LISTEN)/{ print $4 }'
...

Pour transformer cette liste en une liste des ports (indépendamment de l'adresse) ouverts, il faut encore filtrer :

$ sudo netstat -lan -f inet | perl -e 'my %l;
       while (<>) {
         chomp;
         next if (not /udp|LISTEN/);
         @a = split /\./, (split /\s+/)[3]; $l{$a[$#a]} = $a[$#a];
       };
       foreach $p (sort keys %l) { print $p . "\n" }'

Le hachage %l permet de s'économiser le test d'unicité ; il contient (clef et valeur) la chaine après le dernier . (soit le port) pour chaque ligne matchant udp ou LISTEN.

Plus qu'à passer cette liste à lsof(8) :

$ for p in $(... ma commande de la mort tue...); do lsof -i :$p; done
  • blog/qui_ecoute.txt
  • Dernière modification : 2013/03/17 11:26
  • de pc