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