Wie finde ich das andere Ende der Unix-Socket-Verbindung?


44

Ich habe einen Prozess (Dbus-Daemon), der viele offene Verbindungen über UNIX-Sockets hat. Eine dieser Verbindungen ist fd # 36:

=$ ps uw -p 23284
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
depesz   23284  0.0  0.0  24680  1772 ?        Ss   15:25   0:00 /bin/dbus-daemon --fork --print-pid 5 --print-address 7 --session

=$ ls -l /proc/23284/fd/36 
lrwx------ 1 depesz depesz 64 2011-03-28 15:32 /proc/23284/fd/36 -> socket:[1013410]

=$ netstat -nxp | grep 1013410
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
unix  3      [ ]         STREAM     CONNECTED     1013410  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD

=$ netstat -nxp | grep dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1013953  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1013825  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1013726  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1013471  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1013410  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1012325  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1012302  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1012289  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1012151  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011957  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011937  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011900  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011775  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011771  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011769  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011766  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011663  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011635  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011627  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011540  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011480  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011349  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011312  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011284  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011250  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011231  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011155  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011061  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011049  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011035  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011013  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1010961  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1010945  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD

Aufgrund der Anzahl der Verbindungen gehe ich davon aus, dass dbus-daemon tatsächlich ein Server ist. Welches ist in Ordnung. Aber wie kann ich herausfinden, welcher Prozess damit verbunden ist - über die Verbindung, die im dbus-launcher als 36. Dateizugriffspunkt angegeben ist? Versuchte lsof und greift sogar nach / proc / net / unix, aber ich kann keinen Weg finden, den Client-Prozess zu finden.


Antworten:


25

Vor kurzem bin ich auf ein ähnliches Problem gestoßen. Ich war schockiert, als ich herausfand, dass es Fälle gibt, in denen dies möglicherweise nicht möglich ist. Ich habe einen Kommentar des Entwicklers von lsof (Vic Abell) ausgegraben, in dem er darauf hinwies, dass dies stark von der Implementierung des Unix-Sockets abhängt. Manchmal sind so genannte "Endpunkt" -Informationen für den Socket verfügbar und manchmal nicht. Leider ist es unter Linux unmöglich, wie er betont.

Unter Linux zum Beispiel, wo lsof / proc / net / unix verwenden muss, haben alle UNIX-Domain-Sockets einen gebundenen Pfad, aber keine Endpunktinformationen. Oft gibt es keinen gebundenen Weg. Das macht es oft unmöglich, den anderen Endpunkt zu bestimmen, ist aber ein Ergebnis der Implementierung des Linux / Proc-Dateisystems.

Wenn Sie sich / proc / net / unix ansehen, können Sie sich selbst davon überzeugen, dass er (zumindest auf meinem System) absolut recht hat. Ich bin immer noch schockiert, weil ich solche Funktionen bei der Verfolgung von Serverproblemen für unerlässlich halte.



Beachten Sie, dass /proc/net/unixSIE die Zieldatei einer zufälligen Domain-Socket-Referenz erhalten, aus der Sie herausgegraben haben /proc/.../fd/.
i336_

26

Diese Antwort gilt nur für Linux. Basierend auf einer Antwort von Unix & Linux Stack Exchange habe ich erfolgreich das andere Ende eines Unix-Domain-Sockets mithilfe von kerninternen Datenstrukturen identifiziert, auf die mit gdbund zugegriffen wurde /proc/kcore. Sie müssen die Kerneloptionen CONFIG_DEBUG_INFOund aktivieren CONFIG_PROC_KCORE.

Mit können lsofSie die Kernel-Adresse des Sockets ermitteln, die die Form eines Zeigers hat, z 0xffff8803e256d9c0. Diese Nummer ist tatsächlich die Adresse der relevanten kernelinternen Speicherstruktur oder des entsprechenden Kerneltyps struct unix_sock. Diese Struktur hat ein Feld, peerdas am anderen Ende der Buchse steht. Also die Befehle

# gdb /usr/src/linux/vmlinux /proc/kcore
(gdb) p ((struct unix_sock*)0xffff8803e256d9c0)->peer

Gibt die Adresse des anderen Endes der Verbindung aus. Sie können die Ausgabe von lsof -Unach dieser Nummer durchsuchen, um die Prozess- und Dateideskriptornummer des anderen Endes zu identifizieren.

Einige Distributionen scheinen Kernel-Debugsymbole als separates Paket bereitzustellen, das den Platz der vmlinuxDatei im obigen Befehl einnehmen würde .


Das sieht interessant aus, aber die Anforderung, den Kernel neu zu kompilieren, scheint ein Overkill zu sein. Ich denke, dass es vielleicht möglich wäre, es ohne handgemachten Kernel und ohne Verwendung von gdb zu tun, indem man einfach Werte in kcore betrachtet und einige "manuelle" Dekodierungen von Werten vornimmt.

3
@depesz, alles was Sie wissen müssen, ist der Offset des peerMembers in der unix_sockStruktur. Auf meinem x86_64-System beträgt dieser Versatz 656 Byte, sodass ich das andere Ende mit ermitteln kann p ((void**)0xffff8803e256d9c0)[0x52]. Das brauchst du CONFIG_PROC_KCOREnatürlich noch.
MvG

11

Tatsächlich kann ssfrom iproute2(Ersatz für netstat, ifconfig usw.) diese Informationen anzeigen.

Das folgende Beispiel zeigt einen ssh-agent-Unix-Domain-Socket, mit dem ein sshProzess verbunden ist:

$ sudo ss -a --unix -p
Netid  State      Recv-Q Send-Q Local                             Address:Port          Peer    Address:Port
u_str  ESTAB      0      0      /tmp/ssh-XxnMh2MdLBxo/agent.27402 651026                *       651642                users:(("ssh-agent",pid=27403,fd=4)
u_str  ESTAB      0      0       *                                651642                *       651026                users:(("ssh",pid=2019,fd=4))

Hmm. Interessant ... Ich hatte verpasst, dass die "Address: Port" -Spalten übereinstimmen können, obwohl die "Peer" -Spalte für Unix-Domain-Sockets völlig unbrauchbar ist.
SamB

9

Unix-Sockets werden normalerweise paarweise und in der Regel fortlaufend nummeriert. Das Paar für Sie wäre also wahrscheinlich 1013410 +/- 1. Sehen Sie, welcher von beiden existiert, und raten Sie dem Täter.


8

Ich habe ein Tool geschrieben, das die gdb-Methode von MvG verwendet, um zuverlässig Socket-Peer-Informationen abzurufen. Kernel-Debugsymbole werden nicht benötigt.

Um den Prozess mit einem bestimmten Socket zu verbinden, übergeben Sie ihm die Inode-Nummer:

# socket_peer 1013410
3703 thunderbird 

Um herauszufinden, ob alle Prozesse gleichzeitig ausgeführt werden netstat_unix, wird der Ausgabe von netstat eine Spalte hinzugefügt:

# netstat_unix
Proto RefCnt Flags       Type       State         I-Node   PID/Program name     Peer PID/Program name  Path
unix  3      [ ]         STREAM     CONNECTED     6825     982/Xorg             1497/compiz            /tmp/.X11-unix/X0
unix  3      [ ]         STREAM     CONNECTED     6824     1497/compiz          982/Xorg                 
unix  3      [ ]         SEQPACKET  CONNECTED     207142   3770/chromium-brows  17783/UMA-Session-R       
unix  3      [ ]         STREAM     CONNECTED     204903   1523/pulseaudio      3703/thunderbird       
unix  3      [ ]         STREAM     CONNECTED     204902   3703/thunderbird     1523/pulseaudio           
unix  3      [ ]         STREAM     CONNECTED     204666   1523/pulseaudio      3703/thunderbird       
...

Probieren Sie es aus, netstat_unix --dumpwenn Sie eine Ausgabe benötigen, die einfach zu analysieren ist.
Weitere Informationen finden Sie unter https://github.com/lemonsqueeze/unix_sockets_peers .

Zur Information, der Inode + 1 / -1 Hack ist nicht zuverlässig. Es funktioniert die meiste Zeit, wird aber versagen oder (schlimmer) die falsche Steckdose zurückgeben, wenn Sie kein Glück haben.


1

Bearbeiten Sie Ihre system.conf

In dieser Datei können Sie weitere Informationen zum Debuggen hinzufügen.

Speicherort: /etc/dbus-1/system.conf

Zum Debuggen können Sie Ihre system.conf bearbeiten, um das Abhören zuzulassen:

  1. Ersetzen Sie den Richtlinienabschnitt durch:

    <policy context="default">

    <!-- Allow everything to be sent -->

    <allow send_destination="*" eavesdrop="true"/>

    <!-- Allow everything to be received -->

    <allow eavesdrop="true"/>

    <!-- Allow anyone to own anything -->

    <allow own="*"/>

    <!-- XXX: Allow all users to connect -->

    <allow user="*"/> </policy>

  2. Entfernen Sie die mitgelieferte Zeile: system.d

    <includedir>system.d</includedir>

Quelle: http://old.nabble.com/dbus-send-error-td29893862.html


Einige andere nützliche Dinge in Bezug auf Unix-Sockets

Der einfachste Weg, um herauszufinden, was auf dem Bus passiert, besteht darin, das dbus-monitorProgramm auszuführen , das mit dem D-Bus-Paket geliefert wird

Sie können auch versuchen, dbus-cleanup-socketsübrig gebliebene Steckdosen zu bereinigen.

Der folgende Befehl zeigt Ihnen, welcher Prozess wie oft an die D-Bus-Buchsen angeschlossen ist, basierend auf der netstatAusgabe:

sudo netstat -nap | grep dbus | grep CONNECTED | awk '{print $8}' | sort | uniq -c

(getestet auf Ubuntu)

Hardcore Weg: Dieser Befehl findet manuell die Prozesse aus / proc und zeigt an, welche die meisten Verbindungen benutzen (alle Arten von Sockets):

ls -lR */fd/* | grep socket | sed -r "s@([0-9{1}]+)/fd/@_\1_@g" | awk -F_ '{print $2}' | uniq -c | sort -n | awk '{print $1" "$2; print system("ps "$2"|tail -n1")}'

Beispielausgabe:

(count, PID und die nächste Zeile enthalten Details zum Prozess)

25 3732
 3732 ?        Ss     0:38 /usr/bin/wineserver
89 1970
 1970 ?        Ss     0:02 //bin/dbus-daemon --fork --print-pid 5 --print-address 7 --session

(getestet auf Ubuntu)

Habe Spaß.


Siehe auch verwandte Artikel für die Referenz:

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.