Quel process écoute sur un port

De UnixManiax
Aller à : navigation, rechercher


Lorsqu'un port tcp/ip est à l'écoute, il est parfois utile de savoir quel est le process correspondant. Pour le port 22, tout admin système sait que c'est ssh, mais certains ports ne peuvent pas se deviner.

Sous Solaris, pour répondre à cette question, le plus simple est d'utiliser lsof, mais il n'est pas installé par défaut. Sinon on peut utiliser des scripts qui se basent sur la commande pfiles. C'est beaucoup, beaucoup plus long à répondre que lsof, mais normalement ça marche sur tous les Solaris de base.

Ci-dessous, on va voir quels process écoutent sur le port 5666. Pour commencer, on vérifie que le port est bien à l'écoute.

# netstat -an |grep LISTEN |grep 5666
      *.5666               *.*                0      0 49152      0 LISTEN

Avec lsof

# lsof -i :5666
COMMAND   PID   USER   FD   TYPE        DEVICE SIZE/OFF NODE NAME
nrpe     9736 nagios    5u  IPv4 0x3008c674040      0t0  TCP *:5666 (LISTEN)
nrpe    10507 nagios    5u  IPv4 0x3011dd44340      0t0  TCP *:5666 (LISTEN)
nrpe    11080 nagios    5u  IPv4 0x30102752e00      0t0  TCP *:5666 (LISTEN)
nrpe    12388 nagios    5u  IPv4 0x6007a842400      0t0  TCP *:5666 (LISTEN)
nrpe    12573 nagios    5u  IPv4 0x300d05ac7c0      0t0  TCP *:5666 (LISTEN)
nrpe    15447 nagios    5u  IPv4 0x3011ebff540      0t0  TCP *:5666 (LISTEN)
nrpe    16331 nagios    5u  IPv4 0x3015ac4eac0      0t0  TCP *:5666 (LISTEN)
nrpe    16444 nagios    5u  IPv4 0x30159e15c40      0t0  TCP *:5666 (LISTEN)
nrpe    18492 nagios    5u  IPv4 0x3015add71c0      0t0  TCP *:5666 (LISTEN)
nrpe    25023 nagios    5u  IPv4 0x300cfdf55c0      0t0  TCP *:5666 (LISTEN)

Avec un script ksh

Voici le script (récupéré sur le net).

#!/usr/bin/ksh
ID=`id | cut -f 2 -d '=' | cut -f 1 -d '('`
if [ $ID -ne 0 ] ; 
then 
        echo >&2 "Need to be run by root"
        exit 1 
fi
i=0
while getopts :p:P:a opt
do
case "${opt}" in
p ) port="${OPTARG}";i=3;;
P ) pid="${OPTARG}";i=3;;
a ) all=all;i=2;;
esac
done
if [ $OPTIND != $i ]
then
echo >&2 "usage: $0 [-p PORT] [-P PID] [-a] (Wildcards OK) "
exit 1
fi
shift `expr $OPTIND - 1`
if [ "$port" ]
then
# Enter the port number, get the PID
#
port=${OPTARG}
echo "PID\tProcess Name and Port"
echo "_________________________________________________________"
for proc in `ptree -a | awk '/ptree/ {next} {print $1};'`
do
result=`pfiles $proc 2> /dev/null| egrep "port: $port$"`
if [ ! -z "$result" ]
then
program=`ps -fo comm= -p $proc`
echo "$proc\t$program\t$port\n$result"
echo "_________________________________________________________"
fi
done
elif [ "$pid" ]
then
# Enter the PID, get the port
#
pid=$OPTARG
# Print out the information
echo "PID\tProcess Name and Port"
echo "_________________________________________________________"
for proc in `ptree -a | awk '/ptree/ {next} $1 ~ /^'"$pid"'$/ {print $1};'`
do
result=`pfiles $proc 2> /dev/null| egrep port:`
if [ ! -z "$result" ]
then
program=`ps -fo comm= -p $proc`
echo "$proc\t$program\n$result"
echo "_________________________________________________________"
fi
done
elif [ $all ]
then
# Show all PIDs, Ports and Peers
#
echo "PID\tProcess Name and Port"
echo "_________________________________________________________"
for proc in `ptree -a | sort -n | awk '/ptree/ {next} {print $1};'`
do
out=`pfiles $proc 2>/dev/null| egrep "port:"`
if [ ! -z "$out" ]
then
name=`ps -fo comm= -p $proc`
echo "$proc\t$name\n$out"
echo "_________________________________________________________"
fi
done
fi
exit 0


Avec un script perl

Voici le script, également trouvé sur le net.

#! /usr/bin/env perl
##
## Search the processes which are listening on the given port.
##
## For SunOS 5.10.
##

use strict;
use warnings;

die "Port missing" unless $#ARGV >= 0;
my $port = int($ARGV[0]);
die "Invalid port" unless $port > 0;

my @pids;
map { push @pids, $_ if $_ > 0; } map { int($_) } `ls /proc`;

foreach my $pid (@pids) {
    open (PF, "pfiles $pid 2>/dev/null |") 
        || warn "Can not read pfiles $pid";
    $_ = <PF>;
    my $fd;
    my $type;
    my $sockname;
    my $peername;
    my $report = sub {
        if (defined $fd) {
            if (defined $sockname && ! defined $peername) {
                print "$pid $type $sockname\n"; } } };
    while (<PF>) {
        if (/^\s*(\d+):.*$/) {
            &$report();
            $fd = int ($1);
            undef $type;
            undef $sockname;
            undef $peername; }
        elsif (/(SOCK_DGRAM|SOCK_STREAM)/) { $type = $1; }
        elsif (/sockname: AF_INET[6]? (.*)  port: $port/) {
            $sockname = $1; }
        elsif (/peername: AF_INET/) { $peername = 1; } }
    &$report();
    close (PF); }