Encontrar el proceso del propietario de conexiones TCP de corta duración

15

Al ejecutar tcpdumpconexiones locales a un servidor apache, encontré que las conexiones TCP se establecían y cerraban inmediatamente cada 2 segundos. ¿Cómo encuentro qué proceso es responsable de estos? netstat -ctpno ayudó, las conexiones fueron demasiado rápidas y el identificador de proceso no se muestra para TIME_WAIT.

Resultó ser sondas de haproxy, con lo que pude verificar strace, pero todavía no conozco ninguna forma de identificar la haproxy en primer lugar.

pmezard
fuente

Respuestas:

20

Puede usar el marco auditado para este tipo de cosas. No son muy "fáciles de usar" o intuitivos, por lo que requiere un poco de investigación de su parte.

Primero asegúrese de haber auditado instalado, ejecutándose y de que su núcleo lo admita.
Para Ubuntu puedes instalarlo con, apt-get install auditdpor ejemplo.

Luego agrega una política de auditoría para monitorear todas las connectllamadas al sistema como esta:

auditctl -a exit,always -F arch=b64 -S connect -k MYCONNECT

Si está utilizando una instalación de Linux de 32 bits, debe cambiar b64 a b32.

Este comando insertará una política en el marco de auditoría, y todas las llamadas al sistema connect () ahora se registrarán en sus archivos de registro de auditoría (generalmente /var/log/audit/audit.log) para que pueda verlas .

Por ejemplo, una conexión con netcat al puerto 80 de news.ycombinator.com dará como resultado algo como esto:

type=SYSCALL msg=audit(1326872512.453:12752): arch=c000003e syscall=42 success=no exit=-115 a0=3 a1=24e8fa0 a2=10 a3=7fff07a44cd0 items=0 ppid=5675 pid=7270 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts4 ses=4294967295 comm="nc" exe="/bin/nc.openbsd" key="MYCONNECT"
type=SOCKADDR msg=audit(1326872512.453:12752): saddr=02000050AE84E16A0000000000000000

Aquí puede ver que la aplicación /bin/nc.openbsd inició una llamada connect (), si recibe muchas llamadas connect y solo quiere extraer una determinada IP o puerto, debe hacer alguna conversión. La línea SOCKADDR contiene un argumento saddr, comienza con 0200 seguido del número de puerto en hexadecimal (0050), que significa 80, y luego la IP en hexadecimal (AE84E16A), que es la IP de news.ycombinator.com de 174.132.225.106.

El marco de auditoría puede generar muchos registros, así que recuerde deshabilitarlo cuando haya cumplido su misión. Para deshabilitar la política anterior, simplemente reemplace -a con -d como tal:

auditctl -d exit,always -F arch=b64 -S connect -k MYCONNECT

Buena documentación sobre el marco auditado:
http://doc.opensuse.org/products/draft/SLES/SLES-security_sd_draft/part.audit.html

Convierta direcciones IP a / desde hexadecimal, dec, binario, etc.en:
http://www.kloth.net/services/iplocate.php

Convertidor general hexadecimal / dec:
http://www.statman.info/conversions/hexadecimal.html

Una breve introducción a auditado, de IT Security Stack Exchange. http://security.blogoverflow.com/2013/01/a-brief-introduction-to-auditd/

Edición 1 :
Otra forma rápida de hacerlo (sueco: fulhack) es crear un bucle rápido que te devuelva los datos de conexión, así:

while true;do
  ss -ntap -o state established '( dport = :80 )'
  sleep 1
done

Este comando usa el sscomando (estadísticas de socket) para volcar las conexiones establecidas actuales al puerto 80, incluido el proceso que lo inició. Si hay muchos datos que puede agregar | tee /tmp/outputdespués de haberlos hecho, tanto para mostrar la salida en la pantalla como para escribirla en / tmp / output para su posterior procesamiento / excavación. Si no detecta la conexión rápida de haproxy, intente eliminarla sleep 1pero tenga cuidado con el registro extenso si se trata de una máquina muy utilizada. ¡Modifique según sea necesario!

Mattias Ahnberg
fuente
Gracias por la respuesta detallada. Tomaré su palabra para la solución auditada ya que el núcleo del host no lo admite y ahora no tengo tiempo para encontrar una adecuada para la experimentación, pero lo tendré en cuenta. En cuanto a la solución de sondeo, comencé a hacer algo similar con lsof, pero me detuve bastante rápido, ya que no era ... satisfactorio.
pmezard
2
También puedes usar ausearch -ipara tener esas saddrcadenas hexadecimales decodificadas automáticamente para tu.
sch
ss es más satisfactorio que lsof porque es más rápido y tiene buenas reglas de filtrado, sin necesidad de grep. Puedo apreciar los problemas con el soporte: Systemtap es otra herramienta que es excelente, pero hacer que se ejecute en un servidor de producción puede ser ... no satisfactorio.
Max Murphy
1

También puede seleccionar los enormes registros que obtiene de "ausearch -i" para ver solo aquellos enchufes que se conectaron con éxito a otro host en Internet. Escribí una secuencia de comandos simplista para obtener cada proceso y comando que creó un socket para conectarse a un host en Internet junto con la dirección de conexión de ese host de destino y la hora actual en que se "creó" el socket. Aquí está:

#!/bin/bash

if [[ $EUID -ne 0 ]]; then

    echo "You must run this script as root boy!"
    exit 1  

fi

> proccessConnections.dat

connections=`ausearch -i | grep host: | awk -F "msg=audit" '{print $2}' | awk -F ": saddr" '{print $1}'`

connectionsNumber=`echo "$connections" | wc -l`

echo "Number of connections: $connectionsNumber"

echo "$connections" > conTemp.dat

let counter=1
while read connectInfo; do

    success=`ausearch -i | grep "$connectInfo" | grep "type=SYSCALL" | grep success=yes`    
    addressInfo=`ausearch -i | grep "$connectInfo" | grep type=SOCKADDR | awk -F ': ' '{print $2}'`
    processInfo=`ausearch -i | grep "$connectInfo" | grep "type=SYSCALL" | awk -F 'comm=' '{print $2}' | awk -F 'key' '{print $1}'` 

    if [[ $success != "" ]]
    then    
        echo "[$counter - $connectionsNumber] (success)     comm=$processInfo - $addressInfo - $connectInfo"
        echo "[$counter - $connectionsNumber] (success)     comm=$processInfo - $addressInfo - $connectInfo" >> proccessConnections.dat
    else
        echo "[$counter - $connectionsNumber] (no success)  comm=$processInfo - $addressInfo - $connectInfo"
        echo "[$counter - $connectionsNumber] (no success)  comm=$processInfo - $addressInfo - $connectInfo" >> proccessConnections.dat
    fi

    let counter++


done < conTemp.dat
Marcelo Silva
fuente