viernes, 19 de diciembre de 2014

Conocer el proceso que escucha en un puerto

A modo de análisis de un servidor Linux, en ocasiones es útil disponer de un listado de servicios que están a la escucha en distintos puertos.
Mediante el comando netstat se puede obtener esta información. Veamos un ejemplo:

# netstat -lnp --inet
Conexiones activas de Internet (solo servidores)
Proto  Recib Enviad Dirección local         Dirección remota       Estado       PID/Program name
tcp        0      0 0.0.0.0:80              0.0.0.0:*               ESCUCHAR    953/apache2
tcp        0      0 0.0.0.0:22              0.0.0.0:*               ESCUCHAR    670/sshd
tcp        0      0 0.0.0.0:25              0.0.0.0:*               ESCUCHAR    871/master
tcp        0      0 0.0.0.0:5666            0.0.0.0:*               ESCUCHAR    773/nrpe
Los parámetros usados indican:
-l para mostrar los sockets a la escucha.
-n para que no resuelva las IPs en nombres.
-p para indicar el PID de quien está a la escucha en ese puerto.
--inet para que muestre solo las conexiones de la familia inet (raw, tcp y udp).
En este ejemplo se observa que el puerto 5666 está siendo usado por el proceso con PID 773 y con nombre nrpe.
Usando el comando ps podríamos obtener más información acerca del comando, como los parámetros que se le pasaron para su ejecución:
# ps -ef | grep 773
nagios     773     1  0 Nov25 ?        00:03:44 /usr/sbin/nrpe -c /etc/nagios/nrpe.cfg -d
Por último, y a modo de inventario, se podría generar un sencillo script que dijese qué procesos tienen qué puertos abiertos:
#!/bin/sh

LINEAS=$(netstat -lnp | grep -E "^..p.*ESCUCHAR" | tr -s "  " " " | tr -s ":" " " | tr -s "/" " " | cut -d " " -f 1,5,9 | tr -s " " "-")

for LINEA in $LINEAS;
do
  PUERTO=$(echo $LINEA | cut -d "-" -f 2)
  PROTO=$(echo $LINEA | cut -d "-" -f 1)
  PID=$(echo $LINEA | cut -d "-" -f 3)
  PROCESO=$(ps -ef | grep -E "^[a-zA-Z\-]*\ *$PID" | tr -s "  " " " | cut -d " " -f 8-)
  echo "$PUERTO $PROTO: $PROCESO"
done