Wie kann ich den Netzwerkverkehr eines einzelnen Prozesses erfassen?

93

Ich würde gerne den Netzwerkverkehr untersuchen, der von einem einzelnen Prozess verarbeitet wird, aber einfache Netzwerkerfassungen funktionieren nicht, da ich mit einem so ausgelasteten System zu tun habe (viel anderer Verkehr geschieht zur gleichen Zeit). Gibt es eine Möglichkeit, den Netzwerkverkehr eines bestimmten Prozesses zu isolieren tcpdumpoder für diesen zu wiresharkerfassen? (Verwenden netstatist nicht ausreichend.)

Kees Cook
quelle

Antworten:

21

In der Tat gibt es einen Weg, die Wireshark- Filter zu verwenden. Sie können jedoch nicht direkt nach Prozessname oder PID filtern (da es sich nicht um eine Netzwerkgröße handelt).

Sie sollten zuerst die von Ihrem Prozess verwendeten Protokolle und Ports herausfinden (der Befehl netstat im vorherigen Kommentar funktioniert gut).

Verwenden Sie dann Wireshark, um den eingehenden (oder ausgehenden) Port mit demjenigen zu filtern, den Sie gerade abgerufen haben. Das sollte den eingehenden und ausgehenden Verkehr Ihres Prozesses isolieren.

OpenNingia
quelle
6
Für eine einfache Verbindung ist dies möglich, aber ich muss DNS, HTTP usw. nachverfolgen, die alle vorbei sind, sodass es netstatauf einem ausgelasteten Computer keine einfache Möglichkeit gibt, einfach Netzwerkerfassungsfilter zu verwenden.
Kees Cook
OK, öffentliche HTTP- und DNS-Ports werden von vielen Anwendungen verwendet, aber der entsprechende private Port ist eindeutig. Warum filtern Sie nicht nach dem privaten Port?
OpenNingia
Weil schnelle kleine Anfragen von nicht gesehen werden netstat; Ich werde nur langlebige Verbindungen knüpfen können. :(
Kees Cook
was ist, wenn der Prozess dynamische Ports zur Laufzeit verwendet, dann verwendet , um Sie gehen zu können , nicht statische Portfilter
Der Unix Janitor
Ich denke, Sie haben hier die beste Antwort ... Leider arbeitet ein Netzwerk-Sniffing-Tool auf der untersten Ebene des Netzstapels und versucht, alles abzufangen. Es weiß überhaupt nicht, welche Prozesse auf dem Betriebssystem ausgeführt werden. Es wäre äußerst schwierig herauszufinden, woher ein bestimmter Anruf stammt. Ein Paket-Sniffer könnte eventuell (über die Portnummer) eine Prozess-ID ermitteln, kann jedoch nicht herausfinden, welcher Prozess eine DNS-Suche durchgeführt hat, da dies völlig unabhängig ist (dies ist höchstwahrscheinlich der Kernel-Netzstapel, der den Aufruf ausgelöst hat). Wenn Sie jedoch andere Prozesse filtern und stoppen, sollten Sie in der Lage sein, Ihr Ziel zu erreichen.
Huygens
135

So starten und überwachen Sie einen neuen Prozess:

strace -f -e trace=network -s 10000 PROCESS ARGUMENTS

So überwachen Sie einen vorhandenen Prozess mit einer bekannten PID:

strace -p $PID -f -e trace=network -s 10000
  • -f ist für "folge neuen Prozessen"
  • -e definiert einen Filter
  • -s Setzt das Limit von Strings auf mehr als 32
  • -p Nimmt die Prozess-ID, an die angefügt werden soll
Clausi
quelle
2
Dies ist nützlich, da es ohne Root-Zugriff oder spezielle Berechtigungen verwendet werden kann (auf manchen Linux-Distributionen jedoch - unter Ubuntu benötigen Sie möglicherweise spezielle Berechtigungen).
Robin Green
1
Dies ist auch nützlich, da es für einen bereits gestarteten Prozess ausgeführt werden kann und auf praktisch jeder Linux-Box verfügbar ist.
Zakmck
53

Ich weiß, dass dieser Thread ein bisschen alt ist, aber ich denke, das könnte einigen von Ihnen helfen:

Wenn Ihr Kernel dies zulässt, können Sie den Netzwerkverkehr eines einzelnen Prozesses sehr einfach erfassen, indem Sie den Prozess in einem isolierten Netzwerk-Namespace ausführen und im Namespace auch Wireshark (oder andere Standard-Netzwerk-Tools) verwenden.

Das Setup mag etwas komplex erscheinen, aber wenn Sie es erst einmal verstanden haben und sich damit vertraut gemacht haben, wird es Ihnen die Arbeit erheblich erleichtern.

Um dies zu tun:

  • Erstellen Sie einen Testnetzwerk-Namespace:

    ip netns add test
    
  • Erstellen Sie ein Paar virtueller Netzwerkschnittstellen (veth-a und veth-b):

    ip link add veth-a type veth peer name veth-b
    
  • Ändern Sie den aktiven Namespace der Veth-A-Schnittstelle:

    ip link set veth-a netns test
    
  • Konfigurieren Sie die IP-Adressen der virtuellen Schnittstellen:

    ip netns exec test ifconfig veth-a up 192.168.163.1 netmask 255.255.255.0
    ifconfig veth-b up 192.168.163.254 netmask 255.255.255.0
    
  • Konfigurieren Sie das Routing im Testnamespace:

    ip netns exec test route add default gw 192.168.163.254 dev veth-a
    
  • Aktivieren Sie ip_forward und richten Sie eine NAT-Regel ein, um den vom erstellten Namespace eingehenden Datenverkehr weiterzuleiten (Sie müssen die Netzwerkschnittstelle und die SNAT-IP-Adresse anpassen):

    echo 1 > /proc/sys/net/ipv4/ip_forward
    iptables -t nat -A POSTROUTING -s 192.168.163.0/24 -o <your internet interface, e.g. eth0> -j SNAT --to-source <your ip address>
    

    (Sie können auch die MASQUERADE-Regel verwenden, wenn Sie es vorziehen)

  • Schließlich können Sie den zu analysierenden Prozess im neuen Namespace ausführen und auch wireshark:

    ip netns exec test thebinarytotest
    ip netns exec test wireshark
    

    Sie müssen die veth-a-Schnittstelle überwachen.

felahdab
quelle
4
Tolle Idee, aber Vorsicht vor den "Einschränkungen". Da dies ein separater Namespace ist, können Sie nicht mit lokalen Prozessen im Standardnamespace über die Loopback-Adresse (n) oder UNIX-Domain-Sockets kommunizieren. Letzteres wirkt sich auf die Kommunikation über D-Bus aus.
Lekensteyn
@Lekensteyn Sie können weiterhin Unix-Domain-Sockets für alle Netzwerk-Namespaces verwenden. Das Dateisystem wird von ihnen nicht isoliert.
Randunel
1
@randunel Ich hätte genauer darauf eingehen sollen. Ich wollte damit sagen, dass Unix-Domain-Sockets im "abstrakten Socket-Namespace" (der das Dateisystem nicht verwendet) nicht direkt zwischen Netzwerk-Namespaces zugegriffen werden können. Um dieses Problem zu umgehen, können Sie einen Proxy verwenden, zsocat .
Lekensteyn
Welche IP-Adresse verwenden Sie mit dem --to-sourceArgument an iptables? Ist dies die IP-Adresse der Schnittstelle, die Sie an die -oOption übergeben, eine von Ihnen erstellte IP-Adresse oder ??? Ich habe die Maskerade-Version ausprobiert, die nicht benötigt wird --to-source, wie hier beschrieben , und das hat funktioniert!
NTC2
3
All dies scheint Root-Zugriff zu erfordern.
SimpleGamer
15
netstat -taucp | grep <pid or process name>

Hier werden die Verbindungen angezeigt, die eine Anwendung herstellt, einschließlich des verwendeten Ports.

Oli
quelle
8
Dies würde Verbindungen anzeigen, die für diesen Moment bestehen, aber es wird kein Protokoll des Verkehrs selbst bereitgestellt.
Kees Cook
1
Ich bin mir nicht sicher über den Kommentar von Kees Cook. Ein einfacher netstat zeigt für einen Moment Informationen über Verbindungen an, aber mit dem Flag -c erhalten Sie jede Sekunde einen Schnappschuss dieses Status (siehe 'man netstat'). Möglicherweise ist nicht der gesamte Datenverkehr vorhanden, es handelt sich jedoch nicht um eine eindeutige Momentaufnahme der Verbindungen.
tremendows
3
Ich bin mir sicher. Dadurch wird nicht der gesamte Netzwerkverkehr eines Prozesses erfasst.
Reinier Post
Dies war hilfreich, um herauszufinden, welche Portnummer von einer internen Firewall blockiert wurde. Es wurden die TCP-SYNs (zusammen mit der Zieladresse und der Portnummer) angezeigt, die von dem Befehl gesendet wurden, den ich ausgeführt habe.
Anthony Geoghegan
11

Nur eine Idee: Ist es möglich, Ihre Anwendung an eine andere IP-Adresse zu binden? In diesem Fall können Sie die üblichen Verdächtigen ( tcpdump usw.) verwenden.

Tools für Anwendungen, die nicht an eine andere IP-Adresse gebunden werden können:

http://freshmeat.net/projects/fixsrcip

fixsrcipist ein Tool zum Binden von ausgehenden TCP- und UDP-Client-Sockets ( IPv4 ) an bestimmte Quell-IP-Adressen auf mehrfach vernetzten Hosts

http://freshmeat.net/projects/force_bind

force_bindErmöglicht es Ihnen, das Binden einer bestimmten IP und / oder eines bestimmten Ports zu erzwingen. Es funktioniert sowohl mit IPv4 als auch mit IPv6 .

Clausi
quelle
Die meisten Anwendungen unterstützen die Angabe der Quell-IP nicht. Dies ist jedoch möglicherweise möglich, wenn ein Container mit CLONE_NEWNET, jedoch nicht mit CLONE_NEWNS verwendet wird.
Kees Cook
Alternativ können Sie einen Netzwerk-Namespace erstellen und Ihre App darin ausführen. Www.evolware.org/?p=293
Flint,
9

Ich habe ein ähnliches Problem kommen , und ich war in der Lage , es zu klären , basierend auf dieser Antwort von IOError , mit NFLOG wie hier :

# iptables -A OUTPUT -m owner --uid-owner 1000 -j CONNMARK --set-mark 1
# iptables -A INPUT -m connmark --mark 1 -j NFLOG --nflog-group 30 
# iptables -A OUTPUT -m connmark --mark 1 -j NFLOG --nflog-group 30 
# dumpcap -i nflog:30 -w uid-1000.pcap

Dann können Sie den fraglichen Prozess von einem Benutzerkonto aus ausführen, das nichts anderes tut - und voila, Sie haben gerade den Datenverkehr von einem einzelnen Prozess isoliert und erfasst.

Ich wollte nur zurückschicken, falls es jemandem hilft.

szymon
quelle
6

Ich habe eine C-Anwendung geschrieben, die das tut, was in der großartigen Antwort oben von felahdab beschrieben ist!

Siehe hier: nsntrace github repo

Jonas Danielsson
quelle
Das ist cool, aber ich denke, es wäre schön, ein paar Details hinzuzufügen, wie man es bekommt und benutzt :)
Zanna
Vielen Dank! Ich habe einen Link zum Github-Repository bereitgestellt, das eine README.md-Datei mit Verwendungsmöglichkeiten und Beispielen sowie Anweisungen zum Herunterladen enthält.
Jonas Danielsson
5

Dies ist ein schmutziger Hack, aber ich würde entweder eine Umleitung oder ein Protokollziel mit iptables für eine bestimmte UID vorschlagen. z.B:

iptables -t nat -A OUTPUT -p tcp -m owner --uid-owner $USER -m tcp -j LOG 
iptables -t nat -A OUTPUT -p udp -m owner --uid-owner $USER -m udp -j LOG 

Es könnte sich auch lohnen, etwas wie "--log-tcp-sequence", "--log-tcp-options", "--log-ip-options", "--log-uid" für dieses Protokollziel zu untersuchen . Obwohl ich vermute, dass Ihnen das nur dabei helfen wird, einen PCap nachzubearbeiten, der eine Menge anderer Daten enthält.

Das NFLOG-Ziel kann nützlich sein, wenn Sie Pakete kennzeichnen möchten und dann bestimmte markierte Pakete über einen Netlink-Socket an einen Prozess Ihrer Wahl gesendet werden. Ich frage mich, ob das nützlich wäre, um etwas mit wireshark und Ihrer spezifischen Anwendung, die als bestimmter Benutzer ausgeführt wird, zu hacken.

Fehler
quelle
aber das funktioniert nur für ausgehende, was ist mit eingehenden?
Ergebnisse
5

Sie können versuchen, tracedump - http://mutrics.iitis.pl/tracedump

Es macht genau das, was Sie wollen, Sie können ihm entweder eine Prozess-ID geben oder ein Programm ausführen.

pjf
quelle
1
Nettes Projekt, aber ... "Tracedump läuft derzeit nur auf 32-Bit-Linux-Hosts" bringt es leider für mich zum Erliegen.
Gertvdijk
4

Versuchen Sie, den gewünschten Prozess auszuführen :

strace ping www.askubuntu.com

Es gibt Ihnen einige sehr detaillierte Informationen darüber, was Ihr Prozess tut. Da ein Prozess beliebige Ports öffnen kann, können Sie mithilfe eines vordefinierten Filters möglicherweise etwas verpassen.

Ein anderer Ansatz wäre, eine abgespeckte virtuelle Maschine oder eine Testmaschine in Ihrem Netzwerk zu verwenden und Ihren Prozess isoliert darauf abzulegen. Dann können Sie einfach Wireshark verwenden , um alles von dieser Maschine zu fangen. Sie sind sich ziemlich sicher, dass der von Ihnen erfasste Datenverkehr relevant ist.

Der Unix-Hausmeister
quelle
Durch das Hinzufügen eines "-e trace = network" wird ein Teil der Ausgabe reduziert, was den Verlust der tatsächlich in das Netzwerk geschriebenen Daten zur Folge hat. Wenn Ihnen nur die Anzahl der geöffneten Steckdosen oder ähnliches am Herzen liegt, wird dies einfacher.
dannysauer
3

Aufbauend auf der Antwort von ioerror können Sie vermutlichiptables --uid-owner eine Markierung für den Verkehr setzen, und dann können Sie wireshark auffordern, nur den Verkehr mit dieser Markierung zu erfassen. Möglicherweise können Sie einen DSCP-Marker (Differential Services Marker), eine Flow-ID oder einen QOS-Marker verwenden.

Oder Sie können dies verwenden, um diese Pakete über eine andere Schnittstelle zu senden und dann nur auf dieser Schnittstelle zu erfassen.

Poolie
quelle
-1

vielleicht können iptables und ulog funktionieren? Nicht, dass ich ein genaues Rezept hätte, aber ich denke, iptables kann mit Prozessen übereinstimmen. Einmal abgestimmt, könnten Sie ulog verwenden.


quelle
3
Leider iptables -m owner --pid-owner $PIDwurde in Linux 2.6.14 entfernt: ftp.kernel.org/pub/linux/kernel/v2.6/ChangeLog-2.6.14
Kees Cook
-1

Ich denke, Sie können ein Shell-Skript erstellen, um die Ausführung von netstat zu durchlaufen und es in einer Textdatei zu protokollieren. So etwas wie (sehr grobe Schritte):

echo "press q to quit"
while [ <q is not pressed>]
do
    `netstat -taucp | grep <pid or process name> 1>>logfile.txt`
done

Ich bin kein Programmierer, deshalb kann ich das nicht verfeinern. Aber hier kann jemand dort anfangen, wo ich aufgehört habe, und ein funktionierendes Skript für Sie erstellen.

tinhed
quelle
Nicht gut genug. Die Frage ist, den gesamten Netzwerkverkehr zu erfassen , und nicht nur, was gerade aktiv ist, wenn Sie es überprüfen.
Reinier Post