Suchen nach einem kurzlebigen TCP-Verbindungsbesitzerprozess


14

Als tcpdumpich auf lokalen Verbindungen zu einem Apache-Server lief, stellte ich fest, dass alle 2 Sekunden TCP-Verbindungen hergestellt und sofort geschlossen wurden. Wie finde ich, welcher Prozess dafür verantwortlich ist? netstat -ctphat nicht geholfen, die Verbindungen waren zu schnell und die Prozesskennung wird für TIME_WAIT nicht angezeigt.

Es stellte sich heraus, dass es sich um Haproxy-Sonden handelte, die ich überprüfen konnte strace, aber ich weiß immer noch nicht, wie ich Haproxy überhaupt lokalisieren kann.

Antworten:


19

Sie können das auditd-Framework für diese Art von Dingen verwenden. Sie sind nicht sehr "benutzerfreundlich" oder intuitiv, weshalb Sie sich ein wenig umsehen müssen.

Stellen Sie zunächst sicher, dass auditd installiert ist und ausgeführt wird und dass Ihr Kernel dies unterstützt.
Für Ubuntu können Sie es apt-get install auditdzum Beispiel mit installieren .

Anschließend fügen Sie eine Richtlinie für die Überwachung connecthinzu , um alle Systemaufrufe wie folgt zu überwachen :

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

Wenn Sie eine 32-Bit-Installation von Linux verwenden, müssen Sie b64 in b32 ändern.

Mit diesem Befehl wird eine Richtlinie in das Überwachungsframework eingefügt, und alle connect () - Systemaufrufe werden (normalerweise /var/log/audit/audit.log) in Ihren Überwachungsprotokolldateien protokolliert, damit Sie sie anzeigen können .

Eine Verbindung mit netcat zu Port 80 von news.ycombinator.com führt beispielsweise zu folgendem Ergebnis:

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

Hier können Sie sehen, dass die Anwendung /bin/nc.openbsd einen connect () -Aufruf initiiert hat. Wenn Sie viele connect-Aufrufe erhalten und nur eine bestimmte IP oder einen bestimmten Port abrufen möchten, müssen Sie eine Konvertierung durchführen. Die SOCKADDR-Zeile enthält ein saddr-Argument. Sie beginnt mit 0200, gefolgt von der Portnummer in Hexadezimal (0050), was 80 bedeutet, und der IP in Hexadezimal (AE84E16A), die die IP von news.ycombinator.com von 174.132.225.106 ist.

Das Audit-Framework kann eine Vielzahl von Protokollen generieren. Denken Sie also daran, es zu deaktivieren, wenn Sie Ihre Mission erfüllt haben. Um die obige Richtlinie zu deaktivieren, ersetzen Sie einfach -a durch -d:

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

Gute Dokumentation zum auditd-Framework:
http://doc.opensuse.org/products/draft/SLES/SLES-security_sd_draft/part.audit.html

Konvertieren Sie IP-Adressen in / aus hexadezimal, dezimal, binär usw. unter:
http://www.kloth.net/services/iplocate.php

Allgemeiner Hex / Dec-Konverter:
http://www.statman.info/conversions/hexadecimal.html

Eine kurze Einführung in auditd aus dem IT Security Stack Exchange. http://security.blogoverflow.com/2013/01/a-brief-introduction-to-auditd/

Bearbeiten 1 :
Eine andere schnelle Methode, dies zu tun, besteht darin, eine schnelle Schleife zu erstellen, die die Verbindungsdaten zu Ihnen speichert, wie folgt:

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

Dieser Befehl verwendet den ssBefehl (Socket-Statistik), um die aktuell eingerichteten Verbindungen zu Port 80 zu sichern, einschließlich des Prozesses, von dem er initiiert wurde. Wenn es viele Daten gibt, die Sie hinzufügen können, | tee /tmp/outputum die Ausgabe auf dem Bildschirm anzuzeigen, und um sie für die spätere Verarbeitung / das Graben in / tmp / output zu schreiben. Wenn die schnelle Haproxy-Verbindung nicht hergestellt werden kann, versuchen Sie, sie zu entfernen. Seien Sie sleep 1jedoch vorsichtig, wenn es sich um einen stark ausgelasteten Computer handelt. Ändern Sie nach Bedarf!


Vielen Dank für die ausführliche Antwort. Ich nehme Ihr Wort für die auditd-Lösung, da der Host-Kernel sie nicht unterstützt und ich nicht die Zeit habe, eine geeignete Lösung zum Experimentieren zu finden, aber ich werde dies berücksichtigen. Was die Polling-Lösung angeht, habe ich mit lsof etwas Ähnliches begonnen, aber ziemlich schnell aufgehört, da es nicht ... befriedigend war.
Nachmittag

2
Sie können ausearch -idiese saddrhexadezimalen Zeichenfolgen auch automatisch für Ihre dekodieren lassen.
sch

ss ist befriedigender als lsof, weil es schneller ist und gute Filterregeln hat - grep ist nicht erforderlich. Ich kann die Probleme mit dem Support schätzen: Systemtap ist ein weiteres hervorragendes Tool, aber es kann nicht zufriedenstellend sein, es auf einem Produktionsserver zum Laufen zu bringen.
Max Murphy

1

Sie können auch die umfangreichen Protokolle von "ausearch -i" durchsuchen, um nur die Sockets anzuzeigen, die erfolgreich mit einem anderen Host im Internet verbunden sind. Ich habe ein vereinfachtes Skript geschrieben, um jeden Prozess und Befehl abzurufen, der einen Socket für die Verbindung mit einem Host im Internet erstellt hat, zusammen mit der Verbindungsadresse dieses Zielhosts und der aktuellen Uhrzeit, zu der der Socket "erstellt" wurde. Hier ist es:

#!/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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.