
BPF-basierter Linux-IPC-Tracer für Pipes, Signale, Unix-Sockets, Loopback und Pseudoterminals mit Metadaten- und Inhaltserfassung, Filterung und JSON-Ausgabe.
ipcdump ist ein Werkzeug zur Verfolgung der Interprozesskommunikation (IPC) unter Linux. Es deckt die meisten gängigen IPC-Mechanismen ab – Pipes, Fifos, Signale, Unix-Sockets, Loopback-Netzwerk und Pseudoterminals. Es ist ein nützliches Werkzeug zum Debuggen von Multiprozess-Anwendungen und auch eine einfache Möglichkeit zu verstehen, wie die verschiedenen beweglichen Teile in Ihrem System miteinander kommunizieren. ipcdump kann sowohl die Metadaten als auch die Inhalte dieser Kommunikation verfolgen und eignet sich besonders gut zur Verfolgung von IPC zwischen kurzlebigen Prozessen, was mit traditionellen Debugging-Werkzeugen wie strace oder gdb schwierig sein kann. Es verfügt auch über einige grundlegende Filterfunktionen, die Ihnen helfen, große Mengen von Ereignissen zu durchsuchen. Der Großteil der Informationen, die ipcdump sammelt, stammt aus BPF-Hooks, die an kprobes und Tracepoints an wichtigen Funktionen im Kernel platziert sind, obwohl es auch einige Buchhaltungsdaten aus dem /proc-Dateisystem ergänzt. Zu diesem Zweck nutzt ipcdump stark gobpf, das Go-Bindings für das bcc-Framework bereitstellt.
| Ubuntu 18.04 LTS | Ubuntu 20.04 LTS | |
|---|---|---|
| 4.15.0 | Getestet | Nicht getestet |
| 5.4.0 | Nicht getestet | Getestet |
| 5.8.0 | Nicht getestet | Getestet* |
*Erfordert das Erstellen von bcc aus dem Quellcode
snap install go --classic
oder direkt von der golang-Website
git clone https://github.com/guardicore/IPCDump
cd IPCDump/cmd/ipcdump
go build
./ipcdump -h
Usage of ./ipcdump:
-B uint
max number of bytes to dump per event, or 0 for complete event (may be large). meaningful only if -x is specified.
-D value
filter by destination comm (can be specified more than once)
-L do not output lost event information
-P value
filter by comm (either source or destination, can be specified more than once)
-S value
filter by source comm (can be specified more than once)
-c uint
exit after <count> events
-d value
filter by destination pid (can be specified more than once)
-f string
<text|json> output format (default is text) (default "text")
-p value
filter by pid (either source or destination, can be specified more than once)
-s value
filter by source pid (can be specified more than once)
-t value
filter by type (can be specified more than once).
possible values: a|all k|signal u|unix ud|unix-dgram us|unix-stream t|pty lo|loopback lt|loopback-tcp lu|loopback-udp p|pipe
-x dump IPC bytes where relevant (rather than just event details).
Als root ausführen:
# dump all ipc on the system
./ipcdump
# dump signals sent between any two processes
./ipcdump -t kill
# dump loopback TCP connection metadata to or from pid 1337
./ipcdump -t loopback-tcp -p 1337
# dump unix socket IPC metadata and contents from Xorg
./ipcdump -t unix -x -S Xorg
# dump json-formatted pipe i/o metadata and first 64 bytes of contents
./ipcdump -t pipe -x -B 64 -f json
ipcdump ist aus einer Reihe von Collectoren aufgebaut, von denen jeder für eine bestimmte Art von IPC-Ereignis zuständig ist. Zum Beispiel IPC_EVENT_LOOPBACK_SOCK_UDP oder IPC_EVENT_SIGNAL.
In der Praxis sind alle Collectoren mit BPF-Hooks erstellt, die an kprobes und Tracepoints angebunden sind. Ihre Implementierungen sind jedoch vollständig getrennt – es gibt keinen besonderen Grund anzunehmen, dass unsere Informationen immer von BPF stammen. Allerdings müssen die verschiedenen Collectoren ein einziges BPF-Modul gemeinsam nutzen, da es einige gemeinsame Codeanteile gibt, die sie teilen müssen. Zu diesem Zweck teilen wir uns einen einzigen BpfBuilder (der im Wesentlichen ein Wrapper um die Verkettung von Strings von BCC-Code ist), und jeder Collector registriert seinen eigenen Code bei diesem Builder. Das vollständige BCC-Skript wird dann mit gobpf geladen, und jedes Modul platziert die Hooks, die es benötigt.
Es gibt derzeit zwei Arten der Buchhaltung, die zwischen IPC-Collectoren geteilt werden:
SocketIdentifier (internal/collection/sock_id.go) – bildet zwischen struct sock* des Kernels und den Prozessen, die sie verwenden, ab.CommIdentifier (internal/collection/comm_id.go) – bildet zwischen PID-Nummern und den entsprechenden Prozessnamen (/proc/<pid>/comm) ab.Die Buchhaltung, die in diesen beiden ausgeführt wird, ist besonders wichtig für kurzlebige Prozesse; während diese Informationen später im Benutzermodus durch Parsen von /proc ausgefüllt werden können, ist der relevante Prozess oft verschwunden, wenn das Ereignis den Handler erreicht. Allerdings füllen wir manchmal Informationen aus /proc ein. Dies geschieht hauptsächlich für Prozesse, die bereits vor dem Start von ipcdump existierten; in diesem Fall werden wir keine Ereignisse wie Prozessbenennung abfangen. SocketIdentifier und CommIdentifier versuchen irgendwie, diese Dualität zwischen BCC-Code und /proc-Parsing hinter einer einzigen API zu abstrahieren, obwohl es nicht super sauber ist. Übrigens, in superneuen Versionen von Linux (5.8) können BPF-Iteratoren diese Buchhaltung vollständig ersetzen, obwohl wir aus Gründen der Abwärtskompatibilität vorerst wahrscheinlich beim Hooks-und-procfs-Paradigma bleiben sollten.
Die Ereignisausgabe erfolgt über die gemeinsame Funktion EmitIpcEvent(), die ein Standardereignisformat (Quellprozess, Zielprozess, Metadaten-Schlüssel-Wert-Paare und Inhalt) nimmt und in einem einheitlichen Format ausgibt. Um Ereignisbandbreite zu sparen, geben die Collectoren normalerweise keine IPC-Inhalte aus, wenn das Flag -x nicht angegeben ist. Dies wird mit einer ausgefallenen Vorverarbeitungs-Magie in internal/collection/ipc_bytes.go erreicht.
Bitte tun Sie das! Schauen Sie sich TODO für die wirklich wichtigen Dinge an. Die meiste frühe Arbeit an ipcdump wird wahrscheinlich Anpassungen für verschiedene Kernelversionen und Symbole beinhalten.